Repository navigation
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
own-firmware-oracle who13-clock: `*OpenWebNet-HA#13**#0*14*30*00*0530##` is ACKed and echoed on the event session by nine gateways (F454, F459 NACK; MyHomeServer1 silent), `…*124##` by eleven, and the F450 reports the stored `0530` on later reads (who13-clock-readback). `_gateway_timezone` raised ValueError on both and the exception left the event session. The two measured values define two bounded classes, a four-digit value with a sign digit and a three-digit negative offset of 24 h or more. Their layout and meaning are unverified, so `timezone` is None (unknown), never "" (local time), `raw_timezone` keeps the value, and the time / datetime are naive. `200`, `099`, `2000`, `05300` and the like still raise (MyHOME tests/test_gateway_regressions.py pins `099` and `200`). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
d93484d to
5b588fc
Compare
… only The helper's docstring said it raises ValueError for 099, but it returned "+99:00" and the error came from time.fromisoformat in the caller with a timedelta message. It now refuses a positive SHH whose hour is 24 or more (024..099) with its own message, and the shape check is ASCII-bound so a Unicode digit such as "0٢٣" no longer slips through to fromisoformat. Whole-frame behaviour is unchanged (those frames already raised); the docstring states the three classes exactly and two helper-level tests pin them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Self-correction in da77a53 (no review asked for it). @GreenGrassBlueOcean a quick confirmation would be welcome. Context. This PR makes clock echoes with the unmapped timezone classes How it was found. Reading the helper's docstring against what it returns: it said Live check (2026-10-26 16:45 UTC). What changed. The helper refuses a positive |
|
@gdluck could you capture a live trace for this on the F461 2.0.11? "Where are the traces" currently says Plant: F461 only. Per the oracle ( Setup: an event-only listener running for the whole capture, plus a command session for the writes. Use the current local time and today's date in every write rather than Sequence:
Deliverable: a MyHOME trace archive ( This would settle three things: whether the real F461 behaves as its emulation does, whether the read-back path is live on an F461 or only on the F450, and whether |
|
Captured as asked, on the F461 2.0.11 with the sequence you specified (current local time in every write, listener for the whole run, one spontaneous 10-minute broadcast, restore last), plus the same run on a MyHomeServer1 3.87.13 since the user allowed the writes for this test. Archive: OpenWebNet-HA/MyHOME#823 ( The three things it settles:
MyHomeServer1: dimension 0 writes ( |
Requested by A
Summary
*#13**#0*14*30*00*0530##and...*124##are clock writes whose timezone value is not the documentedSHHform: a four-digit value with a sign digit (0530) and a three-digit negative offset of 24 h or more (124). Most gateways ACK such writes and echo them on the event session, and the F450 reports the stored0530on later reads._gateway_timezoneraisedValueError: Invalid gateway timezone: '0530'on the first and, for124,datetime.timezonerefused a 24 h offset; the exception propagated out of the event-session parse.What the values mean is not verified by any capture (an ACK and an echo prove that the gateway stores the value, not what it means), so this PR decodes them as unknown (
timezone is None), never as local time (""), and keepsraw_timezoneas sent. Split out of #138.Changes
OWNd/message/gateway.py:_UNMAPPED_TIMEZONE_REGEX = [01][0-9]{3}|1(?:2[4-9]|[3-9][0-9]), the two classes the measured values belong to, bounded by the sign digit and the length (0000..1999) and by the first negative offsetdatetime.timezonecannot hold (124..199;123is still-23:00)._gateway_timezonereturnsNonefor them (type nowstr | None); the fourfromisoformatcall sites useself._timezone or "", so the parsedtime/datetimeare naive.raw_timezonekeeps the value;is_timezone_unconfiguredstaysFalse(that is the999sentinel). Thetimezoneproperty docstring says whatNonemeans. This covers both the echo of a write (OWNGatewayCommand,*#13**#0*...##and*#13**#22*...##) and the read reply (OWNGatewayEvent, dimensions 0 and 22).200,099,024,2,12,2000,9999,2400,05300,00530. (Revision da77a53:_gateway_timezoneitself refuses a positiveSHHwith hour 24..99 and is ASCII-bound; the first revision's docstring said the helper raised for099while it returned+99:00and the error came fromtime.fromisoformatin the caller.) MyHOME'stests/test_gateway_regressions.py:41(test_malformed_gateway_clock_fields_are_rejected) requires*#13**0*15*00*00*200##and...*099##to keep raising; they do.CHANGELOG.md: entry under[Unreleased]/Fixed.MyHOME does not read
OWNGatewayEvent.timezoneorraw_timezone(custom_components/myhomeatv2-phase1-architecture: no consumer), soNonereaches no integration code today; a future consumer gets "unknown", not "local".State Diagram
stateDiagram-v2 direction TB state "_gateway_timezone(values[3]) for *#13**0*HH*MM*SS*T## and the #0 / #22 / 22 forms" as TZ { [*] --> Classify Classify --> Local : or 999\ntimezone , unchanged Classify --> Offset : SHH, S in 0/1, HH 00..23\n+02 -00 / -23 -00 , unchanged Classify --> Unknown : 0000..1999 , sign + three digits, 0530 measured\nor 124..199 ,24 h or more, 124 measured\ntimezone None, raw_timezone kept, naive time , new - before - ValueError out of the event session Classify --> Rejected : 200, 099, 024, 2000, 05300, ...\nValueError , unchanged }Where are the traces
tests/fixtures/traces/f461_who13_clock_tz_live_2026-10-26/in MyHOME (OpenWebNet-HA/MyHOME#823, commite0426cc): the live F461 2.0.11 capture of 2026-10-26 asked for in the review, 16 event frames / 79 rows,README.md+myhome_trace_F461_who13_clock_tz_live_2026-10-26.jsonwith every row decoded by both OWNdmaster050dc1d (ownd_master_*/ownd_master_error) and this headda77a53(ownd_*), andtests/test_f461_who13_clock_tz_live_2026_10_26_trace.py(22 tests, passing onmaster, on this head and on the 2.0.0b11 pin; the fail-before / pass-after of the written strings is pinned as the two recorded outcomes). The earlier live reads (*#13**0*...*999##on the F461 and MyHomeServer1, trace PR OpenWebNet-HA/MyHOME#799) parsed before and after.Hardware Verification (2026-10-26)
Captured live on the F461 2.0.11 (event-only listener for the whole run + a probe command session, both on this head; the probe refuses to send what its OWNd cannot parse, so
mastercould not have sent these writes). Every write with the current local time and today's date:*#13**#0*HH*MM*SS*0530##,*#13**#0*HH*MM*SS*124##,*#13**#22*HH*MM*SS*0530*W*DD*MM*YYYY##and the124variant were each ACKed in 9-18 ms with no reply, and nothing was echoed on the event session (not within the 3 s after each write, not anywhere in the 13-minute window). Every*#13**0##/*#13**22##read-back, before and after each write, answered999(also delivered on the event session). The spontaneous 10-minute broadcast at 20:50:00 UTC, with124the last value written, was*#13**#1*01*26*10*2026##+*#13**#0*22*50*00*##: empty time-zone field. The restore*#13**#0*HH*MM*SS*999##was ACKed in 12 ms and not echoed either (the oracle's emulated F461020011isack/outon these writes; the physical one isack/silent), read-backs999. So the real F461 behaves like the F454 / F459 "ACK, keep the old value" column rather than its own emulation: it neither stores nor echoes a non-standard offset, the read-back path (OWNGatewayEventwith0530) is live only on the emulated F450, andmaster'sValueErrorcannot escape the event session on a physical F461 echo because the gateway never emits one. Wheremasterdoes raise is on the written command string itself (*#13**#0*22*46*45*0530##->Invalid gateway timezone: '0530'; the124forms -> thetimedeltarange error); this head parses them asOWNGatewayCommandwithtimezone Noneandraw_timezonekept. The same sequence on the MyHomeServer1 3.87.13 (the user allowed the writes for this test): dimension 0 writes (0530,124, even the999restore) get no reply at all (10 s timeout, no ACK / NACK, no echo) and the next command is answered only after ~7 s; dimension 22 writes ACK in 0.01 s without an echo; read-backs999; clock unchanged, as the028206emulation says, so it adds nothing beyond confirming the emulation (its frames stay out of the repository: the listener holds the house's own traffic).What does the Oracle say
Suite
who13-clock,results/<P>/<V>/oracle/full/who13-clock.tsv:ack/out(echoed on the event session)ack/silentnack/silent-/silent*#13**#0*14*30*00*0530##020010, F453010100, F453AV030014, F460020012, F461020011, H4684020054, MH200020102, MH200N010108, MH202010024(9)020051, F459020105028206*#13**#0*14*30*00*124##020105(10)020051(ACK, no echo)028206*#13**#22*14*30*00*0530*03*21*10*2026##028206F453, F453AV, H4684, MH200 and MH200N also put the clock on the bus (
bus:columns). Suitewho13-clock-readback(findings/who13-clock.md, "Read-back after a write"): after*#13**#0*14*30*00*0530##the F450 reportsT=0530on later reads, "the only firmware that echoes a non-standard offset back"; F454 and F459 keep102because they NACKed0530. So both the echo path (OWNGatewayCommand) and the reply path (OWNGatewayEvent) need the tolerance. No row says what the gateway does with the value, henceNone.Testing
tests/test_who13_clock_echo_timezones.py(new, 43 cases): two helper-level tests pin where024..099,200,2000,+02,02and a Unicode-digit value raise and that000/023/123still decode; the#0and#22echoes with0530/124parse asOWNGatewayCommandwithtimezone is None,raw_timezoneas sent,is_timezone_unconfigured False, a naive 14:30:00 and the date kept; the dimension 0 and 22 replies with0530/124parse asOWNGatewayEventthe same way; five unmeasured members of the two classes (0000,1999,1240,125,199) areNonetoo; eleven values outside them still raise (200,099,024,2,12,2000,9999,2400,05300,00530); whole-hour offsets000..123still decode (123is-23:00);999and empty still mean local time.master14 fail, 18 pass (0530raisesInvalid gateway timezone;124raises thetimedeltarange error); on this branch all 32 pass.2082 passed, 1 skipped; 100 % statement coverage,mypyclean (str | Noneend to end),ruffclean,scripts/sync_documentation.py --checkandscripts/verify_library_standards.pypass.Live retest (2026-10-24 and 2026-10-26)
Not exercised live: both plants report
999; no0530/124was written to a real gateway (clock writes on a real home were out of scope).Exercised live on 2026-10-26 on the F461 2.0.11 and the MyHomeServer1 3.87.13 with the
0530/124writes themselves: see Hardware Verification above and OpenWebNet-HA/MyHOME#823.Companion
None. Split from #138 (
#-prefixed dimension 14 setpoints).🤖 Generated with Claude Code