Route combi microwaves onto the existing oven registry (issue #121)

TP1X_DA-KS-MICROWAVE-01041 (MW7300B) reports no oneUiVersion and an
unrecognized consumer token, so it fell back to 'unknown' and only got
common capabilities. It shares the same '/oven/vs/0' cavity resource
and '/mode/vs/0' cook-mode shape (Convection/AirFryer/Grill/MicroWave*)
as the wall oven already supported, so this reuses that registry via a
new '-MICROWAVE-' modelNum fallback rather than adding a new device
type. The only href it didn't already cover was /recipe/cook/vs/0, an
empty quick-recipe-display blob bound with no entity per the 'don't
guess' rule.
This commit is contained in:
Marc Billow
2026-07-27 13:41:36 +00:00
parent 6f10a3b796
commit e44fef7085
7 changed files with 353 additions and 0 deletions
@@ -231,6 +231,15 @@ def for_device_by_model(model_num: str, description: str) -> Optional[DeviceRegi
# oneUiVersion and doesn't match the washer/dryer/dishwasher prefix map.
if key is None and '-OVEN-' in (model_num or '').upper():
key = 'oven'
# Combi microwaves (e.g. TP1X_DA-KS-MICROWAVE-01041, issue #121) -- same
# board family as the wall oven above (an '/oven/vs/0' cavity resource
# with Convection/AirFryer/Grill/MicroWave modes on /mode/vs/0), just a
# different cavity. Reports no oneUiVersion and doesn't match the
# washer/dryer/dishwasher prefix map either. Binds cleanly against the
# existing oven registry once routed here (confirmed against the issue
# #121 dump) -- no microwave-specific device type needed.
if key is None and '-MICROWAVE-' in (model_num or '').upper():
key = 'oven'
# Standalone induction cooktops (e.g. TP1X_DA-KS-COOKTOP-01011, issue
# #86) -- same board family and '/cooktop/status/vs/0' resource shape
# as the range combo above, but no oven attached at all. Distinct from
@@ -15,5 +15,6 @@ REGISTRY = DeviceRegistry(
oven.OVEN_DOOR,
oven.OVEN_CONNECTED,
oven.OVEN_SPEC,
oven.OVEN_RECIPE_COOK,
]),
)
@@ -338,6 +338,12 @@ OVEN_CONNECTED = Capability(
# fields worth exposing.
OVEN_SPEC = Capability(href='/oven/spec/vs/0')
# Quick-recipe display blob (combi microwave, issue #121) -- a JSON-encoded
# string (language/menu/servingSize/option) with every field blank on the
# only dump seen, and no documented write contract. No entity to bind per
# the 'don't guess' rule; a bare Capability still marks the href covered.
OVEN_RECIPE_COOK = Capability(href='/recipe/cook/vs/0')
OVEN_MODE = Capability(
href='/mode/vs/0',
poll_tier='warm',
+25
View File
@@ -0,0 +1,25 @@
{
"state_keys": [
"alarm_code",
"child_lock",
"cloud_connected",
"cook_time",
"current_temp_c",
"cycle_active",
"door_open",
"energy_kwh",
"fast_preheat",
"finish_time",
"firmware_update",
"lamp",
"machine_state",
"natural_steam",
"operation_time_minutes",
"oven_mode",
"oven_setpoint",
"oven_state",
"progress_percentage",
"remote_control",
"sound"
]
}
File diff suppressed because one or more lines are too long
+14
View File
@@ -329,6 +329,20 @@ class TestForDeviceByModel:
assert reg is not None
assert reg.name == 'airconditioner'
def test_oven_via_microwave_token(self):
"""Issue #121: a combi microwave (MW7300B-/EU1) reports no
oneUiVersion and an unrecognized consumer token; falls back to the
'-MICROWAVE-' token in modelNum onto the *existing* oven registry
(same '/oven/vs/0' cavity + cook-mode shape), not a new device
type."""
from custom_components.localthings.registry.by_type import for_device_by_model
reg = for_device_by_model(
'TP1X_DA-KS-MICROWAVE-01041|40475341|50040100021811000A00000000000000',
'MW7300B-/EU1',
)
assert reg is not None
assert reg.name == 'oven'
def test_cooktop_via_legacy_model_description(self):
"""Older cooktops identify themselves as ARTIK051_GLOBAL_COOKTOP."""
from custom_components.localthings.registry.by_type import for_device_by_model
+20
View File
@@ -568,6 +568,26 @@ def test_registry_reproduces_golden_state_keys_for_airconditioner_windfree_oscil
)
def test_registry_reproduces_golden_state_keys_for_oven_mw7300b():
"""TP1X_DA-KS-MICROWAVE-01041 combi microwave (model MW7300B, issue
#121) -- reports no oneUiVersion; resolved via the '-MICROWAVE-'
modelNum token fallback onto the *existing* oven registry rather than
a new device type, since it shares the same '/oven/vs/0' cavity and
'/mode/vs/0' cook-mode shape (Convection/AirFryer/Grill/MicroWave*).
The only href the oven registry didn't already cover was
/recipe/cook/vs/0 (oven.OVEN_RECIPE_COOK, an empty quick-recipe-display
blob with no entity)."""
from tests.conftest import _load_device
resources = _load_device('oven_mw7300b')
golden = json.loads((GOLDEN / 'oven_mw7300b.json').read_text())
state_keys = _new_state_keys('oven_mw7300b', resources)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
)
def test_resources_from_batch_preferred_over_flat():
from tests.conftest import _resources_from_dump
dump = {