feat(registry): cover absence-power-saving and motion-detect-wind on AC (#173)
Lennox-branded heat pump on the Samsung RAC board family (modelNum TP1X_LNX-AC-RAC-01001_0000) already routes correctly via the existing '-RAC-' token, but its dump has two resources no prior AC fixture carried: /mds/absencepowersaving/vs/0 and /option/motiondetectwind/stateful/vs/0. Bind both as read-only sensors, matching the CURRENT_LIMIT/ANOMALY_LOAD precedent -- nothing in the dump confirms write safety on live HVAC hardware.
This commit is contained in:
@@ -27,6 +27,8 @@ REGISTRY = DeviceRegistry(
|
||||
airconditioner.MUTE_ONCE,
|
||||
airconditioner.CURRENT_LIMIT,
|
||||
airconditioner.ANOMALY_LOAD,
|
||||
airconditioner.ABSENCE_POWER_SAVING,
|
||||
airconditioner.MOTION_DETECT_WIND,
|
||||
airconditioner.CURRENT_TEMPERATURE,
|
||||
airconditioner.CURRENT_TEMPERATURE_VS,
|
||||
airconditioner.HUMIDITY,
|
||||
|
||||
@@ -677,6 +677,52 @@ ANOMALY_LOAD = Capability(
|
||||
),
|
||||
)
|
||||
|
||||
# Absence-detection power-saving (issue #173, TP1X_LNX-AC-RAC-01001 --
|
||||
# Lennox-branded heat pump on the RAC board family): `status` toggles the
|
||||
# feature, `switchPowerSaveMode` picks the save intensity out of its own
|
||||
# supportedSwitchPowerSaveMode list. A third field, `motionState`, also
|
||||
# carries a supportedMotionState list but its role (a live sensor readout vs.
|
||||
# a sensitivity setting) isn't distinguishable from the dump, so it's left
|
||||
# unmodeled. Same 'don't guess' read-only treatment as CURRENT_LIMIT/
|
||||
# ANOMALY_LOAD above -- nothing here confirms write safety on live HVAC
|
||||
# hardware.
|
||||
ABSENCE_POWER_SAVING = Capability(
|
||||
href='/mds/absencepowersaving/vs/0',
|
||||
poll_tier='cold',
|
||||
entities=(
|
||||
BinarySensorDesc(key='absence_power_saving_active', field='status',
|
||||
icon='mdi:human-greeting-proximity',
|
||||
entity_category='diagnostic',
|
||||
value_fn=lambda v: v == 'On'),
|
||||
SensorDesc(key='absence_power_saving_mode', field='switchPowerSaveMode',
|
||||
device_class='enum',
|
||||
options=('eco', 'normal', 'comfort'),
|
||||
translation_key='absence_power_saving_mode',
|
||||
icon='mdi:leaf', entity_category='diagnostic',
|
||||
value_fn=lambda v: v.lower() if isinstance(v, str) else v),
|
||||
),
|
||||
)
|
||||
|
||||
# Avoid-direct-wind-on-motion, a sibling AI feature to ABSENCE_POWER_SAVING
|
||||
# above on the same dump: `status` toggles it, `modes` picks Direct/Indirect
|
||||
# airflow out of `supportedModes`. Same read-only treatment.
|
||||
MOTION_DETECT_WIND = Capability(
|
||||
href='/option/motiondetectwind/stateful/vs/0',
|
||||
poll_tier='cold',
|
||||
entities=(
|
||||
BinarySensorDesc(key='motion_detect_wind_active', field='status',
|
||||
icon='mdi:motion-sensor',
|
||||
entity_category='diagnostic',
|
||||
value_fn=lambda v: v == 'On'),
|
||||
SensorDesc(key='motion_detect_wind_mode', field='modes',
|
||||
device_class='enum',
|
||||
options=('direct', 'indirect'),
|
||||
translation_key='motion_detect_wind_mode',
|
||||
icon='mdi:weather-windy', entity_category='diagnostic',
|
||||
value_fn=lambda v: v.lower() if isinstance(v, str) else v),
|
||||
),
|
||||
)
|
||||
|
||||
# The climate entity already surfaces current_temperature as a card
|
||||
# attribute, but that's not enough for history graphs/automations/
|
||||
# statistics -- issue #75 asked for a standalone sensor. Same OCF-standard-
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
"overload_protection_active": {
|
||||
"name": "Overload protection active"
|
||||
},
|
||||
"absence_power_saving_active": {
|
||||
"name": "Absence power saving active"
|
||||
},
|
||||
"motion_detect_wind_active": {
|
||||
"name": "Motion-detect wind avoidance active"
|
||||
},
|
||||
"cycle_active": {
|
||||
"name": "Running"
|
||||
},
|
||||
@@ -669,6 +675,21 @@
|
||||
"powersaving": "Power saving"
|
||||
}
|
||||
},
|
||||
"absence_power_saving_mode": {
|
||||
"name": "Absence power saving mode",
|
||||
"state": {
|
||||
"eco": "Eco",
|
||||
"normal": "Normal",
|
||||
"comfort": "Comfort"
|
||||
}
|
||||
},
|
||||
"motion_detect_wind_mode": {
|
||||
"name": "Motion-detect wind mode",
|
||||
"state": {
|
||||
"direct": "Direct",
|
||||
"indirect": "Indirect"
|
||||
}
|
||||
},
|
||||
"current_temp_c": {
|
||||
"name": "Temperature"
|
||||
},
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
"overload_protection_active": {
|
||||
"name": "Overbelastingsbeveiliging actief"
|
||||
},
|
||||
"absence_power_saving_active": {
|
||||
"name": "Energiebesparing bij afwezigheid actief"
|
||||
},
|
||||
"motion_detect_wind_active": {
|
||||
"name": "Bewegingsdetectie luchtstroomvermijding actief"
|
||||
},
|
||||
"cycle_active": {
|
||||
"name": "Actief"
|
||||
},
|
||||
@@ -669,6 +675,21 @@
|
||||
"powersaving": "Energiebesparing"
|
||||
}
|
||||
},
|
||||
"absence_power_saving_mode": {
|
||||
"name": "Modus energiebesparing bij afwezigheid",
|
||||
"state": {
|
||||
"eco": "Eco",
|
||||
"normal": "Normaal",
|
||||
"comfort": "Comfort"
|
||||
}
|
||||
},
|
||||
"motion_detect_wind_mode": {
|
||||
"name": "Modus luchtstroomvermijding",
|
||||
"state": {
|
||||
"direct": "Direct",
|
||||
"indirect": "Indirect"
|
||||
}
|
||||
},
|
||||
"current_temp_c": {
|
||||
"name": "Temperatuur"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,626 @@
|
||||
{
|
||||
"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": "500",
|
||||
"x.com.samsung.da.filterStatus": "wash",
|
||||
"x.com.samsung.da.filterCapacity": "500",
|
||||
"x.com.samsung.da.filterCapacityUnit": "Hour",
|
||||
"x.com.samsung.da.filterResetType": [
|
||||
"replaceable",
|
||||
"washable"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/temperature/control/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.increment": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mode/convenient/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.modes": "Off",
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"Off",
|
||||
"Sleep",
|
||||
"Quiet",
|
||||
"Smart",
|
||||
"Speed",
|
||||
"MotionIndirect",
|
||||
"MotionDirect",
|
||||
"Nano",
|
||||
"NanoSleep"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/option/autoclean/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.status": "Stop",
|
||||
"x.com.samsung.da.settingStatus": "On",
|
||||
"x.com.samsung.da.progress": "0",
|
||||
"x.com.samsung.da.supportedStatus": [
|
||||
"Start",
|
||||
"Stop"
|
||||
],
|
||||
"x.com.samsung.da.supportedSettingStatus": [
|
||||
"On",
|
||||
"Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/wind/strength/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.modes": "3",
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4"
|
||||
],
|
||||
"x.com.samsung.da.modesName": [
|
||||
"Auto",
|
||||
"Low",
|
||||
"Mid",
|
||||
"High",
|
||||
"Turbo"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/wind/direction/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.modes": "Fix",
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"Fix",
|
||||
"Up_And_Low",
|
||||
"Left_And_Right",
|
||||
"All"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"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-07-28T19:55:08",
|
||||
"x.com.samsung.da.state": "Deleted"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "1",
|
||||
"x.com.samsung.da.description": "Alarm",
|
||||
"x.com.samsung.da.alarmType": "Device",
|
||||
"x.com.samsung.da.code": "FilterAlarm",
|
||||
"x.com.samsung.da.triggeredTime": "2026-07-28T19:55:08",
|
||||
"x.com.samsung.da.state": "Created"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/temperatures/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.items": [
|
||||
{
|
||||
"x.com.samsung.da.id": "0",
|
||||
"x.com.samsung.da.description": "Temperature",
|
||||
"x.com.samsung.da.desired": "70.0",
|
||||
"x.com.samsung.da.current": "69.0",
|
||||
"x.com.samsung.da.maximum": "86",
|
||||
"x.com.samsung.da.minimum": "47",
|
||||
"x.com.samsung.da.increment": "1.0",
|
||||
"x.com.samsung.da.unit": "Fahrenheit"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/temperature/current/0",
|
||||
"rep": {
|
||||
"range": [
|
||||
47,
|
||||
86
|
||||
],
|
||||
"units": "F",
|
||||
"temperature": 69.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/temperature/desired/0",
|
||||
"rep": {
|
||||
"range": [
|
||||
47,
|
||||
86
|
||||
],
|
||||
"units": "F",
|
||||
"temperature": 70.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/energy/consumption/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.instantaneousPower": "0.000000",
|
||||
"x.com.samsung.da.cumulativePower": "631483",
|
||||
"x.com.samsung.da.cumulativeSavedPower": "0",
|
||||
"x.com.samsung.da.cumulativeUnit": "Wh",
|
||||
"x.com.samsung.da.instantaneousPowerUnit": "W"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/energy/consumption/0",
|
||||
"rep": {
|
||||
"power": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mode/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.supportedModes": [
|
||||
"Auto",
|
||||
"Cool",
|
||||
"Dry",
|
||||
"Fan",
|
||||
"Heat"
|
||||
],
|
||||
"x.com.samsung.da.modes": [
|
||||
"Heat"
|
||||
],
|
||||
"x.com.samsung.da.options": [
|
||||
"Sleep_0",
|
||||
"ArtificialWorking_Off",
|
||||
"ComfortAICooling_Off",
|
||||
"AiTempChanged_Off",
|
||||
"AiTemp_990",
|
||||
"OutdoorTemp_78",
|
||||
"CoolCapa_35",
|
||||
"WarmCapa_35",
|
||||
"Volume_Mute",
|
||||
"StopAutoClean_Set",
|
||||
"Autoclean_On",
|
||||
"DiagnosisAI_Off",
|
||||
"ProgressDiagnosisAI_0",
|
||||
"ResultDiagnosisAI_Normal",
|
||||
"KeyInputPermit_On",
|
||||
"ModePermit_NoLimit",
|
||||
"SmartCoolClean_Off",
|
||||
"ProgressSmartClean_0",
|
||||
"FreezeAlarmSetting_Off",
|
||||
"DesiredFreezeAlarm_240",
|
||||
"WashAlarm_Off",
|
||||
"OptionCode_56636",
|
||||
"ExtendOptionCode_246669",
|
||||
"RacInfo_None",
|
||||
"UpdateAllow_NotAllowed",
|
||||
"DurationOn_0",
|
||||
"WelcomeCoolingState_Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/power/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.power": "Off",
|
||||
"operationNumber": "48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/power/0",
|
||||
"rep": {
|
||||
"value": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/sensors/vs/0",
|
||||
"rep": {}
|
||||
},
|
||||
{
|
||||
"href": "/information/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.modelNum": "TP1X_LNX-AC-RAC-01001_0000|10269441|60010523001811014E0048220090A000",
|
||||
"x.com.samsung.da.description": "TP1X_LNX-AC-RAC-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": "0AJV",
|
||||
"x.com.samsung.da.diagSetupid": "AR2",
|
||||
"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": "02646A260327",
|
||||
"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": "102694A24062500",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
},
|
||||
{
|
||||
"x.com.samsung.da.id": "2",
|
||||
"x.com.samsung.da.description": "Version",
|
||||
"x.com.samsung.da.type": "Firmware",
|
||||
"x.com.samsung.da.number": "102472A24042300,102579A10000200",
|
||||
"x.com.samsung.da.newVersionAvailable": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/file/information/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.timeoffset": "-03: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_HEATPUMP_3.0",
|
||||
"AI_3.0",
|
||||
"Auto_To_AI",
|
||||
"AI_Heat"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/humidity/0",
|
||||
"rep": {
|
||||
"humidity": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/humidity/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.humidity": "0",
|
||||
"x.com.samsung.da.fivepercentHumidity": "45"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/drlc/0",
|
||||
"rep": {
|
||||
"DRLevel": 0,
|
||||
"start": "1970-01-01T00:00:00Z",
|
||||
"duration": 0,
|
||||
"override": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/drlc/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.drlcLevel": "0",
|
||||
"x.com.samsung.da.duration": "00:00:00",
|
||||
"x.com.samsung.da.drlcStartTime": "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": "000001D6035C016102490C0F0000",
|
||||
"x.com.samsung.da.id": "RAC",
|
||||
"x.com.samsung.da.version": "1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/keepnormalstate/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.keepnormal": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/remotedatacontrol/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.status": "Off",
|
||||
"x.com.samsung.da.connectionStatus": "Disconnected"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/remotetemperature/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.temperature": "",
|
||||
"x.com.samsung.da.unit": "",
|
||||
"x.com.samsung.da.error": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/remotedeviceinfo/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.didList": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "noHistory",
|
||||
"otnList": [
|
||||
{
|
||||
"type": "WIFI",
|
||||
"modelId": "ARA-WW-TP1-24-ARXX00",
|
||||
"versions": [
|
||||
"11260327"
|
||||
],
|
||||
"visVersion": "260327"
|
||||
},
|
||||
{
|
||||
"type": "Micom",
|
||||
"modelId": "045210269441FFFFFFFF",
|
||||
"versions": [
|
||||
"24062500",
|
||||
"FFFFFFFF"
|
||||
],
|
||||
"visVersion": "240625"
|
||||
},
|
||||
{
|
||||
"type": "Micom",
|
||||
"modelId": "04521024724110257941",
|
||||
"versions": [
|
||||
"24042300",
|
||||
"10000200"
|
||||
],
|
||||
"visVersion": "240423"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": "/timezone/vs/0",
|
||||
"rep": {
|
||||
"timezoneid": "America/Halifax",
|
||||
"offset": "-03:00",
|
||||
"DST": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/option/muteonce/vs/0",
|
||||
"rep": {
|
||||
"muteonce": "Off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/aisleep/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.displayNightMode": "Off",
|
||||
"x.com.samsung.da.elapsedTime": "0",
|
||||
"x.com.samsung.da.requestFeedback": "Off",
|
||||
"x.com.samsung.da.resultFeedback": "0",
|
||||
"x.com.samsung.da.statusFeedback": "Idle",
|
||||
"x.com.samsung.da.sleepTime": "14002200"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/reserverulesets/vs/0",
|
||||
"rep": {
|
||||
"x.com.samsung.da.sets": "AEFFFFFFFF3D564156FFFF2F56FFFF00001F001F00010000001F0000009C00FFFF1E00",
|
||||
"x.com.samsung.da.id": "RAC",
|
||||
"x.com.samsung.da.version": "1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/light/vs/0",
|
||||
"rep": {
|
||||
"mode": "On",
|
||||
"supportedModes": [
|
||||
"On",
|
||||
"Off"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mds/absencepowersaving/vs/0",
|
||||
"rep": {
|
||||
"status": "Off",
|
||||
"modes": "Cooling_Heating",
|
||||
"switchPowerSaveMode": "Normal",
|
||||
"motionState": "Normal",
|
||||
"supportedModes": [
|
||||
"Cooling_Heating",
|
||||
"Standby"
|
||||
],
|
||||
"supportedSwitchPowerSaveMode": [
|
||||
"Eco",
|
||||
"Normal",
|
||||
"Comfort"
|
||||
],
|
||||
"supportedMotionState": [
|
||||
"Normal",
|
||||
"MotionNano",
|
||||
"MotionSoftOff"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/mds/absencestate/vs/0",
|
||||
"rep": {
|
||||
"status": "Off",
|
||||
"maxDetectCount": [
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254",
|
||||
"254"
|
||||
],
|
||||
"supportedTime": [
|
||||
"0",
|
||||
"30",
|
||||
"60"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/option/motiondetectwind/stateful/vs/0",
|
||||
"rep": {
|
||||
"status": "Off",
|
||||
"modes": "Indirect",
|
||||
"supportedModes": [
|
||||
"Direct",
|
||||
"Indirect"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/welcome/temperature/vs/0",
|
||||
"rep": {
|
||||
"operatingStatus": "None",
|
||||
"requestId": "0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/wirelessinfo/vs/0",
|
||||
"rep": {
|
||||
"macaddressWiFi": "**REDACTED**",
|
||||
"macaddressBLE": "**REDACTED**",
|
||||
"connectedApSsid": "KG_IoT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"href": "/quickcontrol/info/vs/0",
|
||||
"rep": {
|
||||
"supportedVersion": "1.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"state_keys": [
|
||||
"absence_power_saving_active",
|
||||
"absence_power_saving_mode",
|
||||
"air_filter_status",
|
||||
"air_filter_usage",
|
||||
"air_filter_usage_hours",
|
||||
"alarm_code",
|
||||
"auto_clean",
|
||||
"beep",
|
||||
"climate",
|
||||
"current_temperature_c",
|
||||
"display_light",
|
||||
"energy_kwh",
|
||||
"energy_saved_kwh",
|
||||
"firmware_update",
|
||||
"humidity",
|
||||
"motion_detect_wind_active",
|
||||
"motion_detect_wind_mode",
|
||||
"mute_once",
|
||||
"power_watts",
|
||||
"tropical_night_mode"
|
||||
]
|
||||
}
|
||||
@@ -467,6 +467,65 @@ def test_fac_bora_subdevices_and_runningmode_are_ignored_not_guessed():
|
||||
assert '/runn/vs/0' in airconditioner._AC_IGNORED
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TP1X_LNX-AC-RAC-01001_0000 -- Lennox-branded heat pump on the Samsung RAC
|
||||
# board family (issue #173). Routes via the existing '-RAC-' modelNum token,
|
||||
# same registry as the plain RAC family. Adds two AI-feature resources not
|
||||
# seen on prior AC dumps: /mds/absencepowersaving/vs/0 (absence-detection
|
||||
# power saving) and /option/motiondetectwind/stateful/vs/0 (avoid-direct-
|
||||
# wind-on-motion) -- both exposed read-only, same 'don't guess' precedent as
|
||||
# CURRENT_LIMIT/ANOMALY_LOAD.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _ac_lnx_rac_heatpump():
|
||||
resources = _load_device('airconditioner_lnx_rac_heatpump')
|
||||
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 test_lnx_rac_heatpump_resolves_to_airconditioner_registry():
|
||||
reg, _ = _ac_lnx_rac_heatpump()
|
||||
assert reg is not None and reg.name == 'airconditioner'
|
||||
|
||||
|
||||
def test_lnx_rac_heatpump_no_unbound_hrefs():
|
||||
reg, resources = _ac_lnx_rac_heatpump()
|
||||
unbound = []
|
||||
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
|
||||
assert unbound == []
|
||||
|
||||
|
||||
def test_lnx_rac_heatpump_absence_power_saving_state():
|
||||
reg, resources = _ac_lnx_rac_heatpump()
|
||||
bound = discover(resources, reg.capabilities, reg.pattern_capabilities)
|
||||
state = flatten(bound, resources)
|
||||
assert state['absence_power_saving_active'] is False
|
||||
assert state['absence_power_saving_mode'] == 'normal'
|
||||
|
||||
|
||||
def test_lnx_rac_heatpump_motion_detect_wind_state():
|
||||
reg, resources = _ac_lnx_rac_heatpump()
|
||||
bound = discover(resources, reg.capabilities, reg.pattern_capabilities)
|
||||
state = flatten(bound, resources)
|
||||
assert state['motion_detect_wind_active'] is False
|
||||
assert state['motion_detect_wind_mode'] == 'indirect'
|
||||
|
||||
|
||||
def test_lnx_rac_heatpump_new_capabilities_are_read_only():
|
||||
"""Nothing in the dump confirms write safety on live HVAC hardware for
|
||||
either feature -- exposed as sensors, not switches/selects."""
|
||||
absence_keys = {e.key for e in airconditioner.ABSENCE_POWER_SAVING.entities}
|
||||
motion_keys = {e.key for e in airconditioner.MOTION_DETECT_WIND.entities}
|
||||
assert absence_keys == {'absence_power_saving_active', 'absence_power_saving_mode'}
|
||||
assert motion_keys == {'motion_detect_wind_active', 'motion_detect_wind_mode'}
|
||||
for entity in (*airconditioner.ABSENCE_POWER_SAVING.entities,
|
||||
*airconditioner.MOTION_DETECT_WIND.entities):
|
||||
assert not hasattr(entity, 'write_fn') or entity.write_fn is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Additive entities layered on the ARTIK051_PRAC family on top of the upstream
|
||||
# registry: beep (Volume_* option), tropical night mode (Sleep_<N> option),
|
||||
|
||||
@@ -439,6 +439,27 @@ def test_registry_reproduces_golden_state_keys_for_airconditioner_windfree():
|
||||
)
|
||||
|
||||
|
||||
def test_registry_reproduces_golden_state_keys_for_airconditioner_lnx_rac_heatpump():
|
||||
"""Lennox-branded heat pump on the Samsung RAC board family (issue #173,
|
||||
modelNum TP1X_LNX-AC-RAC-01001_0000) -- routes via the existing '-RAC-'
|
||||
token, same registry as the plain RAC family. Adds two AI-feature
|
||||
resources not seen on prior AC dumps: /mds/absencepowersaving/vs/0
|
||||
(absence-detection power saving) and /option/motiondetectwind/stateful/vs/0
|
||||
(avoid-direct-wind-on-motion), both exposed read-only per the 'don't
|
||||
guess' rule."""
|
||||
from tests.conftest import _load_device
|
||||
resources = _load_device('airconditioner_lnx_rac_heatpump')
|
||||
golden = json.loads(
|
||||
(GOLDEN / 'airconditioner_lnx_rac_heatpump.json').read_text()
|
||||
)
|
||||
state_keys = _new_state_keys('airconditioner_lnx_rac_heatpump', 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():
|
||||
"""Range/cooktop-oven combo (model TP1X_DA-KS-RANGE-0102X, issue #44) --
|
||||
reports no oneUiVersion; resolved via the '-RANGE-' modelNum token
|
||||
|
||||
Reference in New Issue
Block a user