Skip to content

V2 phase1 architecture - #232

Open
GreenGrassBlueOcean wants to merge 1783 commits into
masterfrom
v2-phase1-architecture
Open

GreenGrassBlueOcean wants to merge 1783 commits into
masterfrom
v2-phase1-architecture

Conversation

@GreenGrassBlueOcean

@GreenGrassBlueOcean GreenGrassBlueOcean commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary of Changes in v2 Phase 1 Architecture

This pull request delivers the complete Phase 1 & Phase 2 Architecture Modernization for the OpenWebNet MyHOME integration. It establishes a modern, asynchronous foundation for Legrand & BTicino MyHOME SCS bus systems, achieving full Home Assistant Core ≥ 2026.3 compliance (Python 3.14), Integration Quality Scale 🏆 Platinum tier standards (54/54 rules satisfied/exempt), official OWNd 2.0.0b13 client library integration, zero strict typing errors under mypy --strict, and 100.0% statement test coverage across 5,324 passing automated tests (plus Syrupy snapshot test suites) spanning 1,770 commits and 361 merged sub-pull requests.

The current pre-release is 2.0.0b17 (#855). Everything below is what v2-phase1-architecture contains; the sections right after this one list what is new in 2.0.0b17 (since 2.0.0b16), 2.0.0b16 (since 2.0.0b15), 2.0.0b15 (since 2.0.0b14), and 2.0.0b14 (since 2.0.0b13).


🆕 What's new since 2.0.0b16 (2.0.0b17)

2.0.0b17 merges 61 pull requests since 2.0.0b16 on OWNd 2.0.0b13. The headlines:

Area What changed PRs
Covers (WHO 2) & Calibration Timed covers full run settle on travel_time + 2 s from known positions; 0.5 s early cutoff tolerance recognizes actuator limits arriving just before travel time; configurable min_position_delta (1–5 %, default 2 %); translated stop frames (*2*1000#0*WHERE##) halt timed runs; calibration refuses whole-minute configurator cutoffs (1–10 min); unknown start handling and device class options. #778, #795, #796, #820, #834, #843, #847
Climate & Thermoregulation (WHO 4) Full BTicino 3550 99-zone central unit state hydration, active setpoint management, and diagnostic attributes (Discussion #819); new thermo actuator switch platform (switch) for manual solenoid control (Issue #785); interface routing, actuator guards, humidity poll gate, and pump ghost filtering. #791, #792, #793, #816, #817, #825, #845, #846
Lighting & Dimmers (WHO 1) Fine dimmer preset echo (WHAT 101–199) and autodiscovered dimmers; coarse preset brightness curve alignment; coexistence of lighting actuator and motion detector on the same bus address; Dimension 22 guard form crash fix; bus-truthful state updates and resync coordinator. #771, #777, #781, #828, #849, #851, #852
Gateways, Engine & Protocol Official OWNd 2.0.0b13 pin; Legrand 067292 gateway profile alias (Issue #832); per-firmware startup requests; manual gateway model identification in config flow; resolved flaky multi-gateway dispatcher callbacks; door-entry WHO 6 gateway boundary enforcement. #794, #801, #804, #835, #848, #850, #854
Audio (WHO 16 / 22) F500 FM tuner entities now support band, preset, and frequency controls with live HL4684 trace replay; stored station frequency range checks and Dimension 10 bounds; fixed-feed amplifier volume. #774, #839, #844
Burglar Alarm (WHO 5) HomeKit arm-away read-only mode; integrated live BTicino 3486 central unit alarm trace replay. #841, #842
Binary Sensors & UI Per-entity UI option to invert binary sensor states. #829
Architecture, CI & Traces Over 5,300 automated tests passing with 100% statement coverage; live plant trace fixtures added for F461, HL4684, Legrand 067292, F454, MH200N, and MH201; Home Assistant 2026.11/2026.12 readiness (compat_name, logger compat, deprecation guards). #769, #772, #776, #779, #783, #786, #788, #790, #799, #807, #810, #815, #818, #823, #824, #827, #841, #845, #853

📦 Previous Beta Summaries (2.0.0b16, 2.0.0b15 & 2.0.0b14)

What shipped in 2.0.0b16 (since 2.0.0b15 — 86 PRs on OWNd 2.0.0b11)

2.0.0b16 merges 86 pull requests since 2.0.0b15 on OWNd 2.0.0b11 (including the post-tag HA 2026.11 compatibility and group resync fixes #769, #771, #772). The headlines:

Area What changed PRs
Expose HA to the bus Declarative expose engine projecting Home Assistant entities and the clock onto free SCS addresses: virtual WHO 1 / WHO 2 actuators that physical wall controls can drive (mirroring HA state back to wall LEDs), WHO 4 virtual temperature probes, WHO 18 virtual energy meters, and the WHO 13 bus clock. Custom actions run as Home Assistant scripts. #750, #753
Covers (WHO 2 & WHO 1) & Locks (WHO 6) Motor start-up floor (min_motor_pulse, default 0.4 s, 0 disables) for timed covers and ≥2% minimum step when stationary for advanced covers; plain UP / DOWN (*2*1*WHERE## / *2*2*WHERE##) full runs at 0% and 100%; timed endpoint runs settle at travel_time + 2 s; timed runs end at the actuator's stop status (*2*0*WHERE##) and full-travel keypad runs report the endpoint; Venetian blind slat tilt (slat_tilt, slat_time); impulse garage/gate covers on WHO 1 relays with optional safety approval, native lock platform for WHO 6 door-entry strikes, and doorbell events; cover stop frames overtake queued commands; pluggable CoverKinematicsStrategy hierarchy; warning when advanced: true is set on standard F411 shutters. #508, #667, #679, #691, #694, #702, #707, #708, #739, #755, #760, #762
Climate (WHO 4) Season frames, generic setpoint mode, and central unit season tracking; holiday and vacation program attributes; zone humidity remembered and queried on Dimension 60 at startup; F461 zones polled, AUTO on standalone zones, fan coils per season, season persisted across restarts; hvac_action derived from season when actuator omits heating flag; standalone default follows the plant; F455 10 s command timeouts eliminated; migrated to native_* temperature API. #649, #657, #665, #675, #689, #698, #712, #714, #715, #718, #719, #721, #724, #725
Lighting (WHO 1) 2-digit Area 0 point-to-point addresses 01–09; ON dimmers on a fresh install probed on Dimension 1 for brightness support; timed turn-on migrated to OWNd builders; lights already reported by the startup sweep are not polled again; area and group re-syncs only skip/cancel once every registered member has echoed in the commanded polarity, and group members inherit the group's bus interface (#4#02). #659, #700, #701, #713, #740, #742, #748, #749, #763, #771
Audio (WHO 16 / 22) Tuner frequency, preset, and RDS read from WHO 22 with optional per-frequency pictures; sound source commands and physical wall transport steps; amplifiers no longer woken by Dimension 1 volume status reports (intercom ducking); centralized power-state decision engine; idle decoders can be claimed from a parked group. #651, #662, #670, #683, #695, #696, #723, #726
Scenarios (WHO 17 / 25) WHO 25 Scenario Plus commands and events; WHO 17 scene lifecycle events (myhome_scene_event). #656, #671, #673
Gateways, scheduling & clock Standalone FrameScheduler with per-target ordering and user commands prioritized ahead of status polls; H4684 / LGRH4684 and MH201 WHO 1013 identification; kernel and distribution queries in the diagnostic sweep; HA websession injected into OWNd discovery; myhome.sync_time rejects half-hour time zones with a translated error instead of truncating the offset. #652, #685, #711, #722, #738, #757, #764
Setup, migration & HA 2026.11+ Device settings in myhome.yaml copied into the config entry so they survive if the file is removed; blank-start discovery suppresses phantom entities; ignored_addresses can be cleared in the UI; restored sensors keep native ID regeneration; legacy entity friendly_name preserved as compat_name across HA 2026.11+ registry migration and availability updates; local brand assets bundled in custom_components/myhome/brand. #666, #672, #678, #686, #727, #741, #742, #769, #772
Architecture, Oracle & CI Monolithic config_flow, gateway, and decoder_pool split into focused subpackages; private OWNd access and runtime shims removed; mypy --strict verified against pinned OWNd 2.0.0b11; 4-tier trace-vs-firmware-oracle conformance gate and empty-bus NACK verification; HA deprecation guard in pytest and container smoke tests. #720, #728, #729, #737, #743, #744, #745, #747, #765, #766

What shipped in 2.0.0b15 (since 2.0.0b14 — 41 PRs on OWNd 2.0.0b10)
Area What changed PRs
Device fault repairs & ignored addresses Actuator hardware anomalies surface as self-clearing Home Assistant repair issues (actuator_fault) and withdraw on recovery; ignored_addresses in the Options Flow silences faulty or unwanted devices and their repair issues. #593, #611, #621
Dimmers & lighting Dimmer no-load state (WHAT 19) handled gracefully without dropping light entities; brightness 0% routes to switch_off to avoid gateway firmware NACKs; dimension and motion frames no longer trigger broadcast resync sweeps; blank-start lighting discovery without myhome.yaml. #567, #580, #614, #622, #635
Thermoregulation (WHO 4) Central unit heating/cooling mode commands aligned with libqtdevices; 99-zone central unit polled with plain status request and exempt from Dimension 14 polling / PollHealth; invalid fan speeds outside 0–3 caught as friendly service errors; exact 0.0 °C WHO 4 readings preserved. #569, #590, #591, #630, #636, #641
Burglar alarm (WHO 5) Empty-WHERE system frames routed to the central alarm panel; read-only auxiliary panel mode with AUX arm/disarm guidance; MH202 and H4890 alarm profile and golden trace support. #567, #572, #576, #583, #608, #609, #618, #620
Scenario controls & sensors CEN and CEN+ triggers isolated so they never fire on each other's events; 4-digit physical CEN addresses and wire-address tolerance; event context forwarded for trigger IDs; broadcast WHERE 0 frames ignored by illuminance discovery; dusk curfew blueprint and hardware-coupled sensor guide. #597, #599, #603, #607, #633, #638, #639
Audio & gateways Physical wall button activation auto-joins the active streaming group and syncs source selection; streaming companions are never guessed; passive event session inactivity timeouts disabled on quiet plants; per-profile default command session counts; firmware-discriminated gateway profiles (F453AV); localized connection failure abort reasons with transient retry; reactive availability for CalibrateAllCoversButtonEntity. #568, #573, #574, #575, #581, #586, #589, #592, #605, #606, #623, #625, #640
What shipped in 2.0.0b14 (since 2.0.0b13 — 105 PRs on OWNd 2.0.0b9)
Area What changed PRs
Multiple gateways Several gateways per installation: separate buses, several gateways sharing one SCS bus, and a warm-standby gateway that takes over while the primary is offline. Topology is asked for in the initial config flow, and whole duplicate devices are pruned when a gateway turns out to share a bus. #459, #525, #531
Audio (WHO 16) Streaming companion discovery (DLNA / UPnP / Google Cast) so Music Assistant can stream to decoders whose own integration cannot play a URL; multi-room group handover, additive join, leader hand-over on OFF, groups that survive restarts and the anti-hiss switch-off; F500 / F500N tuner entities; F441M source selection actually works. Live-tested on an MH200 + F441M. #422, #427, #437, #487, #497, #519, #521, #528, #530, #532, #535, #538, #544, #554
Climate (WHO 4) Home+Control dimension 7 zone state; a pump (0#N) or a temperature probe (PZZ, WHERE ≥ 100) is no longer a zone; a running zone's dimension 12 write is its new setpoint; zones that never answer are no longer polled at startup; one WHO 4 WHERE grammar plus a CI guard against raw WHERE reads. #432, #457, #550, #552, #555, #556
Gateways & identity Gateway identity from WHO 1013 diagnostics and shown in the HA device page and diagnostics export; event-listener crash guard on a general *1*0*0##; event session closed on cancel; command workers capped at the profile's session limit; F461, H4890, MyHomeServer1 traces close the WHO 13 / 1013 gaps; myhome.sync_time also writes DIMENSION 0 for MH200N. #420, #423, #444, #446, #450, #455, #484, #522
Scenarios & sensors CEN+ long_press once per hold with long_press_repeat, CEN+ wire-WHERE addresses (Living Now KW8011); centralized shutter buttons as device triggers; F520 energy meter sweep and discovery; one unique ID per temperature probe. #430, #439, #452, #503, #506, #515
Lights & covers Unknown WHAT keeps the last state and no longer overrides a restored one; a general / area / group cover follows its shutters; adaptive-lighting compatibility; phantom alarm zones on MH200 / MH200N purged. #433 (#436), #456, #458, #462, #465, #490
Home Assistant 2026.12 readiness OptionsFlowWithReload, no entry update listener (fixes the options-flow reload race), and a verify_ha_standards.py rule that keeps it that way. #514, #543
Architecture & docs Four-milestone decomposition of __init__, cover, gateway and light (#467, #468, #472, #475, #485); OWNd timezone monkeypatch removed (#482); anti-drift sentinels, per-beta documentation snapshots with Delta Explorer, hardware trace matrix synced to #466 by CI, Crowdin translation pipeline. #463, #464, #483, #486, #495, #504, #507, #511

🏆 Integration Quality Scale & Architectural Modernization

  1. Home Assistant Core ≥ 2026.3 & Platinum Tier Quality Scale:

  2. Deep Modularization & Package Decomposition:

  3. Unified Platform Skeleton (discovery.py), Frame Router (router.py) & Declarative Expose Engine (expose.py) (refactor: one platform skeleton (restore / configure / discover / route) - all nine platforms #329, feat: quality-scale chain (#349, #321, #325, #326, #329) rebuilt on v2-phase1-architecture #363, fix(light): complete FrameRouter migration for MyHOMELightGroup #391, refactor: one WHO 4 WHERE grammar and a CI guard against raw WHERE reads #556, feat(discovery): resolve blank start lighting discovery and suppress polling avalanche (#578) #580, fix(discovery): improve blank-start discovery quality and suppress phantom entities (#681) #686, feat(discovery): reusable sweep poll gate, dimmer capability probe, and legacy YAML migration (#733) #742, feat(expose): add declarative HA-to-SCS bus expose engine and virtual actuator LED sync #750):


🚀 Key Subsystems & Feature Capabilities

  1. Transports, Gateway Profiles, Scheduling & Connection Resilience (Call to Action :: Gateway Traces :: #291 #292, Trace Builders with the 2.0.0b12 version #297, MH201: unexpected error logs with unclear reason #304, [v2-architecture] [F454 Gateway] No heartbeat received in 120 seconds #315, fix(gateway): identify gateways by precedence; gate startup discovery on the profile #345, [BUG] False gateway identity mismatch: confirmed F454 reports WHO=13 device type 200 #370, fix(gateway): treat WHO=13 device type 200 as ambiguous between F454 and MyHomeServer1 #373, Regression of #254: the first command after ~30 s of silence is silently lost (MyHomeServer1) #378, fix(gateway): close idle command sessions before the gateway drops them #381, feat(gateway): generate repair issue for unconfigured timezone (999) #387, feat(repairs): add repair issue for unknown gateway models #388, chore: bump OWNd to 2.0.0b7 for HMAC refactor #394, Spurious ERROR logged on startup discovery when subsystems are not present (*#4*0##, *#16*0##) #406, test(config_flow): prevent unmocked socket connects on reauth and options flow reload #413, fix(yaml): normalize single-digit MAC octets and harden secondary bus key indexing (#408) #414, Fix false gateway identity mismatch (#370) by using WHO=1013 diagnostics #420, Show the gateway's own model data in HA (device page, diagnostics) #423, fix(gateway): close the event session when the listener is cancelled #444, fix(identity): a same-family model with a code of its own is a contradiction #446, fix(gateway): cap command workers at the gateway profile's session limit #450, test(ownd): accept one or two sends for a NACKed status request #451, fix(gateway): a general "all lights off" (*1*0*0##) killed the event listener — entities unavailable until reload #455, Community Call for Real-World Gateway Traces: Help Us Eliminate Hardware Blind Spots! 📡 #466, docs(gateway): reclassify F455 as single-bus Basic Gateway (#466) #471, refactor(gateway): remove obsolete OWNd timezone monkeypatch #482, feat(gateway): reinstate 4890 family with authentic H4890 traces (#466) #484, feat(ci): auto-sync hardware trace matrix to issue #466 and normalize 4890 family naming #486, fix(services): send DIMENSION 0 alongside DIMENSION 22 during sync_time (#520) #522, refactor(repairs): track device faults per gateway and raise them as self-clearing repair issues #593, feat(config-flow): start new gateways at the profile's default command sessions #606, fix(gateway): support firmware-discriminated gateway profiles (OWNd#80) #623, fix(gateway): disable passive event inactivity timeout on quiet plants (#637) #640, feat(gateway): add H4684 and LGRH4684 models to WHO 1013 identification #652, feat(gateway_sessions): prioritize user commands over status polls in command queue (#680) #685, feat(gateway): include kernel and distribution queries in diagnostic sweep (#466, #709) #711, fix(gateway): identify MH201 via empty-WHERE WHO 1013 and include in device type 200 #722, refactor(protocol): eliminate private OWNd access and runtime shims (#736) #737, feat(scheduler): standalone FrameScheduler and per-target worker serialization (#731) #738, fix(config_flow): inject the HA websession into OWNd discovery and correct the OWNd licence #757, fix(services): reject half-hour time zones in sync_time with a translated error #764):

  2. Multiple Gateways, Shared Buses & Warm Standby (Two gateways in one installation? Help us support shared buses (MH200N + MH201, MHS1 + LN4890, …) #453, feat(gateway): multiple gateway and shared bus support (#453) #459, Adding a second gateway discovers the bus before its shared-bus role can be set, leaving cover devices with only unavailable buttons #524, fix(topology): ask for bus topology when adding a gateway, prune whole duplicate devices (#524) #525, fix(tests): eliminate dispatcher/event-bus race in CEN failover tests #529, fix(gateway): align shared-bus evidence window docs with the 10-minute constant #531):

    • Topologies: Standalone (own isolated bus, entities scoped {mac}-{who}-{where}) or Shared (several gateways on one physical bus) with an explicit role per gateway: Primary, Secondary (delegated WHOs), or Warm standby (automatic failover when primary drops > 60 s).
    • Topology at setup (fix(topology): ask for bus topology when adding a gateway, prune whole duplicate devices (#524) #525): When another IP gateway is already configured, a bus_topology step runs before entry creation, recommending roles and delegated WHOs from the gateway models and pruning duplicate devices cleanly.
  3. Lighting Subsystem (WHO=1) & Adaptive Lighting Compatibility ([FEATURE] DALI RGB / RGBW Color Support & Physical Bus Validation #288, DALI DT8 Light Temperature and RGB Support #307, feat(light): per-light feature lock for DALI DT8 fixtures (#288) — on v2-phase1 #364, P7: lighting groups & general sync — declared groups + reactive re-sync for group/general frames #368, feat: implement declared groups as assumed state lights with member inference (#368) #376, feat: debounced resync for group area general frames (#368 PR A) #377, Who= '1' Where ='10' Not available in the latest v2-phase1-architecture #402, fix(light): allow point-to-point WHERE '10' and correct Area 10 to '100' (#402) #403, fix(light): keep the last state when a light reports an unknown WHAT #456, fix(light): an unknown WHAT does not keep a state restored at startup #458, [RFC] Support & Compatibility for Adaptive Lighting (Circadian Lighting) with MyHOME Fixtures #461, feat(light): adaptive lighting compatibility and bus traffic optimization (#461) #462, fix(gateway): skip lighting scope events when is_on is None #465, refactor(light): extract SoftwareFadeEngine and DaliFeatureLock subsystems (Milestone 4) #475, refactor(light): extract SoftwareFadeEngine and DaliFeatureLock subsystems (Milestone 4) #485, fix(light): prevent dimension and motion frames from triggering broadcast resync sweeps (#612) #614, fix(light): handle dimmer no-load state WHAT 19 and promote to dimmable (#619) #622, fix(light): guard brightness 0 against firmware NACK and clamp 1% brightness #635, feat(lighting): migrate timed turn-on commands to OWNd b11 builders #659, fix(light): skip post-discovery poll for lights the startup sweep already reported (#612) #701, feat(light): support 2-digit Area 0 point-to-point addressing (01-09) (#684) #713, feat(resync,light_group): scope group echo cancellation and multi-entity area sweeps (#734) #740, feat(discovery): reusable sweep poll gate, dimmer capability probe, and legacy YAML migration (#733) #742, fix(resync): require all registered area entities to echo before skipping or cancelling area sweep (#746) #749, fix(resync,light_group): inherit group bus interface for members and seed leading group echoes (#734, #740) #771):

  4. Cover Subsystem (WHO=2 & WHO=1), Venetian Slat Tilt & Video Door Entry Locks (WHO=6) (RFC: timed covers, what I measured on a MyHOMEServer1 (latencies, frame order, non-linear position) #302, feat(frontend): bus-monitor trace/sweep workflow, self-describing exports, node test suite #319, feat(cover): travel-time calibration on the bus - calibrate_cover service, buttons, bus-measured runs (backend; card UI in #355) #349, A full open or close writes a stop at the end of the estimated time instead of letting the cover reach its end stop #379, A cover's position advances even when its direction frame never reached the bus #380, fix(cover): avoid artificial stop frames on full runs (#379) #384, fix(cover): abort motion and prevent position advance on undelivered frames (#380) #385, docs(covers): clarify automated travel time calibration sequence #411, docs(covers): the remaining points from the b13 field test #417, fix: cover level 255, per-family CEN triggers, corrected CEN golden frames #430, Mh201 and General cover button behaviour #433, fix(cover): a general / area / group cover follows its shutters (#433) #436, refactor(cover): encapsulate calibration hub, motion math, and isolate multi-gateway state (Milestone 2) #468, feat(device_trigger): add centralized shutter controls to gateway device triggers (#445, #466) #503, feat(cover): implement venetian blind slat tilt inching and clarify dimension 11 shutter level (#492) #508, feat(cover,lock): impulse garage/gate control, multi-factor safety approval, and intercom events #667, feat(cover): enable native broadcast for general covers behind an interface and pace fan-out #679, feat(gateway_sessions): let a cover stop overtake unrelated queued frames (#645) #694, feat(cover): motor start-up floor and full runs at 0/100% (#466) #702, fix(cover): end timed runs on stop status instead of stop write (#705) #707, feat(cover): per-cover motor start-up floor instead of single constant (#704) #708, feat(cover,light): pluggable CoverKinematicsStrategy hierarchy and low-priority fade step routing (#730) #739, fix(cover): confirm end_stop on full-travel bus runs and scope run timeouts #760, fix(cover,docs): warn and guide when F411 standard shutters set advanced: true (#761) #762):

  5. Climate & Thermoregulation Subsystem (WHO=4) ([BUG] Standalone Climate Zones not exposing FAN #303, Climate entity for Zone 1 incorrectly changes to heating when another zone is heating #333, fix(climate): an actuator status is not a second zone (#333) #336, fix(climate): enable fan mode dynamically for climate zones with fancoils (#303) #352, [BUG} Climate entities show 17 °C instead of the active 7 °C antifreeze target #383, fix(climate): preserve active antifreeze target temperature across status sweeps (#383) #386, [BUG] Standalone Climate Zones are not updating hvac_action. #404, fix(climate): resolve hvac_action idle and preserve auto fan mode (#404, #303) #405, [BUG] Climat Zones do not support Fan OFF #410, fix(climate): omit unsupported 'off' from fancoil fan modes (#410) #412, Climate: bus traces wanted to fix how manual, programmed, holiday and vacation modes are shown #429, Pump actuator incorrectly interpreted as zone actuator #431, fix(climate): a pump status (WHERE 0#N) is not zone N (#431) #432, climate: trailing '3' on WHO 4 dimension 12 is read as protection/off, so _target_temperature goes stale #454, feat(climate): follow WHO 4 dimension 7 zone state on Home+Control plants (#429) #457, Climate: a temperature probe (WHERE >= 100) is routed to zone WHERE-100 and can discover a phantom zone #549, fix(climate): a temperature probe is not zone WHERE-100 #550, fix(climate): a dimension 12 mode 3 of a running zone is its new setpoint (#454) #552, perf(climate): stop polling heating zones that never answer #555, refactor: one WHO 4 WHERE grammar and a CI guard against raw WHERE reads #556, fix(heating): exactly-zero WHO 4 readings are 0.0, freezing/probe/zero tests (#566) #569, fix(climate): exempt central units from Dimension 14 status queries and PollHealth (#582) #590, fix(climate): align central unit mode commands and fan mode with OWNd canonical protocol (OWNd#77) #630, fix(climate): poll 99-zone central unit with plain status request (#629) #636, fix(climate): turn OWNd's fan-speed ValueError into a service error (OWNd#77) #641, feat(climate): support WHO 4 season frames and generic setpoint mode (#649) #657, fix(climate): migrate to the native_* temperature API #665, fix(climate): eliminate 10s command session timeouts on F455 and add authentic trace fixture (#674) #675, feat(climate): support WHO 4 holiday plan and vacation program attributes #689, fix(climate): zones follow the plant for the standalone default (#697) #698, feat(climate): remember zone humidity support and query dimension 60 on startup (#710) #712, fix(climate,services): poll F461 zones, AUTO on standalone zones, fan coil per season, refuse WHO 4 dimension 22 (live F461 capture) #714, fix(climate): restore season and fan_coil_sides across restarts and bridge dim 19 is_active (#714) #715, fix(climate): determine hvac_action from season when active actuator carries no heating flag #721, feat(climate): keep the season of a central unit's mode frames (#699) #725):

  6. Audio & Multi-Room Sound System 2.0 (WHO=16 & WHO=22) (#422, #427, #428, #435, #437, #438, #460, #487, #497, #519, #521, #528, #530, #532, #535, #538, #544, #554, #568, #581, #651, #670, #683, #695, #723):

    • Music Assistant Multi-Room Grouping & Wall Button Sync (#460, #521, #528, #530, #532, #535, #538, #544, #554, #581, #723): Additive async_join_players, leader handover on OFF, persistent .storage group/decoder books across restarts, anti-hiss group parking, automatic group join when a room is switched on at its physical wall button (#581), and claiming idle decoders from parked groups (#723).
    • WHO 22 Tuner RDS & Transport Controls (#427, #497, #651, #695): Reads tuner frequency, preset, and RDS from WHO 22 with optional per-frequency station pictures, modernizes sound source commands, and intercepts physical wall transport steps.
    • Centralized Power-State Engine & Intercom Ducking (#670, #683): Dimension 1 volume status reports sent during video intercom streams no longer wake sleeping amplifiers in Home Assistant.
    • Streaming Companion Bridge (decoder_companion.py, #487, #519, #568): Explicit companion matching (dlna_dmr, upnp, cast) without guessing, forwarding play_media while keeping hardware volume, pre-gain, and F441M routing on the matrix slot.
  7. Scenario Controls (WHO=15 CEN, WHO=25 CEN+ / Scenario Plus & WHO=17 Scenes) (#310, #430, #439, #515, #548, #597, #603, #639, #656, #671):

    • CEN & CEN+ Isolation, 4-Digit Addressing & Wire Tolerance (#439, #515, #597, #603, #639): Strict per-family event isolation, 4-digit physical addresses, wire-address tolerance (Living Now KW8011), long_press deduplication with long_press_repeat, and forwarded event context for trigger IDs.
    • WHO 25 Scenario Plus & WHO 17 Scene Events (#656, #671): Full support for WHO 25 Scenario Plus commands/events and WHO 17 scenario programmer lifecycle events (myhome_scene_event).
  8. Sensors, Binary Sensors & Energy Counters (WHO=1, 4, 9, 18, 25) (#244, #245, #247, #308, #441, #452, #494, #506, #607, #633, #661, #678):

    • F520 Energy Meters & Dimension 1200 Lifecycle (#494, #506, #661): Proactive bus sweep and aligned active-power query / Dimension 1200 stream lifecycle across probe addresses 51–59 and 71–79.
    • Temperature Probes, PIR Motion, Illuminance & Dry Contacts: Deterministic probe unique IDs (#452) with exact 0.0 °C handling (#569); WHO 1 PIR (WHAT = 34) and illuminance (DIMENSION = 6) discovery with broadcast WHERE 0 phantom filtering (#607); WHO 25 dry contacts (3477 / F482) with dusk curfew blueprint (#633).
  9. Burglar Alarm Platform (WHO=5) (#311, #470, #490, #576, #608, #609, #618, #620):

    • Read-only central unit (3485/3486) and partition state tracking with empty-WHERE system frame routing (#618), zone 0 broadcast synchronization, AUX arm/disarm support (#609), MH202/H4890 profile support (#576), and MH200/MH200N phantom zone suppression (#490).
  10. Lovelace Bus Monitor Card v2 (<myhome-bus-card>) (#275, #276, #277, #278, #279, #305, #343, #449, #470, #747):

    • In-band circular ring buffer streaming live bus telegrams via WebSocket API with full buffer backfill, JSON/text trace export (#449), REC trace freeze, Sweep Bus workflow (#470), strict WebSocket frame validation (#747), and node:test frontend suite.
  11. Internationalization & Documentation (#415, #463, #464, #483, #495, #507, #511, #513, #577, #687, #768):

    • Crowdin Localization Pipeline & Anti-Drift Sentinels (#463, #464, #483, #495, #507, #577): Automated synchronization and CI verification across PLATFORMS, SUPPORTED_GATEWAY_MODELS, manifest.json SSDP, OWNd profiles, options-flow fields, device triggers, translations, and the firmware oracle (#743).
    • Complete documentation suite under docs/configuration/ and per-beta Delta Explorer (docs/roadmap/beta-differences.md) updated through v2.0.0b16 (#703, #768).
  12. Golden Corpus, Firmware Oracle & CI Verification:

    • 250+ Golden Corpus fixtures (tests/golden/corpus.json) and 4-tier Firmware Oracle Conformance Gate (tests/test_firmware_oracle_conformance.py, #642, #720, #743, #745, #766) validating gateway profiles and real plant traces against empirical firmware verdicts.
    • Production plant fixtures replayed deterministically in CI across MH200, MH200N, MH201, MH202, F453AV, F454, F455, F461, H4890, and MyHomeServer1 (#247, #280, #288, #292, #297, #303, #311, #333, #370, #377, #390, #434, #469, #473, #484, #486, #488, #489, #491, #496, #499, #502, #505, #512, #526, #527, #551, #576, #584, #596, #627, #634, #638, #646, #648, #655, #656, #660, #662, #664, #673, #675, #691, #692, #696, #700, #724, #748, #751, #752, #753, #755, #763).
    • 4,393 automated tests passing with 100.0% statement coverage across all 15,911 statements in 73 integration modules.

Resolved Issues & Merged Pull Requests

Closes #6
Closes #30
Closes #69
Closes #80
Closes #92
Closes #103
Closes #105
Closes #110
Closes #115
Closes #116
Closes #117
Closes #118
Closes #121
Closes #123
Closes #127
Closes #132
Closes #134
Closes #136
Closes #139
Closes #143
Closes #146
Closes #147
Closes #150
Closes #151
Closes #152
Closes #156
Closes #157
Closes #159
Closes #161
Closes #162
Closes #165
Closes #166
Closes #168
Closes #170
Closes #172
Closes #174
Closes #176
Closes #177
Closes #178
Closes #179
Closes #181
Closes #185
Closes #188
Closes #190
Closes #191
Closes #194
Closes #200
Closes #203
Closes #205
Closes #212
Closes #213
Closes #215
Closes #219
Closes #220
Closes #230
Closes #231
Closes #233
Closes #234
Closes #237
Closes #240
Closes #241
Closes #242
Closes #243
Closes #244
Closes #245
Closes #246
Closes #247
Closes #249
Closes #250
Closes #251
Closes #252
Closes #253
Closes #254
Closes #255
Closes #256
Closes #257
Closes #258
Closes #259
Closes #262
Closes #263
Closes #264
Closes #265
Closes #266
Closes #268
Closes #269
Closes #270
Closes #271
Closes #272
Closes #273
Closes #275
Closes #276
Closes #277
Closes #278
Closes #279
Closes #280
Closes #281
Closes #282
Closes #283
Closes #284
Closes #285
Closes #286
Closes #287
Closes #288
Closes #289
Closes #290
Closes #292
Closes #293
Closes #295
Closes #296
Closes #297
Closes #301
Closes #302
Closes #303
Closes #304
Closes #305
Closes #307
Closes #308
Closes #309
Closes #310
Closes #311
Closes #313
Closes #315
Closes #316
Closes #319
Closes #321
Closes #325
Closes #326
Closes #329
Closes #333
Closes #334
Closes #336
Closes #345
Closes #347
Closes #348
Closes #349
Closes #350
Closes #352
Closes #353
Closes #356
Closes #361
Closes #363
Closes #364
Closes #365
Closes #368
Closes #369
Closes #370
Closes #371
Closes #372
Closes #373
Closes #375
Closes #376
Closes #377
Closes #378
Closes #379
Closes #380
Closes #381
Closes #382
Closes #383
Closes #384
Closes #385
Closes #386
Closes #387
Closes #388
Closes #390
Closes #391
Closes #393
Closes #394
Closes #395
Closes #396
Closes #401
Closes #402
Closes #403
Closes #404
Closes #405
Closes #406
Closes #407
Closes #408
Closes #410
Closes #411
Closes #412
Closes #413
Closes #414
Closes #415
Closes #417
Closes #420
Closes #421
Closes #422
Closes #423
Closes #425
Closes #428
Closes #429
Closes #430
Closes #431
Closes #432
Closes #433
Closes #434
Closes #435
Closes #436
Closes #437
Closes #438
Closes #439
Closes #440
Closes #441
Closes #443
Closes #444
Closes #446
Closes #449
Closes #450
Closes #451
Closes #452
Closes #453
Closes #454
Closes #455
Closes #456
Closes #457
Closes #458
Closes #460
Closes #461
Closes #462
Closes #463
Closes #464
Closes #465
Closes #467
Closes #468
Closes #469
Closes #470
Closes #471
Closes #472
Closes #473
Closes #475
Closes #477
Closes #478
Closes #481
Closes #482
Closes #483
Closes #484
Closes #485
Closes #486
Closes #492
Closes #493
Closes #494
Closes #498
Closes #501
Closes #510
Closes #520
Closes #523
Closes #524
Closes #537
Closes #540
Closes #541
Closes #549
Closes #553
Closes #563
Closes #564
Closes #565
Closes #566
Closes #578
Closes #579
Closes #582
Closes #600
Closes #601
Closes #604
Closes #612
Closes #615
Closes #616
Closes #619
Closes #624
Closes #629
Closes #631
Closes #637
Closes #645
Closes #654
Closes #658
Closes #669
Closes #674
Closes #676
Closes #677
Closes #680
Closes #681
Closes #682
Closes #684
Closes #690
Closes #697
Closes #699
Closes #704
Closes #705
Closes #706
Closes #709
Closes #710
Closes #730
Closes #731
Closes #732
Closes #733
Closes #734
Closes #735
Closes #736
Closes #746
Closes #759
Closes #761
Addresses #445
Addresses #466


👥 Credits & Attribution

This integration is developed and maintained by the OpenWebNet-HA community.

Special thanks to:

  • @anotherjulien for creating the original MyHOME integration and laying the protocol foundations.
  • @GreenGrassBlueOcean for the v2 modernized architecture, gateway profiles, streaming proxy, and test suite.
  • @xtimmy86x for crafting the frontend user experience, administration panel, cover calibration interfaces, and hardware diagnostics.
  • @gdluck for outstanding engineering, invaluable ideas, and rigorous physical F461 plant measurements.
  • @TheDarkWizard for crucial CEN+ wire address captures (KW8011), WHO 1001 diagnostics, and tireless real-world hardware testing across Living Now controls and MyHomeServer1 setups.
  • @wave68runner for the authentic HL4684 touchscreen captures, BTicino 3550 thermoregulation sweeps, and tuner diagnostics.
  • @Interstellar0verdrive for deep hardware actuator analysis, cover timing/concurrency mechanics, and platform extensions.
  • @fedem95, @mantovanellimatteo, @lyubomirtraykov, and Cedric Rohou for key bugfixes, platform extensions, and community testing.
  • @GianlucaCh for preserving and contributing the comprehensive 15-manual BTicino/Legrand specification archive (OWN DOC.zip), the official WHO_24.pdf Lighting Management specification, and CEN+ community automation references.
  • @nicolacavallo84 for the iconic 70+ device plant captures and H4890 touchscreen multi-gateway traces that form our foundational CI replay fixtures.
  • All community testers and trace providers whose real-world bus captures keep our test suite grounded in real hardware: "In traces we find the truth" — their traces prove again and again that we can only build reliable stuff when we get authentic user traces: @manfredgittmaier-afk, @eC0y0te, @simo72mast-lab, @lionelser, @caiosweet, @f18m, @marcob79, @xduss, @pakob81, @Depechie, @nce2704, @ricdijk, @imfreddie, @theveninjeremy, and @Yvan13120.

This was referenced Sep 8, 2026
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@anotherjulien

Copy link
Copy Markdown
Member

Finally had time to spin up that VM.
First impression is that what works works 😄
The transition covered everything, also all device names reverted to <device type> <APL>.

What does not work is:

  • Advanced covers seem to be discovered as regular covers, even after seeing position aware OWN frames (I have Legrand 67557 everywhere)
  • Dry contacts (I have a Legrand 3477 coupled with a mechanical lever to monitor if my garage door is open/closed)
  • Lux Meters (I have a Legrand 048834 for motion/light sensing outdoors)
  • The mechanism to lock/unlock APL endpoints (relies with WHO 14, I've used it occasionally but I'm not sure many people do)

With all that's been discussed today, I'm not sure what was supposed to make the cut at this stage though 😅

gdluck and others added 11 commits November 3, 2026 21:01
… (pin-bump decision, D36 / D38 row)

The pin bump closes the `TODO(OWNd>2.0.0b11)` windows: OWNd 2.0.0b13 (OWNd#147)
aliases the SSDP spellings `H/L4684`, `HL4684`, `HC4684` to `H4684Profile` and
derives the H4684's WHO 22 from firmware 6.0.0 inside the profile, so the
`_MODEL_SPELLINGS` fallback in `_profile_for_model` / `_resolved_model` /
`_model_key`, the `_firmware_at_least` WHO 22 shim in `_profile_supports_who`
and the same shim in `topology.gateway_supported_whos` are dead code with the
pinned release and are removed rather than kept. The `"HL4684"` key of
`supports_zone_status` stays: it covers the brand-prefixed `BTicino H/L4684`,
which no OWNd alias resolves and whose alphanumeric form does not contain
`H4684`.

`tests/test_issue_466_hl4684_trace.py` no longer simulates a pre-#147 OWNd
lookup; it asserts the pinned OWNd resolves the three spellings and the
WHO 22 firmware gate itself. No runtime behaviour changes with the pinned
OWNd (453 tests of the touched modules and the full suite with OWNd master
on PYTHONPATH pass).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The profile lookup sits in a try/except Exception that turned a missing
OWNd or gateway symbol into an empty WHO set for every gateway, which
showed up as eighteen unrelated topology, multi-gateway and config-flow
failures in a local merge (lab audit 2026-11-03). A profile lookup error
still degrades to "no WHOs" (logged at debug); an ImportError propagates.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
chore(deps): pin OWNd==2.0.0b13 and close the OWNd#139 / #142 / #147 transition windows
fix(light): ask Dimension 1 after a coarse preset echo on a fine dimmer (#851)
fix(thermo): follow OWNd's dimension 22 crash-form detector instead of blocking every split-control frame
fix(cover): settle a full run at the actuator's own stop up to 0.5 s before the travel time (#770 end-stop follow-up)
chore(release): 2.0.0b17 version bump, release notes, and README/roadmap refresh
docs(release): point b17 release notes feedback link to discussion #856 and link mention
docs: align README with v2.0.0b17 architecture, 5324 tests, and expanded community credits
gdluck and others added 16 commits November 4, 2026 11:11
…ed by @gimprota76)

Adds two verbatim bus exports from a real BTicino F454 (firmware 2.0.51) on
Home Assistant 2026.10.4 / MyHOME 2.0.0b17 / OWNd 2.0.0b13, contributed on
issue #466, and a trace-replay test pinning them:

- myhome_sweep_F454_all_2026-11-04T08-31-02.json (89 frames): a bus sweep whose
  WHO 5 run captures a full 3486 arm/disarm cycle and whose 36 WHO 18 frames
  read the energy totals (51..59) and the 7N#0 Energy Management Actuator
  address (71#0..79#0).
- myhome_sweep_F454_all_2026-11-04T08-33-48.json (82 frames): taken while the
  MyHOME scenario controller fired, adding four WHO 0 scenario frames and
  WHO 1 / WHO 2 point activations with their 1000#M echoes. The companion
  T08-33-52 export is frame-identical (timestamps aside) and not duplicated.

The test asserts SHA-256 provenance, the F454 2.0.51 / b17 capture environment,
that no gateway network identity (WHO 13 dims 10/11/12) is committed, full
OWNd parse coverage with exact per-class frame counts, the WHO 18 totals and
7N#0 actuator address, the alarm deactivation (*5*2*0## decodes as
deactivation, not a silent alarm) and activation frames, the zone states, and
the four scenario-module frames. Assertions are OWNd-version-stable (no
properties that are absent from the pinned release). The Hardware Trace Matrix
in README.md and docs/trace-availability.md is regenerated by
scripts/update_trace_matrix.py.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… export

Adds the reporter's Bus Monitor sweep export from a plant that is a 3488
HOMETOUCH with a MyHomeServer1 gateway (firmware 3.2.5) connected:
tests/fixtures/traces/issue_466/myhome_sweep_MyHomeServer1_all_2026-11-04T09-35-58.json
(verbatim, 200 frames, a buffer window that is entirely WHO 4 thermoregulation,
no IP/MAC), pinned by tests/test_issue_466_myhomeserver1_sweep_2026_11_04_trace.py:
SHA-256 provenance, the MyHomeServer1 3.2.5 / b17 / b13 environment
(identification.source manual, WHO 13 code 200), no committed network identity,
full OWNd parse coverage with exact class counts (192 heating events + 8 reads),
and the climate sweep decodes (actuator state, setpoints, manual mode 4002,
heating season, the central-unit #0 poll, slave-probe dimension 60 reads).
Assertions are OWNd-version-stable on 2.0.0b13 and dev.

The 3488 is not a web server and cannot be the OpenWebNet endpoint; OWNd
connects over IP, port and password to the MyHomeServer1, which every frame
is received from.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…debug log

The plant is a 3488 HOMETOUCH with a MyHomeServer1 gateway connected. The 3488
is not a web server and cannot be the OpenWebNet endpoint; OWNd connects over IP,
port and password to the MyHomeServer1, which every frame is received from. This
commit adds the reporter's complete home-assistant_myhome log of the 2026-11-04
session as tests/fixtures/traces/issue_466/
MyHomeServer1_full_debug_log_2026-11-04T10-30-17.txt (4935 lines, verbatim from
the first custom_components.myhome line; only the gateway address and MAC, and an
unrelated LAN host in two aioshelly error lines, are synthetic: 192.0.2.9,
00:03:50:00:11:04, 192.0.2.26, as for the 2026-09-29 log fixture), with a
provenance README and tests/test_issue_466_myhomeserver1_full_log_2026_11_04_trace.py
(SHA-256, environment, no network identity, 1374 inbound frames with exact class
counts, OWNd-version-stable on 2.0.0b13 and dev).

The log is not a superset of the 09-35-58 Bus Monitor export: that export is a
200-frame buffer window under the MyHomeServer1 profile before DEBUG logging was
on, while every DEBUG frame here (11:47-12:30 local) follows the reporter's
mid-session switch of the entry to the Generic profile. Both are kept.

What the log pins: WHO 13 auto-detection of firmware 3.2.5, device type 200 and
model code 1013-1-128 on the MyHomeServer1; 950 WHO 4 + 349 WHO 1 frames parsing;
29 WHO 8 door-entry frames parsing as OWNIntercomEvent; two undocumented
*#130**1*6*3*2*5## broadcasts falling through to OWNEvent; and the gateway
echoing the dimension write form *#4*Z#N*#20*V## right before the *20* read
form, which MyHOME logs as unsupported and ignores.

Finding for OWNd: the 3488's video door-entry use (12:27-12:30) puts 44 WHO 7
frames on the event session. The 36 event forms with an empty WHERE
(*7*73#1#100*##, *7*300#127#0#0#1#5000#2*##, *7*0*##, *7*219*##, *7*55*##, ...)
return None from OWNMessage.parse on 2.0.0b13, on dev and on the OWNd #162
branch alike, and MyHOME logs each as "Data received is not a message" (45 such
lines). The WHO 7 dimension forms and the two event forms that carry a WHERE
parse. Pinned as-is; not changed here.

Also renames test_issue_466_3488_as_myhomeserver1_sweep_2026_11_04_trace.py to
test_issue_466_myhomeserver1_sweep_2026_11_04_trace.py and rewords it to the
same framing: the 09-35-58 export is from the MyHomeServer1 gateway of this plant.

Note for the maintainer: scripts/update_trace_matrix.py attributes every .txt
fixture to F454 (hard-coded at the .txt branch), so neither this log nor the
2026-09-29 MyHomeServer1 log reaches the MyHomeServer1 row; the table is unchanged
here because that row already has WHO 1 and WHO 4 from the JSON sweeps. Left as is.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd its gateway

docs/trace-availability.md is keyed by the gateway OWNd connects to, so the
3488 HOMETOUCH plant of #466 only shows up as MyHomeServer1 rows. Adds a
"Devices captured behind a gateway" section after the generated matrix (outside
the TRACE_MATRIX markers, so scripts/update_trace_matrix.py leaves it alone)
naming the 3488 HOMETOUCH, the MyHomeServer1 (firmware 3.2.5) it is connected
through, the subsystems seen in its captures (WHO 1, 4, 7, 8) and the two corpus
files. The generated block and README.md are unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the gateway

Renames tests/test_issue_466_myhomeserver1_sweep_2026_11_04_trace.py to
tests/test_issue_466_3488_hometouch_sweep_2026_11_04_trace.py and
tests/test_issue_466_myhomeserver1_full_log_2026_11_04_trace.py to
tests/test_issue_466_3488_hometouch_full_log_2026_11_04_trace.py, and updates
the fixture README that points at them. The plant under test is a 3488
HOMETOUCH with a MyHomeServer1 connected; the gateway stays in the fixture
file names, which are the verbatim export names. No test content changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…'s WHO 7 frames

The Encyclopedia's WHO 7 event frame is *7*WHAT*WHERE*## and it documents an
address-less release form *7*9**## (empty WHERE, trailing star kept), which
OWNd parses. The 3488 HOMETOUCH emits *7*WHAT*## with the WHERE field absent
altogether, one star short, and that is the form OWNd 2.0.0b13, dev and the
#162 branch return None for. Rewords the docstring, the comment and the fixture
README accordingly, renames the test to say "absent", and adds the assertion
that *7*9**## parses so the distinction is proven, not described. No fixture
or count changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, the dimensions are 51 and 1200

The 36 WHO 18 frames are *#18*5N*51## / *#18*5N*1200## for meters 51..59 and
the same reads on the 7N#0 actuators (WHO 18 PDF p.4 WHERE 5N; p.5 DIMENSION 51
energy/unit totalizer, 1200 automatic-update control). The test variable was
named whats while collecting the WHERE field; renamed, the docstring reworded,
and an assertion added that the dimensions read are 51 and 1200. Fixtures unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (released OWNd 2.0.0b13)

Full custom_components.myhome DEBUG log (1134 lines, 107 sent / 169
received) and the 200-frame bus-monitor export after myhome.sweep_bus,
captured from the physical F461 test plant through a local Home
Assistant 2026.10.2 running MyHOME 2.0.0b17 with the released OWNd
2.0.0b13: lights 06 / 07 / 09#4#01, the F418 dimmer 0010 (level writes,
WHAT 30 / 31, 30#2#255, 1#255, dimension 1 / 4 reads), shutter 05 (basic
and published advanced WHAT 10..14 forms, dimension 10 / 11 reads),
climate zone 2 (every dimension read, setpoint and mode writes, central
forms) and every WHO 13 dimension. Gateway LAN address and MAC synthetic
(192.0.2.92, 00:03:50:00:11:04, also in their WHO 13 byte forms).

What the plant said, pinned by tests/test_f461_live_2026_11_04_trace.py:
WHO 13 dates carry four-digit years and time zone 999; the dimmer answers
the parameterised step with dimension 1 and dimension 4 and every
status read is followed by a WHO 1001 diagnostic frame; the shutter
echoes advanced commands as *2*1000#WHAT#PRI#INFO#1*05## events, NACKs
the dimension 11 read and stays silent on dimension 10; zone 2 answers
every per-dimension read, NACKs dimension 11 on the command session and
the central-unit forms; *14*1*0## is echoed. Trace matrix: F461 gains
WHO 1001.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
test(#466): F454 2.0.51 sweep + scenario-controller traces
test(#466): 3488 HOMETOUCH with MyHomeServer1 connected — real-plant sweep + full debug log
test(f461): live F461 2.0.11 full debug log and bus sweep, 2026-11-04 (released OWNd 2.0.0b13)
…2-climate-trace

test(climate): commit live MH202 FW 1.0 zone status trace and replay test (#866)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment