fix(fridge): stop switch turn-off silently sending 'On'
Six fridge SwitchDesc write_fns built their payload with `'On' if p else 'Off'`. The switch platform passes the literal string 'Off' on turn-off, which is truthy, so the guard always produced 'On' -- turning these switches off silently re-sent On and they could never be turned off: - ICEMAKER_NIGHTTIME (ice.night.status) - STATUS_LOCK helper (devicecontrol + device.sound) - DEFROST_DELAY (delayDefrost) - WELCOME_LIGHTING (status) - CABINET_LIGHT dim (light.dimming.status) - ICEMAKER_STATUS_FALLBACK (iceMaker) Compare `p == 'On'` instead, matching the pattern the other capability files already use. Adds a regression test asserting every affected write_fn sends 'Off' on 'Off' and 'On' on 'On'.
This commit is contained in:
@@ -92,7 +92,7 @@ ICEMAKER_NIGHTTIME = Capability(
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['icemaker', 'nighttime', 'vs', '0'],
|
||||
{'ice.night.status': 'On' if p else 'Off'})),
|
||||
{'ice.night.status': 'On' if p == 'On' else 'Off'})),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -168,7 +168,7 @@ DOOR_ALERT = Capability(
|
||||
def _status_lock_write(field):
|
||||
return lambda p, rep, href=None: (
|
||||
['status', 'lock', 'vs', '0'],
|
||||
{field: 'On' if p else 'Off'}
|
||||
{field: 'On' if p == 'On' else 'Off'}
|
||||
)
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ DEFROST_DELAY = Capability(
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['defrost', 'delay', 'vs', '0'],
|
||||
{'x.com.samsung.da.delayDefrost': 'On' if p else 'Off'})),
|
||||
{'x.com.samsung.da.delayDefrost': 'On' if p == 'On' else 'Off'})),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -300,7 +300,7 @@ WELCOME_LIGHTING = Capability(
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['proximity', 'vs', '0'],
|
||||
{'status': 'On' if p else 'Off'})),
|
||||
{'status': 'On' if p == 'On' else 'Off'})),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -440,7 +440,7 @@ CABINET_LIGHT = Capability(
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['cabinet', 'light', 'total', 'vs', '0'],
|
||||
{'light.dimming.status': 'On' if p else 'Off'})),
|
||||
{'light.dimming.status': 'On' if p == 'On' else 'Off'})),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -669,7 +669,7 @@ ICEMAKER_STATUS_FALLBACK = Capability(
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['icemaker', 'status', 'vs', '0'],
|
||||
{'x.com.samsung.da.iceMaker': 'On' if p else 'Off'})),
|
||||
{'x.com.samsung.da.iceMaker': 'On' if p == 'On' else 'Off'})),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -258,3 +258,39 @@ class TestRefrigeratorAiEnergyLevelFixtureCoverage:
|
||||
assert unbound == []
|
||||
state = flatten(bound, resources)
|
||||
assert state['ai_energy_level'] == '1'
|
||||
|
||||
|
||||
class TestSwitchOffIsNotInverted:
|
||||
"""Regression: several fridge SwitchDesc write_fns used ``'On' if p else 'Off'``.
|
||||
|
||||
The switch platform passes the literal string ``'Off'`` on turn-off (and
|
||||
``'On'`` on turn-on). ``'Off'`` is a non-empty, truthy string, so
|
||||
``'On' if p else 'Off'`` always evaluated to ``'On'`` — turning the switch
|
||||
OFF silently re-sent ``On`` and the switch could never be turned off. The
|
||||
guard must compare ``p == 'On'`` (as the other capability files already do).
|
||||
"""
|
||||
|
||||
# (switch descriptor, payload key it writes)
|
||||
CASES = [
|
||||
(fridge.ICEMAKER_NIGHTTIME.entities[0], 'ice.night.status'),
|
||||
(fridge.STATUS_LOCK.entities[0], 'x.com.samsung.da.ado.devicecontrol'),
|
||||
(fridge.STATUS_LOCK.entities[1], 'x.com.samsung.da.device.sound'),
|
||||
(fridge.DEFROST_DELAY.entities[0], 'x.com.samsung.da.delayDefrost'),
|
||||
(fridge.WELCOME_LIGHTING.entities[0], 'status'),
|
||||
(fridge.CABINET_LIGHT.entities[1], 'light.dimming.status'),
|
||||
(fridge.ICEMAKER_STATUS_FALLBACK.entities[0], 'x.com.samsung.da.iceMaker'),
|
||||
]
|
||||
|
||||
def test_turning_off_sends_off(self):
|
||||
for desc, key in self.CASES:
|
||||
_segs, payload = desc.write_fn('Off', {})
|
||||
assert payload[key] == 'Off', (
|
||||
f"{desc.key}: OFF must send 'Off', got {payload[key]!r} (inverted)"
|
||||
)
|
||||
|
||||
def test_turning_on_sends_on(self):
|
||||
for desc, key in self.CASES:
|
||||
_segs, payload = desc.write_fn('On', {})
|
||||
assert payload[key] == 'On', (
|
||||
f"{desc.key}: ON must send 'On', got {payload[key]!r}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user