Repository navigation
chore(profiles): derive the discovery rows from the OWNd profile (prep for OWNd #142) - #808
Conversation
9dcb76c to
b06248b
Compare
|
@gdluck i double check the firmware oracle and made a fix for the stale who16 please double check with the oracle and fix failing ci |
b06248b to
09dd4b5
Compare
|
Checked with the refreshed oracle and fixed the CI (head 88ed3fa, rebased on the current base, still draft). CI cause and fix. The quality-scale, test-coverage and docs jobs run the docs check without OWNd installed; this PR's first push derived the discovery rows from the installed profile and, with no OWNd, printed "unknown" rows, so the regenerated table no longer matched Oracle re-check (main 72759e8, after #62). F461 020011 and MyHomeServer1 028206 still answer nack / silent to all 86 WHO 16 inputs (77 in Suite 4514 passed at 100 % coverage against the pinned OWNd; against the OWNd #142 branch the profile, conformance and trace-oracle tests pass (711) and only the docs-equality checks report the expected pin-bump drift, resolved by |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@gdluck please rebase |
88ed3fa to
bfc1c27
Compare
|
Rebased onto
Suite with OWNd master 87cafc3: 4965 passed / 1 skipped at 100 % coverage; with the OpenWebNet-HA/OWNd#142 checkout: 4964 passed and the single expected docs-drift failure on the committed tree (the two rows a pin bump regenerates), 4965 passed / 1 skipped with the pin bump rehearsed ( |
…p for OWNd OpenWebNet-HA#142) scripts/update_gateway_profiles.py carried a static `queried_whos` list per discovery row next to the derived one, and the oracle check compared the two, so an OWNd profile change (OWNd OpenWebNet-HA#142 drops WHO 16 from the F461 and the MyHomeServer1) turned the check and the docs test red until the list was edited by hand. The rows now come only from the installed OWNd profile over STARTUP_DISCOVERY_WHOS, the rule the startup gate in gateway.py applies, and the sound wording of a row follows `supports_who(16)`. Green against the pinned OWNd today; after OWNd OpenWebNet-HA#142 lands and the pin is bumped, `sync_documentation.py --update` regenerates the two rows and nothing else needs an edit. Tests pin both shapes with a profile double. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…tical with and without OWNd (CI follow-up)
The quality-scale, test-coverage and docs CI jobs run scripts/verify_ha_standards.py and
scripts/sync_documentation.py --check without OWNd installed ("[OWND] Client library
verification skipped (OWNd not in path: No module named 'OWNd')"). The first push derived
the startup discovery rows from the installed OWNd profile only and printed
"unknown (OWNd profile not available)" otherwise, so those jobs regenerated a table that
differed from the committed docs/getting-started/hardware-compatibility.md:
"[RULE_DOCS_ANTI_DRIFT] Gateway Discovery table out of sync".
Each discovery row now carries pinned_whos, the row the pinned OWNd 2.0.0b11 yields; it is
used only when OWNd is not importable, so the generated table is byte-identical with and
without OWNd. With OWNd importable the row is still derived from profile.supports_who over
STARTUP_DISCOVERY_WHOS, as the startup gate does, and notes_without_who16 applies whenever
the row does not carry WHO 16. verify_profiles_against_oracle() flags a row whose
profile_name resolves to the generic profile (get_gateway_profile() never returns None).
Tests: without OWNd every row carries exactly its pinned_whos and the generated block equals
the committed one; with OWNd the derived block equals the committed one (installed profile ==
committed table == pinned_whos); pinned_whos is ignored when OWNd is importable. Fail-before
on the first-push script: 3 of 18 fail; all pass after. sync_documentation.py --check passes
in a venv without OWNd and with OWNd master (f04d8aa) on PYTHONPATH. Against the OWNd OpenWebNet-HA#142
branch (95dc8a5) the two docs-equality tests report the drift that the pin bump resolves
with --update together with pinned_whos.
Oracle re-check at own-firmware-oracle main 72759e8 (results/mcp_index.json, schema 1.2.0,
529 inputs): F461 020011 and MyHomeServer1 028206 still answer nack/silent to all 86 WHO 16
inputs (*OpenWebNet-HA#16*0*5## sound-who16-source.tsv line 16, *OpenWebNet-HA#16*101*5## line 28), unchanged from
53f9514.
Refs OpenWebNet-HA/OWNd#142.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… bump (rebase on OpenWebNet-HA#794) After the rebase the discovery rows carry both OpenWebNet-HA#794's `sweep_omits` (the general requests the firmware drops) and this branch's `pinned_whos` (the no-OWNd fallback), while the advertised column is derived from the installed OWNd profile. Two tests pin the interplay at the OWNd OpenWebNet-HA#142 pin bump: - `verify_profiles_against_oracle()` checks `sweep_omits` against `pinned_whos`, so once the F461 / MyHomeServer1 rows drop WHO 16 a leftover `*OpenWebNet-HA#16*0*5##` is flagged (and a `pinned_whos` entry the startup sweep never asks for is flagged too); the F455 / unknown-frame cases of OpenWebNet-HA#794 are unchanged. - Without an importable OWNd, `pinned_whos` without WHO 16 yields the `WHO 1, 2, 4, 18` row, the reduced `(firmware drops `*michnovka#4*0##`)` sent column and the WHO 22 wording, so the CI jobs that run the docs check without OWNd regenerate the same table as the pinned OWNd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…O 16 where the row declares it (review follow-up) `verify_profiles_against_oracle()` checked `sweep_omits` against `pinned_whos` but never `pinned_whos` against a profile, so a mistyped pin (an F455 row given WHO 16 and a matching `*OpenWebNet-HA#16*0*5##` omission, or a row that lost WHO 4) passed the check and the no-OWNd table would have followed it. Now a pin that differs from the installed profile is flagged, except by WHO 16 on a row that carries `notes_without_who16` (the F461 / MyHomeServer1 switch of OWNd OpenWebNet-HA#142, the one change the fallback is meant to absorb between the pinned release and the next), so the check is green with the pinned OWNd and with the OWNd OpenWebNet-HA#142 checkout alike and catches a stale pin at the pin bump together with the stale omission. Hardening from the same review: `pinned_whos` that is not a list of WHO numbers is a violation instead of a `ValueError` / `TypeError`, and such a row (or a profile lookup that yields nothing) generates `none` cells with no omissions and the plain notes rather than an unfinished sent cell and an unjustified WHO 22 wording. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…back in sweep order (review follow-up) A `pinned_whos` such as `[1, 1, 2, 4, 18]` or `[2, 1, 4, 18]` compared equal to the profile as a set and, without OWNd, was rendered as written. The oracle check now requires the pin in STARTUP_DISCOVERY_WHOS order without repeats (the order the sweep sends, the order `discovery_whos_for` yields), and the no-OWNd fallback renders the pin in that order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A pin-bump rehearsal (pinned_whos of the F461 / MyHomeServer1 rows set to [1, 2, 4, 18], `*OpenWebNet-HA#16*0*5##` removed from their sweep_omits, `sync_documentation.py --update`) left two tests red for no reason of the code: one asserted the pre-bump WHO 16 literal of the two rows (the committed-docs equality test pins that already), the other assumed the pre-bump sweep_omits of the MyHomeServer1 row. Both now state their own precondition, so the pin bump edits the rows, the docs and nothing in this file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
bfc1c27 to
1e346c3
Compare
|
Rebased once more onto |
GreenGrassBlueOcean
left a comment
There was a problem hiding this comment.
@gdluck Clean rebase and reconciliation with #794 and #818 — verified the discovery_whos_for derivation, the pinned_whos no-OWNd CI fallback, the sweep_omits / notes_without_who16 transition rules, and the refreshed own-firmware-oracle (72759e8) WHO 16 verdicts on F461 (020011) and MyHomeServer1 (028206). All 17 CI checks are green.
One final item before merge (inline below):
- Add a negative unit test in
tests/test_gateway_profiles.pyfor the newGenericGatewayProfileguard inverify_profiles_against_oracle()(scripts/update_gateway_profiles.py:642-646), asserting that a discovery row whoseprofile_nameis"Generic"or an unknown model string (resolving toGenericGatewayProfile) emits the"resolves to the generic profile"violation.
Once that test is added (and you mark the PR Ready for review), I will merge right away.
| if isinstance(prof, GenericGatewayProfile): | ||
| violations.append( | ||
| f"Discovery row {row.get('model')} names an OWNd profile that does not exist: " | ||
| f"{prof_name} (resolves to the generic profile)." | ||
| ) |
There was a problem hiding this comment.
This new isinstance(prof, GenericGatewayProfile) guard fixes the earlier vacuous is None check, but none of the negative tests in tests/test_gateway_profiles.py exercise it yet. Please add a quick negative test case (e.g. inside test_oracle_check_rejects_a_pin_that_disagrees_with_the_installed_profile or a dedicated test) setting a row's profile_name to "Generic" or a nonexistent model name and asserting "resolves to the generic profile" is reported in violations.
…is flagged (review follow-up) Negative test for the GenericGatewayProfile guard of verify_profiles_against_oracle(): a row whose profile_name is "Generic" or an unknown model string reports "resolves to the generic profile" for that row and for no other. Fails with the previous `is None` check, passes with the guard. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Added in fd20792: |
f4a5a90
into
OpenWebNet-HA:v2-phase1-architecture
…s mirror at the edges (OpenWebNet-HA#808 follow-up) The docstring said the script "mirrors MyHOMEGatewayHandler._profile_supports_who"; the runtime gate fails open (every WHO when supports_who is missing or raises), the script fails closed ([] when missing) and propagates when supports_who raises, and test_discovery_whos_follow_the_runtime_gate pins the divergent discovery_whos_for(object()) == []. Real OWNd profiles agree. The docstring and the test's say so. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Requested by A
The MyHOME companion of OpenWebNet-HA/OWNd#142 (
fix(profiles): drop WHO 16 from the F461 and MyHomeServer1 profiles). Sequencing: merge this → merge OpenWebNet-HA/OWNd#142 → OWNd release → bump the OWNd pin here, andscripts/sync_documentation.py --updateregenerates the two docs rows together with thepinned_whosfallback below (one edit inscripts/update_gateway_profiles.py).Rebase after #794 (2026-10-26)
Rebased on
v2-phase1-architectureata27b32f6(after #794, #793, #797, #798, #801 and #804); the two commits of the first push are kept and reconciled with #794 in place, three follow-up commits on top. Base SHAa27b32f6, branch headbfc1c270.What #794 and this PR each bring, and how they are reconciled (the three conflicts:
.github/release-notes/2.0.0b16.md,scripts/update_gateway_profiles.py,tests/test_gateway_profiles.py):sweep_omits(the general requests the firmware drops,*#4*0##/*#16*0*5##), itsnotesper row, the MH200 / MH200N split and the H4684 row, thesweep_omitsvalidator andtests/test_startup_requests_per_firmware.py::test_hardware_compatibility_table_matches_the_sweep(unchanged: it compares the calibrated rows withMyHOMEGatewayHandler._discovery_frames()), plus fix(climate): do not poll humidity (dimension 60) where the emulated firmware did not forward it #793'sKNOWN_GATEWAY_MODELSresolver ingateway.py.discovery_whos_for, the rule of the startup gate), no row carries a staticqueried_whos;pinned_whosis the no-OWNd fallback (the rows the pinned OWNd 2.0.0b11 yields; thequality-scale,test-coverageanddocsCI jobs run the docs check without OWNd);notes_without_who16on the F461 / MyHomeServer1 rows switches the wording with the profile.queried_whosequals the profile" is replaced by the derivation plus thepinned_whosfallback. When a WHO is not advertised, a general request of it is no omission of the sweep (nothing is sent for that WHO at all), socalibrate_discovery_with_ownd()drops that frame from the generated row: with OWNd How to install this extension properly? #142 onPYTHONPATHthe F461 row becomes| WHO 1, 2, 4, 18 | WHO 1, 2, 18 (firmware dropsthe shutters does not work in homekit #40##) | ... Sound is WHO 22 only ... |, exactly what_discovery_frames()sends (*#1*0##,*#2*0##,*#18*51*51##,*#18*51*113##) and what the unchanged fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794 sweep test checks.notes_without_who16carries fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794's firmware facts (*#4*0##dropped, zones polled with*#4*<WHERE>##, the oracle firmware ids and the live confirmations) with the WHO 22 wording.verify_profiles_against_oracle()after the rebase: every row must name a real OWNd profile (not the generic fallback);pinned_whosmust be WHO numbers of the startup sweep, in sweep order without repeats, and must equal the installed profile's advertised WHOs except by WHO 16 on a row that declaresnotes_without_who16(the one profile change the fallback is meant to absorb between the pinned release and the next, fix(profiles): drop WHO 16 from the F461 and MyHomeServer1 profiles OWNd#142), so the check is green with the pinned OWNd and with the OWNd How to install this extension properly? #142 checkout alike and flags a stale pin at the pin bump;sweep_omitsmust be*#4*0##/*#16*0*5##of a WHO inpinned_whos(fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794's rule, now against the pin: a leftover*#16*0*5##is flagged once the pin drops WHO 16). A malformedpinned_whosis a violation rather than an exception, and such a row rendersnonecells with the plain notes.Suite against both OWNd checkouts (venv with HA 2026.10.2, Python 3.14,
pytest -n 4; the OWNd checkout onPYTHONPATH):PYTHONPATHmaster87cafc3(#136 merged; the behaviour of the 2.0.0b11 pin)verify_ownd_coverage.py100 % (16,770 / 16,770 statements, 0 missing)fix/profiles-f461-mhs1-no-who1695dc8a5(OpenWebNet-HA/OWNd#142, onf04d8aa)tests/test_sync_documentation.py::test_check_all_documentation_real_tree, "Gateway Discovery table out of sync" (the F461 / MyHomeServer1 rows the pin bump regenerates);sync_documentation.py --checkreports the same two rows and nothing else (no oracle violation)fix/profiles-f461-mhs1-no-who1695dc8a5, pin-bump rehearsalpinned_whosof the two rows set to[1, 2, 4, 18],*#16*0*5##removed from theirsweep_omits,sync_documentation.py --update: only the F461 and MyHomeServer1 rows change (docs/getting-started/hardware-compatibility.md: 2 lines, `WHO 1, 2, 4, 18Checks on the final head with OWNd
master:ruff check .,scripts/typing_ratchet.py(0 errors, baseline 0),scripts/verify_ha_standards.py(with OWNd and without),scripts/sync_documentation.py --check(with OWNd and without),scripts/manage_translations.py check.tests/test_gateway_profiles.pynow has 25 tests;test_discovery_table_with_ownd_matches_the_committed_docscompares row by row and lets only the rows whose profile differs frompinned_whosdiffer (and requires them to), so it is right before and after the pin bump while--checkkeeps reporting the drift until--updateis run.Independent review (focus: the validator still rejects a wrong
sweep_omits; the derivation cannot silently drop a WHO the sweep sends; the no-OWNd fallback): agreed on all three for the shown rows; found thatpinned_whositself was not checked against any profile (a mistyped pin would have passed), that a malformed pin raised instead of being flagged, that a repeated or reordered pin passed as a set, and that an empty row rendered an unfinished sent cell with the WHO 22 wording. All four are fixed in the two follow-up commits and pinned by tests. Accepted residual, by design: on the two rows that declarenotes_without_who16the validator cannot tell "pin with WHO 16 against OWNd #142" from "pin without WHO 16 against the pinned release" (both OWNds report__version__2.0.0b11); the WHO 16 cell of those rows is pinned bytest_discovery_table_without_ownd_matches_the_committed_docs(pin equals the committed docs) and by thesweep_omitsrule (*#16*0*5##requires WHO 16 in the pin), not by the profile comparison.Review follow-up (review 5651153472)
test_oracle_check_rejects_a_row_that_resolves_to_the_generic_profilefor theGenericGatewayProfileguard ofverify_profiles_against_oracle(): a row whoseprofile_nameisGenericor an unknown model string reportsresolves to the generic profilefor that row and for no other; it fails with the previousis Nonecheck. Full suite 4991 passed / 1 skipped at 100 % coverage. Marked ready for review as asked.Review follow-up (CI red on the first push)
quality-scale,test-coverageanddocsjobs runscripts/verify_ha_standards.py/scripts/sync_documentation.py --checkwithout OWNd installed ([OWND] Client library verification skipped (OWNd not in path: No module named 'OWNd')in the same log). The first push removed the staticqueried_whosand printedunknown (OWNd profile not available)for every row when OWNd is not importable, so the regenerated table differed from the committed one:[RULE_DOCS_ANTI_DRIFT] Gateway Discovery table out of sync in docs/getting-started/hardware-compatibility.md. Locally the check had only been run with OWNd onPYTHONPATH.pinned_whos, the row the pinned OWNd (OWNd==2.0.0b11inmanifest.json) yields; it is used only when OWNd is not importable, so the generated table is byte-identical with and without OWNd. With OWNd importable the row is still derived from the installed profile. Reproduced and fixed locally:sync_documentation.py --checknow passes both in a venv without OWNd (pyyaml + ruff only, as in the CI jobs) and with OWNd master onPYTHONPATH;tests/test_gateway_profiles.py::test_discovery_table_without_ownd_matches_the_committed_docspins the fallback to the committed table and::test_discovery_table_with_ownd_matches_the_committed_docspins the derived table to it, soinstalled profile == committed table == pinned_whosis asserted explicitly.mainto72759e8, fix(oracle): write a past date in who13-clock so the DIM 1 verdict does not depend on the day own-firmware-oracle#61 and fix(results): refresh 7 stale sound-who22 TSVs and MCP index (#58) own-firmware-oracle#62): the WHO 16 verdicts for the F461 020011 and the MyHomeServer1 028206 are unchanged, see "What does the Firmware Oracle / Encyclopedia say" below.verify_profiles_against_oracle()now flags a discovery row whoseprofile_nameresolves to OWNd's generic profile (get_gateway_profile()never returnsNone, so the earlieris Nonecheck could not fire).What is the problem
scripts/update_gateway_profiles.pykeeps a staticqueried_whoslist per startup discovery row next to the list it derives from the installed OWNd profile, andverify_profiles_against_oracle()compares the two. The derived list is what the generateddocs/getting-started/hardware-compatibility.mdtable shows and what the runtime sends (the startup gate ingateway.pyasksprofile.supports_who(who)for every discovery WHO; #794 reads the same flag for the refused requests). When an OWNd profile changes, the static copy goes stale: with OpenWebNet-HA/OWNd#142 the F461 and MyHomeServer1 rows become[1, 2, 4, 18], the oracle check reportsDiscovery row **F461** queried_whos=[1, 2, 4, 16, 18] disagrees with F461 profile [1, 2, 4, 18],sync_documentation.py --checkfails andtests/test_gateway_profiles.pyasserts the old literal row. Hard-coding the new rows instead would be red against the pinned OWNd 2.0.0b11 today.Refs OpenWebNet-HA/OWNd#142; #794 (the runtime gate); #424 / #459 (the F461 / MyHomeServer1 plants that speak WHO 22 only, and the MyHomeServer1 "firmware discards 5, 16, 22" note). The combined test build (
combined/all-prs-2026-10-24, commit4a79e8cb) showed which files and tests are involved; its hard-coded rows are not used here.What is the solution
scripts/update_gateway_profiles.py:GATEWAY_DISCOVERY_METADATArows carrymodel,profile_name,pinned_whos(the no-OWNd fallback, see below) andnotes; noqueried_whos.discovery_whos_for(profile):[w for w in STARTUP_DISCOVERY_WHOS if profile.supports_who(w)], the ruleMyHOMEGatewayHandler._profile_supports_whoapplies at startup;[]for anything withoutsupports_who.calibrate_discovery_with_ownd()fillsqueried_whosfrom the installed profile for every row and keeps only thesweep_omitsof advertised WHOs (a request of a WHO that is not advertised is no omission: nothing is sent for it); the F461 and MyHomeServer1 rows carry anotes_without_who16text that replacesnoteswhen the row does not carry WHO 16 ("Sound is WHO 22 only (nobt_difson; every WHO 16 frame refused ...)", with fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794's*#4*0##facts), so the wording follows the profile too.quality-scale,test-coverageanddocsCI jobs) every row falls back topinned_whos, the row the pinned OWNd 2.0.0b11 yields, so the generated table is the same either way; nothing else is guessed. At a pin bump that changes a profile,pinned_whosis edited together withsync_documentation.py --update(the tests below fail until both are done).verify_profiles_against_oracle()no longer compares a static list with the profile; it checks that every discovery row names a real OWNd profile (not the generic fallback), thatpinned_whosis a sweep-ordered list of startup WHOs equal to the installed profile except by WHO 16 where the row declaresnotes_without_who16, and (fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794's rule, against the pin) that everysweep_omitsentry is*#4*0##/*#16*0*5##of a WHO inpinned_whos; the per-gatewaysupports_who/audio_measured/auth_measuredchecks againstfirmware_oracle.jsonare unchanged.tests/test_gateway_profiles.py: the F461 and MyHomeServer1 cells (advertised and sent) are asserted against the installed profile (right before and after fix(profiles): drop WHO 16 from the F461 and MyHomeServer1 profiles OWNd#142), the other rows stay literal;discovery_whos_formirrors the runtime gate for six profiles; a profile double without WHO 16 yields[1, 2, 4, 18], the reducedsweep_omitsand the WHO 22 wording for both rows while the F454 / MH202 rows are unchanged; without OWNd every row carries exactly itspinned_whosand the generated block equals the committed one; with OWNd the derived block equals the committed one row by row (only rows whose profile differs from the pin may differ);pinned_whosis ignored when OWNd is importable; the validator rejects a stale*#16*0*5##at the pin bump, a pin that disagrees with the installed profile (other than by WHO 16 where declared), a malformed, repeated or reordered pin; the no-OWNd fallback yields the WHO 22 row once the pin drops WHO 16.docs/getting-started/hardware-compatibility.md: unchanged in this PR (against the pinned OWNd the generated table is byte-identical). After the pin bump the F461 and MyHomeServer1 rows regenerate toWHO 1, 2, 4, 18with the WHO 22 note..github/release-notes/2.0.0b16.md: one line under "Other changes".Not changed here, named as follow-ups: the per-zone
*#16*ZONE*5##media-player poll (media_player.py) on a gateway whose profile lacks WHO 16 (one refused frame per configured WHO 16 zone; those entities cannot work on these gateways anyway, and the planned WHO 22 backend is the right gate); and the topology side effect of OpenWebNet-HA/OWNd#142 itself (topology.pydelegation: an F461 primary lets a WHO-16-capable follower own WHO 16 and 22, and a same-tier F454 / F461 pair is now ordered by WHO count rather than by MAC), which is OpenWebNet-HA/OWNd#142's to document and which this PR does not alter.Companion PR: OpenWebNet-HA/OWNd#142 (
fix(profiles): drop WHO 16 from the F461 and MyHomeServer1 profiles, draft). MyHOME #794 is the runtime half (startup requests gated onprofile.supports_who, with a MyHOME fallback table until the OWNd release).State Diagram
stateDiagram-v2 direction LR state "Is OWNd importable" as Check state "Installed OWNd profile" as Profile { [*] --> Pinned : 2.0.0b11 - F461 and MyHomeServer1 supported_who includes 16 [*] --> AfterPinBump : OWNd release with 142 - no 16 } state "Discovery row - docs table, same rule as the startup gate" as Row { Pinned --> Row16 : discovery_whos_for gives 1 2 4 16 18 - notes sound unmeasured class default AfterPinBump --> Row18 : discovery_whos_for gives 1 2 4 18 - notes_without_who16 Sound is WHO 22 only } state "No OWNd - quality-scale, test-coverage and docs CI jobs" as Fallback { [*] --> PinnedRows : pinned_whos per row - the pinned OWNd rows, edited at the pin bump with update PinnedRows --> Row16 : today, identical to the committed table } [*] --> Check Check --> Profile : yes Check --> Fallback : noHardware Verification
*#16*0*5##in 5 ms and*#16*101*5##in 6 ms (run1_oracle_replay_readonly, steporacle_who16, all 18 WHO 16 request forms refused in under 10 ms); the physical MyHomeServer1 3.87.13 NACKs both in 3 ms (run2_reads_thermo_sound_alarm_lights, stepread_who16); the upstreamtests/fixtures/traces/issue_466MyHomeServer1 fixture records the same NACK on*#16*0*5##.*#16*0*5##at startup on the F461 (Skipping WHO=16 discovery: not supported by F461 profile.), the zone and humidity requests were present; other models not tested. This PR's own effect (the regenerated docs row) is not a bus event.How is it tested
tests/test_gateway_profiles.py::test_generate_gateway_discovery_table_and_verify_oracle(updated),::test_discovery_whos_follow_the_runtime_gate,::test_discovery_row_drops_who16_when_the_profile_does,::test_discovery_table_without_ownd_uses_the_pinned_rows,::test_discovery_table_without_ownd_matches_the_committed_docs,::test_discovery_table_with_ownd_matches_the_committed_docs,::test_pinned_rows_are_ignored_when_ownd_is_importable,::test_oracle_check_rejects_a_stale_sweep_omission_at_the_pin_bump,::test_discovery_table_without_ownd_follows_the_pinned_rows_at_the_pin_bump,::test_oracle_check_rejects_a_pin_that_disagrees_with_the_installed_profile,::test_discovery_row_with_an_unreadable_pin_and_no_ownd_is_empty(new); fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794's::test_oracle_check_rejects_a_sweep_omission_the_profile_does_not_advertisekept; 25 tests in the file.discovery_whos_for, rows hard-code their WHOs); on the first-push script (CI red) 3 fail: the table test (rows carry nopinned_whos), the no-OWNd rows test and the no-OWNd-equals-committed-docs test (unknown (OWNd profile not available)cells). All 18 pass after.scripts/sync_documentation.py --checkandscripts/verify_ha_standards.py: pass without OWNd (OWNd made unimportable, the CI jobs' shape:[OWND] Client library verification skipped; before the fix:Gateway Discovery table out of sync) and with OWNd master (87cafc3) onPYTHONPATH.master(87cafc3, the behaviour of the 2.0.0b11 pin), rebased onv2-phase1-architecturea27b32f: 4965 passed, 1 skipped;scripts/verify_ownd_coverage.py100 % (16,770 / 16,770 statements, 0 missing) (before the rebase, on 31ea9fd with OWNd f04d8aa: 4514 passed, 1 skipped; first push on ddc6d60: 4421 passed, 1 skipped).gdluck/OWNdfix/profiles-f461-mhs1-no-who16,95dc8a5) onPYTHONPATH, full suite: 4964 passed, 1 failed, 1 skipped on the committed tree (the failure istests/test_sync_documentation.py::test_check_all_documentation_real_tree, the docs drift the pin bump resolves) and 4965 passed, 1 skipped with the pin bump rehearsed (see "Rebase after fix(gateway): skip the startup requests the firmware refuses, poll each zone's temperature on SCS-only gateways #794");verify_profiles_against_oracle()returns no violation, and the generator yields| **F461** | WHO 1, 2, 4, 18 | WHO 1, 2, 18 (firmware dropsthe shutters does not work in homekit #40##) | Lighting, cover, and energy meter 51 queries. Sound is WHO 22 only (nobt_difson; every WHO 16 frame refused, own-firmware-oracle020011, confirmed live on 2.0.11). The firmware also dropsthe shutters does not work in homekit #40##, so the sweep leaves it out; zones are polled withthe shutters does not work in homekit #4##. Alarm query omitted. |and the same shape for the MyHomeServer1.scripts/typing_ratchet.py0 errors (baseline 0),ruff check .,scripts/verify_ha_standards.py,scripts/manage_translations.py checkpass.pypi_standards.ymlinstalls OWNd from git (OWND_REF, the branch named like the MyHOME branch, elsemaster), so once fix(profiles): drop WHO 16 from the F461 and MyHomeServer1 profiles OWNd#142 is on OWNdmasterthat job reports the same docs drift onv2-phase1-architectureuntil the pin bump lands; this was already the case before this PR (the generator derived the rows from the installed profile when importable).Live retest (2026-10-24)
Not exercised live: docs generator and tests only, no bus effect of its own (the gate it documents was confirmed for this startup configuration, above).
Where are the traces
tests/fixtures/traces/f461_live_2026-10-23/runrun1_oracle_replay_readonlysteporacle_who16;tests/fixtures/traces/myhomeserver1_live_2026-10-24/runrun2_reads_thermo_sound_alarm_lightsstepread_who16(trace PR: #799, merged); upstreamtests/fixtures/traces/issue_466/*#16*0*5##NACK 5 ms / 3 ms,*#16*101*5##NACK 6 ms / 3 ms (note: who16_refused_locally)What does the Firmware Oracle / Encyclopedia say
Re-checked against the refreshed
results/mcp_index.jsonat own-firmware-oraclemain72759e8 (schema 1.2.0, 529 inputs; after OpenWebNet-HA/own-firmware-oracle#61 and OpenWebNet-HA/own-firmware-oracle#62): the F461 020011 and the MyHomeServer1 028206 answernack/silentto all 86 WHO 16 inputs (77 insound-who16-source, 9 intrace-corpus),*#16*0*5##atsound-who16-source.tsvline 16 and*#16*101*5##at line 28 on both, no bus frame, no emitted frame; identical to the 53f9514 rows mirrored intests/golden/firmware_oracle.json(schema 1.1.0, 509 inputs). The refresh added the 20who13-clockinputs and foursound-who22rows per gateway and changed nine MH202lights-area0/interface-routing/trace-corpusreplies (nack→ack); nothing about WHO 16 changed. The golden mirror is left as is: it is refreshed by hand in its own commit together withtests/test_firmware_oracle_conformance.py(which pinsschema_versionto 1.0.0 / 1.1.0) andtests/test_trace_oracle_validation.py(which cites 53f9514), not something this PR should fold in.Published rows (
results/<P>/<V>/oracle/full/sound-who16-source.tsv, index 53f9514 and 72759e8 alike),*#16*0*5##:nack/silenton F450 020010, F459 020105, F460 020012, F461 020011, MH202 010024, MyHomeServer1 028206;ack/out(bus24 30 34 42 35 30 30 38 30 38 46 0d) on F453 010100, F453AV 030014, F454 020051, H4684 020054, MH200 020102, MH200N 010108. OpenWebNet-HA/OWNd#142 drops WHO 16 from the F461 and MyHomeServer1 profiles on the strength of all 86 WHO 16 inputs being refused there; it keeps the MH202 (a live MH202 relays WHO 16 state frames from an F441M matrix, MyHOME #669), so the generated MH202 row does not change either. This PR adds no verdict of its own:verify_profiles_against_oracle()keeps checkingaudio_measuredagainst this row andsupports_whoagainst the WHO 1 / 2 / 3 / 4 / 25 probe rows, unchanged.Checklist
What is the problem,What is the solution,State Diagram,How is it tested,Where are the traces,What does the Firmware Oracle / Encyclopedia say).pytest,ruff, andscripts/verify_ha_standards.pypass.🤖 Generated with Claude Code