mirror of
https://github.com/ruvnet/RuView
synced 2026-08-10 20:31:42 +00:00
f5d787ccde
Per ADR-115 §9.4 (maintainer ACK on #776), v0.7.0 ships **3 starter blueprints**. This commit goes further: all **8** of the catalog proposed in §3.12.2 land as standalone YAML files under `examples/ha-blueprints/`, ready to import into HA. ## Blueprints 1. Notify on possible distress → possible_distress 2. Dim hallway when sleeping → someone_sleeping 3. Wake routine on bed exit → bed_exit (time-window-gated) 4. Alert on elderly inactivity → elderly_inactivity_anomaly (with optional escalation chain) 5. Meeting lights + presence mode → meeting_in_progress (activates a HA scene) 6. Bathroom fan while occupied → bathroom_occupied (privacy-mode-safe; zone-derived) 7. Escalate on fall-risk crossing → fall_risk_elevated (numeric_state trigger) 8. Auto-arm security when not active → group(room_active) + no_movement (composed; multi-room sense) Each blueprint: - Uses HA's blueprint schema (https://www.home-assistant.io/docs/blueprint/schema/) - Declares typed `selector:` for every input (entity-domain-constrained where applicable) - Carries a `source_url` for HACS-style re-import - Includes `mode: single` + `max_exceeded: silent` where appropriate so transient retriggers don't spam - Includes a `cooldown_minutes` / `confirm_minutes` / `ack_timeout_min` parameter where time-debouncing matters ## Validator (`scripts/validate-ha-blueprints.py`) Pure-Python validator that: - Registers no-op constructors for HA's `!input` and `!secret` YAML tags (PyYAML doesn't know them) - Asserts every file has a top-level `blueprint:` mapping with `name`/`description`/`domain` - Asserts `domain` is `automation` or `script` - Asserts at least one declared `input` - Asserts at least one of `trigger`/`action`/`sequence` is present Exits 0 only when all 8 validate. Local run: python scripts/validate-ha-blueprints.py All 8 HA Blueprints validate OK ## CI integration `.github/workflows/mqtt-integration.yml` gains a new `Validate HA Blueprints` step that runs the Python validator before the cargo test phases — fails the workflow on any malformed blueprint in a PR. ## Privacy-mode coverage table 5 of 8 blueprints are unconditionally privacy-mode-safe (no biometric dependency in the state derivation). The other 3 depend on inferred states that themselves derive from biometrics — the inferred state still publishes under `--privacy-mode` (per ADR §3.12.3) but the operator should audit the use case in regulated contexts. Full table in `examples/ha-blueprints/README.md`. Refs #776, PR #778. Co-Authored-By: claude-flow <ruv@ruv.net>
52 lines
1.7 KiB
YAML
52 lines
1.7 KiB
YAML
blueprint:
|
|
name: RuView — notify on possible distress
|
|
description: >
|
|
Send a push notification when RuView's HA-MIND inference layer
|
|
detects sustained elevated heart rate + agitated motion without a
|
|
fall (possible_distress primitive). Includes the explainability
|
|
reason payload so the recipient knows why the alert fired.
|
|
Part of the ADR-115 §3.12 starter blueprint set.
|
|
domain: automation
|
|
source_url: https://github.com/ruvnet/RuView/blob/main/examples/ha-blueprints/01-notify-on-possible-distress.yaml
|
|
input:
|
|
distress_entity:
|
|
name: Possible distress binary_sensor
|
|
description: The `binary_sensor.*_possible_distress` entity published by RuView.
|
|
selector:
|
|
entity:
|
|
domain: binary_sensor
|
|
notify_target:
|
|
name: Notification service
|
|
description: Notify service to call (e.g. `notify.mobile_app_pixel_8`).
|
|
selector:
|
|
text: {}
|
|
cooldown_minutes:
|
|
name: Cooldown (minutes)
|
|
description: Suppress repeat alerts within this window.
|
|
default: 15
|
|
selector:
|
|
number:
|
|
min: 0
|
|
max: 240
|
|
unit_of_measurement: minutes
|
|
|
|
mode: single
|
|
max_exceeded: silent
|
|
|
|
trigger:
|
|
- platform: state
|
|
entity_id: !input distress_entity
|
|
from: "off"
|
|
to: "on"
|
|
|
|
action:
|
|
- service: !input notify_target
|
|
data:
|
|
title: "⚠️ Possible distress detected"
|
|
message: >
|
|
RuView flagged sustained elevated heart rate + agitated motion in
|
|
{{ state_attr(trigger.entity_id, 'friendly_name') or trigger.entity_id }}.
|
|
Reason: {{ state_attr(trigger.entity_id, 'reason') or 'none provided' }}.
|
|
- delay:
|
|
minutes: !input cooldown_minutes
|