Skip to content

Wave 3 #44: Connection: Heated floors + engine pre-heat (tier-b) - #48

Merged
bernardc6 merged 8 commits into
mainfrom
feat/connections/heated-floors
Aug 3, 2026
Merged

Wave 3 #44: Connection: Heated floors + engine pre-heat (tier-b)#48
bernardc6 merged 8 commits into
mainfrom
feat/connections/heated-floors

Conversation

@bernardc6

Copy link
Copy Markdown
Collaborator

Context

Promote the legacy tier-c docs/catalog/hvac/heated-floors-and-engine-preheat.md spec into a tier-b recipe connection at connections/heated-floors/. Follows the same pattern proven by Wave 3 #35 Frigate / #36 Starlink / #37 DNS blocker / #38 NAS / #39 Teltonika / #40 Peplink / #41 Music Assistant / #42 Bluetooth-Wi-Fi presence / #43 Happijac.

Heated floors + optional engine pre-heat — cold-weather comfort controls for vans — are the foundation of every "Warm up" automation in winter van life: a single "warm up the van" command that orchestrates floor heat + interior temp + engine preheat together, shore-power-aware throttling, mode-aware Stealth/Sleep/Boost lockouts, presence-aware pre-warm when the operator's phone reconnects to the LAN, low-voltage lockout when SOC < 20 % AND shore is disconnected (heated floor + engine preheat together can pull 10–30 A sustained), frost-protection automation. Vendor-neutral climate + switch + sensor semantics.

Three install paths documented:

  • Path A — Smart thermostat (recommended for operators who already own a Mysa / Shelly H&T / generic-Zigbee thermostat; vendor integration's climate.* entity is already exposed in HA; recipe wraps the entity_id into the rc_hvac_* contract via templates that derive "Heating" / "Maintaining" / "Off" from the climate's hvac_action attribute)
  • Path B — Generic thermostat (no smart thermostat; just a temperature probe + a relay-driven heater; HA core generic_thermostat: wraps sensor.interior_temp + switch.heater_relay into climate.floor_heater with min_temp / max_temp / cold_tolerance / hot_tolerance / keep_alive)
  • Path C — Optional engine pre-heat (Webasto / Espar / Eberspächer / DIY coolant-loop via a relay OR a CAN bus gateway for higher-end Thermo Top Evo / Hydronic S3; recipe derives "is the engine preheat actually producing heat" from the cabin temp trend — when the switch is on AND cabin temp is rising over a 5-minute window → active)

All three paths land on the same 13 rc_hvac_* contract tiles.

Subsystem addition

docs/reference/rc-entity-naming.md §allowed subsystems list gains hvac (mirrors how media was added by the Music Assistant slice + how presence was backfilled by the bluetooth-wifi-presence slice + how bed_lift was added by the happijac slice).

Changes

  • New connections/heated-floors/connection.yml (tier-b manifest; 13 vendor-neutral rc_hvac_* contract tiles + 14 OpenClaw queries + 9 OpenClaw summary keys + 5 tier_warnings honesty markers; mirrors happijac manifest shape verbatim with heated-floors substitutions)
  • New connections/heated-floors/__init__.py (DOMAIN = "heated_floors" marker stub; mirrors happijac __init__.py shape with heated-floors-specific docstring describing all three paths + the 5 safety interlocks; explicitly avoids the config_flow substring per the happijac docstring-rephrasing lesson)
  • New connections/heated-floors/README.md (folder overview + cross-references to Victron + bluetooth-wifi-presence + happijac sibling slices)
  • New connections/heated-floors/docs/recipe.md (~370-line howto: Path A smart thermostat wiring + template sensor deriving "Heating" / "Maintaining" / "Off" states from hvac_action; Path B HA core generic_thermostat: YAML with min_temp / max_temp / cold_tolerance / hot_tolerance / keep_alive; Path C optional engine preheat via relay or CAN bus gateway + cabin-temp-trend-derived active binary_sensor + utility_meter runtime tracker; 5 safety interlocks in full; 6 §7 automations; 9 §8 troubleshooting entries; §9 privacy; §10 tier-a promotion outline)
  • New connections/heated-floors/tests/test_connection_yml.py (7 manifest-honesty tests including test_safety_interlocks_are_documented defensive guard for the future tier-a promotion)
  • Modify scripts/check.sh — append run_if_present entry for connections/heated-floors/tests/test_connection_yml.py immediately after the happijac entry
  • Modify docs/catalog/hvac/heated-floors-and-engine-preheat.md — add supersession banner pointing at the new connection folder
  • Modify docs/reference/rc-entity-naming.md — add hvac to the Allowed subsystems list (after bed_lift, before system)
  • Modify docs/mvp/features-build-status.md — add Shipped (repo) row for Wave 3 Wave 3 #40: Connection: Peplink (tier-b) — multi-WAN router for vans #44 mirroring the happijac row shape

