From 0cc9486ad52a12b5df722606d9192a41b9ac4156 Mon Sep 17 00:00:00 2001 From: Marc Billow Date: Mon, 3 Aug 2026 19:17:41 +0000 Subject: [PATCH] Add missing dryer cycle labels for DV90DG6845LHU5 (issue #244) Codes 51 (Eco Cotton), 53 (AI Dry+), and 4e (Self Dry) were confirmed by the reporter selecting each program on the physical appliance and reading back the resulting raw course code, same table (Table_03) as the existing issue #80 confirmations. Also fixes an import-sort lint error left over in by_type/dehumidifier.py and a stale comment in dryer.py claiming codes 21/4c were still unidentified when the catalog already had them. --- .../localthings/registry/by_type/dehumidifier.py | 2 +- .../localthings/registry/capabilities/dryer.py | 12 ++++++------ custom_components/localthings/translations/cs.json | 5 ++++- custom_components/localthings/translations/en.json | 5 ++++- custom_components/localthings/translations/es.json | 5 ++++- custom_components/localthings/translations/it.json | 5 ++++- custom_components/localthings/translations/nl.json | 5 ++++- tests/test_dryer_capabilities.py | 12 ++++++++++++ 8 files changed, 39 insertions(+), 12 deletions(-) diff --git a/custom_components/localthings/registry/by_type/dehumidifier.py b/custom_components/localthings/registry/by_type/dehumidifier.py index 9230e60..ee3b041 100644 --- a/custom_components/localthings/registry/by_type/dehumidifier.py +++ b/custom_components/localthings/registry/by_type/dehumidifier.py @@ -8,7 +8,7 @@ air_purifier.py's screen-on/off resource on the identical href/shape, so that's reused too rather than re-defined. """ -from ..capabilities import airconditioner, air_purifier, common, dehumidifier, ignored +from ..capabilities import air_purifier, airconditioner, common, dehumidifier, ignored from ._base import DeviceRegistry, _build REGISTRY = DeviceRegistry( diff --git a/custom_components/localthings/registry/capabilities/dryer.py b/custom_components/localthings/registry/capabilities/dryer.py index 9887bf4..592ad79 100644 --- a/custom_components/localthings/registry/capabilities/dryer.py +++ b/custom_components/localthings/registry/capabilities/dryer.py @@ -41,14 +41,14 @@ DRYER_SETTINGS = Capability( # laundry.cycle_select (options read live from /wm/editcourse/vs/0, written as # an RMW on the options array). Course display names live in translations # under entity.select.dryer_cycle (Table_03, DV5000-class, captured -# 2026-05-29). Codes 0x21 and 0x4C appear in the issue #14 DV90BB5245AES1 -# editCourseList but aren't identified yet -- they render as the raw code -# until named. Codes '01' Normal and '06' Time dry were confirmed on a +# 2026-05-29). Codes '01' Normal and '06' Time dry were confirmed on a # DVE50A8600V/A3 (also Table_03) by selecting each cycle on the physical # appliance and reading back the raw code from the entity's state (issue -# #80). The /st/dryercourse/vs/0 resource re-encodes the same selected -# course and is ignored (ignored.py) -- the mirror of how /st/washercourse/vs/0 -# is ignored for washers. +# #80). Codes '51' Eco Cotton, '53' AI Dry+, and '4e' Self Dry were +# confirmed the same way on a DV90DG6845LHU5 (issue #244). The +# /st/dryercourse/vs/0 resource re-encodes the same selected course and is +# ignored (ignored.py) -- the mirror of how /st/washercourse/vs/0 is ignored +# for washers. # # Drum Clean+ maintenance tracking (issue #258) reuses washer.py's # DrumCleanProposal_/WashingTimes_/DrumCleanLog_ tokens on this same diff --git a/custom_components/localthings/translations/cs.json b/custom_components/localthings/translations/cs.json index 1b3b139..ca69505 100644 --- a/custom_components/localthings/translations/cs.json +++ b/custom_components/localthings/translations/cs.json @@ -325,7 +325,10 @@ "1e": "Outdoor", "1f": "Smíšená náplň", "2b": "Sušení bubnu", - "4c": "Osvěžení vzduchem" + "4c": "Osvěžení vzduchem", + "51": "Eko bavlna", + "53": "AI sušení+", + "4e": "Automatické sušení" } }, "favorite_capacity": { diff --git a/custom_components/localthings/translations/en.json b/custom_components/localthings/translations/en.json index 4f85217..0a620e2 100644 --- a/custom_components/localthings/translations/en.json +++ b/custom_components/localthings/translations/en.json @@ -325,7 +325,10 @@ "1e": "Outdoor", "1f": "Mixed load", "2b": "Self Tub Dry", - "4c": "Air Refresh" + "4c": "Air Refresh", + "51": "Eco Cotton", + "53": "AI Dry+", + "4e": "Self Dry" } }, "favorite_capacity": { diff --git a/custom_components/localthings/translations/es.json b/custom_components/localthings/translations/es.json index 7a053a7..cf5782c 100644 --- a/custom_components/localthings/translations/es.json +++ b/custom_components/localthings/translations/es.json @@ -439,7 +439,10 @@ "1e": "Exterior", "1f": "Carga mixta", "2b": "Secado de tambor", - "4c": "Renovación de aire" + "4c": "Renovación de aire", + "51": "Eco algodón", + "53": "Secado IA+", + "4e": "Autosecado" } }, "favorite_capacity": { diff --git a/custom_components/localthings/translations/it.json b/custom_components/localthings/translations/it.json index cbedc3c..6fdda18 100644 --- a/custom_components/localthings/translations/it.json +++ b/custom_components/localthings/translations/it.json @@ -325,7 +325,10 @@ "1e": "Capi outdoor", "1f": "Carico misto", "2b": "Asciugatura cestello", - "4c": "Rinfresca" + "4c": "Rinfresca", + "51": "Eco cotone", + "53": "Asciugatura AI+", + "4e": "Autoasciugatura" } }, "favorite_capacity": { diff --git a/custom_components/localthings/translations/nl.json b/custom_components/localthings/translations/nl.json index eac94b7..d2ed9a7 100644 --- a/custom_components/localthings/translations/nl.json +++ b/custom_components/localthings/translations/nl.json @@ -325,7 +325,10 @@ "1e": "Outdoor", "1f": "Gemengde was", "2b": "Zelf trommel drogen", - "4c": "Opfrissen" + "4c": "Opfrissen", + "51": "Eco katoen", + "53": "AI drogen+", + "4e": "Zelf drogen" } }, "favorite_capacity": { diff --git a/tests/test_dryer_capabilities.py b/tests/test_dryer_capabilities.py index 1791efb..cb5aa42 100644 --- a/tests/test_dryer_capabilities.py +++ b/tests/test_dryer_capabilities.py @@ -94,3 +94,15 @@ def test_st_dryercourse_is_ignored(): ignored_hrefs = {c.href for c in ignored.IGNORED} assert "/st/dryercourse/vs/0" in ignored_hrefs assert "/st/washercourse/vs/0" in ignored_hrefs + + +def test_table_03_labels_confirmed_on_dv90dg6845lhu5(): + """Issue #244: codes 51/53/4e were confirmed by selecting each program + directly on the physical DV90DG6845LHU5 and reading back the resulting + raw course code -- same verification method as issue #80's '52'/'54'/'60' + on the washer's own course table.""" + from custom_components.localthings.catalog import translated_states + + known = translated_states("select", "dryer_cycle_table_03") + for code in ("51", "53", "4e", "17", "21", "4c"): + assert code in known, code