rename: unit/sub-unit -> subdevice, matching OCF terminology

"Unit"/"sub-unit" from #199's multi-indoor-device support wasn't OCF
idiomatic -- OCF calls each component of a composite device a
"subdevice" (see subdeviceIdList), so rename SubUnit -> Subdevice
throughout: the registry module, coordinator state, BoundEntity's
subdevice field, diagnostics keys (subdevices/subdevices_skipped/
subdevice_probes), entity unique_id prefixes (unit1_/sub_<uuid>_ ->
subdevice1_/subdevice_<uuid>_), device-name fallback labels, golden
fixtures, tests, README, and the adding-device-support skill.

Breaking change to entity unique_ids and diagnostics keys, acceptable
since this hasn't been released yet.
This commit is contained in:
Marc Billow
2026-07-29 22:57:11 +00:00
parent 79ac6f199d
commit 9e85395b44
32 changed files with 676 additions and 659 deletions
+17 -16
View File
@@ -859,12 +859,12 @@ def test_registry_reproduces_golden_state_keys_for_airconditioner_fac_bora():
)
def _new_sub_unit_aware_state_keys(name):
"""Like _new_state_keys, but runs the full sub-unit-aware pipeline
(enumerate_sub_units + discover_partitioned, issue #177) instead of a
def _new_subdevice_aware_state_keys(name):
"""Like _new_state_keys, but runs the full subdevice-aware pipeline
(enumerate_subdevices + discover_partitioned, issue #177) instead of a
single discover() call, so the golden for a composite-device fixture
captures every materialized unit's keys (unit1_-/sub_<uuid>_-prefixed),
not just the master's."""
captures every materialized subdevice's keys
(subdevice1_-/subdevice_<uuid>_-prefixed), not just the master's."""
from custom_components.localthings.registry.adapter import flatten
from tests.conftest import _discover_full, _load_device_full
resources, oic_res, seeds = _load_device_full(name)
@@ -877,15 +877,16 @@ def _new_sub_unit_aware_state_keys(name):
def test_registry_reproduces_golden_state_keys_for_airconditioner_artik051_dongle_fac_18k():
"""HJcom's ARTIK051_DONGLE_FAC_18K (issue #177, Pattern A -- indexed
siblings): a real v0.16.0 dump with a genuine second indoor unit at
`/device/1` (unit1_-prefixed keys below) and an unused SmartThings slot
at `/device/2` that answers its seed but never produces a materialized
unit (see DESIGN-177.md section 4 and test_subdevice_discovery.py's
explicit "/device/2 produces no entities" assertion) -- so this golden
has no `unit2_`-prefixed keys at all, which is the point."""
siblings): a real v0.16.0 dump with a genuine second indoor subdevice at
`/device/1` (subdevice1_-prefixed keys below) and an unused SmartThings
slot at `/device/2` that answers its seed but never produces a
materialized subdevice (see DESIGN-177.md section 4 and
test_subdevice_discovery.py's explicit "/device/2 produces no entities"
assertion) -- so this golden has no `subdevice2_`-prefixed keys at all,
which is the point."""
name = 'airconditioner_artik051_dongle_fac_18k'
golden = json.loads((GOLDEN / f'{name}.json').read_text())
state_keys = _new_sub_unit_aware_state_keys(name)
state_keys = _new_subdevice_aware_state_keys(name)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
@@ -915,17 +916,17 @@ def test_registry_reproduces_golden_state_keys_for_airconditioner_cac():
def test_registry_reproduces_golden_state_keys_for_airconditioner_fac_bora_2in1():
"""jhkwon19's TP2X_FAC_BORA_21K (issue #177, Pattern B -- UUID-prefixed
tree): device0/oic_res are real; the wall-mounted sub-unit's own
tree): device0/oic_res are real; the wall-mounted subdevice's own
/information/vs/0 is real (confirmed live by the reporter), the rest of
its seed tree is constructed (see the fixture's own seeds_note) -- just
enough to bind a real climate card under the
`sub_6c2dff6dee5cdad16a5e000000000001_` prefix below. Distinct from
`subdevice_6c2dff6dee5cdad16a5e000000000001_` prefix below. Distinct from
tests/fixtures/airconditioner_fac_bora_device.json, which is
deliberately left unchanged as the redacted-subdeviceIdList regression
case (zero sub-units)."""
case (zero subdevices)."""
name = 'airconditioner_fac_bora_2in1'
golden = json.loads((GOLDEN / f'{name}.json').read_text())
state_keys = _new_sub_unit_aware_state_keys(name)
state_keys = _new_subdevice_aware_state_keys(name)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"