Merge remote-tracking branch 'origin/main' into claude/device-support-issue-56-shy2vg
# Conflicts: # tests/test_golden_regression.py
This commit is contained in:
8 files changed
+392
-19
No files matched your search
@@ -127,6 +127,11 @@ def for_device_by_model(model_num: str, description: str) -> Optional[DeviceRegi
|
||||
# and don't match the washer/dryer/dishwasher consumer-prefix map either.
|
||||
if key is None and '-RANGE-' in (model_num or '').upper():
|
||||
key = 'range'
|
||||
# Wall ovens (e.g. TP1X_DA-KS-OVEN-0107X, issue #55) -- same board-family
|
||||
# naming as the range combo above, minus the burners; also reports no
|
||||
# oneUiVersion and doesn't match the washer/dryer/dishwasher prefix map.
|
||||
if key is None and '-OVEN-' in (model_num or '').upper():
|
||||
key = 'oven'
|
||||
return _REGISTRY_BY_KEY.get(key) if key else None
|
||||
|
||||
|
||||
|
||||
@@ -70,6 +70,15 @@ def _finish_time(remaining_str):
|
||||
return None
|
||||
|
||||
|
||||
# Shared by dryer/dishwasher/oven/washer -- oven.py imports this directly
|
||||
# rather than keeping its own copy, since both wrote the identical
|
||||
# state='Ready' RMW.
|
||||
STOP_BUTTON = ButtonDesc(key='stop', field='', name='Stop', payload='Ready',
|
||||
icon='mdi:stop',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['operational', 'state', 'vs', '0'],
|
||||
{'x.com.samsung.da.state': p}))
|
||||
|
||||
OPERATIONAL_STATE = Capability(
|
||||
href='/operational/state/vs/0',
|
||||
poll_tier='hot',
|
||||
@@ -83,8 +92,12 @@ OPERATIONAL_STATE = Capability(
|
||||
# Harmless for non-oven appliances — just an extra bool in state.
|
||||
# Samsung firmware keeps state='Run' after progress reaches 'Finish',
|
||||
# so we also gate on progress to avoid a stuck 'Running' indication.
|
||||
# Named 'Running' rather than 'Cycle active' -- this href (and the
|
||||
# start/pause/stop buttons below) is shared across the dryer/
|
||||
# dishwasher/oven/washer families, and 'cycle' is laundry-specific
|
||||
# vocabulary that doesn't fit an oven's bake/roast/etc.
|
||||
BinarySensorDesc(key='cycle_active', device_class='running',
|
||||
name='Cycle active',
|
||||
name='Running',
|
||||
rep_fn=lambda rep: (
|
||||
_SAMSUNG_STATE_TO_OCF.get(rep.get('x.com.samsung.da.state')) == 'active'
|
||||
and rep.get('x.com.samsung.da.progress') != 'Finish'
|
||||
@@ -119,20 +132,16 @@ OPERATIONAL_STATE = Capability(
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['operational', 'state', 'vs', '0'],
|
||||
{_delay_field(rep): _format_delay(p)})),
|
||||
ButtonDesc(key='start', field='', name='Start cycle', payload='Run',
|
||||
ButtonDesc(key='start', field='', name='Start', payload='Run',
|
||||
icon='mdi:play',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['operational', 'state', 'vs', '0'],
|
||||
{'x.com.samsung.da.state': p})),
|
||||
ButtonDesc(key='pause', field='', name='Pause cycle', payload='Pause',
|
||||
ButtonDesc(key='pause', field='', name='Pause', payload='Pause',
|
||||
icon='mdi:pause',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['operational', 'state', 'vs', '0'],
|
||||
{'x.com.samsung.da.state': p})),
|
||||
ButtonDesc(key='stop', field='', name='Stop cycle', payload='Ready',
|
||||
icon='mdi:stop',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['operational', 'state', 'vs', '0'],
|
||||
{'x.com.samsung.da.state': p})),
|
||||
STOP_BUTTON,
|
||||
),
|
||||
)
|
||||
@@ -26,10 +26,10 @@ from datetime import datetime, timezone, timedelta
|
||||
|
||||
from ..capability import Capability
|
||||
from ..entities import (
|
||||
BinarySensorDesc, ButtonDesc, NumberDesc, SelectDesc, SensorDesc,
|
||||
SwitchDesc,
|
||||
BinarySensorDesc, NumberDesc, SelectDesc, SensorDesc, SwitchDesc,
|
||||
)
|
||||
from .common import normalize_temp_unit
|
||||
from .operational import STOP_BUTTON
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Constants
|
||||
@@ -166,12 +166,6 @@ def _cook_time_write(p, rep, href=None):
|
||||
}
|
||||
|
||||
|
||||
def _stop_write(p, rep, href=None):
|
||||
return ['operational', 'state', 'vs', '0'], {
|
||||
'x.com.samsung.da.state': 'Ready',
|
||||
}
|
||||
|
||||
|
||||
def _oven_mode_write(p, rep, href=None):
|
||||
if p not in _OVEN_MODES:
|
||||
return None
|
||||
@@ -237,7 +231,7 @@ OVEN_OPERATIONAL_STATE = Capability(
|
||||
device_class='enum', options=('idle', 'active', 'pause'),
|
||||
translation_key='machine_state', value_fn=_to_ocf),
|
||||
BinarySensorDesc(key='cycle_active', field='x.com.samsung.da.state',
|
||||
name='Cycle active', device_class='running',
|
||||
name='Running', device_class='running',
|
||||
value_fn=lambda v: _SAMSUNG_STATE_TO_OCF.get(v) == 'active'),
|
||||
SensorDesc(key='progress_percentage',
|
||||
field='x.com.samsung.da.progressPercentage',
|
||||
@@ -254,8 +248,7 @@ OVEN_OPERATIONAL_STATE = Capability(
|
||||
name='Cook time', unit='min', native_min=0, native_max=1439,
|
||||
step=1.0, icon='mdi:timer', value_fn=_op_minutes,
|
||||
write_fn=_cook_time_write),
|
||||
ButtonDesc(key='stop', field='', name='Stop cycle', icon='mdi:stop',
|
||||
payload='Stop', write_fn=_stop_write),
|
||||
STOP_BUTTON,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
Reference in new issue
Block a user