merge temp_setpoint

This commit is contained in:
vmvarga
2026-07-26 11:05:13 +02:00
parent 00cf8d676d
commit 2fd8ff8260
4 changed files with 31 additions and 42 deletions
+4 -1
View File
@@ -564,7 +564,10 @@ class LocalThingsCoordinator(DataUpdateCoordinator[dict[str, Any]]):
translation_domain=DOMAIN,
translation_key=error,
)
result = write_fn(payload, rep, href)
try:
result = write_fn(payload, rep, href, resources)
except TypeError:
result = write_fn(payload, rep, href)
if result is None:
self._log.warning("write_fn rejected payload %r for %s", payload, href)
return
@@ -33,8 +33,7 @@ REGISTRY = DeviceRegistry(
]),
pattern_capabilities=[
fridge.TEMP_CURRENT_GENERIC,
fridge.TEMP_SETPOINT_VENDOR,
fridge.TEMP_SETPOINT_GENERIC,
fridge.TEMP_SETPOINT,
fridge.ICEMAKER_GENERIC,
fridge.DOOR_GENERIC,
],
@@ -62,48 +62,38 @@ TEMP_CURRENT_GENERIC = Capability(
),
)
def _temp_setpoint_vendor_write(p, rep, href=None):
"""Write temperature via the vendor /temperatures/vs/0 resource.
def _temp_setpoint_write(p, rep, href=None, resources=None):
"""Write temperature — prefer vendor /temperatures/vs/0 when available,
fall back to direct OCF /temperature/desired/ write otherwise.
Samsung fridges expose both OCF-standard /temperature/desired/* (readable)
and vendor /temperatures/vs/0 (writable). The OCF resource ACKs POSTs but
ignores them; only the vendor path actually commits the setpoint change.
Samsung fridges expose both OCF-standard /temperature/desired/* and vendor
/temperatures/vs/0. On some models only the vendor path commits the change;
on others both work. Using the vendor path when present is always correct.
Item IDs follow the Samsung convention: "0" = Freezer, "1" = Fridge/Cooler.
"""
if not href:
return None
if '/cooler/' in href:
item_id = '1'
elif '/freezer/' in href:
item_id = '0'
else:
return None
if resources and '/temperatures/vs/0' in resources:
if '/cooler/' in href:
item_id = '1'
elif '/freezer/' in href:
item_id = '0'
else:
return None
return (
['temperatures', 'vs', '0'],
{'x.com.samsung.da.items': [
{'x.com.samsung.da.id': item_id,
'x.com.samsung.da.desired': str(int(round(float(p))))}
]}
)
return (
['temperatures', 'vs', '0'],
{'x.com.samsung.da.items': [
{'x.com.samsung.da.id': item_id,
'x.com.samsung.da.desired': str(int(round(float(p))))}
]}
[s for s in href.strip('/').split('/') if s],
{'temperature': int(round(float(p)))}
)
TEMP_SETPOINT_VENDOR = Capability(
href=None,
href_prefix='/temperature/desired/',
strip_prefix_in_key=True,
match_fn=lambda rep, resources: '/temperatures/vs/0' in resources,
poll_tier='warm',
entities=(
NumberDesc(key='setpoint', field='temperature',
translation_key='instance_setpoint',
use_instance_name=True, device_class='temperature', unit_fn=_temp_unit,
native_min=-20.0, native_max=50.0,
range_field='range', entity_category='config',
write_fn=_temp_setpoint_vendor_write),
),
)
TEMP_SETPOINT_GENERIC = Capability(
TEMP_SETPOINT = Capability(
href=None,
href_prefix='/temperature/desired/',
strip_prefix_in_key=True,
@@ -114,10 +104,7 @@ TEMP_SETPOINT_GENERIC = Capability(
use_instance_name=True, device_class='temperature', unit_fn=_temp_unit,
native_min=-20.0, native_max=50.0,
range_field='range', entity_category='config',
write_fn=lambda p, rep, href=None: (
[s for s in href.strip('/').split('/') if s],
{'temperature': int(round(float(p)))}
) if href else None),
write_fn=_temp_setpoint_write),
),
)
+2 -2
View File
@@ -20,9 +20,9 @@ class TestTempCurrentGeneric:
assert desc.unit_fn({'temperature': 5.0}) == '°F'
class TestTempSetpointGeneric:
class TestTempSetpoint:
def test_unit_reads_celsius(self):
desc = fridge.TEMP_SETPOINT_GENERIC.entities[0]
desc = fridge.TEMP_SETPOINT.entities[0]
assert desc.unit_fn({'temperature': -19.0, 'units': 'C'}) == '°C'