diff --git a/tests/golden/README.md b/tests/golden/README.md index 0bbc87c4..fdc8ad09 100644 --- a/tests/golden/README.md +++ b/tests/golden/README.md @@ -21,23 +21,23 @@ Every other source (`legrand-spec`, `encyclopedia`, `openwebnet4j`, `public-read - A `builder:` block proves the builder matches the fixture, not that either is right. When both are written in the same change from the same reading, the test only compares the code with itself. Prefer builder parity against a capture or an independent source such as `openwebnet4j`. - When a capture arrives for a frame that so far exists only as a spec-derived fixture, add the capture and keep the spec entry only if it agrees. -## Supported Subsystems Catalog (183 Fixtures) +## Supported Subsystems Catalog (184 Fixtures) > Frames marked `community-plant-capture` come from real installations contributed by users. They are the only authority for behaviour the official PDFs leave undefined, and they are kept verbatim except where a fixture note records a deliberate substitution. - **Signaling (`who00_signaling.yaml`)**: Gateway ACK (`*#*1##`) and NACK (`*#*0##`). - **WHO=0 Scenarios (`who00_scenario.yaml`)**: Basic scenario execution and stop. - **WHO=1 Lighting (`who01_lighting.yaml`)**: Point-to-point ON/OFF, status requests, local bus routing (`0311#4#01`), group broadcast, speed transitions (`*1*1#5*12##`), and dimension writes. An MH200 dimmer capture (MyHOME#434) pins what a dimmer actually sends: a keypad hold is one `*1*LEVEL*WHERE##` per 10% step, a `DIMENSION 1` reply of `100` means OFF, and a `DIMENSION 4` request is NACKed; no source produced a `DIMENSION 4` frame, so the `openwebnet4j` one (`*#1*0714*4*200*2##`) is still the only evidence for its layout. A subsequent physical MH200 capture (MyHOME#466, comment 5849245960) adds the classic **BTicino F414** 10-level dimmer on point `99`, settling the question of whether older dimmers behave differently: the F414 also uses Dimension 1 (`*#1*99*1*LEVEL*SPEED##`), accepts Dimension 1 writes (`*#1*99*#1*150*0##`), reports discrete levels via a non-linear mapping (`10`=100%, `9`=74%, `8`=63%), and also rejects Dimension 4 with NACK. Authentic captures on physical **BTicino F418U2** universal modular dimmers across three gateway generations (F454 FW 2.0.51 in comment 5854469497, MH200 FW 2.1.0 on point `62`, and MH202 FW 1.0.21 in comment 5854805415, #501) demonstrate key cross-gateway mechanics: all gateways confirm identical non-linear WHAT dimming curves (Level 3 = 10%, Level 5 = 30%, Level 7 = 50%, Level 10 = 100%) and Dimension 1 write support; on F454, querying while OFF produces Dimension 4 (`*#1*32*4*100*2##`) and Dimension 4 writes are ignored; on MH200, querying while OFF returns Dimension 1 (`*#1*62*1*100*2##`) and Dimension 4 is unhandled; on MH202, querying while OFF returns Dimension 1 (`*#1*32*1*100*0##`) or Dimension 4 (`*#1*32*4*100*0##`), positive Dimension 4 writes are fully functional (`*#1*32*#4*130*0##` -> `*#1*32*4*130*2##`), and extended command translation events (`*1*1000#5*32##`) and Dimension 13 multi-parameter feedback (`*#1*32*13*2*130*5*0##`) are emitted. -- **WHO=2 Automation (`who02_automation.yaml`)**: Shutter UP/DOWN/STOP, private bus routing (`21#4#1`), absolute position percentages, and slat tilt angles. Records tagged `scope` pin OWNd's general / area / group classification; an MH201 capture (MyHOME#433) adds an area-1 stop echo (`*2*0*1##`) and the per-actuator end-of-run stop that closes a general UP: a scope command never gets a stop of its own (WHO_2.pdf §3.0.1). A MyHomeServer1 capture with an LN-4660M2 centralized controller (MyHOME#445, #466) adds Advanced General UP/DOWN/STOP multi-parameter commands (`*2*11#100#001#1*0##`, `*2*12#100#001#1*0##`, `*2*10#001#1*0##`) and multi-actuator Dimension 10 feedback bursts across 4-digit actuator addresses (`0010`, `0011`). A 2026-09-28 follow-up capture confirms the STOP/PRESET button sends that same Advanced STOP frame when pressed on already-stationary shutters, and that the LN-4660M2's own local room button (not the centralized one) uses the plain `*2*WHAT*WHERE##` syntax at its own address instead — including the first captured transitional Dimension 10 report (`*#2*02*10*12*100*001*0##`, status code `12` = closing from 100%). +- **WHO=2 Automation (`who02_automation.yaml`)**: Shutter UP/DOWN/STOP, local bus routing (`21#4#01`; the firmware refuses a one-digit interface), absolute position percentages, and slat tilt angles. Records tagged `scope` pin OWNd's general / area / group classification; an MH201 capture (MyHOME#433) adds an area-1 stop echo (`*2*0*1##`) and the per-actuator end-of-run stop that closes a general UP: a scope command never gets a stop of its own (WHO_2.pdf §3.0.1). A MyHomeServer1 capture with an LN-4660M2 centralized controller (MyHOME#445, #466) adds Advanced General UP/DOWN/STOP multi-parameter commands (`*2*11#100#001#1*0##`, `*2*12#100#001#1*0##`, `*2*10#001#1*0##`) and multi-actuator Dimension 10 feedback bursts across 4-digit actuator addresses (`0010`, `0011`). A 2026-09-28 follow-up capture confirms the STOP/PRESET button sends that same Advanced STOP frame when pressed on already-stationary shutters, and that the LN-4660M2's own local room button (not the centralized one) uses the plain `*2*WHAT*WHERE##` syntax at its own address instead — including the first captured transitional Dimension 10 report (`*#2*02*10*12*100*001*0##`, status code `12` = closing from 100%). - **WHO=4 Thermoregulation (`who04_thermo.yaml`)**: Measured temperature queries (`21.5°C`), setpoint writes, Antifreeze/Protection modes, and negative temperature probe status (`-4.8°C`). Two MyHomeServer1 + Home+Control plants (#429) add dimension 7, which carries the zone state and setpoint on those plants and is not in `WHO_4 2.pdf`: cooling and heating setpoints, protection (the zone is OFF, with `*4*202*Z##`), the 35.0 °C protection value sent just before a real setpoint, MyHomeServer1's `*#4*Z*#7*...##` program writes, and the dimension 5 re-assert. An MH200N capture (#466) adds local knob offset transitions (Dimension 13: `*#4*4*13*01##` / `*#4*4*13*11##`). The full traces are in `tests/fixtures/traces/issue_429` and `tests/fixtures/traces/issue_466`. - **WHO=5 Burglar Alarm (`who05_alarm.yaml`)**: Status requests and silent alarm events across zones and central units. - **WHO=9 Auxiliary (`who09_auxiliary.yaml`)**: Activation and deactivation of AUX relay channels. - **WHO=13 Gateway Management (`who13_gateway.yaml`)**: Firmware versions and gateway internal datetime responses. `*#13**15*4##` is the device type a physical MH200 (firmware 2.1.0) answers. It is also the regression frame for an MH200 set up by hand as MH200N (live 2026-09-23): the code corrects that label to MH200, because the MH200N has a code of its own (`44`) and a family match (`MH200N` → `MH200`) is no longer enough (`test_manual_mh200n_on_a_live_mh200_is_corrected`). An MH200N capture (#466) adds on-wire firmware version 1.1.8 (`*#13**16*1*1*8##`). -- **WHO=15 CEN Pushbuttons (`who15_cen.yaml`)**: Pressure, short release, long release and extended pressure (`*15*BUTTON[#1|#2|#3]*WHERE##`). +- **WHO=15 CEN Pushbuttons (`who15_cen.yaml`)**: Pressure, short release, long release and extended pressure (`*15*BUTTON[#1|#2|#3]*WHERE##`), with a four-digit source address captured on an MH200N + MyHomeServer1 bus (`0512`, #624). - **WHO=16 Sound System (`who16_sound.yaml`)**: Source devices (`101`-`109`), matrix routing (`1` + environment + source), amplifier ON/OFF, volume (`DIMENSION 1`) and RDS (`DIMENSION 8`). Captured on two independent F441M installations — an MH200 and an MH200N — rather than derived from the specification, because the routing address is not documented in `WHO_16.pdf`. - **WHO=22 Sound Diffusion (`who22_sound_diffusion.yaml`)**: The mirror frames an MH200N emits alongside every WHO=16 sound event. Kept as structural evidence for the WHO=16 addressing: this dialect writes the environment and the source into separate fields (`*22*2#4#AREA*5#2#SOURCE##`) where WHO=16 packs them into one pseudo address. Judged against the Encyclopedia's WHO=22 reference, since `openwebnet-mcp`'s catalog for this family is still a stub. - **WHO=18 Energy Management (`who18_energy.yaml`)**: Instantaneous active power and cumulative energy totalizers (`*#18*51*51*23791364##`, captured on an MH200N on #466), and F520 active power trigger / totalizer request frames (`*#18*51*1200##`, `*#18*51*51##`, `*#18*71#0*1200##`, `*#18*71#0*51##`) verified on a physical MH200 gateway (#494). -- **WHO=25 CEN+ / Dry Contacts (`who25_cen_plus.yaml`)**: CEN+ short press, hold start, hold repeat and release (`*25*21..24#PUSHBUTTON*2OBJECT##`, captured on an MH201) and a dry-contact event (`*25*31#1*WHERE##`). +- **WHO=25 CEN+ / Dry Contacts (`who25_cen_plus.yaml`)**: CEN+ short press, hold start, hold repeat and release (`*25*21..24#PUSHBUTTON*2OBJECT##`, captured on an MH201) and a dry-contact event captured on an H4890 (`*25*31#1*339##`; on the bus, dry-contact WHEREs start with `3`). ## Directory Structure diff --git a/tests/golden/SOURCE.yaml b/tests/golden/SOURCE.yaml index e93c13e5..064c6c79 100644 --- a/tests/golden/SOURCE.yaml +++ b/tests/golden/SOURCE.yaml @@ -158,6 +158,24 @@ authorities: date: "2026-09-24" gateway: "BTicino F454 + MH202 and MyHomeServer1 + H4890" devices: "Shared SCS bus verification: physical lighting, covers, CEN+, alarm, audio diffusion, heating, energy totalizers, and cross-gateway echo correlation" + - name: "Physical Bus Capture (BTicino H4890, WHO 25 dry contacts)" + reference: "https://github.com/OpenWebNet-HA/MyHOME/issues/466#issuecomment-5846053726" + author: "@nicolacavallo84" + date: "2026-09-26" + gateway: "BTicino H4890 touch screen, firmware 4.0.15" + devices: "Dry contacts reported as *25*31#1*33N## / *25*32#1*33N## (WHERE 33, 331-339)" + - name: "Physical Bus Capture (BTicino F454, WHO 4 99-zone central unit)" + reference: "https://github.com/OpenWebNet-HA/MyHOME/issues/629#issuecomment-5993412070" + author: "@ricdijk" + date: "2026-10-05" + gateway: "BTicino F454, firmware 1.0.34" + devices: "99-zone central unit #0 with zones 1-7 and 11-15: *#4*#0## answered within 0.13 s (*4*202*#0##, *4*21*#0##, *4*22*#0##, *4*24*#0##); *#4*#0*14## not answered" + - name: "Physical Bus Capture (MH200N + MyHomeServer1 on one bus, WHO 15 four-digit CEN address)" + reference: "https://github.com/OpenWebNet-HA/MyHOME/issues/624#issuecomment-6002817949" + author: "@wave68runner" + date: "2026-10-05" + gateway: "BTicino MH200N (fw 1.0 as reported over SSDP) and MyHomeServer1 on the same SCS bus" + devices: "CEN unit 0512 (A 5, PL 12): press, short release, hold (#3 repeated) and long release, emitted identically by both gateways" role: "Provides authentic on-wire bus frames and status replies captured from live physical hardware." diff --git a/tests/golden/corpus.json b/tests/golden/corpus.json index 93ca418a..7d98f4ba 100644 --- a/tests/golden/corpus.json +++ b/tests/golden/corpus.json @@ -1543,42 +1543,42 @@ }, { "id": "cover.cmd.up.bus.21", - "frame": "*2*1*21#4#1##", + "frame": "*2*1*21#4#01##", "direction": "command", "who": 2, "what": 1, "where": "21", - "interface": "1", - "source": "legrand-spec", + "interface": "01", + "source": "encyclopedia", "mcp_valid": true, - "mcp_notes": "Automation: UP at address 21 on private SCS bus 1", + "mcp_notes": "Automation: UP at address 21 on local bus interface 01 (Encyclopedia functional/who-2-automation/addressing.md: APL#4#INTERFACE, INTERFACE = [0-1][1-9]). Corrected from *2*1*21#4#1##: the MyHomeServer1 firmware refuses a one-digit interface (*2*1*31#4#1## NACK, *2*1*31#4#01## ACK, au2.own, OWNd#77) and so does the MH200N emulation; every interface capture in this file uses two digits", "roundtrip": true, "builder": { "class": "OWNAutomationCommand", "method": "raise_shutter", "args": [ - "21#4#1" + "21#4#01" ] }, "_file": "who02_automation.yaml" }, { "id": "cover.cmd.stop.bus.21", - "frame": "*2*0*21#4#1##", + "frame": "*2*0*21#4#01##", "direction": "command", "who": 2, "what": 0, "where": "21", - "interface": "1", - "source": "legrand-spec", + "interface": "01", + "source": "encyclopedia", "mcp_valid": true, - "mcp_notes": "Automation: STOP at address 21 on private SCS bus 1", + "mcp_notes": "Automation: STOP at address 21 on local bus interface 01 (Encyclopedia who-2-automation/addressing.md, INTERFACE = [0-1][1-9]). Corrected from *2*0*21#4#1##, a one-digit interface the firmware refuses (au2.own, OWNd#77)", "roundtrip": true, "builder": { "class": "OWNAutomationCommand", "method": "stop_shutter", "args": [ - "21#4#1" + "21#4#01" ] }, "_file": "who02_automation.yaml" @@ -2083,27 +2083,27 @@ }, { "id": "thermo.cmd.mode.antifreeze.zone1", - "frame": "*4*110*1##", + "frame": "*4*102*#1##", "direction": "command", "who": 4, - "what": 110, - "where": "1", - "source": "legrand-spec", + "what": 102, + "where": "#1", + "source": "encyclopedia", "mcp_valid": true, - "mcp_notes": "Set Zone 1 to Antifreeze protection mode", + "mcp_notes": "Set Zone 1 (through the central unit) to Antifreeze, WHAT 102 (Encyclopedia functional/who-4-temperature-control/what.md, zone setup: *4*102*#WHERE##). Corrected from *4*110*1##: 110 is manual heating (same table; libqtdevices TS10_1_0_23 WIN_MANUAL) and the MyHomeServer1 firmware forwards nothing for it (OWNd#77). The MyHomeServer1 captures in this file report an antifreeze zone as *4*102*Z##. The judge's description of 102 is not used", "roundtrip": true, "_file": "who04_thermo.yaml" }, { "id": "thermo.cmd.mode.protection.zone1", - "frame": "*4*111*1##", + "frame": "*4*302*#1##", "direction": "command", "who": 4, - "what": 111, - "where": "1", - "source": "legrand-spec", + "what": 302, + "where": "#1", + "source": "encyclopedia", "mcp_valid": true, - "mcp_notes": "Set Zone 1 to Thermal Protection mode", + "mcp_notes": "Set Zone 1 (through the central unit) to generic protection, WHAT 302 (Encyclopedia what.md zone setup: *4*302*#WHERE##; libqtdevices TS10_1_0_23 ControlledProbeDevice::setProtection sends PROT_GENERIC 302 to #zone). Corrected from *4*111*1##: 111 is programmed/automatic heating (same table; libqtdevices WIN_AUTOMATIC), which the MyHomeServer1 firmware forwards as automatic heating (OWNd#77). The judge's description of 302 (manual cooling setpoint) is wrong", "roundtrip": true, "_file": "who04_thermo.yaml" }, @@ -2246,15 +2246,8 @@ "dimension_values": [], "source": "legrand-spec", "mcp_valid": true, - "mcp_notes": "Request 99-zone Central Unit status on Dimension 14 (rejected with NACK on physical F454 firmware, issue #629)", + "mcp_notes": "Request 99-zone Central Unit status on Dimension 14 (rejected with NACK on physical F454 firmware, issue #629; a real MyHomeServer1 refuses it too, OWNd#77). No builder block: OWNd#83 deprecates central_status(), which builds this frame; MyHOME polls with status('#0'). roundtrip means OWNd re-serializes it exactly, not that a gateway accepts it", "roundtrip": true, - "builder": { - "class": "OWNHeatingCommand", - "method": "central_status", - "args": [ - "#0" - ] - }, "_file": "who04_thermo.yaml" }, { @@ -3309,8 +3302,29 @@ "where": "0001", "source": "openwebnet4j", "mcp_valid": true, - "mcp_notes": "CEN: Button 1 extended pressure on module 0001", + "mcp_notes": "CEN: Button 1 extended pressure on module 0001. Disputed: the Encyclopedia CEN table allows [00][01-15] (functional/who-15-cen/README.md), but the MyHomeServer1 firmware refuses WHERE 0001 (*15*01*0001## produces no bus frame, au1.tsv, OWNd#77; four digits only when A or PL is 10 or more). No capture either way; see cen.event.extended_press.btn3.0512 for a captured four-digit address", + "roundtrip": true, + "_file": "who15_cen.yaml" + }, + { + "id": "cen.event.extended_press.btn3.0512", + "frame": "*15*03#3*0512##", + "direction": "event", + "who": 15, + "what": "03#3", + "where": "0512", + "source": "community-plant-capture", + "mcp_valid": true, + "mcp_notes": "CEN: extended pressure on button 3 of source 0512 (A 5, PL 12: four digits because PL is 10 or more). Captured on an MH200N and a MyHomeServer1 on the same bus, which emit the same WHERE with its leading zero (MyHOME tests/fixtures/traces/issue_624/, MyHOME#624). The full press: *15*03*0512##, *15*03#3*0512## (repeated while held), *15*03#2*0512##", "roundtrip": true, + "builder": { + "class": "OWNCenCommand", + "method": "start_long_press", + "args": [ + "0512", + 3 + ] + }, "_file": "who15_cen.yaml" }, { @@ -4171,15 +4185,15 @@ "_file": "who25_cen_plus.yaml" }, { - "id": "dry_contact.event.on.15", - "frame": "*25*31#1*15##", + "id": "dry_contact.event.on.339", + "frame": "*25*31#1*339##", "direction": "event", "who": 25, "what": "31#1", - "where": "15", - "source": "encyclopedia", + "where": "339", + "source": "community-plant-capture", "mcp_valid": true, - "mcp_notes": "Dry contact 15 ON / IR detection; #1 marks an event, #0 a state reply (Encyclopedia functional/who-25-transversal/dry-contact-ir.md @c57dcec)", + "mcp_notes": "Dry contact ON / IR detection at WHERE 339; #1 marks an event, #0 a state reply (Encyclopedia functional/who-25-transversal/dry-contact-ir.md). Captured on an H4890 (MyHOME tests/fixtures/traces/issue_466/myhome_trace_H4890_all_2026-09-26T11-51-26.json, MyHOME#466). Replaces the Encyclopedia-derived *25*31#1*15##: on the bus every captured dry contact has a WHERE that starts with 3 (33, 331..339 on MH200N, MH202, F454 and H4890), and the firmware's bt_luci uses the same rule (gdluck's audit, OWNd#77). The judge warns that 339 is outside the documented 1..201; the captures show the bus form", "roundtrip": true, "_file": "who25_cen_plus.yaml" }, diff --git a/tests/golden/frames/who02_automation.yaml b/tests/golden/frames/who02_automation.yaml index ca9c6449..cf2caef9 100644 --- a/tests/golden/frames/who02_automation.yaml +++ b/tests/golden/frames/who02_automation.yaml @@ -59,36 +59,36 @@ args: ["93"] - id: cover.cmd.up.bus.21 - frame: "*2*1*21#4#1##" + frame: "*2*1*21#4#01##" direction: command who: 2 what: 1 where: "21" - interface: "1" - source: legrand-spec + interface: "01" + source: encyclopedia mcp_valid: true - mcp_notes: "Automation: UP at address 21 on private SCS bus 1" + mcp_notes: "Automation: UP at address 21 on local bus interface 01 (Encyclopedia functional/who-2-automation/addressing.md: APL#4#INTERFACE, INTERFACE = [0-1][1-9]). Corrected from *2*1*21#4#1##: the MyHomeServer1 firmware refuses a one-digit interface (*2*1*31#4#1## NACK, *2*1*31#4#01## ACK, au2.own, OWNd#77) and so does the MH200N emulation; every interface capture in this file uses two digits" roundtrip: true builder: class: OWNAutomationCommand method: raise_shutter - args: ["21#4#1"] + args: ["21#4#01"] - id: cover.cmd.stop.bus.21 - frame: "*2*0*21#4#1##" + frame: "*2*0*21#4#01##" direction: command who: 2 what: 0 where: "21" - interface: "1" - source: legrand-spec + interface: "01" + source: encyclopedia mcp_valid: true - mcp_notes: "Automation: STOP at address 21 on private SCS bus 1" + mcp_notes: "Automation: STOP at address 21 on local bus interface 01 (Encyclopedia who-2-automation/addressing.md, INTERFACE = [0-1][1-9]). Corrected from *2*0*21#4#1##, a one-digit interface the firmware refuses (au2.own, OWNd#77)" roundtrip: true builder: class: OWNAutomationCommand method: stop_shutter - args: ["21#4#1"] + args: ["21#4#01"] - id: cover.cmd.up.gen.0 frame: "*2*1*0##" diff --git a/tests/golden/frames/who04_thermo.yaml b/tests/golden/frames/who04_thermo.yaml index 55375422..237dd34c 100644 --- a/tests/golden/frames/who04_thermo.yaml +++ b/tests/golden/frames/who04_thermo.yaml @@ -41,25 +41,25 @@ args: ["1", 20.5, "heat", true] - id: thermo.cmd.mode.antifreeze.zone1 - frame: "*4*110*1##" + frame: "*4*102*#1##" direction: command who: 4 - what: 110 - where: "1" - source: legrand-spec + what: 102 + where: "#1" + source: encyclopedia mcp_valid: true - mcp_notes: "Set Zone 1 to Antifreeze protection mode" + mcp_notes: "Set Zone 1 (through the central unit) to Antifreeze, WHAT 102 (Encyclopedia functional/who-4-temperature-control/what.md, zone setup: *4*102*#WHERE##). Corrected from *4*110*1##: 110 is manual heating (same table; libqtdevices TS10_1_0_23 WIN_MANUAL) and the MyHomeServer1 firmware forwards nothing for it (OWNd#77). The MyHomeServer1 captures in this file report an antifreeze zone as *4*102*Z##. The judge's description of 102 is not used" roundtrip: true - id: thermo.cmd.mode.protection.zone1 - frame: "*4*111*1##" + frame: "*4*302*#1##" direction: command who: 4 - what: 111 - where: "1" - source: legrand-spec + what: 302 + where: "#1" + source: encyclopedia mcp_valid: true - mcp_notes: "Set Zone 1 to Thermal Protection mode" + mcp_notes: "Set Zone 1 (through the central unit) to generic protection, WHAT 302 (Encyclopedia what.md zone setup: *4*302*#WHERE##; libqtdevices TS10_1_0_23 ControlledProbeDevice::setProtection sends PROT_GENERIC 302 to #zone). Corrected from *4*111*1##: 111 is programmed/automatic heating (same table; libqtdevices WIN_AUTOMATIC), which the MyHomeServer1 firmware forwards as automatic heating (OWNd#77). The judge's description of 302 (manual cooling setpoint) is wrong" roundtrip: true - id: thermo.resp.probe.status.neg_temp @@ -162,12 +162,8 @@ dimension_values: [] source: legrand-spec mcp_valid: true - mcp_notes: "Request 99-zone Central Unit status on Dimension 14 (rejected with NACK on physical F454 firmware, issue #629)" + mcp_notes: "Request 99-zone Central Unit status on Dimension 14 (rejected with NACK on physical F454 firmware, issue #629; a real MyHomeServer1 refuses it too, OWNd#77). No builder block: OWNd#83 deprecates central_status(), which builds this frame; MyHOME polls with status('#0'). roundtrip means OWNd re-serializes it exactly, not that a gateway accepts it" roundtrip: true - builder: - class: OWNHeatingCommand - method: central_status - args: ["#0"] - id: thermo.resp.central.status.cu99.off frame: "*4*202*#0##" diff --git a/tests/golden/frames/who15_cen.yaml b/tests/golden/frames/who15_cen.yaml index 464871cf..ba07a68a 100644 --- a/tests/golden/frames/who15_cen.yaml +++ b/tests/golden/frames/who15_cen.yaml @@ -50,5 +50,20 @@ where: "0001" source: openwebnet4j mcp_valid: true - mcp_notes: "CEN: Button 1 extended pressure on module 0001" + mcp_notes: "CEN: Button 1 extended pressure on module 0001. Disputed: the Encyclopedia CEN table allows [00][01-15] (functional/who-15-cen/README.md), but the MyHomeServer1 firmware refuses WHERE 0001 (*15*01*0001## produces no bus frame, au1.tsv, OWNd#77; four digits only when A or PL is 10 or more). No capture either way; see cen.event.extended_press.btn3.0512 for a captured four-digit address" roundtrip: true + +- id: cen.event.extended_press.btn3.0512 + frame: "*15*03#3*0512##" + direction: event + who: 15 + what: "03#3" + where: "0512" + source: community-plant-capture + mcp_valid: true + mcp_notes: "CEN: extended pressure on button 3 of source 0512 (A 5, PL 12: four digits because PL is 10 or more). Captured on an MH200N and a MyHomeServer1 on the same bus, which emit the same WHERE with its leading zero (MyHOME tests/fixtures/traces/issue_624/, MyHOME#624). The full press: *15*03*0512##, *15*03#3*0512## (repeated while held), *15*03#2*0512##" + roundtrip: true + builder: + class: OWNCenCommand + method: start_long_press + args: ["0512", 3] diff --git a/tests/golden/frames/who25_cen_plus.yaml b/tests/golden/frames/who25_cen_plus.yaml index 6971d9ad..774a56a2 100644 --- a/tests/golden/frames/who25_cen_plus.yaml +++ b/tests/golden/frames/who25_cen_plus.yaml @@ -88,15 +88,15 @@ method: release args: ["21", 1] -- id: dry_contact.event.on.15 - frame: "*25*31#1*15##" +- id: dry_contact.event.on.339 + frame: "*25*31#1*339##" direction: event who: 25 what: "31#1" - where: "15" - source: encyclopedia + where: "339" + source: community-plant-capture mcp_valid: true - mcp_notes: "Dry contact 15 ON / IR detection; #1 marks an event, #0 a state reply (Encyclopedia functional/who-25-transversal/dry-contact-ir.md @c57dcec)" + mcp_notes: "Dry contact ON / IR detection at WHERE 339; #1 marks an event, #0 a state reply (Encyclopedia functional/who-25-transversal/dry-contact-ir.md). Captured on an H4890 (MyHOME tests/fixtures/traces/issue_466/myhome_trace_H4890_all_2026-09-26T11-51-26.json, MyHOME#466). Replaces the Encyclopedia-derived *25*31#1*15##: on the bus every captured dry contact has a WHERE that starts with 3 (33, 331..339 on MH200N, MH202, F454 and H4890), and the firmware's bt_luci uses the same rule (gdluck's audit, OWNd#77). The judge warns that 339 is outside the documented 1..201; the captures show the bus form" roundtrip: true - id: cen_plus.event.start_long_press.btn2.22047 diff --git a/tests/test_gateway_messages.py b/tests/test_gateway_messages.py index 35aaf0e0..663a436e 100644 --- a/tests/test_gateway_messages.py +++ b/tests/test_gateway_messages.py @@ -399,7 +399,9 @@ def test_who0_generic(self): assert isinstance(cmd, OWNCommand) def test_who25_dry_contact(self): - cmd = OWNCommand.parse("*25*0*31##") + # A dry contact is WHAT 31/32 (frame captured on MyHOME#466 plants); + # OWNd routes other WHO 25 WHATs elsewhere (OWNd#77 fix 9). + cmd = OWNCommand.parse("*25*31#1*339##") assert isinstance(cmd, OWNDryContactCommand)