Add internal air-filter support for TP1X_REF_21K refrigerators (issue #318)
/filter/airdustfilter/vs/0 was the dump's only unbound href -- this board's internal deodorizing filter, same filterUsage/filterStatus field pair as common.WATER_FILTER, but filterUsage here is already a 0-100 percentage with no filterCapacity to divide by (confirmed by filterStatus=="wash" at filterUsage=="100"). Uses air_-prefixed keys so a fridge with both a water and an air filter gets two distinct entities.
This commit is contained in:
@@ -13,6 +13,7 @@ REGISTRY = DeviceRegistry(
|
|||||||
fridge.STATUS_LOCK,
|
fridge.STATUS_LOCK,
|
||||||
fridge.DOOR_ALERT,
|
fridge.DOOR_ALERT,
|
||||||
common.WATER_FILTER,
|
common.WATER_FILTER,
|
||||||
|
fridge.AIR_FILTER,
|
||||||
dishwasher.DIAGNOSIS,
|
dishwasher.DIAGNOSIS,
|
||||||
fridge.ICEMAKER_NIGHTTIME,
|
fridge.ICEMAKER_NIGHTTIME,
|
||||||
fridge.FLEX_ZONE,
|
fridge.FLEX_ZONE,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from ..entities import (
|
|||||||
SwitchDesc,
|
SwitchDesc,
|
||||||
TimeDesc,
|
TimeDesc,
|
||||||
)
|
)
|
||||||
from .common import normalize_temp_unit
|
from .common import int_or_none, normalize_temp_unit
|
||||||
|
|
||||||
# Display names for the beverage zone, flex zone, ice type, and
|
# Display names for the beverage zone, flex zone, ice type, and
|
||||||
# ice-making-status enums below live in translations/en.json, keyed by the
|
# ice-making-status enums below live in translations/en.json, keyed by the
|
||||||
@@ -266,6 +266,39 @@ DOOR_ALERT = Capability(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Internal deodorizing filter (issue #318, TP1X_REF_21K). Same
|
||||||
|
# filterUsage/filterStatus field pair as common.WATER_FILTER, but
|
||||||
|
# filterUsage here is already a 0-100 percentage with no filterCapacity to
|
||||||
|
# divide by (confirmed by filterStatus=="wash" at filterUsage=="100") --
|
||||||
|
# 'air_'-prefixed keys so a fridge with both a water and an air filter gets
|
||||||
|
# two distinct entities rather than a unique_id collision.
|
||||||
|
AIR_FILTER = Capability(
|
||||||
|
href="/filter/airdustfilter/vs/0",
|
||||||
|
poll_tier="cold",
|
||||||
|
entities=(
|
||||||
|
SensorDesc(
|
||||||
|
key="air_filter_usage",
|
||||||
|
field="x.com.samsung.da.filterUsage",
|
||||||
|
unit="%",
|
||||||
|
state_class="measurement",
|
||||||
|
icon="mdi:air-filter",
|
||||||
|
entity_category="diagnostic",
|
||||||
|
value_fn=int_or_none,
|
||||||
|
),
|
||||||
|
SensorDesc(
|
||||||
|
key="air_filter_status",
|
||||||
|
field="x.com.samsung.da.filterStatus",
|
||||||
|
device_class="enum",
|
||||||
|
options=("normal", "wash", "replace"),
|
||||||
|
translation_key="filter_status",
|
||||||
|
icon="mdi:air-filter",
|
||||||
|
entity_category="diagnostic",
|
||||||
|
value_fn=lambda v: v.lower() if isinstance(v, str) else v,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _status_lock_write(field):
|
def _status_lock_write(field):
|
||||||
return lambda p, rep, href=None: (
|
return lambda p, rep, href=None: (
|
||||||
["status", "lock", "vs", "0"],
|
["status", "lock", "vs", "0"],
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"state_keys": [
|
||||||
|
"ai_energy_level",
|
||||||
|
"air_filter_status",
|
||||||
|
"air_filter_usage",
|
||||||
|
"alarm_code",
|
||||||
|
"auto_door_opener",
|
||||||
|
"brightness_level",
|
||||||
|
"cabinet_light_dim",
|
||||||
|
"cabinet_light_switch",
|
||||||
|
"cooler_setpoint",
|
||||||
|
"cooler_temperature",
|
||||||
|
"day_brightness",
|
||||||
|
"door_alert",
|
||||||
|
"door_cooler_open",
|
||||||
|
"door_freezer_open",
|
||||||
|
"energy_kwh",
|
||||||
|
"energy_saved_kwh",
|
||||||
|
"firmware_update",
|
||||||
|
"freezer_setpoint",
|
||||||
|
"freezer_temperature",
|
||||||
|
"fridge_sound",
|
||||||
|
"ice_night_mode",
|
||||||
|
"icemaker_one_enabled",
|
||||||
|
"icemaker_one_making_status",
|
||||||
|
"night_end",
|
||||||
|
"night_start",
|
||||||
|
"power_energy_kwh",
|
||||||
|
"power_watts",
|
||||||
|
"rapid_freezing",
|
||||||
|
"rapid_fridge",
|
||||||
|
"selfcheck_error",
|
||||||
|
"selfcheck_result",
|
||||||
|
"selfcheck_status"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,623 @@
|
|||||||
|
{
|
||||||
|
"device0": [
|
||||||
|
{
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.devcol",
|
||||||
|
"oic.wk.col"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.ll",
|
||||||
|
"oic.if.b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/alarms/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"href": "/alarms/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.alarms"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/bespoke/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.BespokeProduct": "On",
|
||||||
|
"href": "/bespoke/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/cabinet/light/enhanced/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"light.control.status": "On",
|
||||||
|
"level.brightness.daytime": "100",
|
||||||
|
"level.brightness.nighttime": "33",
|
||||||
|
"night.starttime": "2026-08-07T12:00:00",
|
||||||
|
"night.duration.minute": "540",
|
||||||
|
"timezone.offset": "+09:00",
|
||||||
|
"href": "/cabinet/light/enhanced/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.light.enhanced"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/cabinet/light/total/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.lightLevel": "100",
|
||||||
|
"x.com.samsung.da.lightResolution": "3",
|
||||||
|
"x.com.samsung.da.lightControl.off.include": "Off",
|
||||||
|
"x.com.samsung.da.lightControl": "Off",
|
||||||
|
"x.com.samsung.da.lightControl.hide": "true",
|
||||||
|
"light.dimming.status": "On",
|
||||||
|
"href": "/cabinet/light/total/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.cabinetlight"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/configuration/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.region": "",
|
||||||
|
"x.com.samsung.da.countryCode": "",
|
||||||
|
"href": "/configuration/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "/defrost/prediction/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"ai.cooling.care": "Off",
|
||||||
|
"href": "/defrost/prediction/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/dginformation/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"enrolmentstatus": "Unknown",
|
||||||
|
"devicestate": "Unknown",
|
||||||
|
"lockstatus": "Normal",
|
||||||
|
"nextduedate": "",
|
||||||
|
"workingminutes": 0,
|
||||||
|
"paymentinfo": {
|
||||||
|
"emiplan": "Unknown",
|
||||||
|
"currency": "Unknown",
|
||||||
|
"totalemi": 0,
|
||||||
|
"totalemipaid": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/door/cooler/0",
|
||||||
|
"rep": {
|
||||||
|
"openState": "Close",
|
||||||
|
"href": "/door/cooler/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.door"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.s"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/door/freezer/0",
|
||||||
|
"rep": {
|
||||||
|
"openState": "Close",
|
||||||
|
"href": "/door/freezer/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.door"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.s"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/doors/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.items": [
|
||||||
|
{
|
||||||
|
"x.com.samsung.da.openState": "Close",
|
||||||
|
"x.com.samsung.da.id": "0",
|
||||||
|
"x.com.samsung.da.description": "Door"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x.com.samsung.da.openState": "Close",
|
||||||
|
"x.com.samsung.da.id": "1",
|
||||||
|
"x.com.samsung.da.description": "Door"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"href": "/doors/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/drlc/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.drlcLevel": "2",
|
||||||
|
"x.com.samsung.da.override": "Not_Supported",
|
||||||
|
"x.com.samsung.da.durationminutes": "1441",
|
||||||
|
"x.com.samsung.da.start": "2026-08-07T00:00:41Z",
|
||||||
|
"x.com.samsung.da.realSaving": "On",
|
||||||
|
"href": "/drlc/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/energy/ailevel/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"aiLevel": "1",
|
||||||
|
"supportedAiLevel": [
|
||||||
|
"1",
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"href": "/energy/ailevel/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/energy/consumption/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.cumulativeConsumption": "25344",
|
||||||
|
"x.com.samsung.da.instantaneousPower": "48",
|
||||||
|
"x.com.samsung.da.cumulativePower": "413385",
|
||||||
|
"x.com.samsung.da.cumulativeSavedPower": "50694",
|
||||||
|
"x.com.samsung.da.cumulativeUnit": "Wh",
|
||||||
|
"x.com.samsung.da.instantaneousPowerUnit": "W",
|
||||||
|
"href": "/energy/consumption/vs/0",
|
||||||
|
"x.com.samsung.da.cumulativeDateUTC": "1786020360"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/file/information/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.timeoffset": "+09:00",
|
||||||
|
"x.com.samsung.supprtedtype": 1,
|
||||||
|
"href": "/file/information/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/filter/airdustfilter/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.filterUsage": "100",
|
||||||
|
"x.com.samsung.da.filterUsageResolution": "1",
|
||||||
|
"x.com.samsung.da.filterResetType": [
|
||||||
|
"washable"
|
||||||
|
],
|
||||||
|
"x.com.samsung.da.filterStatus": "wash",
|
||||||
|
"href": "/filter/airdustfilter/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/icemaker/nighttime/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"ice.night.status": "On",
|
||||||
|
"ice.night.starttime": "2026-08-07T12:00:00",
|
||||||
|
"ice.night.duration": "540",
|
||||||
|
"ice.night.timezone": "+09:00",
|
||||||
|
"href": "/icemaker/nighttime/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.ice.night"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/icemaker/one/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.iceMaker.name": "ICE_MAKER",
|
||||||
|
"x.com.samsung.da.iceMaker.state": "On",
|
||||||
|
"x.com.samsung.da.iceType.desired": "NORMAL",
|
||||||
|
"x.com.samsung.da.iceMaker.iceMakingStatus": "ICESTATUS_STOP",
|
||||||
|
"x.com.samsung.da.iceMaker.type": "toggle",
|
||||||
|
"href": "/icemaker/one/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.icemaker"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/icemaker/status/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.iceMaker": "On",
|
||||||
|
"href": "/icemaker/status/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/information/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.modelNum": "TP1X_REF_21K|70664141|0000033C011913114100000041FB5F00",
|
||||||
|
"x.com.samsung.da.description": "TP1X_REF_21K",
|
||||||
|
"x.com.samsung.da.serialNum": "**REDACTED**",
|
||||||
|
"x.com.samsung.da.otnDUID": "**REDACTED**",
|
||||||
|
"x.com.samsung.da.diagDumpType": "file",
|
||||||
|
"x.com.samsung.da.diagEndPoint": "SSM",
|
||||||
|
"x.com.samsung.da.diagLogType": [
|
||||||
|
"errCode",
|
||||||
|
"dump"
|
||||||
|
],
|
||||||
|
"x.com.samsung.da.diagMnid": "0AJT",
|
||||||
|
"x.com.samsung.da.diagSetupid": "RR7",
|
||||||
|
"x.com.samsung.da.diagProtocolType": "BLE_OCF",
|
||||||
|
"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": "WiFi Module",
|
||||||
|
"x.com.samsung.da.type": "Software",
|
||||||
|
"x.com.samsung.da.number": "260618",
|
||||||
|
"x.com.samsung.da.newVersionAvailable": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x.com.samsung.da.id": "1",
|
||||||
|
"x.com.samsung.da.description": "Micom",
|
||||||
|
"x.com.samsung.da.type": "Firmware",
|
||||||
|
"x.com.samsung.da.number": "2605071D, 24120906, 26040701, FFFFFFFF, 25082208, FFFFFFFF",
|
||||||
|
"x.com.samsung.da.newVersionAvailable": "0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"href": "/information/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/mode/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.supportedModes": [
|
||||||
|
"HOMECARE_WIZARD_V2",
|
||||||
|
"ENERGY_REPORT_MODEL",
|
||||||
|
"18K_REF_OUTDOOR_CONTROL_V2"
|
||||||
|
],
|
||||||
|
"href": "/mode/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.mode"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/otninformation/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.target": "Micom",
|
||||||
|
"x.com.samsung.da.newVersionAvailable": "false",
|
||||||
|
"x.com.samsung.da.newVersionNo": "26040701",
|
||||||
|
"x.com.samsung.da.currentVersionInfo": "10000000",
|
||||||
|
"otnStatus": "None",
|
||||||
|
"flashingProgress": "0",
|
||||||
|
"otnTarget": "inverter",
|
||||||
|
"otnCompleteDate": "noHistory",
|
||||||
|
"scheduledTime": "None",
|
||||||
|
"swVersionInfo": {
|
||||||
|
"platform": "Tizen Lite",
|
||||||
|
"oneUiVersion": "7.0 Refrigerator",
|
||||||
|
"osVersion": "4.0"
|
||||||
|
},
|
||||||
|
"otnList": [
|
||||||
|
{
|
||||||
|
"type": "WIFI",
|
||||||
|
"modelId": "A-RFWW-TP1-24-T4-RE1",
|
||||||
|
"versions": [
|
||||||
|
"20260618"
|
||||||
|
],
|
||||||
|
"visVersion": "260618"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Micom",
|
||||||
|
"modelId": "823070664141FFFFFFFF",
|
||||||
|
"versions": [
|
||||||
|
"2605071D",
|
||||||
|
"FFFFFFFF"
|
||||||
|
],
|
||||||
|
"visVersion": "260507"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Micom",
|
||||||
|
"modelId": "823070664041FFFFFFFF",
|
||||||
|
"versions": [
|
||||||
|
"24120906",
|
||||||
|
"FFFFFFFF"
|
||||||
|
],
|
||||||
|
"visVersion": "241209"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Micom",
|
||||||
|
"modelId": "02307066414170664041",
|
||||||
|
"versions": [
|
||||||
|
"2605071D",
|
||||||
|
"24120906"
|
||||||
|
],
|
||||||
|
"visVersion": "260507"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Micom",
|
||||||
|
"modelId": "023070680641FFFFFFFF",
|
||||||
|
"versions": [
|
||||||
|
"26040701",
|
||||||
|
"FFFFFFFF"
|
||||||
|
],
|
||||||
|
"visVersion": "260407"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Micom",
|
||||||
|
"modelId": "023070668841FFFFFFFF",
|
||||||
|
"versions": [
|
||||||
|
"25082208",
|
||||||
|
"FFFFFFFF"
|
||||||
|
],
|
||||||
|
"visVersion": "250822"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/quickcontrol/info/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"supportedVersion": "1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/realtimenotiforclient/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.timeforshortnoti": "0",
|
||||||
|
"x.com.samsung.da.periodicnotisubscription": "true",
|
||||||
|
"href": "/realtimenotiforclient/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/refrigeration/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.rapidFridge": "Off",
|
||||||
|
"x.com.samsung.da.rapidFreezing": "Off",
|
||||||
|
"href": "/refrigeration/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.fridge"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/rm/control/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"minPeriod": "9000",
|
||||||
|
"href": "/rm/control/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/runningmode/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.runningMode": 0,
|
||||||
|
"href": "/runningmode/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/selfcheck/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.supportedActions": [
|
||||||
|
"Start"
|
||||||
|
],
|
||||||
|
"x.com.samsung.da.status": "Ready",
|
||||||
|
"x.com.samsung.da.result": "Success",
|
||||||
|
"x.com.samsung.da.error": [
|
||||||
|
"ErrorCode_None"
|
||||||
|
],
|
||||||
|
"href": "/selfcheck/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/settings/sound/alert/door/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"alert.door": "1",
|
||||||
|
"supportedAlert.door": [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4"
|
||||||
|
],
|
||||||
|
"href": "/settings/sound/alert/door/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.alert.door"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/status/lock/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"x.com.samsung.da.device.sound": "On",
|
||||||
|
"x.com.samsung.da.preciseCooling": "On",
|
||||||
|
"x.com.samsung.da.doorAlarmSound": "On",
|
||||||
|
"cleaning.status": "On",
|
||||||
|
"cleaning.type": "SPI_AND_UV",
|
||||||
|
"href": "/status/lock/vs/0",
|
||||||
|
"rt": [
|
||||||
|
"x.com.samsung.da.lockstatus"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/temperature/current/cooler/0",
|
||||||
|
"rep": {
|
||||||
|
"temperature": 2.0,
|
||||||
|
"range": [
|
||||||
|
1.0,
|
||||||
|
7.0
|
||||||
|
],
|
||||||
|
"units": "C",
|
||||||
|
"href": "/temperature/current/cooler/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.temperature"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/temperature/current/freezer/0",
|
||||||
|
"rep": {
|
||||||
|
"temperature": -19.0,
|
||||||
|
"range": [
|
||||||
|
-23.0,
|
||||||
|
-15.0
|
||||||
|
],
|
||||||
|
"units": "C",
|
||||||
|
"href": "/temperature/current/freezer/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.temperature"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/temperature/desired/cooler/0",
|
||||||
|
"rep": {
|
||||||
|
"temperature": 2.0,
|
||||||
|
"range": [
|
||||||
|
1.0,
|
||||||
|
7.0
|
||||||
|
],
|
||||||
|
"units": "C",
|
||||||
|
"href": "/temperature/desired/cooler/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.temperature"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/temperature/desired/freezer/0",
|
||||||
|
"rep": {
|
||||||
|
"temperature": -19.0,
|
||||||
|
"range": [
|
||||||
|
-23.0,
|
||||||
|
-15.0
|
||||||
|
],
|
||||||
|
"units": "C",
|
||||||
|
"href": "/temperature/desired/freezer/0",
|
||||||
|
"rt": [
|
||||||
|
"oic.r.temperature"
|
||||||
|
],
|
||||||
|
"if": [
|
||||||
|
"oic.if.baseline",
|
||||||
|
"oic.if.a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/temperatures/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"temperature.unit.control": "true",
|
||||||
|
"x.com.samsung.da.items": [
|
||||||
|
{
|
||||||
|
"x.com.samsung.da.id": "0",
|
||||||
|
"x.com.samsung.da.description": "Freezer",
|
||||||
|
"x.com.samsung.da.desired": "-19",
|
||||||
|
"x.com.samsung.da.current": "-19",
|
||||||
|
"x.com.samsung.da.maximum": "-15",
|
||||||
|
"x.com.samsung.da.minimum": "-23",
|
||||||
|
"x.com.samsung.da.unit": "Celsius"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x.com.samsung.da.id": "1",
|
||||||
|
"x.com.samsung.da.description": "Fridge",
|
||||||
|
"x.com.samsung.da.desired": "2",
|
||||||
|
"x.com.samsung.da.current": "2",
|
||||||
|
"x.com.samsung.da.maximum": "7",
|
||||||
|
"x.com.samsung.da.minimum": "1",
|
||||||
|
"x.com.samsung.da.unit": "Celsius"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"href": "/temperatures/vs/0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/timezone/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"timezoneid": "Asia/Seoul",
|
||||||
|
"offset": "+09:00",
|
||||||
|
"DST": "OFF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/wirelessinfo/vs/0",
|
||||||
|
"rep": {
|
||||||
|
"macaddressWiFi": "**REDACTED**",
|
||||||
|
"macaddressBLE": "**REDACTED**",
|
||||||
|
"connectedApSsid": "eomkim_IoT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -277,6 +277,24 @@ def test_registry_reproduces_golden_state_keys_for_tp1x_ref_21k_eu():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_registry_reproduces_golden_state_keys_for_tp1x_ref_21k_airfilter():
|
||||||
|
"""TP1X_REF_21K, air-filter-equipped variant (issue #318) -- reports
|
||||||
|
/filter/airdustfilter/vs/0 (internal deodorizing filter), the one
|
||||||
|
unbound href on this dump. Unlike airconditioner.AIR_FILTER's
|
||||||
|
filterUsage/filterCapacity pair, this board's filterUsage is already a
|
||||||
|
0-100 percentage with no filterCapacity to divide by."""
|
||||||
|
from tests.conftest import _load_device
|
||||||
|
|
||||||
|
resources = _load_device("refrigerator_tp1x_ref_21k_airfilter")
|
||||||
|
golden = json.loads((GOLDEN / "refrigerator_tp1x_ref_21k_airfilter.json").read_text())
|
||||||
|
state_keys = _new_state_keys("refrigerator_tp1x_ref_21k_airfilter", 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_registry_reproduces_golden_state_keys_for_range_hood():
|
def test_registry_reproduces_golden_state_keys_for_range_hood():
|
||||||
from tests.conftest import _load_device
|
from tests.conftest import _load_device
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
"""Tests for the TP1X_REF_21K air-filter-equipped variant (issue #318).
|
||||||
|
|
||||||
|
The dump's only unbound href was /filter/airdustfilter/vs/0, this board's
|
||||||
|
internal deodorizing filter -- same filterUsage/filterStatus field pair as
|
||||||
|
common.WATER_FILTER, but filterUsage here is already a 0-100 percentage
|
||||||
|
(no filterCapacity to divide by, unlike airconditioner.AIR_FILTER).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from custom_components.localthings.registry.adapter import flatten
|
||||||
|
from custom_components.localthings.registry.by_type import resolve
|
||||||
|
from custom_components.localthings.registry.discovery import discover
|
||||||
|
from tests.conftest import _load_device
|
||||||
|
|
||||||
|
|
||||||
|
def _bound():
|
||||||
|
resources = _load_device("refrigerator_tp1x_ref_21k_airfilter")
|
||||||
|
reg = resolve(resources)
|
||||||
|
return discover(resources, reg.capabilities, reg.pattern_capabilities), resources
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_unbound_hrefs():
|
||||||
|
_, resources = _bound()
|
||||||
|
unbound = []
|
||||||
|
reg = resolve(resources)
|
||||||
|
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
|
||||||
|
assert unbound == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_air_filter_usage_and_status():
|
||||||
|
bound, resources = _bound()
|
||||||
|
state = flatten(bound, resources)
|
||||||
|
assert state["air_filter_usage"] == 100
|
||||||
|
assert state["air_filter_status"] == "wash"
|
||||||
Reference in New Issue
Block a user