Skip to content

fix(legacy_yaml): warn when myhome.yaml has no section under this gateway's MAC (#106) - #801

Merged
GreenGrassBlueOcean merged 2 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
gdluck:fix/legacy-yaml-mac-mismatch
Oct 24, 2026
Merged

GreenGrassBlueOcean merged 2 commits into
OpenWebNet-HA:v2-phase1-architecturefrom
gdluck:fix/legacy-yaml-mac-mismatch

Conversation

@gdluck

@gdluck gdluck commented Oct 24, 2026 •

Copy link
Copy Markdown

Requested by A

What is the problem

When myhome.yaml has gateway sections but none of them is keyed by this entry's MAC, _load_live_yaml returns False silently and the entities from the file simply do not appear. #106 is the classic form of it: the user edited the file, nothing loaded, and only the maintainers could tell that the top-level key did not match the gateway. The existing DEBUG line ("no section for this MAC") is not visible at the default log level.

Refs #106 (closed; the diagnosis there is what this warning now prints).


What is the solution

  1. legacy_yaml.py: new _log_mac_mismatch, called where _load_live_yaml gives up.
    • WARNING naming the entry MAC and the section keys that match no configured gateway: myhome.yaml has no section for gateway <mac>; sections found under <keys> match no configured gateway. Rename the section to this gateway's MAC to load it.
    • When every section belongs to another configured gateway (a multi-gateway file) it stays at DEBUG, so a correct two-gateway setup is not nagged.
    • _same_mac compares through dr.format_mac, so 00-03-50-..., 0003.50... and raw hex spellings count as the same gateway.
    • Review follow-up (6b23c38): _same_mac falls back to a plain string comparison when dr.format_mac raises, so a malformed section key keeps the WARNING instead of surfacing as the generic "Failed to parse" ERROR; other entries without a MAC are skipped instead of being compared against "None"; disabled entries still count as owners of their section (the entry exists), stated in a comment.
  2. tests/test_legacy_yaml.py: test_legacy_yaml_mac_mismatch_warns_with_entry_mac_and_keys (failed before) and test_legacy_yaml_section_of_another_gateway_does_not_warn (guard, passes before and after). Follow-up tests: mixed orphan and other-gateway keys, a hyphen-spelled section of the other gateway, dr.format_mac raising inside the helper (loader level and helper level), another entry without a MAC. Fixture MACs are synthetic 00:03:50:… placeholders.
  3. .github/release-notes/2.0.0b16.md: one line under "Other changes".

Companion PR: None.


State Diagram

stateDiagram-v2
    direction TB
    state "myhome.yaml with gateway sections" as Yaml {
        [*] --> MatchEntry : a top-level key equals this entrys MAC , dr.format_mac
        [*] --> OtherGateway : every key belongs to another configured gateway
        [*] --> Orphan : a key matches no configured gateway
        MatchEntry --> Loaded : entities created from the section , unchanged
        OtherGateway --> Debug : DEBUG, nothing loaded for this entry , unchanged, multi-gateway file
        Orphan --> Warning : WARNING names the entry MAC and the orphan keys , new - before this PR - DEBUG only
    }
Loading

