diff --git a/custom_components/localthings/registry/capabilities/dishwasher.py b/custom_components/localthings/registry/capabilities/dishwasher.py index 993bbe3..eed00d7 100644 --- a/custom_components/localthings/registry/capabilities/dishwasher.py +++ b/custom_components/localthings/registry/capabilities/dishwasher.py @@ -14,7 +14,6 @@ from .laundry import ( bool_option_switch, cycle_select, drum_clean_cycles_remaining, - drum_clean_last_cleaned, ) # --------------------------------------------------------------------------- @@ -62,9 +61,14 @@ DISHWASHER_SETTINGS = Capability( # #258) DrumCleanProposal_/WashingTimes_/DrumCleanLog_ tokens riding on this # same options[] array -- a live dump confirmed the dishwasher reports the # identical trio (WashingTimes_18/DrumCleanProposal_20, plus a '|'-joined -# DrumCleanLog_ history matching the dryer's multi-entry shape), so the -# shared laundry.drum_clean_cycles_remaining/drum_clean_last_cleaned readers -# apply unchanged; see laundry.py for the field semantics. +# DrumCleanLog_ history matching the dryer's multi-entry shape), so +# laundry.drum_clean_cycles_remaining applies unchanged. +# +# laundry.drum_clean_last_cleaned (DrumCleanLog_'s own newest entry) is +# deliberately NOT wired up here (issue #398): a live dishwasher dump +# showed it moving every 30-90s on its own, including well after a cycle +# had already finished -- unlike the washer/dryer reports this reader was +# built from (issues #9, #258), it never settles on a value worth showing. CYCLE_OPTIONS = Capability( href="/course/vs/0", @@ -82,14 +86,6 @@ CYCLE_OPTIONS = Capability( exists_fn=lambda rep, resources: drum_clean_cycles_remaining(rep) is not None, rep_fn=drum_clean_cycles_remaining, ), - SensorDesc( - key="drum_clean_last_cleaned", - device_class="timestamp", - icon="mdi:calendar-clock", - entity_category="diagnostic", - exists_fn=lambda rep, resources: drum_clean_last_cleaned(rep) is not None, - rep_fn=drum_clean_last_cleaned, - ), ), ) diff --git a/tests/fixtures/golden/dishwasher.json b/tests/fixtures/golden/dishwasher.json index c2df5f6..cf5b055 100644 --- a/tests/fixtures/golden/dishwasher.json +++ b/tests/fixtures/golden/dishwasher.json @@ -9,7 +9,6 @@ "delay_start_hours", "diagnosis_status", "drum_clean_cycles_remaining", - "drum_clean_last_cleaned", "energy_kwh", "energy_saved_kwh", "finish_time", @@ -43,7 +42,6 @@ "samsung_dishwasher_diagnosis_start", "samsung_dishwasher_diagnosis_status", "samsung_dishwasher_drum_clean_cycles_remaining", - "samsung_dishwasher_drum_clean_last_cleaned", "samsung_dishwasher_energy_kwh", "samsung_dishwasher_energy_saved_kwh", "samsung_dishwasher_finish_time", diff --git a/tests/test_dishwasher_capabilities.py b/tests/test_dishwasher_capabilities.py index f49a139..05c3a5f 100644 --- a/tests/test_dishwasher_capabilities.py +++ b/tests/test_dishwasher_capabilities.py @@ -5,8 +5,6 @@ cycle_options, cycle_write) is tested in test_laundry_capabilities.py; here we check the dishwasher wiring and its device-specific options. """ -from datetime import UTC, datetime - from custom_components.localthings.registry.capabilities import dishwasher from custom_components.localthings.registry.entities import SensorDesc, SwitchDesc @@ -68,7 +66,13 @@ class TestDrumClean: """Drum Clean+ maintenance tracking shares washer.py's (issue #9) / dryer.py's (issue #258) options[]-array readers -- a live dishwasher dump confirmed the same WashingTimes_/DrumCleanProposal_/DrumCleanLog_ - trio, so these entities are wired the same way here.""" + trio, so drum_clean_cycles_remaining is wired the same way here. + + drum_clean_last_cleaned is deliberately not (issue #398): a live dump + showed DrumCleanLog_'s newest entry moving every 30-90s on its own, + including well after a cycle had finished -- unlike the washer/dryer + reports this reader was built from (issues #9, #258), it never settles + on a value worth showing.""" def test_cycles_remaining(self): desc = next( @@ -87,28 +91,10 @@ class TestDrumClean: rep = {"x.com.samsung.da.options": ["WashingTimes_18", "DrumCleanProposal_20"]} assert desc.exists_fn(rep, {}) is True - def test_last_cleaned(self): - """A live dump's DrumCleanLog_ is a '|'-joined history (the dryer - shape, not the washer's single-entry one) -- the last entry wins.""" - desc = next( - e for e in dishwasher.CYCLE_OPTIONS.entities if e.key == "drum_clean_last_cleaned" + def test_last_cleaned_is_not_wired(self): + assert not any( + e.key == "drum_clean_last_cleaned" for e in dishwasher.CYCLE_OPTIONS.entities ) - assert desc.rep_fn is not None - rep = { - "x.com.samsung.da.options": [ - "DrumCleanLog_2026-06-26T04:18:58|2026-06-28T00:36:34", - ] - } - assert desc.rep_fn(rep) == datetime(2026, 6, 28, 0, 36, 34, tzinfo=UTC) - - def test_last_cleaned_missing(self): - desc = next( - e for e in dishwasher.CYCLE_OPTIONS.entities if e.key == "drum_clean_last_cleaned" - ) - assert desc.rep_fn is not None - assert desc.rep_fn({"x.com.samsung.da.options": []}) is None - assert desc.exists_fn is not None - assert desc.exists_fn({"x.com.samsung.da.options": []}, {}) is False def test_diagnosis_status_is_a_translatable_enum():