Recover a consumer's bus_id from its source block - #1757
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1757 +/- ##
=======================================
Coverage 99.54% 99.54%
=======================================
Files 228 228
Lines 18203 18203
=======================================
Hits 18121 18121
Misses 82 82
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Fixes a bug in the devices.esphome.io importer where bus dependencies (i2c/uart) could not be lifted for id-less, same-platform consumers by recovering the consumer’s <bus>_id directly from its original source block.
Changes:
- Stash each finalized featured entry’s source YAML block transiently and use it to recover
<bus>_idduring bus dependency collection (then strip before serialization). - Update validation/test coverage to treat
_UNSATISFIED_BUS_ALLOW_LISTas a per-(board,bus) allow-list and confirm the list can be empty. - Regenerate KinCony board manifests/bodies so required i2c/uart components are featured and wired via
requires.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
script/sync_esphome_devices.py |
Stashes _source_block on finalized entries, uses it to recover <bus>_id in _collect_bus_dep_refs, and strips it before writing records. |
script/validate_definitions.py |
Converts the unsatisfied-bus allow-list to a typed, currently-empty frozenset and keeps per-(board,bus) semantics. |
tests/test_sync_esphome_devices_bus_dep.py |
Adds a regression test ensuring bus id recovery works when _find_consumer_block can’t disambiguate id-less same-platform consumers. |
tests/test_validate_featured.py |
Updates tests to monkeypatch the allow-list as (board, bus) pairs (and not rely on real board ids). |
esphome_device_builder/definitions/boards/kincony_mb/manifest.yaml |
Adds featured i2c buses (bus_a/bus_b) and stamps requires on INA226 sensors; updates occupied pins. |
esphome_device_builder/definitions/boards/kincony_kc868_e8t/manifest.yaml |
Adds featured UARTs (uart_1/uart_2) and stamps requires on BL0939 sensors; updates occupied pins. |
esphome_device_builder/definitions/boards/kincony_ag8/manifest.yaml |
Adds featured UART (uart_232) and stamps requires on the UART switch; updates occupied pins. |
esphome_device_builder/definitions/board_bodies/kincony_mb.json |
Regenerated body including i2c buses and per-sensor requires. |
esphome_device_builder/definitions/board_bodies/kincony_kc868_e8t.json |
Regenerated body including UARTs and per-sensor requires. |
esphome_device_builder/definitions/board_bodies/kincony_ag8.json |
Regenerated body including UART and requires. |
|
|
esphbot
left a comment
There was a problem hiding this comment.
No blocking issues found.
ag8/e8t/mb have multiple same-platform leaves (2 switch.uart, 2 bl0939, 16 ina226) with no id: on the consumer block, so _find_consumer_block can't tell them apart, the <bus>_id ref is lost, and with multiple buses present _materialize_bus can't pick one, so the bus never lifts. _Candidate already keeps the source block and each entry's id equals its local_id, so stash the source block on the finalized entry, read it in _collect_bus_dep_refs (falling back to _find_consumer_block), and strip it in _make_record before serialization. Empties the guard's allow list; regenerated against ESPHome 2026.6.3.
433ff1e to
b5fcf67
Compare
|
Thanks @esphbot — applied your suggestion 1 (read-and-discard) in
Behavior-preserving: the regenerated catalog is byte-identical, no |
Verified on PR head. Pop sits above every |
PR Review — Recover a consumer's bus_id from its source blockCorrect, well-scoped importer fix; read-and-discard hardening applied; merge-ready. Strengths:
Verification performed:
Checklist
Automated review by Kōan (Claude) |
esphbot
left a comment
There was a problem hiding this comment.
No blocking issues found.
What does this implement/fix?
The last 3 boards allow-listed by #1755 —
kincony_ag8(uart),kincony_kc868_e8t(uart),
kincony_mb(i2c) — shipped a full-setup config that wouldn't compilebecause their bus was never lifted. The allow-list comments claimed "source has no
top-level block", but the live devices.esphome.io pages (and the cached source)
show the bus is there, with explicit ids, in the same code block as the leaf —
so that was a misdiagnosis. The real cause is an importer bug.
Each board has multiple same-platform leaves with no
id:on the consumerblock (2
switch.uart, 2sensor.bl0939, 16sensor.ina226), each binding a busvia
uart_id:/i2c_id:. That ref is dropped from the finalized entry (the busisn't a featured component yet), so
_collect_bus_dep_refsre-finds the sourceblock via
_find_consumer_block— which filters by platform, gets N id-lessblocks, can't disambiguate, and returns
None. With the ref lost and multiplebuses present,
_materialize_buscan't pick one, so the bus never lifts.Fix:
_Candidatealready retains the source block and each finalized entry'sidequals its unique
local_id, so stash the source block on the entry at finalize,read it back in
_collect_bus_dep_refs(falling back to_find_consumer_blockfor entries built outside the extractor, e.g. unit tests), and strip the transient
key in
_make_recordbefore serialization. Each consumer's<bus>_idis nowrecovered directly:
kincony_mb's 16 ina226 split correctly acrossbus_a/bus_b,ag8/e8t wire each leaf to its own uart.
This empties the guard's
_UNSATISFIED_BUS_ALLOW_LIST— every imported board'sfeatured bus dependencies now lift, and
validate_definitions.pyproves it (0errors). Regenerated against ESPHome 2026.6.3; the diff is exactly the 3 boards
gaining their uart/i2c entries +
requires.Related issue or feature (if applicable):
Types of changes
bugfixFrontend coordination
Checklist
ruff,codespell, yaml/json/python checks).tests/where applicable.components.index.json/definitions/components/*.jsonhave not been hand-edited.docs/ARCHITECTURE.mdand/ordocs/API.md.