Close gas-cooktop coverage gap for TP2X_DA-KS-COOKTOP-000001 (issue #314)
/alarms/vs/0 and /kidslock/vs/0 were the dump's two unbound hrefs -- both are the exact shapes common.UNIVERSAL already models elsewhere (common.ALARMS, common.KIDS_LOCK_VS_FALLBACK), picked individually rather than pulling in all of UNIVERSAL to match this registry's existing hand-picked-common style. The six-vs-three burner count the reporter originally asked about is expected behavior (the board's own /mode/vs/0 options genuinely advertise six OperationState slots on hardware with three physical burners, with no per-device signal to tell real slots from phantom ones) -- already explained on the issue; this commit is scoped to the coverage warning.
This commit is contained in:
@@ -22,6 +22,12 @@ REGISTRY = DeviceRegistry(
|
||||
cooktop.COOKTOP_CONNECTED,
|
||||
cooktop.PAIRED_HOOD_STATUS,
|
||||
common.FIRMWARE_UPDATE,
|
||||
# issue #314: /alarms/vs/0 and /kidslock/vs/0 are the same
|
||||
# generic shapes common.UNIVERSAL already models elsewhere --
|
||||
# picked individually rather than pulling in all of UNIVERSAL,
|
||||
# matching this registry's existing hand-picked-common style.
|
||||
common.ALARMS,
|
||||
common.KIDS_LOCK_VS_FALLBACK,
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"device0": [
|
||||
{
|
||||
"rt": [
|
||||
"x.com.samsung.devcol",
|
||||
"oic.wk.col"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.ll",
|
||||
"oic.if.b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"href": "/alarms/vs/0",
|
||||
"rep": {
|
||||
"rt": [
|
||||
"x.com.samsung.da.alarms"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.a"
|
||||
],
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "Alarm",
|
||||
"x.com.samsung.da.alarmType": "Device",
|
||||
"x.com.samsung.da.code": "CT_E",
|
||||
"x.com.samsung.da.triggeredTime": "2026-08-06T14:24:02"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/bluetooth/hood/status/vs/0",
|
||||
"rep": {
|
||||
"connectionState": "disconnected",
|
||||
"micomModelId": "",
|
||||
"firmwareVersion": "",
|
||||
"power": "off",
|
||||
"fanSpeed": 0,
|
||||
"lampState": "off",
|
||||
"timer": {},
|
||||
"rt": [
|
||||
"bluetoothHoodStatus"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.s"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/configuration/vs/0",
|
||||
"rep": {}
|
||||
},
|
||||
{
|
||||
"href": "/connected/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.connected": "On",
|
||||
"rt": [
|
||||
"x.com.samsung.da.connected"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.a"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/kidslock/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.kidsLock": "Ready"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mode/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.options": [
|
||||
"DeviceType_NV8000T-/KO0",
|
||||
"Pause_Off",
|
||||
"SyncFlex_Off",
|
||||
"FlexCoil_0",
|
||||
"MainTimerCurrent_0",
|
||||
"MainTimerSet_0",
|
||||
"MainTimerState_Ready",
|
||||
"IndependentTimerCheck_Enable",
|
||||
"OperationState0_Ready",
|
||||
"HotSurface0_Normal",
|
||||
"PowerLevel0_0",
|
||||
"OperationState1_Ready",
|
||||
"HotSurface1_Normal",
|
||||
"PowerLevel1_0",
|
||||
"OperationState2_Ready",
|
||||
"HotSurface2_Normal",
|
||||
"PowerLevel2_0",
|
||||
"OperationState3_Ready",
|
||||
"HotSurface3_Normal",
|
||||
"PowerLevel3_0",
|
||||
"OperationState4_Ready",
|
||||
"HotSurface4_Normal",
|
||||
"PowerLevel4_0",
|
||||
"OperationState5_Ready",
|
||||
"HotSurface5_Normal",
|
||||
"PowerLevel5_0"
|
||||
],
|
||||
"rt": [
|
||||
"x.com.samsung.da.mode"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.a"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/otninformation/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.target": "",
|
||||
"x.com.samsung.da.newVersionAvailable": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/power/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.power": "Off",
|
||||
"rt": [
|
||||
"x.com.samsung.da.operation"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.a"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"state_keys": [
|
||||
"alarm_code",
|
||||
"any_burner_active",
|
||||
"burner_0_state",
|
||||
"burner_1_state",
|
||||
"burner_2_state",
|
||||
"burner_3_state",
|
||||
"burner_4_state",
|
||||
"burner_5_state",
|
||||
"child_lock",
|
||||
"cloud_connected",
|
||||
"firmware_update",
|
||||
"main_timer_current",
|
||||
"main_timer_state",
|
||||
"paired_hood_connected",
|
||||
"paired_hood_fan_speed",
|
||||
"paired_hood_firmware",
|
||||
"paired_hood_light",
|
||||
"paired_hood_model",
|
||||
"paired_hood_power",
|
||||
"power_state"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Tests for the TP2X_DA-KS-COOKTOP-000001 gas cooktop (issue #314).
|
||||
|
||||
The reporter's actual complaint (six advertised burner slots when only
|
||||
three are physically present) is expected: the registry declares a
|
||||
generous static superset of slots and gates each on the live options array
|
||||
per cooktop.py's own comment; there's no per-device signal that
|
||||
distinguishes an advertised-but-nonexistent slot from a real one, so the
|
||||
extra entities are disabled by the user, not filtered by the integration.
|
||||
This file locks in the actual gap from that issue -- /alarms/vs/0 and
|
||||
/kidslock/vs/0 -- now bound via common.ALARMS/KIDS_LOCK_VS_FALLBACK.
|
||||
"""
|
||||
|
||||
from custom_components.localthings.registry.adapter import flatten
|
||||
from custom_components.localthings.registry.by_type import resolve
|
||||
from custom_components.localthings.registry.discovery import discover
|
||||
from tests.conftest import _load_device
|
||||
|
||||
|
||||
def _bound():
|
||||
resources = _load_device("gas_cooktop_tp2x_ks")
|
||||
reg = resolve(resources)
|
||||
return discover(resources, reg.capabilities, reg.pattern_capabilities), resources
|
||||
|
||||
|
||||
def test_resolves_to_gas_cooktop_registry():
|
||||
resources = _load_device("gas_cooktop_tp2x_ks")
|
||||
reg = resolve(resources)
|
||||
assert reg is not None and reg.name == "gas_cooktop"
|
||||
|
||||
|
||||
def test_no_unbound_hrefs():
|
||||
_, resources = _bound()
|
||||
reg = resolve(resources)
|
||||
unbound = []
|
||||
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
|
||||
assert unbound == []
|
||||
|
||||
|
||||
def test_alarm_code_and_child_lock_bound():
|
||||
bound, resources = _bound()
|
||||
state = flatten(bound, resources)
|
||||
assert state["alarm_code"] == "CT_E"
|
||||
# x.com.samsung.da.kidsLock == "Ready" reads as unlocked, same polarity
|
||||
# as every other board KIDS_LOCK_VS_FALLBACK covers.
|
||||
assert state["child_lock"] is True
|
||||
|
||||
|
||||
def test_advertises_six_burner_slots_only_three_of_which_are_real():
|
||||
"""Not a bug to fix -- the board's own /mode/vs/0 options genuinely
|
||||
list six OperationState slots (issue #314); the reporter's physical
|
||||
cooktop only has three. Locks in the current, documented behavior."""
|
||||
bound, resources = _bound()
|
||||
state = flatten(bound, resources)
|
||||
for i in range(6):
|
||||
assert f"burner_{i}_state" in state
|
||||
@@ -231,6 +231,25 @@ def test_registry_reproduces_golden_state_keys_for_water_purifier_coffee():
|
||||
)
|
||||
|
||||
|
||||
def test_registry_reproduces_golden_state_keys_for_gas_cooktop_tp2x_ks():
|
||||
"""TP2X_DA-KS-COOKTOP-000001 (issue #314) -- routes via
|
||||
for_device_by_resources' DeviceType_/OperationState signature, same as
|
||||
the original cooktop fixture. /alarms/vs/0 and /kidslock/vs/0 were the
|
||||
dump's only unbound hrefs; both are common.UNIVERSAL shapes this
|
||||
registry now picks up individually (common.ALARMS,
|
||||
common.KIDS_LOCK_VS_FALLBACK)."""
|
||||
from tests.conftest import _load_device
|
||||
|
||||
resources = _load_device("gas_cooktop_tp2x_ks")
|
||||
golden = json.loads((GOLDEN / "gas_cooktop_tp2x_ks.json").read_text())
|
||||
state_keys = _new_state_keys("gas_cooktop_tp2x_ks", 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_registry_reproduces_golden_state_keys_for_cooktop():
|
||||
from tests.conftest import _load_device
|
||||
|
||||
|
||||
Reference in New Issue
Block a user