Add battery binary sensor to Yale Smart Alarm (#129277)

* Add battery binary sensor to Yale Smart Alarm

* Fix docstrings
This commit is contained in:
G Johansson 2024-10-27 20:57:10 +01:00 committed by GitHub
parent 4ac23bf14c
commit 7a448f5528
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 182 additions and 5 deletions

View File

@ -49,9 +49,13 @@ async def async_setup_entry(
"""Set up the Yale binary sensor entry."""
coordinator = entry.runtime_data
sensors: list[YaleDoorSensor | YaleProblemSensor] = [
sensors: list[YaleDoorSensor | YaleDoorBatterySensor | YaleProblemSensor] = [
YaleDoorSensor(coordinator, data) for data in coordinator.data["door_windows"]
]
sensors.extend(
YaleDoorBatterySensor(coordinator, data)
for data in coordinator.data["door_windows"]
)
sensors.extend(
YaleProblemSensor(coordinator, description) for description in SENSOR_TYPES
)
@ -70,6 +74,27 @@ class YaleDoorSensor(YaleEntity, BinarySensorEntity):
return bool(self.coordinator.data["sensor_map"][self._attr_unique_id] == "open")
class YaleDoorBatterySensor(YaleEntity, BinarySensorEntity):
"""Representation of a Yale door sensor battery status."""
_attr_device_class = BinarySensorDeviceClass.BATTERY
def __init__(
self,
coordinator: YaleDataUpdateCoordinator,
data: dict,
) -> None:
"""Initiate Yale door battery Sensor."""
super().__init__(coordinator, data)
self._attr_unique_id = f"{data["address"]}-battery"
@property
def is_on(self) -> bool:
"""Return true if the battery is low."""
state: bool = self.coordinator.data["sensor_battery_map"][self._attr_unique_id]
return state
class YaleProblemSensor(YaleAlarmEntity, BinarySensorEntity):
"""Representation of a Yale problem sensor."""

View File

@ -60,6 +60,9 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
for device in updates["cycle"]["device_status"]:
state = device["status1"]
if device["type"] == "device_type.door_contact":
device["_battery"] = False
if "device_status.low_battery" in state:
device["_battery"] = True
if "device_status.dc_close" in state:
device["_state"] = "closed"
door_windows.append(device)
@ -77,6 +80,10 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
_sensor_map = {
contact["address"]: contact["_state"] for contact in door_windows
}
_sensor_battery_map = {
f"{contact["address"]}-battery": contact["_battery"]
for contact in door_windows
}
_temp_map = {temp["address"]: temp["status_temp"] for temp in temp_sensors}
return {
@ -86,6 +93,7 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
"status": updates["status"],
"online": updates["online"],
"sensor_map": _sensor_map,
"sensor_battery_map": _sensor_battery_map,
"temp_map": _temp_map,
"panel_info": updates["panel_info"],
}

View File

@ -175,7 +175,7 @@
"address": "RF4",
"type": "device_type.door_contact",
"name": "Device4",
"status1": "device_status.dc_close",
"status1": "device_status.dc_close,device_status.low_battery",
"status2": null,
"status_switch": null,
"status_power": null,
@ -763,7 +763,7 @@
"address": "RF4",
"type": "device_type.door_contact",
"name": "Device4",
"status1": "device_status.dc_close",
"status1": "device_status.dc_close,device_status.low_battery",
"status2": null,
"status_switch": null,
"status_power": null,

View File

@ -1,4 +1,51 @@
# serializer version: 1
# name: test_binary_sensor[load_platforms0][binary_sensor.device4_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.device4_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Battery',
'platform': 'yale_smart_alarm',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'RF4-battery',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device4_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'Device4 Battery',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.device4_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device4_door-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -46,6 +93,53 @@
'state': 'off',
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device5_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.device5_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Battery',
'platform': 'yale_smart_alarm',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'RF5-battery',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device5_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'Device5 Battery',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.device5_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device5_door-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
@ -93,6 +187,53 @@
'state': 'on',
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device6_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.device6_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Battery',
'platform': 'yale_smart_alarm',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'RF6-battery',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device6_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'Device6 Battery',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.device6_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensor[load_platforms0][binary_sensor.device6_door-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@ -203,6 +203,7 @@
'type_no': '72',
}),
dict({
'_battery': True,
'_state': 'closed',
'address': '**REDACTED**',
'area': '1',
@ -234,7 +235,7 @@
'sresp_button_2': None,
'sresp_button_3': None,
'sresp_button_4': None,
'status1': 'device_status.dc_close',
'status1': 'device_status.dc_close,device_status.low_battery',
'status2': None,
'status_dim_level': None,
'status_fault': list([
@ -264,6 +265,7 @@
'type_no': '4',
}),
dict({
'_battery': False,
'_state': 'open',
'address': '**REDACTED**',
'area': '1',
@ -325,6 +327,7 @@
'type_no': '4',
}),
dict({
'_battery': False,
'_state': 'unavailable',
'address': '**REDACTED**',
'area': '1',
@ -855,7 +858,7 @@
'sresp_button_2': None,
'sresp_button_3': None,
'sresp_button_4': None,
'status1': 'device_status.dc_close',
'status1': 'device_status.dc_close,device_status.low_battery',
'status2': None,
'status_dim_level': None,
'status_fault': list([