KIDS_LOCK_VS_FALLBACK's write_fn wrote 'Enable', a value no dump in the fixture corpus (washers, dryers, dishwashers, ovens, ranges, microwaves, air purifiers, air dressers -- everything that lacks the OCF-standard /kidslock/0) has ever reported back; every one reports 'Ready' or 'Run'. It was never a confirmed write contract. #181's reporter tested directly: writing the *correct* value ('Run') still returns 4.05, and the SmartThings app itself has no control for kids lock either -- the resource is genuinely read-only on that hardware, not just wrong-valued. #183's reporter hit the identical symptom (toggle does nothing) on a different device family reporting the same Run/Ready vocabulary. Convert the entity to a read-only BinarySensorDesc. binary_sensor's 'lock' device class is inverted from the old switch reading (On means open/unlocked), so value_fn flips accordingly -- callers reading the flattened 'child_lock' state key need to account for the new polarity. KIDS_LOCK_GENERIC (the OCF-standard /kidslock/0 boolean) is untouched; nothing suggests that one is broken.
This commit is contained in:
@@ -313,12 +313,19 @@ KIDS_LOCK_VS_FALLBACK = Capability(
|
||||
href='/kidslock/vs/0',
|
||||
match_fn=lambda rep, resources: '/kidslock/0' not in resources,
|
||||
entities=(
|
||||
SwitchDesc(key='child_lock', field='x.com.samsung.da.kidsLock',
|
||||
device_class='lock',
|
||||
value_fn=lambda v: v != 'Ready',
|
||||
write_fn=lambda p, rep, href=None: (
|
||||
['kidslock', 'vs', '0'],
|
||||
{'x.com.samsung.da.kidsLock': 'Enable' if p == 'On' else 'Ready'})),
|
||||
# Read-only, not a SwitchDesc (issues #181/#183): the write side of
|
||||
# this capability wrote 'Enable', a value no dump in the fixture
|
||||
# corpus has ever reported back -- every one reports either 'Ready'
|
||||
# or 'Run', so it was never a confirmed contract. #181's reporter
|
||||
# confirmed this directly: writing the *correct* value ('Run')
|
||||
# still 4.05s, and the SmartThings app itself has no control for
|
||||
# it either -- the resource is genuinely read-only on this
|
||||
# hardware, not just wrong-valued. binary_sensor's 'lock' device
|
||||
# class is inverted from the switch reading below it used to be:
|
||||
# On means open/unlocked, so value_fn flips to `v == 'Ready'`.
|
||||
BinarySensorDesc(key='child_lock', field='x.com.samsung.da.kidsLock',
|
||||
device_class='lock',
|
||||
value_fn=lambda v: v == 'Ready'),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"burner_pan_detected": {
|
||||
"name": "Burner {number} pan detected"
|
||||
},
|
||||
"child_lock": {
|
||||
"name": "Child lock"
|
||||
},
|
||||
"cloud_connected": {
|
||||
"name": "Cloud connected"
|
||||
},
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"burner_pan_detected": {
|
||||
"name": "Brander {number} pan gedetecteerd"
|
||||
},
|
||||
"child_lock": {
|
||||
"name": "Kinderslot"
|
||||
},
|
||||
"cloud_connected": {
|
||||
"name": "Verbonden met cloud"
|
||||
},
|
||||
|
||||
@@ -15,9 +15,13 @@ def _reg():
|
||||
|
||||
|
||||
def test_kids_lock_vs_value_fn():
|
||||
"""binary_sensor's 'lock' device class is inverted from a plain on/off
|
||||
switch: On means open/unlocked (issues #181/#183 -- see
|
||||
TestKidsLockFallback.test_vs_fallback_is_read_only for why this is a
|
||||
binary_sensor at all)."""
|
||||
desc = common.KIDS_LOCK_VS_FALLBACK.entities[0]
|
||||
assert desc.value_fn('Lock') is True
|
||||
assert desc.value_fn('Ready') is False
|
||||
assert desc.value_fn('Lock') is False
|
||||
assert desc.value_fn('Ready') is True
|
||||
|
||||
|
||||
def test_common_caps_discover_on_dishwasher(dishwasher_resources):
|
||||
@@ -241,6 +245,16 @@ class TestKidsLockFallback:
|
||||
assert common.KIDS_LOCK_VS_FALLBACK.match_fn(
|
||||
{}, {'/kidslock/0': {}, '/kidslock/vs/0': {}}) is False
|
||||
|
||||
def test_vs_fallback_is_read_only(self):
|
||||
"""Issues #181/#183: writing this resource 4.05s on real hardware
|
||||
even with the *correct* value ('Run'), and no dump in the fixture
|
||||
corpus has ever reported the value this used to write ('Enable')
|
||||
back -- every one reports 'Ready' or 'Run'. Never a confirmed write
|
||||
contract, so it's a binary_sensor (no write_fn field at all), not
|
||||
a switch."""
|
||||
desc = common.KIDS_LOCK_VS_FALLBACK.entities[0]
|
||||
assert isinstance(desc, BinarySensorDesc)
|
||||
|
||||
|
||||
class TestRemoteControlFallback:
|
||||
def test_generic_read(self):
|
||||
|
||||
@@ -56,7 +56,10 @@ def test_energy_saving_and_cooktop_alert_present():
|
||||
def test_child_lock_already_reads_correctly():
|
||||
"""issue #183 also reported child lock as unreadable -- but this dump's
|
||||
/kidslock/vs/0 ('Run') and /doors/vs/0's door lock field ('Lock') already
|
||||
agree the door is locked, and the existing common.KIDS_LOCK_VS_FALLBACK
|
||||
already reads that correctly with no code change needed."""
|
||||
agree the door is locked, and common.KIDS_LOCK_VS_FALLBACK already reads
|
||||
that correctly with no further code change needed. Now a read-only
|
||||
binary_sensor (issues #181/#183 -- the write side was never a confirmed
|
||||
contract), whose 'lock' device class is inverted from a switch's plain
|
||||
on/off: False means locked/closed, matching 'Run' here."""
|
||||
state = _state()
|
||||
assert state['child_lock'] is True
|
||||
assert state['child_lock'] is False
|
||||
|
||||
Reference in New Issue
Block a user