Skip to content

feat(gateway): WHO 13 dimension 27 model-name decoder - #139

Draft
gdluck wants to merge 1 commit into
OpenWebNet-HA:masterfrom
gdluck:feat/who13-model-name-and-who1001-diagnostic
Draft

gdluck wants to merge 1 commit into
OpenWebNet-HA:masterfrom
gdluck:feat/who13-model-name-and-who1001-diagnostic

Conversation

@gdluck

@gdluck gdluck commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Requested by A

Summary

The physical F461 2.0.11 answers *#13**27## with *#13**27*70#52#54#49##: its model name as #-separated ASCII codes (70 52 54 49 = "F461"). A physical MyHomeServer1 3.87.13 answers *#13**27*77#121#72#111#109#101#83#101#114#118#101#114#49## ("MyHomeServer1"). The dimension-reply regex accepts only digits in values, so OWNMessage.parse returned None, the event session handed the raw str on and MyHOME logged "Data received is not a message". It was the only one of the 69 events captured on 2026-10-23 (68 typed, 1 raw) that did not come back as a typed class.

Refs OpenWebNet-HA/MyHOME#799 (both captures). The WHO 1001 diagnostic event that this PR carried at first is now its own PR (see Companion): different evidence, different reviewers.

Changes

  • OWNd/message/base.py: _HASH_VALUE_REPLIES, a narrow allowlist of reply shapes that carry a # inside a value, limited here to WHO 13 Dimension 27 with a single #-separated value (*#13**27*C1#C2#...##). It is tried after the general reply regex, which is unchanged. The new branch fills the same fields as the general one, including _dimension_param.
  • OWNd/message/gateway.py: OWNGatewayEvent.model_name decodes Dimension 27 only when the reply has exactly one value that contains # and every code is printable ASCII (32..126); human_readable_log reads "Gateway's model name is: F461.". The general *-separated form (*#13**27*70*52*54*49##) and a single code without # (*#13**27*70##) are not a model name: model_name stays None (fail closed; the first version of this PR would have decoded the former as "F"). *#13**27## is still an OWNGatewayCommand dimension request.
  • CHANGELOG.md: entry under [Unreleased] / Added.

State Diagram

stateDiagram-v2
    direction TB

    state "OWNMessage.parse(*#13**27*...##)" as Parse {
        [*] --> General
        General --> Plain : *#13**27*70*52*54*49## , *-separated, general regex\nOWNGatewayEvent, model_name None , fail closed
        General --> HashAllowlist : # inside the value - general regex does not match
        HashAllowlist --> Name : *#13**27*70#52#54#49## , one value, #-separated, printable ASCII\nOWNGatewayEvent, model_name F461 , new - before - None, Data received is not a message
        HashAllowlist --> NoName : *#13**27*70#7#300## , non-printable code\nOWNGatewayEvent, model_name None
        HashAllowlist --> NoneResult : *#13**27*70#52#54#49*1##, *#13**12*70#52##, *#1*11*1*#5##\nNone , unchanged
    }
Loading

Where are the traces

Subsystem Capture Plant Frames verified by this PR
WHO 13 dimension 27 trace PR: OpenWebNet-HA/MyHOME#799 (merged), f461_live_2026-10-23 run 1 (run1_oracle_replay_readonly); the frame is in pending_decoder_rx of tests/test_trace_oracle_validation.py there, citing this PR BTicino F461 2.0.11 (*#13**16*2*0*11##) *#13**27## -> *#13**27*70#52#54#49## ("F461"), returned on the command session and delivered on the event session
WHO 13 dimension 27 trace PR: OpenWebNet-HA/MyHOME#799 (merged), myhomeserver1_live_2026-10-24 run 1 (run1_identify) MyHomeServer1 3.87.13 (*#13**16*3*87*13##) *#13**27## -> *#13**27*77#121#72#111#109#101#83#101#114#118#101#114#49## ("MyHomeServer1")

What does the Oracle say