Hardware Verification

  • Physical F461 2.0.11, local Home Assistant 2026.10.2 (test instance, not production): reload with the section key changed to a wrong MAC.
  • Live retest 2026-10-24 (report-15 consensus label confirmed for the tested case): third start with the plant section keyed 00:03:50:00:00:01 logged WARNING myhome.yaml has no section for gateway 00:03:50:00:10:23; sections found under 00:03:50:00:00:01 match no configured gateway. Rename the section to this gateway's MAC to load it (gateway MAC shown here as the fixture's synthetic value), then INFO Using the imported copy of myhome.yaml … (the arch(discovery): gate poll-on-add across all paced sweeps, probe ON dimmers, and migrate myhome.yaml once into ConfigEntry #733 fallback); all 5 entities present. The start with a matching section plus a ghost section keyed to no gateway logged nothing at WARNING, as designed (not a mismatch). The yaml was restored afterwards.

How is it tested

  • tests/test_legacy_yaml.py::test_legacy_yaml_mac_mismatch_warns_with_entry_mac_and_keys (new, failed before), ::test_legacy_yaml_section_of_another_gateway_does_not_warn (new guard).
  • Fail-before / pass-after, the test file on the original source: 1 fail (the mismatch warning test), 22 pass (the guard among them); all pass after.
  • Review follow-up (6b23c38): ::test_legacy_yaml_mixed_sections_warn_only_for_orphan_keys, ::test_legacy_yaml_other_gateway_section_spelled_differently_does_not_warn, ::test_legacy_yaml_mac_mismatch_keeps_warning_when_format_mac_raises, ::test_same_mac_falls_back_to_string_comparison_when_format_mac_raises, ::test_legacy_yaml_mac_mismatch_skips_other_entry_without_mac. On the first commit's source: 2 fail (the two format_mac-raises tests), 26 pass (the other three are guards); 28 pass after.
  • Full suite against OWNd master (f04d8aa, the behaviour of the 2.0.0b11 pin): 4425 passed, 1 skipped (first commit: 4420 passed, 1 skipped; base v2-phase1-architecture ddc6d60: 4418 passed, 1 skipped).
  • scripts/verify_ownd_coverage.py 100 %, scripts/typing_ratchet.py 0 errors (baseline 0), ruff check ., scripts/verify_ha_standards.py, scripts/sync_documentation.py --check, scripts/manage_translations.py check all pass.

Live retest (2026-10-24)

Consensus label: confirmed for the tested case (the wrong-MAC start above); no bus frame is involved.


Where are the traces

Subsystem Capture Plant Frames verified by this PR
Legacy YAML loading No physical trace applies: this change touches no bus frame (configuration / diagnostics / validation only) F461 2.0.11 (log lines above) none

What does the Firmware Oracle / Encyclopedia say

No oracle stimulus exists for this change: YAML loading diagnostics only.


Checklist

  • PR Description: Follows the structured sections above (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).
  • Trace-Backed (if protocol/device change): N/A, YAML loading diagnostics only.
  • V2 Architecture: N/A, no entity changes.
  • Tests & Linters: pytest, ruff, and scripts/verify_ha_standards.py pass.

🤖 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
gdluck pushed a commit to gdluck/HomeAssistant-MyHOME that referenced this pull request Oct 24, 2026
MyHomeServer1 README: "OWnd" typo; the alarm gate, the config-flow
identification and the liveness probe rows name MyHOME OpenWebNet-HA#803, OpenWebNet-HA#804, OpenWebNet-HA#806.
F461 README: the "What this capture backs" table extends to MyHOME OpenWebNet-HA#800-OpenWebNet-HA#806
(OpenWebNet-HA#802 the dimension 27 wire form, OpenWebNet-HA#803 *michnovka#5*0##, OpenWebNet-HA#804 the WHO 13 / 1013
identification replies, OpenWebNet-HA#806 the *OpenWebNet-HA#13**0## echo; OpenWebNet-HA#800 / OpenWebNet-HA#801 / OpenWebNet-HA#805 have no
frame in this capture); it states that f461_live_2026-10-15 holds the
dimension 22 reboot behind OWNd OpenWebNet-HA#136, the *4*311*2## / *4*311*#2## pair
behind OWNd OpenWebNet-HA#137 and probe_area0 behind OWNd OpenWebNet-HA#141 / MyHOME OpenWebNet-HA#798; and one
sentence says reply_time_s is measured while tx.t is reconstructed from the
probe log.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gdluck
gdluck force-pushed the fix/legacy-yaml-mac-mismatch branch from 94a50d1 to afa5b13 Compare October 24, 2026 15:43
@gdluck gdluck mentioned this pull request Oct 24, 2026
4 tasks done
@gdluck
gdluck marked this pull request as ready for review October 24, 2026 16:27
GreenGrassBlueOcean pushed a commit that referenced this pull request Oct 24, 2026
MyHomeServer1 README: "OWnd" typo; the alarm gate, the config-flow
identification and the liveness probe rows name MyHOME #803, #804, #806.
F461 README: the "What this capture backs" table extends to MyHOME #800-#806
(#802 the dimension 27 wire form, #803 *#5*0##, #804 the WHO 13 / 1013
identification replies, #806 the *#13**0## echo; #800 / #801 / #805 have no
frame in this capture); it states that f461_live_2026-10-15 holds the
dimension 22 reboot behind OWNd #136, the *4*311*2## / *4*311*#2## pair
behind OWNd #137 and probe_area0 behind OWNd #141 / MyHOME #798; and one
sentence says reply_time_s is measured while tx.t is reconstructed from the
probe log.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@GreenGrassBlueOcean GreenGrassBlueOcean left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observations / minor nits
Robustness of _same_mac / orphan filtering

_same_mac calls dr.format_mac without a try/except. The rest of the loader still protects the matching loop with try/except Exception: continue (the PR notes the except is effectively unreachable for normal inputs).

If a post-validation key is so malformed that dr.format_mac raises, _log_mac_mismatch will raise. That is caught by the outer except in _load_live_yaml and turned into a generic “Failed to parse…” ERROR, so the nice WARNING is lost.

This is an edge case (validation already tries to normalize or keep the original key), but a narrow try/except around the format calls inside the orphan filter would make the diagnostic path fully fail-soft.
Disabled entries

Other entries are included regardless of disabled_by. A section belonging only to a disabled entry is therefore treated as “belongs to another configured gateway” and stays at DEBUG. This is reasonable (the entry still exists), but differs from the top-level-platforms path which filters disabled entries. Not a problem in practice.
None / missing MACs

e.data.get(CONF_MAC) can be None. str(None) → "None", which will not match, so the key remains an orphan and is reported. Harmless, but the warning would contain the string "None" if that ever occurred.

Test coverage gaps (optional)
Mixed case (some orphan keys + some keys belonging to other gateways).
Different MAC spellings on the orphan side (the loading path already has strong coverage for this).
Behavior when format_mac would raise inside the new helper.
Not required for merge; the two tests that exist are the important ones and are correctly written.

@gdluck

gdluck commented Oct 24, 2026

Copy link
Copy Markdown
Author

Thanks for the careful read. Follow-up pushed as 6b23c38:

  • _same_mac now wraps the dr.format_mac calls in a narrow try/except and falls back to a plain string comparison, so a key format_mac rejects keeps the orphan WARNING instead of surfacing as the generic "Failed to parse" ERROR.
  • Other entries whose CONF_MAC is None/missing are skipped rather than compared against "None", so that string can never reach the warning.
  • Disabled entries are kept as owners of their section (the entry still exists, so the file stays at DEBUG); this is intentional and now stated in a comment next to the loop, noting the difference from the top-level-platforms path.
  • Added the suggested tests: mixed orphan + other-gateway keys, a hyphen-spelled section of the other gateway, format_mac raising (loader level and helper level), and an entry without a MAC; the two format_mac-raises tests fail on the previous commit, the others are guards.
  • Full suite against OWNd master f04d8aa: 4425 passed, 1 skipped; ruff, typing ratchet (0, baseline 0), verify_ha_standards.py and sync_documentation.py --check pass. PR body updated accordingly.

gdluck and others added 2 commits October 24, 2026 20:55
…eway's MAC (OpenWebNet-HA#106)

A file whose top-level keys match no configured gateway loaded nothing
and said so only at DEBUG (OpenWebNet-HA#106). Log a WARNING naming the entry MAC
and the orphan section keys; stay at DEBUG when every section belongs
to another configured gateway. Confirmed live on an F461 2.0.11 with a
deliberately wrong section MAC.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing (review follow-up)

Review follow-up for the OpenWebNet-HA#106 mismatch warning: _same_mac now falls back
to a plain string comparison when dr.format_mac raises, so a malformed
section key keeps the WARNING instead of surfacing as the generic
"Failed to parse" ERROR. Other entries without a MAC are skipped rather
than compared against "None". The disabled-entry behaviour is unchanged
and now stated in a comment. Tests: mixed orphan/other-gateway keys, a
hyphen-spelled section of the other gateway, format_mac raising inside
the helper (loader and helper level), and an entry without a MAC.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gdluck
gdluck force-pushed the fix/legacy-yaml-mac-mismatch branch from 6b23c38 to ae73942 Compare October 24, 2026 18:18

@GreenGrassBlueOcean GreenGrassBlueOcean left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Audit notes
Logic is correct and fail-soft. The diagnostic path cannot raise into the outer generic ERROR.
MAC normalization is consistent with the existing matching loop that already uses dr.format_mac.
Disabled-entry behavior is intentional and now documented; it differs from the top-level-platforms path but is reasonable (the entry still exists and owns its section).
Logging is precise, actionable, and does not spam multi-gateway setups.
No protocol, entity, or runtime behavior changes outside the missing-MAC diagnostic.
Style, typing, and HA standards checks pass.
Minor: the broad except Exception is appropriate for a diagnostic-only helper.

@GreenGrassBlueOcean
GreenGrassBlueOcean merged commit d8bac15 into OpenWebNet-HA:v2-phase1-architecture Oct 24, 2026
17 checks passed
gdluck pushed a commit to gdluck/HomeAssistant-MyHOME that referenced this pull request Oct 26, 2026
…penWebNet-HA#801 follow-up)

The `except Exception` fallback of _same_mac was unreachable and its
docstring described a path that does not exist: HA's dr.format_mac never
raises (a value that is no MAC comes back unchanged), and a malformed
section key never reaches _log_mac_mismatch because validate.config_schema
(`Optional(CONF_MAC): MacAddress()`) rejects it first with the generic
"Failed to parse myhome.yaml ...: Invalid MAC address" ERROR, the very outcome
the docstring claimed the fallback avoided. The two tests passed only by
monkeypatching format_mac to raise.

The helper now compares the two format_mac results, the docstring says why
no fallback is needed, and the two monkeypatch tests are replaced by one on
real spellings (hyphens, dots, junk against itself) and one showing that a
'not-a-mac' section key is one schema ERROR with no WARNING and no mismatch
check.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GreenGrassBlueOcean added a commit that referenced this pull request Oct 26, 2026
…e-arg-and-log

fix(config_flow,legacy_yaml): drop an inert profile argument, say what moved, no unreachable MAC fallback (#804 / #798 / #801 / #808 follow-up)
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.

3 participants