From e568145deb6ced2a73f401057a955689483ac913 Mon Sep 17 00:00:00 2001 From: Marc Billow Date: Tue, 28 Jul 2026 14:03:56 +0000 Subject: [PATCH] Fix microwave lamp switch reading/writing the wrong tokens (#152) The lamp SwitchDesc was modeled on issue #137's dump, which only ever showed 'Lamp_Off' -- 'On' was never actually confirmed as the paired value. Issue #152's ME7500D dump (same TP1X_DA-KS-MICROWAVE-01051 family) is the first to report a real non-Off value, and it's 'Lamp_High' (a brightness level), not 'Lamp_On'. So the switch always read as off regardless of the device's real state, and toggling it on wrote a token ('On') the device has never been observed to accept -- matching the reported "light control does not have any effect." value_fn now treats any non-Off/non-absent value as on; write_fn now writes back 'High'/'Off', the two tokens actually confirmed live, instead of the never-confirmed 'On'. The reporter's suspicion about the fan is unconfirmed and this dump's own /hood/fanspeed/vs/0 shape already matches the no-separate-power case fan.py's LocalThingsRangeHoodFan handles correctly (issues #137/#142), so no fan change was needed here. A second dump attached in a comment on this issue (model ME8000T, a large combi wall-oven with a very different mode vocabulary) reports its own distinct gap and doesn't resolve to any known device type at all -- that's a separate, substantial device-support task left for its own follow-up rather than folded into this fix. --- .../registry/capabilities/microwave.py | 15 ++++++++++++--- tests/test_microwave_capabilities.py | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/custom_components/localthings/registry/capabilities/microwave.py b/custom_components/localthings/registry/capabilities/microwave.py index 7dcb7f5..4e815ad 100644 --- a/custom_components/localthings/registry/capabilities/microwave.py +++ b/custom_components/localthings/registry/capabilities/microwave.py @@ -21,7 +21,12 @@ different from an oven, and defined fresh here: * Lamp: this family's option-array token is bare 'Lamp' (issue #137's 'Lamp_Off'), not oven.py's 'UpperLamp' -- and it's genuinely absent on the combi dump (issue #121), so it's gated with exists_fn rather than - assumed universal like oven.py's lamp switch. + assumed universal like oven.py's lamp switch. Issue #137's dump only + ever showed 'Off', so 'On' was a guess at the paired value; issue #152's + ME7500D dump is the first to show a real non-Off value, and it's 'High' + (a brightness level, not literally 'On') -- the switch now treats any + non-Off/non-None value as "on" for reads, and writes back 'High'/'Off' + (the two confirmed tokens) rather than the never-confirmed 'On'. Note: cooking-mode writes are unproven here, same caveat as oven.py's OVEN_MODE -- exposed as a SelectDesc for fidelity, first real-world write @@ -132,8 +137,12 @@ def _lamp_write(p, rep, href=None): return None if not rep.get('x.com.samsung.da.options'): return None + # 'High' and 'Off' are the two tokens actually confirmed on live dumps + # (issues #137/#152) -- 'On' has never been observed and the device + # likely doesn't recognize it (see module docstring). + token = 'High' if p == 'On' else 'Off' return ['mode', 'vs', '0'], { - 'x.com.samsung.da.options': option_write('Lamp', p), + 'x.com.samsung.da.options': option_write('Lamp', token), } @@ -189,7 +198,7 @@ MICROWAVE_MODE = Capability( SwitchDesc(key='lamp', field='x.com.samsung.da.options', icon='mdi:track-light', exists_fn=_lamp_exists, - value_fn=lambda opts: option_value(opts, 'Lamp') == 'On', + value_fn=lambda opts: option_value(opts, 'Lamp') not in (None, 'Off'), write_fn=_lamp_write), ), ) diff --git a/tests/test_microwave_capabilities.py b/tests/test_microwave_capabilities.py index 05f0b91..5629322 100644 --- a/tests/test_microwave_capabilities.py +++ b/tests/test_microwave_capabilities.py @@ -165,13 +165,28 @@ def test_lamp_gated_present_when_lamp_option_reported(): def test_lamp_write_is_single_token(): + """issue #152: the device has never been observed accepting 'On' -- + only 'High'/'Off' -- so the switch's "on" write uses 'High'.""" desc = next(e for e in microwave.MICROWAVE_MODE.entities if e.key == 'lamp') rep = {'x.com.samsung.da.options': ['Lamp_Off']} path, body = desc.write_fn('On', rep) assert path == ['mode', 'vs', '0'] - assert body == {'x.com.samsung.da.options': ['Lamp_On']} + assert body == {'x.com.samsung.da.options': ['Lamp_High']} def test_lamp_write_requires_existing_options(): desc = next(e for e in microwave.MICROWAVE_MODE.entities if e.key == 'lamp') assert desc.write_fn('On', {}) is None + + +def test_lamp_reads_off_as_false(): + desc = next(e for e in microwave.MICROWAVE_MODE.entities if e.key == 'lamp') + assert desc.value_fn(['Lamp_Off']) is False + + +def test_lamp_reads_any_non_off_level_as_true(): + """issue #152's ME7500D reports 'Lamp_High', not the binary 'Lamp_On' + #137's dump implied -- any non-Off/non-absent value must read as on, not + just a literal 'On'.""" + desc = next(e for e in microwave.MICROWAVE_MODE.entities if e.key == 'lamp') + assert desc.value_fn(['Lamp_High']) is True