No oracle stimulus exists for this frame: no suite sends *#13**27##. The two physical captures above are the evidence.

Testing

  • tests/test_who13_model_name.py (new, 10 cases): the F461 and MyHomeServer1 replies parse as OWNGatewayEvent with the raw dimension_value, dimension_param == [], the decoded model_name, the log line and str(message) unchanged; non-printable codes leave model_name None; the *-separated form and a single code without # leave it None; *#13**27## is a dimension request; a second value after the codes, another dimension with a # value and a WHO 1 # value still do not parse.
  • Fail before / pass after: on master 5 fail, 5 pass (OWNMessage.parse('*#13**27*70#52#54#49##') has no model_name; the request shape and the negative cases already pass); on this branch all 10 pass. Re-verified 2026-10-24 on both plants with plain OWNd master as the sender: *#13**27## -> *#13**27*70#52#54#49## (F461 2.0.11, 14 ms) and *#13**27*77#121#72#111#109#101#83#101#114#118#101#114#49## (MyHomeServer1 3.87.13, 21 ms); this head decodes them to F461 / MyHomeServer1, master to None.
  • Full suite: 1917 passed, 1 skipped (master: 1907 passed, 1 skipped); 100 % statement coverage, mypy clean, ruff clean, scripts/sync_documentation.py --check and scripts/verify_library_standards.py pass.

Live retest (2026-10-24)

Confirmed, narrowly: on the F461 2.0.11 with this decoder, *#13**27## -> *#13**27*70#52#54#49## and the HA log reads Gateway's model name is: F461. instead of "Data received is not a message". It is not wired into MyHOME's diagnostics (identification.who13_model stays null); that is a separate MyHOME change.

Companion

MyHOME: none required (OpenWebNet-HA/MyHOME#802 rate-limits the warning meanwhile; OpenWebNet-HA/MyHOME#799 carries the traces). Related OWNd PR (split from this one): feat(lighting): WHO 1001 dimension 11 diagnostic event: #145.

CI note (expected red check)

The MyHOME test suite job runs MyHOME against this branch. MyHOME's tests/test_trace_oracle_validation.py lists the two dimension-27 frames of the merged trace PR OpenWebNet-HA/MyHOME#799 in pending_decoder_rx and, by the maintainers' request on that PR, asserts loudly that they still parse to None until the OWNd pin is bumped. This decoder makes them parse, so that single job is red by construction (remove … from pending_decoder_rx: the OWNd pin now decodes it). The cleanup is a one-line MyHOME change that belongs with the pin bump; every other check is green.

🤖 Generated with Claude Code

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@gdluck
gdluck marked this pull request as draft October 24, 2026 13:39
A live F461 2.0.11 answers `*OpenWebNet-HA#13**27##` with `*OpenWebNet-HA#13**27*70#52#54#49##`
("F461" as '#'-separated ASCII codes) and a live MyHomeServer1 3.87.13
with `*OpenWebNet-HA#13**27*77#121#…OpenWebNet-HA#49##` ("MyHomeServer1"); both are in the
MyHOME#799 trace fixtures. The dimension-reply regex accepts digits only,
so OWNMessage.parse returned None and MyHOME logged "Data received is not
a message".

A narrow allowlist (_HASH_VALUE_REPLIES, WHO 13 dimension 27 only) routes
the single '#'-separated value to OWNGatewayEvent, whose model_name
decodes it when every code is printable ASCII. The general '*'-separated
form (`*OpenWebNet-HA#13**27*70*52*54*49##`) and a single code without '#' are not
decoded (model_name None). `*OpenWebNet-HA#13**27##` stays a dimension request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gdluck
gdluck force-pushed the feat/who13-model-name-and-who1001-diagnostic branch from 0bf88b6 to d51cf77 Compare October 24, 2026 15:49
@gdluck gdluck changed the title feat(message): WHO 13 dimension 27 model-name decoder and WHO 1001 dimension 11 diagnostic event feat(gateway): WHO 13 dimension 27 model-name decoder Oct 24, 2026

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants