Add range/oven detection for boards missing /information/vs/0 (issue #74)

NE63B8411SS reports no oneUiVersion and no /information/vs/0 resource at
all, so neither for_device nor for_device_by_model's modelNum tokens have
anything to key off -- it fell through to the unknown-device fallback,
which also mis-binds /temperatures/vs/0 against fridge.py's setpoint
capability (a collision the oven family's own capabilities are normally
excluded from the global registry specifically to avoid).

Add a resources-based signature to for_device_by_resources(): 'Bake' in
/mode/vs/0's supportedModes is oven/range-exclusive vocabulary, and paired
with the /oven/vs/0 cavity resource it reliably identifies this family
even with no model info at all. Route to 'range' when a cooktop-status
resource is also present, else plain 'oven'.

This board's cooktop half also doesn't expose the per-burner
/cooktop/status/vs/0 array range.py already models -- only the coarser
/cooktopmonitoring/vs/0 summary resource. Add a read-only
COOKTOP_MONITORING capability for it (cooktop running state, warming
center state) rather than leaving it unbound.
This commit is contained in:
Marc Billow committed 2026-07-27 00:23:04 +00:00
1 parent aff7647460
commit c72b5a988e
10 files changed
+395

No files matched your search

@@ -170,4 +170,18 @@ def for_device_by_resources(resources: dict[str, dict]) -> Optional[DeviceRegist
and '/hood/lamp/vs/0' in resources
):
return _REGISTRY_BY_KEY['range_hood']
# Oven/range-combo boards that report no /information/vs/0 at all
# (issue #74's NE63B8411SS -- the resource is simply absent from the
# dump, not just empty) can't be matched via for_device_by_model's
# modelNum tokens either. 'Bake' is oven/range cook-mode vocabulary that
# no other family's /mode/vs/0 uses (confirmed against the microwave,
# cooktop, and every laundry fixture), so its presence alongside the
# oven cavity resource is a safe signature. Distinguish range (has a
# cooktop half) from a plain wall oven by which cooktop-status resource,
# if any, is also present.
supported_modes = mode.get('x.com.samsung.da.supportedModes') or ()
if '/oven/vs/0' in resources and 'Bake' in supported_modes:
if '/cooktopmonitoring/vs/0' in resources or '/cooktop/status/vs/0' in resources:
return _REGISTRY_BY_KEY['range']
return _REGISTRY_BY_KEY['oven']
return None
@@ -25,5 +25,6 @@ REGISTRY = DeviceRegistry(
range_caps.COOKTOP_STATUS,
range_caps.COOKTOP_SPEC,
range_caps.COOKTOP_SAFETY,
range_caps.COOKTOP_MONITORING,
]),
)
@@ -133,3 +133,22 @@ COOKTOP_SAFETY = Capability(
value_fn=lambda v: (v or {}).get('state') == 'on'),
),
)
# Some range boards (issue #74's NE63B8411SS) report no /cooktop/status/vs/0
# burner array at all -- their local API only exposes this coarse
# monitoring resource for the cooktop half, with no per-burner detail.
# Meaning of `cooktopMonitoring` (a bare "0" on the only dump seen) and
# `warmingCenterState`'s full value set aren't confirmed, so both are
# exposed as plain sensors rather than guessed at as a switch/select --
# `supportedHoodLampStateList` has no corresponding live-state field on
# this resource, so nothing to bind it to yet.
COOKTOP_MONITORING = Capability(
href='/cooktopmonitoring/vs/0',
poll_tier='warm',
entities=(
SensorDesc(key='cooktop_running_state', field='x.com.samsung.da.cooktopRunningState',
icon='mdi:pot-steam-outline'),
SensorDesc(key='warming_center_state', field='x.com.samsung.da.warmingCenterState',
icon='mdi:heat-wave', entity_category='diagnostic'),
),
)
@@ -448,6 +448,9 @@
"poll": "Polling"
}
},
"cooktop_running_state": {
"name": "Cooktop running state"
},
"cooktop_state": {
"name": "Cooktop state"
},
@@ -592,6 +595,9 @@
"super_fine_dust": {
"name": "Super fine dust"
},
"warming_center_state": {
"name": "Warming center state"
},
"water_liters": {
"name": "Water consumption"
},
@@ -448,6 +448,9 @@
"poll": "Polling"
}
},
"cooktop_running_state": {
"name": "Loopstatus kookplaat"
},
"cooktop_state": {
"name": "Status kookplaat"
},
@@ -592,6 +595,9 @@
"super_fine_dust": {
"name": "Ultrafijnstof"
},
"warming_center_state": {
"name": "Status warmhoudzone"
},
"water_liters": {
"name": "Waterverbruik"
},