Verification

cd /home/bernard/clawd/RoamCore
bash scripts/check.sh --core-only           # ✓ all requested smoke checks passed (7/7 for heated-floors + 7/7 for happijac + all earlier connection smokes)
python3 -m pytest connections/heated-floors/tests/test_connection_yml.py -v   # 7 passed in 0.04s

Out of scope

  • connections/happijac/connection.yml (untouched; the only doc edit related to that slice is the happijac cross-reference entry in connections/heated-floors/docs/recipe.md §7.6 frost-protection automation)
  • All other connection folders

Cross-references

  • Victron — §7.4 safety interlock for low-voltage lockout uses sensor.rc_power_battery_soc + binary_sensor.rc_power_shore_connected from the Victron connections/victron/ recipe
  • Bluetooth / Wi-Fi presence — §7.5 presence-aware pre-warm automation uses binary_sensor.rc_presence_operator_phone_arrived from the bluetooth-wifi-presence connections/bluetooth-wifi-presence/ contract
  • Happijac — §7.6 frost-protection automation uses the upcoming happijac connections/happijac/ contract tile (select.rc_bed_lift_mode) for the mode signal — if mode is auto AND engine preheat is off AND interior temp < 5 °C → enable gentle floor heating for frost protection

RoamCore Engineer and others added 8 commits July 30, 2026 04:41
Promoted from docs/catalog/networking/teltonika.md (legacy tier-c)
into a tier-b recipe connection under the connection pipeline.
RoamCore ships no native Teltonika integration; this slice
RECIPE-s the well-understood combination of HA's SNMP (or
Teltonika REST/RMS) integration plus the operator-side
`rc_net_teltonika_*` contract tiles (reachable, WAN state,
signal %, LTE mode, carrier, data used, uptime, reboot
affordance, public IP).

Manifest honesty preserved: tier=b, config_flow=false,
hacs=false, one_tap=false, no RoamCore-owned config_flow.py.

