Add dehumidifier display switch and watertank lighting (issues #271, #231)

The TP1X_DA_AC_DHM_01001_0000 revision (model AY70H18100GTD) additionally
reports /display/vs/0 (same shape as air_purifier's screen toggle, reused
directly) and /watertank/lighting/vs/0 (on/off, color, and brightness for
the tank's ambient light, plus a diagnostic alarm-status flag). Both issues
submitted the identical dump, so one fix covers both reports.

Also adds x.com.st.d.dehumidifier to the /oic/d device-type routing table
now that a dump confirms it.
This commit is contained in:
Marc Billow committed 2026-08-03 18:59:22 +00:00
1 parent 51103fa341
commit 3ef64eae52
12 files changed
+2018 -1284

No files matched your search

@@ -259,6 +259,7 @@ _OIC_TYPE_TO_KEY: dict[str, str] = {
"oic.d.refrigerator": "refrigerator",
"oic.d.washer": "washer",
"x.com.st.d.airqualitysensor": "air_monitor",
"x.com.st.d.dehumidifier": "dehumidifier",
"x.com.st.d.hood": "range_hood", # AHD-WW-TP1-22-COMMON
"x.com.st.d.stickcleaner": "vacuum_station",
"x.com.st.d.steamcloset": "air_dresser",
@@ -2,10 +2,13 @@
Shares the DA_AC_ board family with airconditioner.py (power, air filter,
auto-clean, mute-once all use the identical resource shapes), so those three
Capability objects are reused directly rather than duplicated.
Capability objects are reused directly rather than duplicated. The
TP1X_DA_AC_DHM_01001_0000 revision (issues #271/#231) also reports
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, common, dehumidifier, ignored
from ..capabilities import airconditioner, air_purifier, common, dehumidifier, ignored
from ._base import DeviceRegistry, _build
REGISTRY = DeviceRegistry(
@@ -17,9 +20,11 @@ REGISTRY = DeviceRegistry(
*common.POWER,
dehumidifier.MODE,
dehumidifier.HUMIDITY,
dehumidifier.WATERTANK_LIGHTING,
airconditioner.AUTO_CLEAN,
airconditioner.AIR_FILTER,
airconditioner.MUTE_ONCE,
air_purifier.DISPLAY,
*dehumidifier.COVERAGE,
]
),
@@ -9,7 +9,7 @@ entities rather than folded into one card.
"""
from ..capability import Capability
from ..entities import NumberDesc, SelectDesc, SensorDesc
from ..entities import NumberDesc, SelectDesc, SensorDesc, SwitchDesc
from .common import int_or_none
@@ -77,6 +77,60 @@ HUMIDITY = Capability(
),
)
# Water-tank ambient light (issues #271/#231, TP1X_DA_AC_DHM_01001_0000):
# on/off, color, and brightness are three independent controls on this one
# resource. `waterfullAlarmStatus` differs between the two dumps that
# reported this href (On vs. Off) so it's a real live flag, not a constant --
# but its exact meaning (tank actually full vs. the chime feature merely
# enabled) isn't confirmed by either dump alone, and /alarms/vs/0's
# alarm_code already surfaces a live WaterTankFull condition when one fires
# (see common._active_alarm_codes), so this is exposed read-only as a plain
# diagnostic value rather than guessed at as a binary_sensor.
WATERTANK_LIGHTING = Capability(
href="/watertank/lighting/vs/0",
poll_tier="cold",
entities=(
SwitchDesc(
key="watertank_light",
field="status",
icon="mdi:led-on",
entity_category="config",
value_fn=lambda v: v == "On",
write_fn=lambda p, rep, href=None: (
["watertank", "lighting", "vs", "0"],
{"status": "On" if p == "On" else "Off"},
),
),
SelectDesc(
key="watertank_light_color",
field="colorOption",
icon="mdi:palette",
entity_category="config",
options_field="colorSupportedList",
write_fn=lambda p, rep, href=None: (
["watertank", "lighting", "vs", "0"],
{"colorOption": p},
),
),
SelectDesc(
key="watertank_light_brightness",
field="mode",
icon="mdi:brightness-6",
entity_category="config",
options_field="modeSupportedList",
write_fn=lambda p, rep, href=None: (
["watertank", "lighting", "vs", "0"],
{"mode": p},
),
),
SensorDesc(
key="watertank_full_alarm_status",
field="waterfullAlarmStatus",
entity_category="diagnostic",
),
),
)
# ---------------------------------------------------------------------------
# Dehumidifier-scoped coverage: vendor plumbing with no user-actionable state
# or no documented write contract, following the same 'don't guess' rule as
File diff suppressed because it is too large. Load diff
@@ -621,6 +621,22 @@
},
"zone_mode": {
"name": "Zone mode"
},
"watertank_light_color": {
"name": "Water tank light color",
"state": {
"warmwhite": "Warm white",
"naturalwhite": "Natural white",
"coolwhite": "Cool white",
"green": "Green",
"purple": "Purple",
"blue": "Blue",
"orange": "Orange",
"pink": "Pink"
}
},
"watertank_light_brightness": {
"name": "Water tank light brightness"
}
},
"sensor": {
@@ -969,6 +985,9 @@
},
"zone_temperature": {
"name": "Zone temperature"
},
"watertank_full_alarm_status": {
"name": "Water tank full alarm status"
}
},
"switch": {
@@ -1136,6 +1155,9 @@
},
"away_mode": {
"name": "Away mode"
},
"watertank_light": {
"name": "Water tank light"
}
},
"time": {
@@ -735,6 +735,22 @@
},
"zone_mode": {
"name": "Modo de zona"
},
"watertank_light_color": {
"name": "Color de la luz del depósito de agua",
"state": {
"warmwhite": "Blanco cálido",
"naturalwhite": "Blanco natural",
"coolwhite": "Blanco frío",
"green": "Verde",
"purple": "Púrpura",
"blue": "Azul",
"orange": "Naranja",
"pink": "Rosa"
}
},
"watertank_light_brightness": {
"name": "Brillo de la luz del depósito de agua"
}
},
"sensor": {
@@ -1083,6 +1099,9 @@
},
"zone_temperature": {
"name": "Temperatura de zona"
},
"watertank_full_alarm_status": {
"name": "Estado de alarma de depósito de agua lleno"
}
},
"switch": {
@@ -1250,6 +1269,9 @@
},
"zone_power": {
"name": "Alimentación de zona"
},
"watertank_light": {
"name": "Luz del depósito de agua"
}
},
"time": {
@@ -621,6 +621,22 @@
},
"zone_mode": {
"name": "Modalità zona"
},
"watertank_light_color": {
"name": "Colore della luce del serbatoio dell'acqua",
"state": {
"warmwhite": "Bianco caldo",
"naturalwhite": "Bianco naturale",
"coolwhite": "Bianco freddo",
"green": "Verde",
"purple": "Viola",
"blue": "Blu",
"orange": "Arancione",
"pink": "Rosa"
}
},
"watertank_light_brightness": {
"name": "Luminosità della luce del serbatoio dell'acqua"
}
},
"sensor": {
@@ -969,6 +985,9 @@
},
"zone_temperature": {
"name": "Temperatura zona"
},
"watertank_full_alarm_status": {
"name": "Stato allarme serbatoio d'acqua pieno"
}
},
"switch": {
@@ -1136,6 +1155,9 @@
},
"away_mode": {
"name": "Modalità assenza"
},
"watertank_light": {
"name": "Luce del serbatoio dell'acqua"
}
},
"time": {
@@ -621,6 +621,22 @@
},
"zone_mode": {
"name": "Zonemodus"
},
"watertank_light_color": {
"name": "Kleur van het waterreservoirlicht",
"state": {
"warmwhite": "Warm wit",
"naturalwhite": "Natuurlijk wit",
"coolwhite": "Koel wit",
"green": "Groen",
"purple": "Paars",
"blue": "Blauw",
"orange": "Oranje",
"pink": "Roze"
}
},
"watertank_light_brightness": {
"name": "Helderheid van het waterreservoirlicht"
}
},
"sensor": {
@@ -969,6 +985,9 @@
},
"zone_temperature": {
"name": "Zonetemperatuur"
},
"watertank_full_alarm_status": {
"name": "Status alarm waterreservoir vol"
}
},
"switch": {
@@ -1136,6 +1155,9 @@
},
"away_mode": {
"name": "Afwezigheidsmodus"
},
"watertank_light": {
"name": "Waterreservoirlicht"
}
},
"time": {