mirror of
https://github.com/ruvnet/RuView
synced 2026-08-04 19:31:42 +00:00
820258e932
Iter 30. Ships the three ADR-122 §2.6 operator-ready Home Assistant
automation blueprints. Each blueprint binds to one BFLD MQTT entity
(presence / motion / identity_risk) and lets an HA operator import
+ configure without writing YAML by hand.
Added (under v2/crates/cog-ha-matter/blueprints/bfld/):
- presence-lighting.yaml
binary_sensor.<node>_bfld_presence ⇒ light.turn_on / turn_off
with a configurable hold_seconds delay before the off action
(ADR-122 §2.6 requirement: "configurable hold time")
- motion-hvac.yaml
sensor.<node>_bfld_motion ⇒ climate.set_temperature
Operator picks motion_threshold (default 0.3, per ADR §2.6),
delta_temperature_c (°C adjustment), and quiet_seconds debounce
- identity-risk-anomaly.yaml
sensor.<node>_bfld_identity_risk ⇒ notify.<target>
Two trigger paths:
- Absolute spike (raw score >= spike_threshold, default 0.8)
- Rolling 7-day z-score deviation (default 3 sigma)
Requires a Statistics helper entity for the baseline; documented
in the inline description and the blueprints README.
- README.md
Lists the three blueprints + privacy caveat for identity_risk
(only present at PrivacyClass::Anonymous; class 3 deployments
will fail validation by design)
Added (in v2/crates/wifi-densepose-bfld/tests/ha_blueprints.rs):
- 7 named tests using include_str! to embed each YAML at build time
and validate structure without adding a serde_yaml dep:
presence_lighting_blueprint_is_structurally_valid
motion_hvac_blueprint_is_structurally_valid
identity_risk_blueprint_is_structurally_valid
blueprints_carry_source_url_pointing_at_canonical_path
(catches path drift when files move)
presence_blueprint_uses_mqtt_integration_filter
motion_blueprint_uses_mqtt_integration_filter
identity_risk_blueprint_carries_privacy_class_caveat_in_description
(operators running class 3 should know not to install)
- Helper assert_required_blueprint_fields(yaml, name_substring, label)
enforces blueprint.{name,domain,input,trigger,action,mode} per HA spec
ACs progressed:
- ADR-122 §2.6 — all three blueprints shipped with the documented
configurable inputs (hold_seconds for #1, motion_threshold +
delta_temperature_c for #2, z_score_threshold + statistics_entity
for #3). Operator installs via HA UI; no YAML editing required.
- ADR-118 §1.5 privacy_mode visibility — identity-risk blueprint
documents the class-2-only availability so operators understand
why the blueprint fails on class-3 deployments.
Test config:
- cargo test --no-default-features → 72 passed
- cargo test → 210 passed (203 + 7)
Out of scope (next iter target):
- GitHub Actions workflow with mosquitto Docker so iters 24 + 29
e2e tests actually run in CI with BFLD_MQTT_BROKER set.
- cog-ha-matter cargo crate-internal test that loads each blueprint
via serde_yaml + validates against an HA blueprint schema (instead
of the string-only checks here). Optional; current coverage is
sufficient to catch drift in the YAML files themselves.
Co-Authored-By: claude-flow <ruv@ruv.net>
88 lines
2.6 KiB
YAML
88 lines
2.6 KiB
YAML
blueprint:
|
||
name: BFLD Motion-Aware HVAC
|
||
description: >
|
||
Adjust an HVAC climate entity's setpoint when BFLD's normalized motion
|
||
score crosses a threshold, indicating active occupancy. Off-trigger
|
||
restores the original setpoint after a debounce window. Sourced from
|
||
ADR-122 §2.6.
|
||
domain: automation
|
||
source_url: https://github.com/ruvnet/RuView/blob/main/v2/crates/cog-ha-matter/blueprints/bfld/motion-hvac.yaml
|
||
input:
|
||
bfld_motion:
|
||
name: BFLD Motion sensor
|
||
description: The `sensor.<node>_bfld_motion` entity (0.0–1.0 scalar).
|
||
selector:
|
||
entity:
|
||
domain: sensor
|
||
integration: mqtt
|
||
target_climate:
|
||
name: Climate entity to adjust
|
||
selector:
|
||
target:
|
||
entity:
|
||
domain: climate
|
||
motion_threshold:
|
||
name: Motion threshold
|
||
description: Motion-score level above which HVAC is considered "active occupancy".
|
||
default: 0.3
|
||
selector:
|
||
number:
|
||
min: 0.05
|
||
max: 0.95
|
||
step: 0.05
|
||
delta_temperature_c:
|
||
name: Setpoint adjustment (°C)
|
||
description: How much to raise the heating setpoint during active occupancy.
|
||
default: 1.5
|
||
selector:
|
||
number:
|
||
min: 0.5
|
||
max: 5.0
|
||
step: 0.5
|
||
unit_of_measurement: "°C"
|
||
quiet_seconds:
|
||
name: Quiet hold (seconds)
|
||
description: Continuous below-threshold time before restoring the original setpoint.
|
||
default: 600
|
||
selector:
|
||
number:
|
||
min: 60
|
||
max: 7200
|
||
unit_of_measurement: seconds
|
||
|
||
variables:
|
||
motion_threshold: !input motion_threshold
|
||
delta_c: !input delta_temperature_c
|
||
|
||
trigger:
|
||
- platform: numeric_state
|
||
entity_id: !input bfld_motion
|
||
above: !input motion_threshold
|
||
id: occupied
|
||
- platform: numeric_state
|
||
entity_id: !input bfld_motion
|
||
below: !input motion_threshold
|
||
for:
|
||
seconds: !input quiet_seconds
|
||
id: quiet
|
||
|
||
action:
|
||
- choose:
|
||
- conditions:
|
||
- condition: trigger
|
||
id: occupied
|
||
sequence:
|
||
- service: climate.set_temperature
|
||
target: !input target_climate
|
||
data_template:
|
||
temperature: "{{ (state_attr(this.attributes.target.entity_id, 'temperature') | float(20.0)) + delta_c }}"
|
||
- conditions:
|
||
- condition: trigger
|
||
id: quiet
|
||
sequence:
|
||
- service: climate.set_temperature
|
||
target: !input target_climate
|
||
data_template:
|
||
temperature: "{{ (state_attr(this.attributes.target.entity_id, 'temperature') | float(20.0)) - delta_c }}"
|
||
mode: restart
|