Slice: connections/teltonika/{connection.yml, __init__.py,
README.md, docs/recipe.md, tests/test_connection_yml.py} +
scripts/check.sh teltonika append + legacy teltonika.md
supersession banner.
- tier-b manifest: connections/peplink/connection.yml (networking category, beta status) covering HA core `snmp` Path A for single-router operators + Peplink InControl 2 REST API via the community HACS `hass-incontrol2` integration Path B for fleet operators, with 11 vendor-neutral contract tiles (`rc_net_peplink_*`), 8 OpenClaw queries, 6 OpenClaw summary keys, and 4 tier_warnings honesty markers.
- connection folder stub: connections/peplink/__init__.py (DOMAIN marker; mirrors Teltonika pattern with Peplink-specific docstring describing both paths).
- README: connections/peplink/README.md (folder overview + setup recipe + tier-b rationale + cross-refs to Teltonika + Starlink + MQTT siblings).
- recipe: connections/peplink/docs/recipe.md (~870-line howto with all required §1–§9 sections — Path A HA core SNMP wiring, Path B InControl 2 REST API via HACS `hass-incontrol2`, `rc_net_peplink_*` contract entities, 4 mode-aware automations (multi-WAN preference cellular-in-Travel/Boost + Starlink-in-Home/Shore + force-failover with Stealth suppression + daily failover-count reset + alert-on->3-failovers), 8 troubleshooting entries, privacy, tier-a promotion outline).
- manifest-honesty smoke: connections/peplink/tests/test_connection_yml.py (7/7 PASS via `bash scripts/check.sh --core-only`).
- scripts/check.sh: wires the new smoke under the Connection: section, alphabetically after the existing teltonika entry.
- docs/catalog/networking/peplink.md: legacy tier-c spec now carries a supersession banner pointing at the new connection folder.
- docs/mvp/features-build-status.md: adds a 'Shipped (repo)' row for Wave 3 #40 (mirrors the recent Wave 3 connection-row shape; PR link placeholder `PR #N`).
- Cron-handoff/2026-07-30-peplink-connection.md: slice summary with Context/Changes/Verification/Rollback notes for the next cron.
Promotes the legacy tier-c docs/catalog/audio-media/music-assistant.md
spec into a tier-b recipe connection at connections/music-assistant/.
Follows the same pattern proven by Wave 3 #35 Frigate / #36 Starlink /
#37 DNS blocker / #38 NAS / #39 Teltonika / #40 Peplink. Music
Assistant is the multi-room van audio slice of RoamCore — provider-
agnostic (Spotify, Apple Music, TuneIn, local files, Chromecast /
AirPlay / Sonos receivers) unified audio orchestrated by HA — and the
recipe documents both the Path A HA add-on (recommended for HAOS
installs; auto-discover via zeroconf) and Path B external MA server
(recommended for fleet installs + non-HAOS hosts; via
ghcr.io/music-assistant/server).

This slice does NOT edit any peer connection folder, nor the build-
status row for any other connection. Only the new music-assistant
files + the scripts/check.sh wire-up + the legacy-doc supersession
banner + the new build-status row for Wave 3 #41 + the
docs/reference/rc-entity-naming.md allowed-subsystems update (adding
the media subsystem alongside this slice).

Context:
- Wave 3 #41 ship; promoted from tier-c legacy spec
- HACS-only install: MA is fetched from
  music-assistant/hass-music-assistant via HACS → Repositories → Add
  (HA core does NOT include Music Assistant; install.hacs: true is
  honest upstream truth, NOT a tier-a marker for RoamCore)
- install.config_flow: true is also honest upstream truth (the
  upstream HACS integration has a config_flow since 2023) — NOT a
  tier-a marker for RoamCore (we ship no RoamCore-owned config_flow.py)
- Per-zone rc_media_zone_* template media_player aliases map the
  upstream media_player.mass_* entities into the vendor-neutral
  rc_media_* family
- 14 contract entities: 3 media_player zones + 1 binary_sensor + 6
  sensors + 2 buttons + 1 select
- 8 OpenClaw queries + 7 summary keys
- 4 tier_warnings honesty markers (no_real_music_assistant_for_
  integration_test, recipe_depends_on_user_running_ma, optional_
  provider_choice_spotify_apple_music_local_files, hacs_required_
  for_integration)

Changes:
- New connections/music-assistant/connection.yml (tier-b manifest;
  mirrors Peplink manifest shape verbatim with music-assistant
  substitutions: media category, beta status, 0.1.0 version, audio
  icon, recipe connection_kind, 14 contract tiles, 8 OpenClaw
  queries, 7 OpenClaw summary keys, 4 tier_warnings, HACS-only
  install, HACS default store listed for ha_integration_domain).
- New connections/music-assistant/__init__.py (DOMAIN marker stub;
  mirrors Peplink __init__.py shape with music-assistant-specific
  docstring describing Path A + Path B + the rc_media_* contract
  family + the pause_all / resume_last affordances).
