Repository navigation
fix(#77): review follow-ups (fan zone, brightness log, WHO 25 commands) and golden corrections - #83
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Same corrections as OpenWebNet-HA/OWNd#83 in MyHOME's copy of the corpus: antifreeze and protection zone commands (*4*102*#1##, *4*302*#1## instead of 110/111), the two-digit local-bus interface for cover 21, the H4890 dry-contact capture *25*31#1*339## instead of *25*31#1*15##, a note on the disputed CEN WHERE 0001 and the MH200N + MyHomeServer1 capture *15*03#3*0512## (MyHOME#624). SOURCE.yaml lists the new captures; README and corpus.json follow (184 fixtures). Passes with OWNd 2.0.0b9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l_status, share zone parsing Review of #83: - thermo.cmd.mode.antifreeze.zone1 / .protection.zone1 now have builder blocks: set_central_mode("#1", "antifreeze") and ("#1", "protection") build *4*102*#1## and *4*302*#1##. set_mode only builds 303 and 311, so without these nothing pinned what a caller gets for antifreeze or protection. - central_status() raises a DeprecationWarning pointing to status(where). It still builds *#4*WHERE*14## for existing callers, which an F454 (MyHOME#629) and a real MyHomeServer1 refuse; status("#0") is the poll the F454 answers. thermo.cmd.central.status.cu99.dim14_legacy loses its builder block, so the corpus no longer parity-tests a deprecated method, and its note says roundtrip only means OWNd re-serializes it exactly. - set_mode and set_temperature take the zone from the first WHERE field, through the same _zone_number helper as set_fan_speed: "#23#1" was zone 1 and "23#1" raised ValueError. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Same corrections as OpenWebNet-HA/OWNd#83 in MyHOME's copy of the corpus: antifreeze and protection zone commands (*4*102*#1##, *4*302*#1## instead of 110/111), the two-digit local-bus interface for cover 21, the H4890 dry-contact capture *25*31#1*339## instead of *25*31#1*15##, a note on the disputed CEN WHERE 0001 and the MH200N + MyHomeServer1 capture *15*03#3*0512## (MyHOME#624). SOURCE.yaml lists the new captures; README and corpus.json follow (184 fixtures). Passes with OWNd 2.0.0b9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…25 commands Three small findings from the audit of OWNd#82: - set_fan_speed takes the zone from the first WHERE field. "#23#1" built zone 1 (the last field). libqtdevices sends the plain zone for a probe addressed #23#1: *#4*23*#11*3##. "23#1" now gives zone 23 instead of "Invalid zone address". #0 and #0#N are still refused. - set_brightness logs the level it sends: 120 logs "brightness to 100% (requested 120%)" instead of "120%". The frame is unchanged (*#1*W*#1*200*S##). - The WHO 25 command parser follows the event parser's rule from fix 9: only WHAT 31/32 (and *#25* status requests) are OWNDryContactCommand, 21..28 stay OWNCenPlusCommand, and any other numeric WHAT is a plain OWNCommand. A non-numeric WHAT stays a dry contact, as in the event parser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntradict Found while checking the golden corpus against the OWNd#77 firmware data (gdluck's sweeps and gateway probe, own-firmware-oracle) and the MyHOME plant traces. None of the community captures disagreed; these document- derived fixtures did. Each corrected entry names its new source, as the golden README requires. - thermo.cmd.mode.antifreeze.zone1: *4*110*1## -> *4*102*#1##, and thermo.cmd.mode.protection.zone1: *4*111*1## -> *4*302*#1##. 110 and 111 are manual and automatic heating (Encyclopedia what.md, libqtdevices WIN_MANUAL / WIN_AUTOMATIC); the firmware drops 110 and treats 111 as automatic. The Encyclopedia zone-setup table gives *4*102*#WHERE## and *4*302*#WHERE##, and libqtdevices sends 302 to #zone. - cover.cmd.up.bus.21 / cover.cmd.stop.bus.21: interface 1 -> 01. The firmware refuses a one-digit interface (au2.own) and the Encyclopedia WHO 2 grammar is INTERFACE = [0-1][1-9]. - dry_contact.event.on.15 -> dry_contact.event.on.339, the H4890 capture *25*31#1*339## (MyHOME#466): every captured dry contact has a WHERE that starts with 3, as in the firmware's bt_luci rule. - thermo.cmd.central.status.cu99 is now the F454 capture *#4*#0## (status() builder, MyHOME#629). The old *#4*#0*14## stays as thermo.cmd.central.status.cu99.dim14_legacy so central_status() keeps a parity check, with the note that gateways refuse it. Mirrors MyHOME's golden copy. - cen.event.extended_press.btn1.0001 keeps its frame but notes the dispute (the spec allows 0001, bt_luci refuses it). New capture cen.event.extended_press.btn3.0512 (*15*03#3*0512##, MH200N + MyHomeServer1, MyHOME#624) with OWNCenCommand builder parity. SOURCE.yaml lists the three new captures; README and corpus.json follow (117 fixtures). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l_status, share zone parsing Review of #83: - thermo.cmd.mode.antifreeze.zone1 / .protection.zone1 now have builder blocks: set_central_mode("#1", "antifreeze") and ("#1", "protection") build *4*102*#1## and *4*302*#1##. set_mode only builds 303 and 311, so without these nothing pinned what a caller gets for antifreeze or protection. - central_status() raises a DeprecationWarning pointing to status(where). It still builds *#4*WHERE*14## for existing callers, which an F454 (MyHOME#629) and a real MyHomeServer1 refuse; status("#0") is the poll the F454 answers. thermo.cmd.central.status.cu99.dim14_legacy loses its builder block, so the corpus no longer parity-tests a deprecated method, and its note says roundtrip only means OWNd re-serializes it exactly. - set_mode and set_temperature take the zone from the first WHERE field, through the same _zone_number helper as set_fan_speed: "#23#1" was zone 1 and "23#1" raised ValueError. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29040c9 to
a8614c2
Compare
…ng, zone validation)
fedem95
left a comment
There was a problem hiding this comment.
The zone-parsing row cites libqtdevices TS10_1_0_23 (setFancoilSpeed). In that library, probe_device.h:156 documents the probe address as "probe#central", and test/test_probe_device.cpp creates the device as ControlledProbeDevice("23#1", "1", "23", ...) (line 111), then expects:
- fan speed:
*#4*23*#11*3##(line 139), plain zone; - automatic:
*4*311*#23#1##(line 132), full address; - manual setpoint:
*#4*#23#1*#14*0250*3##(line 125), full address.
On 83c4756 the address #23#1 gives:
set_fan_speed("#23#1", 2)→*#4*23*#11*2##(master:*#4*1*#11*2##);set_mode("#23#1", "auto")→*4*311*#23##(master:*4*311*#1##);set_temperature("#23#1", 22.5, "heat")→*#4*#23*#14*0225*1##(master:*#4*#1*#14*0225*1##).
So the fan-speed frame matches libqtdevices, while set_mode and set_temperature drop the #1 that libqtdevices keeps. Should those two keep the full address? The addresses 1, #1, #5, 99, #0 and #0#1 give the same frames as on master.
Other checks on 83c4756:
*25*11#121*10##parses asOWNCommand(master:OWNDryContactCommand);*25*31#1*339##,*25*32#0*33##and*#25*339##parse asOWNDryContactCommand,*25*21#1*21##asOWNCenPlusCommand.set_brightness("31", 120)builds*#1*31*#1*200*0##and logs "brightness to 100% (requested 120%)".central_status()emits aDeprecationWarning; MyHOME'scustom_componentshas no call to it.- Every dry-contact frame (
*25*31/*25*32) in MyHOME'stests/fixtures/traceshas a WHERE starting with 3 (31,33,331–339). - OWNd suite: 1226 passed, 2 skipped (
test_metadataexcluded, my local env has an old OWNd installed). MyHOMEv2-phase1-architecture(394c028) against 83c4756, locally: 3452 passed, 1 skipped.
…ture Review of #83 (fedem95): libqtdevices TS10_1_0_23 test_probe_device.cpp (line 111, ControlledProbeDevice) expects plain zone for fan speed (*#4*23*#11*3##), but retains the full #probe#central address for automatic (*4*311*#23#1##) and setpoint (*#4*#23#1*#14*0250*3##). Use _zone_address_and_name helper to retain compound addresses (#23#1, 23#1, #0#1) for set_mode and set_temperature, while keeping _zone_number extracting the plain zone for set_fan_speed.
…0_23 - Support protection, antifreeze, and thermal_protection in set_mode and set_protection matching ControlledProbeDevice::setProtection. - Add get_fan_speed matching ControlledProbeDevice::requestFancoilStatus. - Support external sensor parameter in get_probe_temperature matching NonControlledProbeDevice::requestStatus. - Add set_central_program, set_central_scenario, set_timed_manual, set_central_weekend, set_central_holiday, and dimensions 30/31/32 end date/time methods matching ThermalDevice. - Support timed manual (112, 212, 312), program (3101..3116), scenario (3201..3216), and holiday (33001..33255) modes and dimensions 30/31/32 in OWNHeatingEvent. - Update who04_thermo.yaml fixtures to use set_mode for protection modes. - 100.0% statement and branch coverage on heating.py.
|
Good catch on Taking a step back,
|
fedem95
left a comment
There was a problem hiding this comment.
Thanks, the compound address now matches libqtdevices: for #23#1 and 23#1, set_mode auto/off build *4*311*#23#1## / *4*303*#23#1##, set_temperature builds *#4*#23#1*#14*0225*1##, fan speed stays *#4*23*#11*2##. Plain addresses (1, #1, #5, 99, #0, #0#1, 0) build the same frames as master, with and without standalone; a three-part address like #0#1#2 now raises ValueError (master turned it into zone 2).
Checked f2df920's new central-unit builders against test/test_thermal_device.cpp: set_central_program(13) → *4*3113*#0## (l. 94), set_central_scenario(12) → *4*3212*#0## (l. 325), set_central_weekend(12) → *4*315#3112*#0## (l. 86), set_central_holiday(days=2, program=15) → *4*33002#3115*#0## (l. 78), end date/time *#4*#0*#30*13*02*2009## / *#4*#0*#31*23*31## (ll. 108–120), timed end *#4*#1#2*#32*13*05## (l. 301). The dimension 30/31/32 parsers decode the frames of ll. 232–245.
Notes:
- The PR description doesn't list f2df920's additions; only your comment does.
- In libqtdevices the
#2in*4*312#TTTT#2and the 2 days in*4*33002#…are commented as dummy values (thermal_device.cpp:371,:166); the end is always set by the following dimension 32 / 30+31 frames. Herehoursanddaysare exposed as real durations, in separate methods. set_central_programaccepts 1..16; libqtdevices has no range check there, and its enum comments describe weekly programs as "1 out of 3" (ll. 56, 66). Where does 16 come from?
OWNd suite 1234 passed locally; MyHOME v2-phase1-architecture (394c028) against f2df920: 3452 passed, 1 skipped.
|
Thanks for the thorough review and verification against Regarding your notes:
|
Summary
Follow-ups from the review of #82: code fixes from the audit, golden fixtures that the firmware data and the plant captures contradict, addressing all review nits, and achieving full protocol parity with BTicino's 10-inch Touch Screen reference client (
libqtdevicestagTS10_1_0_23) (f2df920). Rebased cleanly ontomasterfollowing the release of2.0.0-b10(#78).1. Protocol Parity with
libqtdevices TS10_1_0_23(f2df920)Empirical parity with BTicino's reference touch screen stack (
ControlledProbeDevice,NonControlledProbeDevice,ThermalDevice, andThermalDevice4Zones):set_mode/set_protection*4*102*#Z##, generic protection*4*302*#Z##, cooling protection*4*202*#Z##ControlledProbeDevice::setProtectionget_fan_speed*#4*Z*#11*2##ControlledProbeDevice::requestFancoilStatusget_probe_temperature*#4*Z*14*P##NonControlledProbeDevice::requestStatusset_central_program(p)*4*3100+p*#0##(programs 1..16)ThermalDevice::setWeekProgram(test_thermal_device.cpp:94tests p=13)set_central_scenario(s)*4*3200+s*#0##(scenarios 1..16)ThermalDevice::setScenario(test_thermal_device.cpp:325tests s=12)set_central_weekend(p)*4*315#3100+p*#0##ThermalDevice::setWeekendDateTime(test_thermal_device.cpp:86tests p=12)set_central_holiday(d, p)*4*33000+d#3100+p*#0##ThermalDevice::setHolidayDateTime(test_thermal_device.cpp:78tests d=2, p=15)set_timed_manual(t, h)*4*312#TTTT#h*#WHERE##ThermalDevice4Zones::setManualTempTimed(thermal_device.cpp:371)set_holiday_end_date(d)*#4*#0*#30*DD*MM*YYYY##ThermalDevice::setHolidayEndDate(test_thermal_device.cpp:108)set_holiday_end_time(t)*#4*#0*#31*HH*MM##ThermalDevice::setHolidayEndTime(test_thermal_device.cpp:115)set_timed_manual_end_time(t)*#4*#WHERE*#32*HH*MM##ThermalDevice4Zones::setEndTime(test_thermal_device.cpp:301)OWNHeatingEventparsing112/212/312), weekly programs (3101..3116), scenarios (3201..3216), holidays (33001..33255), and dimension 30/31/32 end dates/timesThermalDevice::parseFrame(test_thermal_device.cpp:232-245)2. Code Fixes & Address Parsing (
853b23d,83c4756)set_fan_speed,set_mode, andset_temperaturetake the zone from the first field via shared_zone_number:#23#1and23#1resolve to zone 23. In83c4756,_zone_numberstrictly validates addresses, rejecting##..., negative numbers, non-digits, and multi-part addresses like#0#1#2withValueError. MatchesControlledProbeDevice::setFancoilSpeed(*#4*23*#11*3##).test_fix2_fan_speed_takes_the_zone_from_the_first_field,test_zone_builders_take_the_zone_from_the_first_field,test_zone_builders_refuse_invalid_addressesset_brightnesslogs the level it sends: 120 now logsbrightness to 100% (requested 120%). Frame remains*#1*W*#1*200*S##.test_fix7_log_shows_the_level_that_is_sent_parse_who25_commandfollows the event rule: WHAT 31/32 and*#25*status requests areOWNDryContactCommand, 21–28 areOWNCenPlusCommand, and any other numeric WHAT is a plainOWNCommand.test_fix9_command_parser_uses_the_same_who25_rule3. Golden Corpus Corrections (
6021f2a,83c4756)Corpus checked against OWNd#77 firmware data, real-gateway probes (
own-firmware-oracle), and MyHOME plant traces. All 48community-plant-capturefixtures pass. Corrections to document-derived fixtures:thermo.cmd.mode.antifreeze.zone1*4*110*1##*4*102*#1##WIN_MANUAL). Antifreeze is*4*102*#WHERE##.thermo.cmd.mode.protection.zone1*4*111*1##*4*302*#1##*4*302*#WHERE##.thermo.cmd.mode.thermal_protection.zone1(new)*4*202*#1##*4*202*#WHERE##).cover.cmd.up.bus.21,cover.cmd.stop.bus.2121#4#121#4#01INTERFACE = [0-1][1-9].dry_contact.event.on.15→.339*25*31#1*15##*25*31#1*339##3.thermo.cmd.central.status.cu99*#4*#0*14##*#4*#0##…cu99.dim14_legacywith deprecation note.cen.event.extended_press.btn3.0512(new)*15*03#3*0512##4. Review Follow-ups (
a8614c2,83c4756,f2df920)set_central_mode("#1", "antifreeze")and("#1", "protection")build*4*102*#1##and*4*302*#1##.central_status()deprecated: RaisesDeprecationWarningpointing tostatus(where)and documents F454/MyHomeServer1 dimension 14 drop/NACK behavior.#0#1#2) raiseValueError.corpus.jsonhas 118 entries.Downstream
Companion PR OpenWebNet-HA/MyHOME#643 has been merged into
v2-phase1-architecture. BothGolden corpus & smoke gatesandMyHOME test suitepass cleanly (3,452 passed, 1 skipped).Verification
heating.py.ruff check,mypy OWNd, andtools/golden/validate_corpus.py(118 frames) clean.