Wave 3 #41: Connection: Music Assistant (tier-b) — multi-room van audio - #45
Merged
Conversation
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.
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
pushed a commit
that referenced
this pull request
Jul 30, 2026
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 smoke / CO / gas
safety monitoring for vans — the 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 +
detector ownership + analog wiring comfort):
- Path A — Smart detectors (Nest Protect / First Alert Z-Wave /
X-Sense Zigbee / Heiman Z-Wave / Zipato Zigbee); the vendor
integration's binary_sensor.* + sensor.* entities are already
exposed in HA; we wrap them into the rc_safety_* contract tiles
via a template: binary_sensor that aggregates multiple sensors
via is_state(...) or is_state(...) (e.g. one smoke detector in
the bedroom + one in the cab → either triggering lights the
smoke_detected tile)
- Path B — Generic smoke/CO alarms (basic Kidde / First Alert
battery-only alarms do NOT have HA integration). Minimum
safety baseline — local audible alarm only, no contract tiles
wired
- Path C — Propane/LPG detectors (Mopeka / Atemox / GasAlert /
MQ-series via ESPHome). Analog 4-20 mA sensors wired via
Modbus bridge or ESPHome ADC; sensor.gas_ppm derived from
analog voltage
All three paths land on the same 13 rc_safety_* contract tiles
(vendor-neutral per docs/reference/rc-entity-naming.md §safety
subsystem — newly added to the allowed subsystems list alongside
this slice, mirroring how media was added by Music Assistant +
how presence was backfilled alongside bluetooth-wifi-presence +
how bed_lift was added alongside happijac + how hvac was added
alongside heated-floors).
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_automations_are_documented
defensive guard for the future tier-a promotion's hard-enforced
safety-automation asserts.
PR #49 (Wave 3 #45).
This was referenced Jul 30, 2026
bernardc6
pushed a commit
that referenced
this pull request
Aug 3, 2026
…Smoke / CO / gas sensors (tier-b) — lifesafety for vans [PR #49]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wave 3 #41: Connection: Music Assistant (tier-b) — multi-room van audio
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:
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)
upstream HACS integration has a config_flow since 2023) — NOT a
tier-a marker for RoamCore (we ship no RoamCore-owned config_flow.py)
upstream media_player.mass_* entities into the vendor-neutral
rc_media_* family
sensors + 2 buttons + 1 select
integration_test, recipe_depends_on_user_running_ma, optional_
provider_choice_spotify_apple_music_local_files, hacs_required_
for_integration)
Changes:
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).
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).
mirrors Peplink README shape with music-assistant-specific setup
recipe + cross-references to Starlink + Teltonika + Peplink +
MQTT siblings).
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).
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).
connections/music-assistant/tests/test_connection_yml.py directly
after the existing Peplink entry.
supersession banner at the top pointing at the new connection
folder (matches the Wave 3 Wave 3 #36: Connection: Starlink (tier-b) — sleep timer + bring-back-up controls #40 Peplink supersession banner shape;
legacy content below the banner is preserved for historical
context).
row for Wave 3 Wave 3 #37: Connection: DNS blocker (Pi-hole / AdGuard Home, tier-b) — network-wide DNS ad blocker #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).
Allowed subsystems (recommended set) list alongside this slice
(the new §media subsystem under which the rc_media_* contract
family lives).
Verification:
→ 7/7 PASS
→ ✓ all requested smoke checks passed.
Rollback:
carries a supersession banner pointing at connections/music-
assistant/, so even post-revert operators have a pointer to the
new connection folder.
--delete feat/connections/music-assistant once the PR is closed.
Notes for next slice:
Peplink + MQTT connection folders as 'companion slices' — keep
the cross-refs intact as those slices evolve.
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.
container image + default provider stub + CI bench container
needed to flip this to tier-a.