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:
@@ -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": {
|
||||
|
||||
@@ -0,0 +1,426 @@
|
||||
{
|
||||
"device0": [
|
||||
{
|
||||
"rt": [
|
||||
"x.com.samsung.devcol",
|
||||
"oic.wk.col"
|
||||
],
|
||||
"if": [
|
||||
"oic.if.baseline",
|
||||
"oic.if.ll",
|
||||
"oic.if.b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"href": "/personality/presence/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "",
|
||||
"x.com.samsung.da.deviceId": "**REDACTED**",
|
||||
"x.com.samsung.da.value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/realtimenotiforclient/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.timeforshortnoti": "0",
|
||||
"x.com.samsung.da.longnotisubscription": "false",
|
||||
"x.com.samsung.da.periodicnotisubscription": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/filter/airdustfilter/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.filterUsage": "100",
|
||||
"x.com.samsung.da.filterUsageResolution": "1",
|
||||
"x.com.samsung.da.filterDesiredUsage": "224",
|
||||
"x.com.samsung.da.filterStatus": "wash",
|
||||
"x.com.samsung.da.filterCapacity": "224",
|
||||
"x.com.samsung.da.filterCapacityUnit": "Hour",
|
||||
"x.com.samsung.da.filterResetType": [
|
||||
"washable"
|
||||
],
|
||||
"x.com.samsung.da.supportedFilterDesiredUsage": [
|
||||
"224",
|
||||
"300",
|
||||
"500",
|
||||
"700"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mode/convenient/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"Off",
|
||||
"Sleep"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/option/autoclean/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.status": "Stop",
|
||||
"x.com.samsung.da.settingStatus": "On",
|
||||
"x.com.samsung.da.progress": "0",
|
||||
"cleaningTime": "30",
|
||||
"minCleaningTime": "10",
|
||||
"maxCleaningTime": "60",
|
||||
"cleaningTimeUnit": "10",
|
||||
"x.com.samsung.da.supportedStatus": [
|
||||
"Start",
|
||||
"TimedClean",
|
||||
"Stop"
|
||||
],
|
||||
"x.com.samsung.da.supportedSettingStatus": [
|
||||
"On",
|
||||
"TimedClean",
|
||||
"Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/alarms/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "Alarm",
|
||||
"x.com.samsung.da.alarmType": "Device",
|
||||
"x.com.samsung.da.code": "ErrorCode_OFF",
|
||||
"x.com.samsung.da.triggeredTime": "2026-08-03T14:54:15",
|
||||
"x.com.samsung.da.state": "Deleted"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "2",
|
||||
"x.com.samsung.da.description": "Alarm",
|
||||
"x.com.samsung.da.alarmType": "Device",
|
||||
"x.com.samsung.da.code": "WaterTankFull_OFF",
|
||||
"x.com.samsung.da.triggeredTime": "2026-08-03T14:54:15",
|
||||
"x.com.samsung.da.state": "Deleted"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/energy/consumption/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.instantaneousPower": "145.000000",
|
||||
"x.com.samsung.da.cumulativePower": "101100",
|
||||
"x.com.samsung.da.cumulativeSavedPower": "0",
|
||||
"x.com.samsung.da.cumulativeUnit": "Wh",
|
||||
"x.com.samsung.da.instantaneousPowerUnit": "W",
|
||||
"x.com.samsung.da.cumulativePowerType": "total"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mode/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"Smart",
|
||||
"Max",
|
||||
"High",
|
||||
"Medium",
|
||||
"Quiet",
|
||||
"ClothesDrying"
|
||||
],
|
||||
"x.com.samsung.da.modes": [
|
||||
"Quiet"
|
||||
],
|
||||
"x.com.samsung.da.options": [
|
||||
"Volume_Mute",
|
||||
"RacInfo_None",
|
||||
"UpdateAllow_NotAllowed",
|
||||
"WelcomeCoolingState_Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/power/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.power": "On",
|
||||
"operationNumber": "1",
|
||||
"displayCondition": "Enable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/sensors/vs/0",
|
||||
"rep": {}
|
||||
},
|
||||
{
|
||||
"href": "/information/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.modelNum": "TP1X_DA_AC_DHM_01001_0000|10283341|77000000001700000A00000000000000",
|
||||
"x.com.samsung.da.description": "TP1X_DA_AC_DHM_01001_0000",
|
||||
"x.com.samsung.da.serialNum": "**REDACTED**",
|
||||
"x.com.samsung.da.otnDUID": "**REDACTED**",
|
||||
"x.com.samsung.da.diagProtocolType": "BLE_OCF",
|
||||
"x.com.samsung.da.diagLogType": [
|
||||
"errCode",
|
||||
"dump"
|
||||
],
|
||||
"x.com.samsung.da.diagDumpType": "file",
|
||||
"x.com.samsung.da.diagEndPoint": "SSM",
|
||||
"x.com.samsung.da.diagMnid": "0AJT",
|
||||
"x.com.samsung.da.diagSetupid": "AY0",
|
||||
"x.com.samsung.da.diagMinVersion": "3.0",
|
||||
"x.com.samsung.da.diagTsId": "DA01",
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "Version",
|
||||
"x.com.samsung.da.type": "Software",
|
||||
"x.com.samsung.da.number": "02544A260401",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "1",
|
||||
"x.com.samsung.da.description": "Version",
|
||||
"x.com.samsung.da.type": "Firmware",
|
||||
"x.com.samsung.da.number": "02833A26010600,FFFFFFFFFFFFFF",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "2",
|
||||
"x.com.samsung.da.description": "Version",
|
||||
"x.com.samsung.da.type": "Outdoor",
|
||||
"x.com.samsung.da.number": "02590A10000100,FFFFFFFFFFFFFF"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "4",
|
||||
"x.com.samsung.da.description": "Version",
|
||||
"x.com.samsung.da.type": "Touch IC",
|
||||
"x.com.samsung.da.number": "02552A23020200,FFFFFFFFFFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/file/information/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.timeoffset": "+09:00",
|
||||
"x.com.samsung.supprtedtype": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/configuration/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.region": "0000000000",
|
||||
"x.com.samsung.da.airconOptionList": [
|
||||
"SingleCommand_1",
|
||||
"DR",
|
||||
"HOMECARE_WIZARD_V2",
|
||||
"PRODUCT_GLOBAL",
|
||||
"AI_RAC_GLOBAL_2.0",
|
||||
"AI_Heat"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/humidity/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.humidity": "63",
|
||||
"x.com.samsung.da.desiredHumidity": "60",
|
||||
"increment": "5",
|
||||
"x.com.samsung.da.fivepercentHumidity": "64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/drlc/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.drlcLevel": "0",
|
||||
"x.com.samsung.da.durationminutes": "0",
|
||||
"x.com.samsung.da.start": "1970-01-01T00:00:00Z",
|
||||
"x.com.samsung.da.override": "Off",
|
||||
"x.com.samsung.da.realSaving": "Off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/availablecontrolsets/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.sets": "04001E46070A5A00000000000000",
|
||||
"x.com.samsung.da.id": "DHM",
|
||||
"x.com.samsung.da.version": "1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/da/softreset/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.softwarereset": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/keepnormalstate/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.keepnormal": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/otninformation/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.target": "",
|
||||
"x.com.samsung.da.newVersionAvailable": "false",
|
||||
"x.com.samsung.da.newVersionNo": "00000000",
|
||||
"x.com.samsung.da.currentVersionInfo": "00000000",
|
||||
"otnStatus": "None",
|
||||
"flashingProgress": "",
|
||||
"otnTarget": "main",
|
||||
"otnCompleteDate": "2026-06-24",
|
||||
"otnList": [
|
||||
{
|
||||
"type": "WIFI",
|
||||
"modelId": "ADH-WW-TP1-23-AY7100",
|
||||
"versions": [
|
||||
"18260401"
|
||||
],
|
||||
"visVersion": "260401"
|
||||
},
|
||||
{
|
||||
"type": "Micom",
|
||||
"modelId": "042110283341FFFFFFFF",
|
||||
"versions": [
|
||||
"26010600",
|
||||
"FFFFFFFF"
|
||||
],
|
||||
"visVersion": "260106"
|
||||
},
|
||||
{
|
||||
"type": "Micom",
|
||||
"modelId": "042110259041FFFFFFFF",
|
||||
"versions": [
|
||||
"10000100",
|
||||
"FFFFFFFF"
|
||||
],
|
||||
"visVersion": "100001"
|
||||
},
|
||||
{
|
||||
"type": "Micom",
|
||||
"modelId": "042110255241FFFFFFFF",
|
||||
"versions": [
|
||||
"23020200",
|
||||
"FFFFFFFF"
|
||||
],
|
||||
"visVersion": "230202"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/timezone/vs/0",
|
||||
"rep": {
|
||||
"timezoneid": "Asia/Seoul",
|
||||
"offset": "+09:00",
|
||||
"DST": "OFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/option/muteonce/vs/0",
|
||||
"rep": {
|
||||
"muteonce": "Off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/reserverulesets/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.sets": "3F1E461E461E46FFFFFFFF1E4600",
|
||||
"x.com.samsung.da.id": "DHM",
|
||||
"x.com.samsung.da.version": "1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/display/vs/0",
|
||||
"rep": {
|
||||
"mode": "On",
|
||||
"supportedModes": [
|
||||
"On",
|
||||
"Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/connectionconfig/vs/0",
|
||||
"rep": {
|
||||
"autoReconnectionMinVersion": "1.0",
|
||||
"autoReconnection": "true",
|
||||
"autoReconnectionProtocolType": [
|
||||
"helper_hotspot",
|
||||
"ble_ocf"
|
||||
],
|
||||
"supportedWiFiAuthType": [
|
||||
"OPEN",
|
||||
"WEP",
|
||||
"WPA-PSK",
|
||||
"WPA2-PSK",
|
||||
"SAE"
|
||||
],
|
||||
"supportedWiFiCryptoType": [
|
||||
"TKIP",
|
||||
"AES",
|
||||
"WEP-64",
|
||||
"WEP-128"
|
||||
],
|
||||
"supportedWiFiFreq": [
|
||||
"2.4G"
|
||||
],
|
||||
"calmConnectionCare": {
|
||||
"version": "1.0",
|
||||
"role": [
|
||||
"things"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/welcome/humidity/vs/0",
|
||||
"rep": {
|
||||
"requestId": "0000",
|
||||
"operatingStatus": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/kidslock/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.kidsLock": "Ready"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/watertank/lighting/vs/0",
|
||||
"rep": {
|
||||
"status": "On",
|
||||
"colorOption": "NaturalWhite",
|
||||
"mode": "High",
|
||||
"waterfullAlarmStatus": "On",
|
||||
"colorSupportedList": [
|
||||
"WarmWhite",
|
||||
"NaturalWhite",
|
||||
"CoolWhite",
|
||||
"Green",
|
||||
"Purple",
|
||||
"Blue",
|
||||
"Orange",
|
||||
"Pink"
|
||||
],
|
||||
"modeSupportedList": [
|
||||
"High",
|
||||
"Low"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/wirelessinfo/vs/0",
|
||||
"rep": {
|
||||
"macaddressWiFi": "**REDACTED**",
|
||||
"macaddressBLE": "**REDACTED**"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/quickcontrol/info/vs/0",
|
||||
"rep": {
|
||||
"supportedVersion": "1.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"state_keys": [
|
||||
"air_filter_status",
|
||||
"air_filter_threshold",
|
||||
"air_filter_usage",
|
||||
"air_filter_usage_hours",
|
||||
"alarm_code",
|
||||
"auto_clean",
|
||||
"auto_clean_progress",
|
||||
"auto_clean_running",
|
||||
"child_lock",
|
||||
"display",
|
||||
"energy_kwh",
|
||||
"energy_saved_kwh",
|
||||
"firmware_update",
|
||||
"humidity",
|
||||
"mute_once",
|
||||
"operating_mode",
|
||||
"power_switch",
|
||||
"power_watts",
|
||||
"target_humidity",
|
||||
"watertank_full_alarm_status",
|
||||
"watertank_light",
|
||||
"watertank_light_brightness",
|
||||
"watertank_light_color"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
"""Tests for the TP1X_DA_AC_DHM_01001_0000 dehumidifier revision
|
||||
(issues #271/#231, model AY70H18100GTD).
|
||||
|
||||
Both issues submitted the identical dump: same board, same two previously
|
||||
unbound hrefs (/display/vs/0, /watertank/lighting/vs/0). Confirms both the
|
||||
new capabilities and the /oic/d device-type routing added alongside them.
|
||||
"""
|
||||
|
||||
from custom_components.localthings.registry.adapter import flatten
|
||||
from custom_components.localthings.registry.by_type import (
|
||||
for_device_by_model,
|
||||
for_device_by_oic_type,
|
||||
)
|
||||
from custom_components.localthings.registry.discovery import discover
|
||||
from custom_components.localthings.registry.entities import SelectDesc, SwitchDesc
|
||||
from tests.conftest import _load_device
|
||||
|
||||
|
||||
def _dehumidifier():
|
||||
resources = _load_device("dehumidifier_tp1x_dhm01001")
|
||||
info = resources["/information/vs/0"]
|
||||
reg = for_device_by_model(
|
||||
info["x.com.samsung.da.modelNum"],
|
||||
info["x.com.samsung.da.description"],
|
||||
)
|
||||
return reg, resources
|
||||
|
||||
|
||||
def _bound():
|
||||
reg, resources = _dehumidifier()
|
||||
return discover(resources, reg.capabilities, reg.pattern_capabilities), resources
|
||||
|
||||
|
||||
def _state():
|
||||
bound, resources = _bound()
|
||||
return flatten(bound, resources)
|
||||
|
||||
|
||||
def _desc(key):
|
||||
bound, _ = _bound()
|
||||
return next(b.desc for b in bound if b.desc.key == key)
|
||||
|
||||
|
||||
def test_model_resolves_to_dehumidifier_registry():
|
||||
reg, _ = _dehumidifier()
|
||||
assert reg is not None and reg.name == "dehumidifier"
|
||||
|
||||
|
||||
def test_oic_device_type_resolves_to_dehumidifier_registry():
|
||||
reg = for_device_by_oic_type(("oic.wk.d", "x.com.st.d.dehumidifier"))
|
||||
assert reg is not None and reg.name == "dehumidifier"
|
||||
|
||||
|
||||
def test_no_unbound_hrefs():
|
||||
reg, resources = _dehumidifier()
|
||||
unbound = []
|
||||
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
|
||||
assert unbound == []
|
||||
|
||||
|
||||
def test_display_switch_present_and_reads_on():
|
||||
state = _state()
|
||||
assert state["display"] is True
|
||||
|
||||
|
||||
def test_watertank_light_switch_write_contract():
|
||||
desc = _desc("watertank_light")
|
||||
assert isinstance(desc, SwitchDesc)
|
||||
path, body = desc.write_fn("On", {})
|
||||
assert path == ["watertank", "lighting", "vs", "0"]
|
||||
assert body == {"status": "On"}
|
||||
|
||||
|
||||
def test_watertank_light_color_options_come_from_live_supported_list():
|
||||
desc = _desc("watertank_light_color")
|
||||
assert isinstance(desc, SelectDesc)
|
||||
assert desc.options_field == "colorSupportedList"
|
||||
path, body = desc.write_fn("Green", {})
|
||||
assert path == ["watertank", "lighting", "vs", "0"]
|
||||
assert body == {"colorOption": "Green"}
|
||||
|
||||
|
||||
def test_watertank_light_brightness_options_come_from_live_supported_list():
|
||||
desc = _desc("watertank_light_brightness")
|
||||
assert isinstance(desc, SelectDesc)
|
||||
assert desc.options_field == "modeSupportedList"
|
||||
path, body = desc.write_fn("Low", {})
|
||||
assert path == ["watertank", "lighting", "vs", "0"]
|
||||
assert body == {"mode": "Low"}
|
||||
|
||||
|
||||
def test_watertank_full_alarm_status_exposed_read_only():
|
||||
state = _state()
|
||||
assert state["watertank_full_alarm_status"] == "On"
|
||||
@@ -1226,6 +1226,23 @@ def test_registry_reproduces_golden_state_keys_for_range_ne6516a():
|
||||
)
|
||||
|
||||
|
||||
def test_registry_reproduces_golden_state_keys_for_dehumidifier_tp1x_dhm01001():
|
||||
"""TP1X_DA_AC_DHM_01001_0000 revision (issues #271/#231) additionally
|
||||
reports /display/vs/0 (air_purifier.DISPLAY's exact shape, reused as-is)
|
||||
and /watertank/lighting/vs/0 (new WATERTANK_LIGHTING capability), both
|
||||
unbound on the original issue #88 dump."""
|
||||
from tests.conftest import _load_device
|
||||
|
||||
resources = _load_device("dehumidifier_tp1x_dhm01001")
|
||||
golden = json.loads((GOLDEN / "dehumidifier_tp1x_dhm01001.json").read_text())
|
||||
state_keys = _new_state_keys("dehumidifier_tp1x_dhm01001", resources)
|
||||
assert set(state_keys) == set(golden["state_keys"]), (
|
||||
f"state_keys mismatch:\n"
|
||||
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
|
||||
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
|
||||
)
|
||||
|
||||
|
||||
def test_resources_from_batch_preferred_over_flat():
|
||||
from tests.conftest import _resources_from_dump
|
||||
|
||||
|
||||
Reference in New Issue
Block a user