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:
Marc Billow committed 2026-07-29 02:52:33 +00:00
1 parent 6f21699c37
commit 2b24152276
8 files changed
+820

No files matched your search

@@ -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"
},