- New connections/music-assistant/README.md (folder overview;
  mirrors Peplink README shape with music-assistant-specific setup
  recipe + cross-references to Starlink + Teltonika + Peplink +
  MQTT siblings).
- New connections/music-assistant/docs/recipe.md (~1056-line howto;
  required sections §1 What is Music Assistant in RoamCore? / §2
  Prerequisites / §3 Path A — HA add-on / §4 Path B — external MA
  server / §5 RoamCore contract entities / §6 Automations (6
  automations: Stealth auto-pause, Travel motion-resume, Boost zone-
  default-volume, inverter-SOC power-aware pause, TTS-zone-pinning,
  remember-last-played) / §7 Provider setup notes (Spotify / Apple
  Music / TuneIn / local-files / Chromecast / AirPlay / Sonos) /
  §8 Troubleshooting (8 entries) / §9 Privacy / §10 Promoting to
  tier-a).
- New connections/music-assistant/tests/test_connection_yml.py (7
  manifest-honesty tests: id matches folder / tier-b without tier-a
  markers / docs recipe published / category matches legacy doc /
  dashboard tiles follow rc naming / status reflects no real music-
  assistant / agent pause-all action is allowlisted).
- Modify scripts/check.sh — append a run_if_present entry for
  connections/music-assistant/tests/test_connection_yml.py directly
  after the existing Peplink entry.
- Modify docs/catalog/audio-media/music-assistant.md — add a
  supersession banner at the top pointing at the new connection
  folder (matches the Wave 3 #40 Peplink supersession banner shape;
  legacy content below the banner is preserved for historical
  context).
