Repository navigation
fix(gateway): WHO 13 value fields are ASCII digits only; docs: conformance-matrix read form and oracle suites, Dimension 10/11/12 request caveats, #Z#C wording, F461 and H/L4684 golden replies (Encyclopedia audit, group 7) - #161
Conversation
…uators_status report 21 G5 and the OpenWebNet-HA#140 leftover. docs/protocol_conformance_matrix.md showed `*OpenWebNet-HA#13*0*0##` / `*OpenWebNet-HA#13*0*22##` (WHERE 0) as the verified WHO 13 examples. The published read form has an empty WHERE, `*OpenWebNet-HA#13**DIMENSION##` (Encyclopedia who-13-integration-gateway/dimensions.md "Read form", capabilities.md "Command-session behavior"); the review-session oracle run of 2026-11-03 (audit_ency/ORACLE_CONFIRM.md row G5) has `*OpenWebNet-HA#13*0*0##` nack, silent on all twelve emulated gateways and `*OpenWebNet-HA#13**0##` answered on all twelve, and the builders (`request_time`, the event keepalive) already emit the empty form. OWNHeatingCommand.actuators_status called `#Z#N` "an actuator addressed through the central unit"; per who-4-temperature-control/addressing.md "Historical central-unit variants" the form is `#Z#C`, zone Z through a four-zone central unit C. Wording only; the accepted grammar is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ekday, tz 100 and log wording report 21 G2, G3, G4, G6, G7, G8, G9, G10. G1 not changed: settled by OWNd#144 (closed 2026-10-28), master keeps raising ValueError for out-of-table clock values and the sessions catch it. G2 / G3: Dimension 12 decodes six decimal octets in 0..255 only (Encyclopedia who-13-integration-gateway/dimensions.md "DIMENSION 12 - MAC address"); an octet above 255 or an eight-value reply (the ZigBee interface IEEE address, zigbee-network-management.md "DIMENSION 12 - Interface IEEE address", ENCY_CONFIRM ZB-108) leaves mac_address None with the values raw in dimension_value. G4 / G10: a Dimension 1 / 22 year must be four digits (dimensions.md "DIMENSION 1 - Date"): `*OpenWebNet-HA#13**1*04*15*10*26##` stays a valid message as on master, with date None instead of 0026-10-15. New `weekday` property, 0..6 from `00..06`, None outside, date unchanged and no calendar cross-check (the TS10 client writes a fixed `00`, ENCY_CONFIRM G10). G7: `T` 100 (GMT-0) reads `+00:00` like `000`. G6: a parsed write frame `*OpenWebNet-HA#13**#0/michnovka#1/OpenWebNet-HA#22*...##` logs "Setting gateway time/date to: ..." (dimensions.md "Write form": client -> gateway writes, ENCY_CONFIRM G6); the reply form built by report_* keeps "broadcasting". G8: an addressed Dimension 16 reply (`*OpenWebNet-HA#13*123400#9*16*1*2*3##`) logs "Product 123400#9's firmware version" (zigbee-network-management.md "DIMENSION 16 and 17", ENCY_CONFIRM ZB-109/110); firmware_version and where are unchanged. G9: device_type docstring and the WHO13_DEVICE_TYPES comment say that an unlisted code stays `Unknown (N)` and that the non-unique 200 is a list of sharers, not a product identity (capabilities.md "Product identification", dimensions.md "DIMENSION 15 - Device type"). Tests: tests/test_message_protocol.py (tz 100 and 0530 still raising, year / weekday, write-frame logs, MAC range, eight-value dimension 12, addressed dimension 16). The pinned-raise tests of tests/test_message_edges.py and test_malformed_gateway_clock_is_rejected are untouched. Golden fixtures unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nly WHO 13 helpers (decisions D59, D12, D14) report 21 G2, G3 (precedent gate). MyHOME#804 pins that OWNGatewayEvent.mac_address formats any six values without a 0..255 range check (tests/test_config_flow_identify.py: an octet 256 reads "100" and the config flow refuses it itself), so mac_address keeps that behaviour and the range-checked value moves to the new valid_mac_address property (six decimal ASCII octets in 0..255, Encyclopedia who-13-integration-gateway/dimensions.md "DIMENSION 12 - MAC address"; None for the eight-value ZigBee interface IEEE address of zigbee-network-management.md). _gateway_weekday, _gateway_date and the octet check take ASCII digits only (OWNd#139 rule: non-ASCII digits never decode). The docs-only CHANGELOG bullet is dropped (OWNd#143: no CHANGELOG entry when no runtime behaviour changed). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ock writes (MyHOME pin) report 21 G6 (precedent gate). MyHOME pins the log of the write form *OpenWebNet-HA#13**#0*22*50*00*## as "Gateway broadcasting internal time: 22:50:00." (tests/test_f461_who13_clock_tz_live_2026_10_26_trace.py::test_written_strings_fail_before_pass_after), so the "Setting gateway ... to" wording is not applied to parsed frames; the set_* builders keep their own "Setting gateway ..." text as on master. CHANGELOG bullet trimmed accordingly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…w follow-up) report 21 G4. _gateway_date validated day / month only for a four-digit year, so *OpenWebNet-HA#13**1*04*99*32*26## parsed with date None where master raised on month 99 / day 32 (OWNd#144: out-of-table clock values keep raising inside parse). Day and month are now validated first exactly as on master (against a leap year, so 29 February passes), for dimension 1 and dimension 22 on both OWNGatewayEvent and OWNGatewayCommand; only a well-formed date with a non-four-digit year gives date None (Encyclopedia who-13-integration-gateway/dimensions.md "DIMENSION 1 - Date"). Tests cover both orders. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…s H4684 and MH200 The firmware oracle shows *OpenWebNet-HA#13**10##, *OpenWebNet-HA#13**11## and *OpenWebNet-HA#13**12## (IP address, netmask, MAC) as nack/crash on H4684 020054 and MH200 020102 and as ack/out on the other ten emulated gateways (findings/who13-identification.md). OWNd builds no request for them; the decoders only read replies seen on the bus. No send-layer guard is added on purpose: the frames are legitimate on most gateways, so a refusal would need the gateway model at send time. Recorded in gateway.py and the CHANGELOG (2026-11-04 audit G1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
One documentation commit here from the 2026-11-04 cross-check: |
|
Live on the F461 2.0.11 test plant (2026-11-04), supporting the note that only H4684 / MH200 crash on WHO 13 dims 10/11/12: the F461 answers all of them without crashing (network values redacted) — So dims 10/11/12 are safe on this gateway, consistent with the oracle rows; the crash is H4684/MH200-specific. (These dims echo the gateway's live network interface, which is also why a committed oracle TSV had to be aligned with CI's jail interface rather than a capture host's.) |
GreenGrassBlueOcean
left a comment
There was a problem hiding this comment.
Thanks for catching the *#13*0*0## conformance-matrix error (confirmed NACK (*#*0##), SILENT across all 12/12 emulated gateways in lookup_firmware_verdict) and the #Z#C docstring leftover from #140!
Under our standing rule — if we don't have real, committed on-wire plant traces from physical hardware, we don't change behaviour — the documentation and conformance-matrix fixes here are spot-on and ready to merge, whereas the OWNd/message/gateway.py runtime changes are doc-derived without real plant captures and should be reverted so we can merge the doc fixes cleanly.
What can stay (ready to merge once trimmed)
docs/protocol_conformance_matrix.md(G5): Updating theWHO 13read examples from*#13*0*0##/*#13*0*22##(refused12/12in the firmware oracle) to*#13**0##/*#13**22##(answered12/12).OWNd/message/heating.py(#140leftover): Fixing theOWNHeatingCommand.actuators_statusdocstring so#Z#Cis accurately described as zoneZvia 4-zone central unitC.OWNd/message/gateway.pydocstrings / comments (G9): Clarifying thedevice_typedocstring andWHO13_DEVICE_TYPEScomment.
Blockers — Behaviour changes without committed plant traces (please revert)
| # | Symbol / File | Behaviour change without real plant trace | Required action |
|---|---|---|---|
| 1 | _gateway_date (DIMENSION 1 & 22) in OWNd/message/gateway.py |
Changes 2-digit years (*#13**1*04*15*10*26##, *#13**22*...*26##, and write frames) from returning a datetime.date to returning None, driven solely by dimensions.md field-width prose with zero real gateway traces showing malformed 2-digit year emissions requiring a decoder change. |
Revert _gateway_date runtime behaviour to master. |
| 2 | _gateway_timezone ("100") in OWNd/message/gateway.py |
Changes timezone code "100" from "-00:00" to "+00:00" purely from dimensions.md (ownkb:claim:c001701 / c001702) with zero on-wire captures showing a gateway emitting "100" — indeed, your own live F461 2.0.11 check showed real hardware emits "999" (unconfigured), not "100". (Also note: please avoid citing uncommitted local reports/data/live_f461_allprs_2026-11-04/ paths; any live capture worth referencing should be committed as a fixture.) |
Revert _gateway_timezone "100" decoding to master. |
| 3 | DIMENSION 12 8-octet ZigBee log, addressed DIMENSION 16 log, & valid_mac_address / weekday in OWNd/message/gateway.py |
Rewrites human_readable_log on 8-value DIMENSION 12 (Gateway's IEEE address is: ...) and addressed DIMENSION 16 (Product X firmware version is: ...), and adds valid_mac_address / weekday properties with zero ZigBee (ownkb:caution:k000009) or addressed-product WHO 13 plant traces. |
Revert the gateway.py runtime decoding, log, and property changes (keeping only the G9 docstring/comment clarifications) so this PR merges cleanly as a docs + conformance-matrix fix. |
…ces; keep the conformance-matrix and docstring fixes Maintainer review of OpenWebNet-HA#161: documentation and conformance-matrix fixes stay; runtime decoding, log strings and new properties derived from the documentation alone are reverted to master, since no committed on-wire plant traces back them. Blocker 1 (_gateway_date, Dimensions 1 and 22): reverted to master. A two-digit year (*OpenWebNet-HA#13**1*04*15*10*26##, *OpenWebNet-HA#13**22*...*26##, and the write frames) reads a datetime.date / datetime again instead of None; the _gateway_date helper is gone. Blocker 2 (_gateway_timezone): reverted to master. T "100" reads "-00:00" again, not "+00:00"; the added docstring is gone. Blocker 3: reverted the eight-value Dimension 12 "ZigBee interface IEEE address" log, the addressed Dimension 16 "Product X's firmware version" log, the valid_mac_address and weekday properties (event and command), the _gateway_weekday helper, the Dimension 12 octet range check and the Dimension 10/11/12 crash comment. Dimension 12 decoding is master's again (unchecked six-octet formatting, "Gateway's MAC address is" log). Kept: docs/protocol_conformance_matrix.md WHO 13 read examples *OpenWebNet-HA#13**0## / *OpenWebNet-HA#13**22## (G5); the OWNHeatingCommand.actuators_status docstring describing #Z#C as zone Z through a four-zone central unit C; the OWNGatewayEvent.device_type docstring and the WHO13_DEVICE_TYPES comment clarifications (G9). Tests: removed the eight tests pinning the reverted behaviour from tests/test_message_protocol.py; kept test_gateway_parsed_clock_frames_keep_the_broadcasting_log, which pins master's unchanged log text. CHANGELOG [Unreleased]: the five WHO 13 "Changed" entries are replaced by one documentation-only entry that claims no behaviour change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Applied in
Kept, as listed under "What can stay": the conformance-matrix WHO 13 read examples Committed plant evidence. The WHO 13 replies physical gateways actually send are already in MyHOME's fixtures and all carry four-digit years, so the reverted 2-digit branch is exercised by no plant: F461 2.0.11 Update (2026-11-04, 16:07Z): New committed plant trace for WHO 13: MyHOME#865 ( |
GreenGrassBlueOcean
left a comment
There was a problem hiding this comment.
Thanks for reverting the speculative WHO 13 runtime changes in 4b5b8a2. Looking at what remains in 95e99ee, the current diff is purely documentation + one log-regression test, which fixes two real doc errata (*#13**0## / *#13**22## in docs/protocol_conformance_matrix.md and the #Z#C docstring leftover from #140 on OWNHeatingCommand.actuators_status).
Before this can land, please address the following:
1. Rewrite the PR title and PR description so they reflect what the PR is now about
We don't care about the past iterations or what was reverted along the way — the PR title and body (## Summary, ## Changes, ## Testing, ## Precedent check) still describe six reverted runtime changes (valid_mac_address, weekday, 4-digit year enforcement in _gateway_date, 100 -> +00:00 in _gateway_timezone, 8-octet ZigBee Dimension 12 log, and addressed Dimension 16 log). That makes the PR confusing to read and will corrupt the squash-merge commit message on master.
- Please rewrite both the PR title and the entire PR description from scratch so they state only what this PR actually changes today (no changelog of reverted commits/features).
- In the "Committed plant evidence" section, fix the misattributed trace citation:
*#13**22*22*59*16*999*01*26*10*2026##(999timezone) comes from the physicalF461capturef461_who13_clock_tz_live_2026-10-26/myhome_trace_F461_who13_clock_tz_live_2026-10-26.json:309, notMH200N(001, already inwho13_gateway.yaml:116) orMH202(002,*#13**22*20*54*00*002*06*26*09*2026##inissue_466/myhome_trace_MH202_all_2026-09-26T16-59-17.json:73). - If you cite the new
F461(f461_live_2026-11-04/myhome_sweep_F461_all_2026-11-04T15-45-56.json) andHL4684(issue_466/config_entry-myhome_HL4684_fw6_0_11.json) captures (*#13**0*17*45*24*999##,*#13**16*2*0*11##,*#13**23*5*10*35##,*#13**24*2*26*4##,*#13**15*23##), please actually add those frames totests/golden/frames/who13_gateway.yaml.
2. Rebase onto origin/master and fix CHANGELOG.md (D14 / OWNd#143)
- The branch is currently 35 commits behind
origin/master. - Per
D14(OWNd#143— and as your own commit3e682a6noted),CHANGELOG.mdonly records user-visible runtime changes. Drop the- **Documentation only, no behaviour change**: ... (2026-11-04 audit G5, G9)bullet (or, if you include the fail-closed parser fixes in item 5 below, record only those runtime fixes and strip internal worksheet tags like(2026-11-04 audit G5, G9)).
3. docs/protocol_conformance_matrix.md: remove private local path & fix gateway count (12 -> 13)
On line 39:
(review-session oracle run of 2026-11-03, audit_ency/ORACLE_CONFIRM.md row G5; *#13**0## is answered with ACK and the current time on all twelve)
audit_ency/ORACLE_CONFIRM.md row G5is a private local scratch file — cite the publicown-firmware-oraclesuites (ownd-audit-frames,who13-clock,who13-clock-readback) instead.own-firmware-oracleruns those suites across thirteen emulated gateways (3488 030205included), not twelve: all 13 returnNACK (*#*0##), SILENTon*#13*0*0##, and all 13 returnACK (*#*1##)+ clock reply on*#13**0##and*#13**22##.
4. Dimensions 10 / 11 / 12 request builders (request_ip_address, request_netmask, request_mac_address)
In #issuecomment-6619565077 you wrote that "OWNd builds no request for them", overlooking OWNGatewayCommand.request_ip_address() (*#13**10##), request_netmask() (*#13**11##), and request_mac_address() (*#13**12##) in OWNd/message/gateway.py:621-633.
- Do not refuse them at the send layer (8/13 emulated gateways and physical
F461/MyHomeServer1answer them, andF453,F453AV,MH200NACK + SILENT), but please add a one-line docstring caveat onrequest_ip_address(),request_netmask(), andrequest_mac_address()noting thatH4684 020054andMH200 020102NACKand crash their worker process inwho13-identification.
5. Real WHO 13 fail-closed parser bugs on master that this audit missed
Because OWNMessage._DIMENSION_REQUEST_REPLY and _DIMENSION_WRITING (OWNd/message/base.py:102-110) match (?P<dimension_value>(?:\*\d*)+) (which permits empty tokens "" between stars as well as non-ASCII Unicode \d) and OWNEvent.parse / OWNCommand.parse do not catch ValueError, _parse_dimension in OWNd/message/gateway.py currently crashes OWNMessage.parse() with an uncaught ValueError on malformed wire frames:
- Dimensions
1/#1(gateway.py:208-210) &22/#22(gateway.py:255-259):_gateway_date()checks_is_ascii_digitsand returnsNonewhen the weekday token is empty (*#13**1**01*01*2026##or*#13**22*12*00*00*001**01*01*2026##), and then the very next line unconditionally runsweekday = int(self._dimension_values[0])(or[4]), raisingValueError: invalid literal for int() with base 10: ''. - Dimension
12(gateway.py:224-228):f"{int(val):02x}" for val in self._dimension_valuesraisesValueErrorif any token is empty (*#13**12*0**80*1*214*135##) and accepts non-ASCII digits. - Dimension
15(gateway.py:231-233):if len(self._dimension_values) >= 1: dtype = int(self._dimension_values[0])raisesValueErroron*#13**15*##(whereself._dimension_values == [""]) and accepts non-ASCII digits. - Dimension
19(gateway.py:240-245):int(self._dimension_values[0..3])raisesValueErrorif any of the first four tokens is empty (*#13**19**0*0*0##) and accepts non-ASCII digits. _gateway_timezone(gateway.py:89):re.fullmatch(r"[01]\d{2}", value)omitsre.ASCII, so fullwidth Unicode digits like"0\uff10\uff11"match and parse as"+01:00"instead of returningNone(unlike_gateway_timeand_gateway_date, which enforce_is_ascii_digits).
Hardening those five spots with _is_ascii_digits (leaving existing attributes and log messages on valid frames untouched) would actually fix a real fail-closed parser issue in WHO 13 on par with #155–#160.
| ## [Unreleased] | ||
|
|
||
| ### Changed | ||
| - **Documentation only, no behaviour change**: `docs/protocol_conformance_matrix.md` shows the WHO 13 reads in the published empty-`WHERE` form (`*#13**0##`, `*#13**22##`) instead of `*#13*0*0##` / `*#13*0*22##`, the form `OWNGatewayCommand.request_time()` and the keepalive already emit; the `OWNHeatingCommand.actuators_status` docstring describes `#Z#C` as zone `Z` through a four-zone central unit `C` (a controlled-zone address, not an actuator); the `OWNGatewayEvent.device_type` docstring and the `WHO13_DEVICE_TYPES` comment say that an unlisted Dimension 15 code stays `Unknown (N)` and that the non-unique `200` is a list of sharers, not a product identity (2026-11-04 audit G5, G9). |
There was a problem hiding this comment.
Per D14 (OWNd#143), CHANGELOG.md only records user-visible runtime changes. Drop this Documentation only, no behaviour change entry (and avoid internal audit worksheet labels like (2026-11-04 audit G5, G9)). If you fix the fail-closed empty-token / ASCII-digit crashes in OWNd/message/gateway.py, record only that runtime fix under ### Fixed.
| | **25** | **CEN+ / Dry Contacts**| Short press; start, hold and release of an extended press; WHERE `2` + object 0–2047 | `*25*21#1*21##`, `*25*22#1*21##`, `*25*23#1*21##`, `*25*24#1*21##` | Valid | Matched | **VERIFIED (100%)** | | ||
|
|
||
| Sources for the examples changed in [OWNd#77](https://github.com/OpenWebNet-HA/OWNd/issues/77). The MyHomeServer1 firmware, run on an emulated bus, produces a bus frame for each of them and refuses the examples they replace. The WHO 15 press and short release (`*15*01*73##`, `*15*01#1*73##`) were captured on an MH200N + MyHomeServer1 bus in [MyHOME#541](https://github.com/OpenWebNet-HA/MyHOME/issues/541). Long release and extended hold (`#2`, `#3`) rest on the firmware alone. The WHO 25 examples are an MH201 capture from [MyHOME#418](https://github.com/OpenWebNet-HA/MyHOME/issues/418). The energy request `*#18*51*52#26#9##` was accepted by a real MyHomeServer1. | ||
| Sources for the examples changed in [OWNd#77](https://github.com/OpenWebNet-HA/OWNd/issues/77). The MyHomeServer1 firmware, run on an emulated bus, produces a bus frame for each of them and refuses the examples they replace. The WHO 15 press and short release (`*15*01*73##`, `*15*01#1*73##`) were captured on an MH200N + MyHomeServer1 bus in [MyHOME#541](https://github.com/OpenWebNet-HA/MyHOME/issues/541). Long release and extended hold (`#2`, `#3`) rest on the firmware alone. The WHO 25 examples are an MH201 capture from [MyHOME#418](https://github.com/OpenWebNet-HA/MyHOME/issues/418). The energy request `*#18*51*52#26#9##` was accepted by a real MyHomeServer1. The WHO 13 reads use the published empty-`WHERE` form `*#13**DIMENSION##` (Encyclopedia who-13-integration-gateway/dimensions.md "Read form"): on the twelve emulated gateways `*#13**0##` is answered with `*#13**0*H*M*S*T##` by all twelve, while the `WHERE 0` spelling `*#13*0*0##` this table used to show is `nack, silent` on all twelve (review-session oracle run of 2026-11-03, `audit_ency/ORACLE_CONFIRM.md` row G5; `OWNGatewayCommand.request_time()` and the event keepalive emit `*#13**0##`). |
There was a problem hiding this comment.
- Replace the private local file reference
(review-session oracle run of 2026-11-03, audit_ency/ORACLE_CONFIRM.md row G5; ...)with the publicown-firmware-oraclesuites (ownd-audit-frames,who13-clock). own-firmware-oraclereplays these across thirteen emulated gateways (3488 030205included), not twelve — all 13 returnNACK, SILENTon*#13*0*0##and all 13 returnACK+ the current time on*#13**0##and*#13**22##.
…13-gateway counts in the matrix; Dimension 10/11/12 request caveats; F461 and H/L4684 golden replies Review round 2 on OpenWebNet-HA#161 (GreenGrassBlueOcean, 2026-11-10): - gateway.py: Dimensions 1, 12, 15 and 19 read their value fields only when they are ASCII digits (_is_ascii_digits); fullwidth digits used to decode a MAC, an uptime or an Unknown (..) device type, or raise from date() / fromisoformat. _gateway_timezone matches with re.ASCII so a fullwidth timezone raises the same ValueError as any malformed clock value (OpenWebNet-HA#144). The review's empty-token cases (dims 1 / 22 weekday, 12, 15, 19) never raised on master; pinned by tests/test_who13_ascii_values.py. - request_ip_address / request_netmask / request_mac_address docstrings note the who13-identification verdicts (8 of 13 answer; F453, F453AV, MH200N ACK silently; H4684 020054 and MH200 020102 NACK and crash their worker). - docs/protocol_conformance_matrix.md cites own-firmware-oracle by suite (ownd-audit-frames, who13-clock, who13-clock-readback) and the 13-gateway counts; the private worksheet path is gone. - CHANGELOG: the documentation bullet is gone (D14); a Fixed entry covers the ASCII hardening only. - Golden: six community-plant-capture records (F461 2.0.11 Dimensions 0 and 22 with the 999 timezone field, 16, 23, 24; H/L4684 6.0.11 Dimension 15 code 23) from MyHOME's committed fixtures; corpus 172 frames; README count. - origin/master (1cb2dc1) merged in. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Round 2 applied in
Checks: |
… except The coverage gate (100 % on OWNd/) flagged gateway.py 200-201 (an except that ASCII-gated int() can never reach) and 247 / 456 (the Dimension 22 raise, which the tests missed with seven-value frames). The test frames now carry the eight Dimension 22 values with a fullwidth hour, year or day. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd cover it tests/test_message_exhaustive.py feeds *OpenWebNet-HA#13**19*99999999999999999999*0*0*0##: int() of ASCII digits is fine but timedelta raises on the magnitude, so the except stays (OverflowError, ValueError) and a test covers it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With six ASCII-digit fields int() cannot raise; the empty-token case that used to hit this except now leaves the frame untyped before the branch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
@gdluck please rebase |
…lows Golden README fixture count: master's 166 (OpenWebNet-HA#159) plus the six WHO 13 records of this PR = 172; corpus.json regenerated with tools/golden/validate_corpus.py (172 frames). Co-Authored-By: Claude <noreply@anthropic.com>
landed OpenWebNet-HA#159 (merged in c546a2e's history) pins the golden README count and the corpus length at 166 in test_golden_corpus_dimension_10_write_is_conflict_and_no_tilt; this PR adds six WHO 13 records, so the pin becomes 172 (tests/golden/README.md and corpus.json already say 172). Co-Authored-By: Claude <noreply@anthropic.com>
|
Checks on Generated by Claude Code |
GreenGrassBlueOcean
left a comment
There was a problem hiding this comment.
LGTM.The ASCII-only hardening for WHO 13 value fields is correct and minimal: fullwidth digits no longer decode as MAC/uptime/device-type, clock fields raise the same ValueError already used for other malformed values, and every pure-ASCII frame still decodes exactly as before. Documentation updates (conformance-matrix read form, Dimension 10/11/12 oracle caveats, #Z#C wording) are carefully qualified. The six new golden records come from already-committed plant captures. Branch is rebased onto current master, CI is green, and the MyHOME suite passes unchanged.Ready to merge.
Requested by A
Summary
One narrow parser hardening for WHO 13, documentation fixes, and six golden records from committed MyHOME captures. Every ASCII frame decodes exactly as before.
Fixed (runtime)
OWNGatewayEvent: value fields are ASCII digits only.str.isdigitandintaccept fullwidth digits, so*#13**12*0*3*80*1*214*135##decoded a MAC address,*#13**19*1*2*3*4##an uptime and*#13**15*23##anUnknown (23)device type; such frames now stay untyped events with the raw frame as their log, as the Dimension 27 allowlist already did (_is_ascii_digits). A fullwidth digit in a clock field (*#13**1*03*26*10*2026##,*#13**0*12*00*00*001##, the Dimension 22 form) raised aValueErrorout ofdate()/fromisoformat; it now raises the sameValueError("Invalid gateway date" / "Invalid gateway timezone")as any other malformed clock value, which the sessions catch (fix(gateway): WHO 13 clock echoes with timezone 0530/124 no longer raise #144;_gateway_timezonematches withre.ASCII). The review's empty-token cases (*#13**1**01*01*2026##,*#13**22*...*001**01*...##,*#13**12*0**80*...##,*#13**15*##,*#13**19**0*0*0##) never raised onmaster(no weekday is decoded; Dimensions 12 / 19 are guarded) and are pinned as such intests/test_who13_ascii_values.py.Documentation only
docs/protocol_conformance_matrix.md: the WHO 13 examples are the published empty-WHEREread form*#13**0##/*#13**22##(Encyclopedia who-13-integration-gateway/dimensions.md "Read form"), the formOWNGatewayCommand.request_time()and the keepalive emit; own-firmware-oracleownd-audit-frames,who13-clockandwho13-clock-readbackhave all thirteen emulated gateways answering them with ACK and the time, while the old*#13*0*0##isnack, silenton all thirteen (ownd-audit-frames).OWNGatewayCommand.request_ip_address/request_netmask/request_mac_address: docstring caveat fromwho13-identification: answered by 8 of 13, ACKed silently by F453, F453AV and MH200N, NACKed with a worker crash by H4684 020054 and MH200 020102. Not refused at the send layer.OWNHeatingCommand.actuators_status:#Z#Cis zoneZthrough a four-zone central unitC(a controlled-zone address, not an actuator; feat(heating): OWNHeatingCommand.actuators_status(where) builder for *#4*WHERE*20## #140 leftover).OWNGatewayEvent.device_type/WHO13_DEVICE_TYPES: an unlisted Dimension 15 code staysUnknown (N); the non-unique200is a list of sharers, told apart by WHO 1013 Dimension 1.tests/golden/frames/who13_gateway.yaml(+6,community-plant-capture): F461 2.0.11*#13**0*17*45*24*999##,*#13**16*2*0*11##,*#13**23*5*10*35##,*#13**24*2*26*4##(MyHOME#865,f461_live_2026-11-04sweep),*#13**22*22*59*16*999*01*26*10*2026##(f461_who13_clock_tz_live_2026-10-26, line 309) and H/L4684 6.0.11*#13**15*23##(issue_466/config_entry-myhome_HL4684_fw6_0_11.json); corpus regenerated (172 frames), golden README count 172.tests/test_message_protocol.py: a regression test pinning the "Gateway broadcasting ..." log text MyHOME relies on.Review follow-up (round 2, 2026-11-10)
999attribution; golden frames999datetime is the physical F461 (f461_who13_clock_tz_live_2026-10-26line 309), not MH200N (001) or MH202 (002). The six frames are now golden records.origin/master(1cb2dc1) merged; the documentation bullet is gone; the### Fixedentry covers the ASCII hardening only.master(code and probe: no weekday decoding, Dimensions 12 / 19 guarded,*#13**15*##readsUnknown ()); the non-ASCII half of each case does, and is fixed with_is_ascii_digits/re.ASCII. Clock fields keep raisingValueError, by #144.Review follow-up (round 3, 2026-11-12)
masterafter #157, #159 and #160 landed)origin/masterc546a2emerged (fa54e90, one conflict: the golden README fixture count, #159's 166 against this PR's 172);corpus.jsonregenerated (172, byte-identical to the merge result). #159's testtest_golden_corpus_dimension_10_write_is_conflict_and_no_tiltpins that count literally, so the pin moves from 166 to 172 (a8573f2). No other file differs from the round-2 head.Testing
ruff check OWNd tests setup.py scripts,mypy OWNd tests/typing,python scripts/verify_library_standards.py,python scripts/sync_documentation.py --check,python tools/golden/validate_corpus.py(172 frames).python -m pytest -q -p pytest_cov --cov=OWNd --cov-report=xmlona8573f2: 3348 passed;python scripts/verify_coverage.py coverage.xml 80.0: 28 of 28 OWNd modules at 100 % (tests/test_who13_ascii_values.py: 14).v2-phase1-architecture(f19adc57) suite witha8573f2onPYTHONPATH:5601 passed, 1 deselected in 452.43s(the deselected one is the knowntest_check_all_documentation_real_treepin signal).corpus.jsonand fix(automation): WHO 2 builders validate WHERE with require_address_where, ASCII-only priority string; WHO 2 / WHO 9 documentation and golden-corpus errata (Encyclopedia audit, group 2) #159's pin intests/test_who2_audit_fixes.pyto 172.🤖 Generated with Claude Code