Add problem sensor to yale_smart_alarm (#67699)

This commit is contained in:
G Johansson 2022-03-06 21:16:09 +01:00 committed by GitHub
parent b6c962726a
commit 208e8b16db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 21 deletions

View file

@ -23,10 +23,8 @@ from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import ( from .const import (
CONF_AREA_ID, CONF_AREA_ID,
@ -35,12 +33,11 @@ from .const import (
DEFAULT_NAME, DEFAULT_NAME,
DOMAIN, DOMAIN,
LOGGER, LOGGER,
MANUFACTURER,
MODEL,
STATE_MAP, STATE_MAP,
YALE_ALL_ERRORS, YALE_ALL_ERRORS,
) )
from .coordinator import YaleDataUpdateCoordinator from .coordinator import YaleDataUpdateCoordinator
from .entity import YaleAlarmEntity
PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( 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.""" """Represent a Yale Smart Alarm."""
coordinator: YaleDataUpdateCoordinator coordinator: YaleDataUpdateCoordinator
@ -94,12 +91,6 @@ class YaleAlarmDevice(CoordinatorEntity, AlarmControlPanelEntity):
super().__init__(coordinator) super().__init__(coordinator)
self._attr_name = coordinator.entry.data[CONF_NAME] self._attr_name = coordinator.entry.data[CONF_NAME]
self._attr_unique_id = coordinator.entry.entry_id 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: async def async_alarm_disarm(self, code=None) -> None:
"""Send disarm command.""" """Send disarm command."""

View file

@ -4,14 +4,44 @@ from __future__ import annotations
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass, BinarySensorDeviceClass,
BinarySensorEntity, BinarySensorEntity,
BinarySensorEntityDescription,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import COORDINATOR, DOMAIN from .const import COORDINATOR, DOMAIN
from .coordinator import YaleDataUpdateCoordinator 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( async def async_setup_entry(
@ -22,14 +52,17 @@ async def async_setup_entry(
coordinator: YaleDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ coordinator: YaleDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
COORDINATOR 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( async_add_entities(sensors)
YaleBinarySensor(coordinator, data) for data in coordinator.data["door_windows"]
)
class YaleBinarySensor(YaleEntity, BinarySensorEntity): class YaleDoorSensor(YaleEntity, BinarySensorEntity):
"""Representation of a Yale binary sensor.""" """Representation of a Yale door sensor."""
_attr_device_class = BinarySensorDeviceClass.DOOR _attr_device_class = BinarySensorDeviceClass.DOOR
@ -37,3 +70,30 @@ class YaleBinarySensor(YaleEntity, BinarySensorEntity):
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if the binary sensor is on.""" """Return true if the binary sensor is on."""
return self.coordinator.data["sensor_map"][self._attr_unique_id] == "open" 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"
)

View file

@ -119,6 +119,7 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator):
"online": updates["online"], "online": updates["online"],
"sensor_map": _sensor_map, "sensor_map": _sensor_map,
"lock_map": _lock_map, "lock_map": _lock_map,
"panel_info": updates["panel_info"],
} }
def get_updates(self) -> dict[str, Any]: def get_updates(self) -> dict[str, Any]:
@ -136,9 +137,11 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator):
try: try:
arm_status = self.yale.get_armed_status() arm_status = self.yale.get_armed_status()
cycle = self.yale.get_cycle() data = self.yale.get_all()
status = self.yale.get_status() cycle = data["CYCLE"]
online = self.yale.get_online() status = data["STATUS"]
online = data["ONLINE"]
panel_info = data["PANEL INFO"]
except AuthenticationError as error: except AuthenticationError as error:
raise ConfigEntryAuthFailed from error raise ConfigEntryAuthFailed from error
@ -150,4 +153,5 @@ class YaleDataUpdateCoordinator(DataUpdateCoordinator):
"cycle": cycle, "cycle": cycle,
"status": status, "status": status,
"online": online, "online": online,
"panel_info": panel_info,
} }

View file

@ -1,6 +1,7 @@
"""Base class for yale_smart_alarm entity.""" """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.entity import DeviceInfo, Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -25,3 +26,22 @@ class YaleEntity(CoordinatorEntity, Entity):
identifiers={(DOMAIN, data["address"])}, identifiers={(DOMAIN, data["address"])},
via_device=(DOMAIN, self.coordinator.entry.data[CONF_USERNAME]), 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"],
)