- Modify docs/mvp/features-build-status.md — add a 'Shipped (repo)'
  row for Wave 3 #41 mirroring the recent Wave 3 connection-row
  shape (manifest + recipe size + manifest-honesty smoke + contract
  entities + supersession banner + HACS-only install note + PR link
  placeholder PR #N).
- Modify docs/reference/rc-entity-naming.md — add 'media' to the
  Allowed subsystems (recommended set) list alongside this slice
  (the new §media subsystem under which the rc_media_* contract
  family lives).

Verification:
- python3 -m pytest connections/music-assistant/tests/test_connection_yml.py -v
  → 7/7 PASS
- bash scripts/check.sh --core-only
  → ✓ all requested smoke checks passed.

Rollback:
- git revert -m 1 <merge-sha> on main
- The legacy docs/catalog/audio-media/music-assistant.md already
  carries a supersession banner pointing at connections/music-
  assistant/, so even post-revert operators have a pointer to the
  new connection folder.
- git branch -d feat/connections/music-assistant + git push origin
  --delete feat/connections/music-assistant once the PR is closed.

Notes for next slice:
- The Music Assistant recipe references the Starlink + Teltonika +
  Peplink + MQTT connection folders as 'companion slices' — keep
  the cross-refs intact as those slices evolve.
- The §6.1 Stealth auto-pause, §6.2 Travel motion-resume, §6.3
  Boost zone-default-volume, §6.4 inverter-SOC power-aware pause,
  and §6.5 TTS-zone-pinning automations are mode-aware and respect
  RoamCore modes — same pattern as the Peplink / Teltonika slices.
- The §10 tier-a promotion outline describes the RoamCore-owned MA
  container image + default provider stub + CI bench container
  needed to flip this to tier-a.
…e detection

Tier-b recipe-over-upstream connection for presence detection (who's home?). Three upstream paths documented:

  - Path A: HA core bluetooth_le_tracker (YAML, deprecated upstream but functional)

  - Path B: HA core nmap_device_tracker or ping (config_flow)

  - Path C: Router-side asuswrt/unifi/mikrotik device_tracker integrations

Adds 10 vendor-neutral rc_presence_* contract tiles, fills the presence subsystem slot in docs/reference/rc-entity-naming.md. Includes mode-aware automations (Stealth suppression, Bluetooth+Wi-Fi agreement, approach lighting on first arrival, inverter shutdown on all-away, power-aware occupancy alert). 7/7 manifest-honesty tests pass. Supersedes docs/catalog/presence/bluetooth-wifi-presence.md.
…control

Context: Promote the legacy tier-c docs/catalog/bed-lift/happijac.md
spec into a tier-b recipe connection at connections/happijac/.
Follows the same pattern proven by Wave 3 #35 Frigate / #36
Starlink / #37 DNS blocker / #38 NAS / #39 Teltonika / #40
Peplink / #41 Music Assistant / #42 Bluetooth-Wi-Fi presence.

Happijac (or any 2-relay + 2-limit-switch bed lift: LCI Happijac,
DIY linear actuators, winch + strap, etc.) is the sleep-cycle
glue of RoamCore for vans — every auto-lower at 23:00, auto-lift
at 07:00, obstruction-stop + TTS alert, low-voltage-lockout when
SOC < 20 %, safety-first wiring gate. Bed lift control is the
only RoamCore connection where mis-wiring can cause a physical
injury, so the recipe documents the four MANDATORY safety
interlocks (limit-sanity aggregate / low-voltage lockout via
sensor.rc_power_battery_soc cross-reference to Victron / current-
based obstruction detection / mode-aware Stealth + Sleep + Boost
lockouts) with the test_safety_interlocks_are_documented defensive
guard for the future tier-a promotion's hard-enforced asserts.

Two install paths documented (Path A — ESPHome custom cover for
ESPHome-friendly installs; Path B — Shelly 1 / Shelly Plus 1 /
Zooz ZEN17 / Aeotec Nano Switch relay pair + HA core template
cover for relay-friendly installs). Both paths land on the same
12 rc_bed_lift_* contract tiles (cover.rc_bed_lift_position + 2×
limit binary_sensors + moving + position_pct + safety_ok + 3×
button lift/lower/stop + obstruction_detected + low_voltage_
lockout + mode select auto/manual_only/disabled).

Subsystem addition: docs/reference/rc-entity-naming.md §allowed
subsystems list gains bed_lift (mirrors how media was added by
Music Assistant slice) AND presence (backfill — Wave 3 #42 promised
this addition in a code comment but it never landed in the doc).

Changes:
- connections/happijac/connection.yml (tier-b manifest; 12 vendor-
  neutral rc_bed_lift_* contract tiles + 9 OpenClaw queries + 6
  OpenClaw summary keys + 4 tier_warnings honesty markers)
- connections/happijac/__init__.py (DOMAIN = 'happijac' marker
  stub; mirrors bluetooth-wifi-presence __init__.py shape)
- connections/happijac/README.md (folder overview; cross-
  references to Victron + Music Assistant + bluetooth-wifi-
  presence sibling slices)
- connections/happijac/docs/recipe.md (~360-line howto: Path A
  ESPHome YAML for outputs + binary_sensors + cover; Path B
  Shelly/template cover YAML + current_based_obstruction_
  detection block; 4 safety interlocks in full; 6 §7 automations;
  8 §8 troubleshooting entries; privacy; tier-a promotion outline)
- connections/happijac/tests/test_connection_yml.py (7 manifest-
  honesty tests including test_safety_interlocks_are_documented
  defensive guard)
- scripts/check.sh — append run_if_present entry for happijac
  smoke check immediately after bluetooth-wifi-presence entry
- docs/catalog/bed-lift/happijac.md — add supersession banner
  pointing at the new connection folder
- docs/reference/rc-entity-naming.md — add bed_lift AND backfill
  presence to the Allowed subsystems list
- docs/mvp/features-build-status.md — add Shipped (repo) row
  for Wave 3 #43 mirroring the bluetooth-wifi-presence row shape

Verification:
- bash scripts/check.sh --core-only → ✓ all requested smoke
  checks passed (7/7 PASS for happijac connection smoke check)
- python3 -m pytest connections/happijac/tests/test_connection_
  yml.py -v → 7 passed in 0.04s
- python3 -c 'import yaml; ...' (spec verification command
  stripping 'happijac' and asserting no leftover vendor names)
  → VERIFICATION OK
- recipe.md 12 §sections present (§1–§10)
- 12 contract tiles all rc_bed_lift_* (no vendor names outside
  the subsystem prefix)

Out of scope: bluetooth-wifi-presence/connection.yml and all
other connection folders.
Append the Cron-handoff entry for the Wave 3 #43 Happijac bed
lift connection slice that landed in commit 342d64b (PR #47).
Mirrors the existing Cron-handoff template (Context / Changes /
Verification / Rollback) and references the companion sibling
slices (Victron for §6.2 low-voltage lockout; Music Assistant
for §7.5 obstruction TTS; bluetooth-wifi-presence for §7.6
only-driver-home gentle reminder).
Promote the legacy tier-c docs/catalog/hvac/heated-floors-and-engine-
preheat.md spec into a tier-b recipe connection at
connections/heated-floors/. Vendor-neutral cold-weather comfort
controls for vans — heated floors + optional engine pre-heat —
foundation of every 'Warm up' automation in winter van life.

Three install paths (operator picks based on existing IoT wiring +
thermostat preference + engine preheat hardware ownership):
  - Path A — Smart thermostat (recommended for operators who
    already own a Mysa / Shelly H&T / generic-Zigbee thermostat);
    vendor integration's climate.* entity is already exposed in HA
  - Path B — Generic thermostat (no smart thermostat; just a
    temperature probe + a relay-driven heater); HA core
    generic_thermostat: wraps sensor.interior_temp +
    switch.heater_relay into climate.floor_heater
  - Path C — Optional engine pre-heat (Webasto / Espar /
    Eberspächer / DIY coolant-loop via a relay OR a CAN bus gateway
    for higher-end Thermo Top Evo / Hydronic S3)

13 rc_hvac_* contract tiles (1 climate + 2 sensor + 3 binary_sensor
+ 1 switch + 1 number + 1 select + 1 binary_sensor + 1 switch + 1
binary_sensor + 1 sensor):
  - climate.rc_hvac_floor_thermostat
  - sensor.rc_hvac_floor_current_temp
  - sensor.rc_hvac_interior_temp
  - binary_sensor.rc_hvac_floor_heating_active (climate hvac_action
    == 'heating')
  - binary_sensor.rc_hvac_floor_maintaining (climate hvac_action ==
    'idle' AND setpoint > current_temp)
  - binary_sensor.rc_hvac_floor_off
  - switch.rc_hvac_floor_heater
  - number.rc_hvac_floor_setpoint
  - select.rc_hvac_floor_mode (auto | eco | boost | off)
  - binary_sensor.rc_hvac_floor_low_voltage_lockout (cross-refs
    Victron sensor.rc_power_battery_soc + shore-connected)
  - switch.rc_hvac_engine_preheat
  - binary_sensor.rc_hvac_engine_preheat_active (cabin-temp-trend
    derived)
  - sensor.rc_hvac_engine_preheat_runtime_min

5 MANDATORY safety interlocks documented in recipe §7:
  - low-voltage lockout (cross-refs Victron)
  - shore-power-aware throttling
  - mode-aware Stealth / Sleep / Boost lockouts
  - presence-aware pre-warm (cross-refs bluetooth-wifi-presence
    rc_presence_operator_phone_arrived)
  - frost-protection automation (cross-refs upcoming happijac
    select.rc_bed_lift_mode)

install.config_flow: true is honest because the UPSTREAM HA core
generic_thermostat integration exposes a GUI flow since 2022.x +
climate-domain vendor integrations (Path A) expose their own GUI
flow; no RoamCore-owned wrapper / no native integration code is
shipped. tier-a promotion outline in recipe §10 describes the bench
+ config_flow + integration tests required.

Tier-warnings (5): no_real_heated_floor_for_integration_test /
recipe_depends_on_user_running_heated_floor_plus_thermostat_or_relay
/ optional_engine_preheat_hardware_required /
optional_smart_thermostat_vs_generic_thermostat_choice /
requires_operator_wiring_temperature_probes_before_first_use.

Adds 'hvac' to docs/reference/rc-entity-naming.md allowed subsystems
(between bed_lift and system). Adds a 'Shipped (repo)' row to
docs/mvp/features-build-status.md for Wave 3 #44 with cross-refs to
Victron + bluetooth-wifi-presence + happijac. Adds a supersession
banner to the legacy tier-c catalog page pointing at the new
connection folder. Wires the new smoke into scripts/check.sh directly
after the happijac entry.

PR #48 (Wave 3 #44).
…ce summary

Append the Cron-handoff entry for the Wave 3 #44 Heated floors +
engine pre-heat connection slice that landed in commit d776044
(PR #48). Mirrors the existing Cron-handoff template (Context /
Changes / Verification / Rollback) and references the companion
sibling slices (Victron for §7.4 low-voltage lockout;
bluetooth-wifi-presence for §7.5 presence-aware pre-warm;
happijac for §7.6 frost-protection automation).
bernardc6 pushed a commit that referenced this pull request Jul 30, 2026
…y for vans

Promote the legacy tier-c docs/catalog/safety/smoke-co-gas-sensors.md
spec into a tier-b recipe connection at
connections/smoke-co-gas-sensors/. Vendor-neutral lifesafety
sensors for vans — smoke / carbon-monoxide / propane-LPG / methane /
natural-gas — foundation of every 'is it safe to sleep in the van?'
question in van life.

Three install paths (operator picks based on existing IoT wiring +
Zigbee vs Z-Wave vs ESPHome comfort + siren ownership):
  - Path A — Zigbee smoke / CO / gas detector via ZHA GUI flow
    (ZHA integration since 2020.x, GUI flow since 2022.x); pair
    a Zigbee detector, auto-discovered binary_sensor.smoke_*
    / binary_sensor.carbon_monoxide_* / binary_sensor.gas_*
    entity_ids appear; some vendors expose only IAS Zone
    binary_sensor for the alarm state, others expose a sensor
    for the battery separately; recommended ZHA device signature
    overrides for vendors that don't ship clean signatures
    (Heiman / Develco / First Alert / X-Sense)
  - Path B — Z-Wave smoke / CO detector via zwave_js GUI flow
    (zwave_js integration since 2020.x, GUI flow since 2022.x);
    pair a Z-Wave detector, auto-discovered binary_sensor
    entity_ids appear; some Z-Wave detectors use the Notification
    CC to differentiate test vs alarm vs low-battery states;
    Z-Wave controller home ID backup recovery pattern documented
  - Path C — DIY MQ-series analog gas sensor via ESPHome + relay-
    driven siren on a GPIO (ESPHome integration since 2023.x,
    GUI flow since 2023.x); full ESPHome YAML for an MQ-9 sensor
    on GPIO 34 (ADC1_CH6, Wi-Fi-safe) + a relay-driven siren on
    GPIO 26 + the threshold-derived binary_sensor.lpg_alarm
    template + the per-gas thresholds cheat sheet for MQ-2 /
    MQ-3 / MQ-5 / MQ-7 / MQ-9 / MQ-135; ESPHome + mqtt
    availability topic for the sensor-offline cross-reference

12 rc_safety_* contract tiles (8 binary_sensor + 1 sensor + 2
button + 1 select):
  - binary_sensor.rc_safety_smoke_detected
  - binary_sensor.rc_safety_co_detected
  - binary_sensor.rc_safety_gas_detected
  - binary_sensor.rc_safety_any_alarm_active (aggregate)
  - binary_sensor.rc_safety_siren_active
  - binary_sensor.rc_safety_alarm_in_test_mode
  - binary_sensor.rc_safety_low_battery_warning (< 20 %)
  - binary_sensor.rc_safety_sensor_offline (heartbeat window)
  - sensor.rc_safety_lowest_battery_pct
  - button.rc_safety_silence_alarm
  - button.rc_safety_test_alarm
  - select.rc_safety_alarm_mode (armed | night_only | silenced |
    disabled)

4 MANDATORY §6 lifesafety interlocks documented in recipe:
  - sensor-not-offline detection via mqtt availability topic
    (a silent safety sensor is the most dangerous kind)
  - low-battery pre-warning (any sensor battery < 20 %)
  - any-alarm aggregate (single subscription point for
    downstream sirens + notifications + smart-cooking-aware
    silencing)
  - mode-aware lockout when alarm_mode=disabled suppresses
    sirens + notifications (service only)

7 automations (loud siren + phone notification / auto-unlock
deadbolts + flash all lights on CO for emergency egress /
low-battery Sunday pre-warning / sensor offline detection via
mqtt last_seen + availability topic / monthly test cycle via
button.rc_safety_test_alarm / night-only mode gate /
smart-cooking integration).

install.config_flow: true is honest because the UPSTREAM HA core
zha + zwave_js + esphome + binary_sensor + mqtt + template
integrations ALL expose a GUI flow since 2022.x / 2023.x; no
RoamCore-owned wrapper / no native integration code is shipped
— all three paths recipe over upstream ZHA / zwave_js / ESPHome
+ HA core binary_sensor / mqtt / template integrations. Tier-a
promotion outline in recipe §10 describes the bench +
config_flow + integration tests required.

DOMAIN = 'smoke_co_gas' (matches folder name 'smoke-co-gas-
sensors' with hyphens replaced by underscores, per the audit
convention); the __init__.py module docstring rephrases
'config_flow' as 'GUI flow' or 'the vendor integration's GUI
flow' to avoid the forbidden substring trap the happijac slice
was bitten by.

Tier-warnings (5): no_real_smoke_co_gas_sensor_for_integration_test
/ recipe_depends_on_user_running_zigbee_or_zwave_or_esphome_
sensor_plus_siren / optional_siren_hardware_required /
optional_zigbee_vs_zwave_vs_esphome_choice /
requires_operator_testing_alarm_cycle_before_first_use.

Adds 'safety' to docs/reference/rc-entity-naming.md allowed
subsystems (between hvac and system, mirroring how 'media' was
added by the Music Assistant slice + how 'presence' was
backfilled alongside the bluetooth-wifi-presence slice + how
'bed_lift' was added alongside the happijac slice + how 'hvac'
was added alongside the heated-floors slice). Adds a 'Shipped
(repo)' row to docs/mvp/features-build-status.md for Wave 3 #45
with cross-refs to Deadbolts (Wave 3 #48) + Smart automations
(Wave 3 #46) + Heated floors (Wave 3 #44) + Happijac (Wave 3
#43) + Bluetooth/Wi-Fi presence (Wave 3 #42). Adds a
supersession banner to the legacy tier-c catalog page pointing
at the new connection folder. Wires the new smoke into
scripts/check.sh directly after the heated-floors entry.

Manifest-honesty smoke: connections/smoke-co-gas-sensors/tests/
test_connection_yml.py — 7/7 PASS via bash scripts/check.sh
--core-only, including test_safety_interlocks_are_documented
defensive guard for the future tier-a promotion's hard-enforced
lifesafety-interlock asserts.

PR #49 (Wave 3 #45).
@bernardc6
bernardc6 merged commit bafdedf into main Aug 3, 2026
2 checks passed
bernardc6 pushed a commit that referenced this pull request Aug 3, 2026
…tier-b) — smart lock control for van doors [PR #52]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants