diff --git a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py index 7849f1a9db8596808db9014baeeaec3a820f909e..ad38f30991b9c282ad61b8bc423979bd42ac4600 100644 --- a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py +++ b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py @@ -23,10 +23,8 @@ from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType -from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ( CONF_AREA_ID, @@ -35,12 +33,11 @@ from .const import ( DEFAULT_NAME, DOMAIN, LOGGER, - MANUFACTURER, - MODEL, STATE_MAP, YALE_ALL_ERRORS, ) from .coordinator import YaleDataUpdateCoordinator +from .entity import YaleAlarmEntity PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( { @@ -81,7 +78,7 @@ async def async_setup_entry( ) -class YaleAlarmDevice(CoordinatorEntity, AlarmControlPanelEntity): +class YaleAlarmDevice(YaleAlarmEntity, AlarmControlPanelEntity): """Represent a Yale Smart Alarm.""" coordinator: YaleDataUpdateCoordinator @@ -94,12 +91,6 @@ class YaleAlarmDevice(CoordinatorEntity, AlarmControlPanelEntity): super().__init__(coordinator) self._attr_name = coordinator.entry.data[CONF_NAME] self._attr_unique_id = coordinator.entry.entry_id - self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, coordinator.entry.data[CONF_USERNAME])}, - manufacturer=MANUFACTURER, - model=MODEL, - name=self._attr_name, - ) async def async_alarm_disarm(self, code=None) -> None: """Send disarm command.""" diff --git a/homeassistant/components/yale_smart_alarm/binary_sensor.py b/homeassistant/components/yale_smart_alarm/binary_sensor.py index b017c4e33e389ba2ca3fd074f085bc965f1feb12..42f8b446abc5cae9d436b789f6b5b8b7111cd566 100644 --- a/homeassistant/components/yale_smart_alarm/binary_sensor.py +++ b/homeassistant/components/yale_smart_alarm/binary_sensor.py @@ -4,14 +4,44 @@ from __future__ import annotations from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, + BinarySensorEntityDescription, ) from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import COORDINATOR, DOMAIN from .coordinator import YaleDataUpdateCoordinator -from .entity import YaleEntity +from .entity import YaleAlarmEntity, YaleEntity + +SENSOR_TYPES = ( + BinarySensorEntityDescription( + key="acfail", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + name="Power Loss", + ), + BinarySensorEntityDescription( + key="battery", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + name="Battery", + ), + BinarySensorEntityDescription( + key="tamper", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + name="Tamper", + ), + BinarySensorEntityDescription( + key="jam", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + name="Jam", + ), +) async def async_setup_entry( @@ -22,14 +52,17 @@ async def async_setup_entry( coordinator: YaleDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ COORDINATOR ] + sensors: list[YaleDoorSensor | YaleProblemSensor] = [] + for data in coordinator.data["door_windows"]: + sensors.append(YaleDoorSensor(coordinator, data)) + for description in SENSOR_TYPES: + sensors.append(YaleProblemSensor(coordinator, description)) - async_add_entities( - YaleBinarySensor(coordinator, data) for data in coordinator.data["door_windows"] - ) + async_add_entities(sensors) -class YaleBinarySensor(YaleEntity, BinarySensorEntity): - """Representation of a Yale binary sensor.""" +class YaleDoorSensor(YaleEntity, BinarySensorEntity): + """Representation of a Yale door sensor.""" _attr_device_class = BinarySensorDeviceClass.DOOR @@ -37,3 +70,30 @@ class YaleBinarySensor(YaleEntity, BinarySensorEntity): def is_on(self) -> bool: """Return true if the binary sensor is on.""" return self.coordinator.data["sensor_map"][self._attr_unique_id] == "open" + + +class YaleProblemSensor(YaleAlarmEntity, BinarySensorEntity): + """Representation of a Yale problem sensor.""" + + entity_description: BinarySensorEntityDescription + + def __init__( + self, + coordinator: YaleDataUpdateCoordinator, + entity_description: BinarySensorEntityDescription, + ) -> None: + """Initiate Yale Problem Sensor.""" + super().__init__(coordinator) + self.entity_description = entity_description + self._attr_name = ( + f"{coordinator.entry.data[CONF_NAME]} {entity_description.name}" + ) + self._attr_unique_id = f"{coordinator.entry.entry_id}-{entity_description.key}" + + @property + def is_on(self) -> bool: + """Return true if the binary sensor is on.""" + return ( + self.coordinator.data["status"][self.entity_description.key] + != "main.normal" + ) diff --git a/homeassistant/components/yale_smart_alarm/coordinator.py b/homeassistant/components/yale_smart_alarm/coordinator.py index 879b68bfde1a807b87d94cf41c8880df841d7d80..1a350d1db9861a06ab6fb6541be86b5b16227f26 100644 --- a/homeassistant/components/yale_smart_alarm/coordinator.py +++ b/homeassistant/components/yale_smart_alarm/coordinator.py @@ -119,6 +119,7 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator): "online": updates["online"], "sensor_map": _sensor_map, "lock_map": _lock_map, + "panel_info": updates["panel_info"], } def get_updates(self) -> dict[str, Any]: @@ -136,9 +137,11 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator): try: arm_status = self.yale.get_armed_status() - cycle = self.yale.get_cycle() - status = self.yale.get_status() - online = self.yale.get_online() + data = self.yale.get_all() + cycle = data["CYCLE"] + status = data["STATUS"] + online = data["ONLINE"] + panel_info = data["PANEL INFO"] except AuthenticationError as error: raise ConfigEntryAuthFailed from error @@ -150,4 +153,5 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator): "cycle": cycle, "status": status, "online": online, + "panel_info": panel_info, } diff --git a/homeassistant/components/yale_smart_alarm/entity.py b/homeassistant/components/yale_smart_alarm/entity.py index 318989a018caf8dbee336dae65cae2e703fb9d74..065d1f4fecbfda46b565618c486e414d0ca5d1ce 100644 --- a/homeassistant/components/yale_smart_alarm/entity.py +++ b/homeassistant/components/yale_smart_alarm/entity.py @@ -1,6 +1,7 @@ """Base class for yale_smart_alarm entity.""" -from homeassistant.const import CONF_USERNAME +from homeassistant.const import CONF_NAME, CONF_USERNAME +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.entity import DeviceInfo, Entity from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -25,3 +26,22 @@ class YaleEntity(CoordinatorEntity, Entity): identifiers={(DOMAIN, data["address"])}, via_device=(DOMAIN, self.coordinator.entry.data[CONF_USERNAME]), ) + + +class YaleAlarmEntity(CoordinatorEntity, Entity): + """Base implementation for Yale Alarm device.""" + + coordinator: YaleDataUpdateCoordinator + + def __init__(self, coordinator: YaleDataUpdateCoordinator) -> None: + """Initialize an Yale device.""" + super().__init__(coordinator) + panel_info = coordinator.data["panel_info"] + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, coordinator.entry.data[CONF_USERNAME])}, + manufacturer=MANUFACTURER, + model=MODEL, + name=coordinator.entry.data[CONF_NAME], + connections={(CONNECTION_NETWORK_MAC, panel_info["mac"])}, + sw_version=panel_info["version"], + )