Files
localthings/tests/test_range_ne6516a_capabilities.py
T
Marc Billow e46e935ba0 fix(common): make the vendor kids-lock fallback read-only (#181, #183)
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.
2026-07-31 02:09:58 +00:00

66 lines
2.4 KiB
Python

"""Tests for the NE6516A-class range (issue #183).
Same no-/information/vs/0, no-burner-status shape as issues #74/#138. Its
/mode/vs/0 options[] carries EnergySaving_On and BurnerOnAlert_Off -- both
previously unbound entirely -- but no fastpreheat_*/NaturalSteam_* tokens at
all, which is what exposed the pre-existing fast_preheat/natural_steam
phantom-switch bug (both were shipped with no exists_fn, so they bound
unconditionally, always read off, and any write went to a token this
firmware never recognized).
"""
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import for_device_by_resources
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
def _range():
resources = _load_device('range_ne6516a')
reg = for_device_by_resources(resources)
return reg, resources
def _state():
reg, resources = _range()
bound = discover(resources, reg.capabilities, reg.pattern_capabilities)
return flatten(bound, resources)
def test_resolves_to_range_registry():
reg, _ = _range()
assert reg is not None and reg.name == 'range'
def test_no_unbound_hrefs():
reg, resources = _range()
unbound = []
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
assert unbound == []
def test_fast_preheat_and_natural_steam_absent_without_their_tokens():
"""Neither token is in this dump's options[] -- both switches must stay
unbound rather than silently reading as an always-off phantom control."""
state = _state()
assert 'fast_preheat' not in state
assert 'natural_steam' not in state
def test_energy_saving_and_cooktop_alert_present():
state = _state()
assert state['energy_saving'] is True
assert state['cooktop_on_alert'] is False
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 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 False