From c13e55ca025821767aa6e51e3da0cf789f6646e5 Mon Sep 17 00:00:00 2001 From: Robert Hillis Date: Sun, 5 Jun 2022 15:56:31 -0400 Subject: [PATCH] Move Skybell attributes to their own sensors (#73089) --- .../components/skybell/binary_sensor.py | 12 --- homeassistant/components/skybell/entity.py | 20 ----- homeassistant/components/skybell/sensor.py | 80 ++++++++++++++++++- 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/homeassistant/components/skybell/binary_sensor.py b/homeassistant/components/skybell/binary_sensor.py index 1af85398d47..05f007e9455 100644 --- a/homeassistant/components/skybell/binary_sensor.py +++ b/homeassistant/components/skybell/binary_sensor.py @@ -1,8 +1,6 @@ """Binary sensor support for the Skybell HD Doorbell.""" from __future__ import annotations -from datetime import datetime - from aioskybell.helpers import const as CONST import voluptuous as vol @@ -69,16 +67,6 @@ class SkybellBinarySensor(SkybellEntity, BinarySensorEntity): super().__init__(coordinator, description) self._event: dict[str, str] = {} - @property - def extra_state_attributes( - self, - ) -> dict[str, str | int | datetime | tuple[str, str]]: - """Return the state attributes.""" - attrs = super().extra_state_attributes - if event := self._event.get(CONST.CREATED_AT): - attrs["event_date"] = event - return attrs - @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" diff --git a/homeassistant/components/skybell/entity.py b/homeassistant/components/skybell/entity.py index 6b4683dda6b..0e5c246a8ed 100644 --- a/homeassistant/components/skybell/entity.py +++ b/homeassistant/components/skybell/entity.py @@ -1,8 +1,6 @@ """Entity representing a Skybell HD Doorbell.""" from __future__ import annotations -from datetime import datetime - from aioskybell import SkybellDevice from homeassistant.const import ATTR_CONNECTIONS @@ -45,24 +43,6 @@ class SkybellEntity(CoordinatorEntity[SkybellDataUpdateCoordinator]): """Return the device.""" return self.coordinator.device - @property - def extra_state_attributes( - self, - ) -> dict[str, str | int | datetime | tuple[str, str]]: - """Return the state attributes.""" - attr: dict[str, str | int | datetime | tuple[str, str]] = { - "device_id": self._device.device_id, - "status": self._device.status, - "location": self._device.location, - "motion_threshold": self._device.motion_threshold, - "video_profile": self._device.video_profile, - } - if self._device.owner: - attr["wifi_ssid"] = self._device.wifi_ssid - attr["wifi_status"] = self._device.wifi_status - attr["last_check_in"] = self._device.last_check_in - return attr - async def async_added_to_hass(self) -> None: """When entity is added to hass.""" await super().async_added_to_hass() diff --git a/homeassistant/components/skybell/sensor.py b/homeassistant/components/skybell/sensor.py index c769570b10c..eeb81e07aaf 100644 --- a/homeassistant/components/skybell/sensor.py +++ b/homeassistant/components/skybell/sensor.py @@ -1,10 +1,17 @@ """Sensor support for Skybell Doorbells.""" from __future__ import annotations +from collections.abc import Callable +from dataclasses import dataclass +from typing import Any + +from aioskybell import SkybellDevice +from aioskybell.helpers import const as CONST import voluptuous as vol from homeassistant.components.sensor import ( PLATFORM_SCHEMA, + SensorDeviceClass, SensorEntity, SensorEntityDescription, ) @@ -12,15 +19,79 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ENTITY_NAMESPACE, CONF_MONITORED_CONDITIONS from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from .entity import DOMAIN, SkybellEntity -SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( - SensorEntityDescription( + +@dataclass +class SkybellSensorEntityDescription(SensorEntityDescription): + """Class to describe a Skybell sensor.""" + + value_fn: Callable[[SkybellDevice], Any] = lambda val: val + + +SENSOR_TYPES: tuple[SkybellSensorEntityDescription, ...] = ( + SkybellSensorEntityDescription( key="chime_level", name="Chime Level", icon="mdi:bell-ring", + value_fn=lambda device: device.outdoor_chime_level, + ), + SkybellSensorEntityDescription( + key="last_button_event", + name="Last Button Event", + icon="mdi:clock", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=lambda device: device.latest("button").get(CONST.CREATED_AT), + ), + SkybellSensorEntityDescription( + key="last_motion_event", + name="Last Motion Event", + icon="mdi:clock", + device_class=SensorDeviceClass.TIMESTAMP, + value_fn=lambda device: device.latest("motion").get(CONST.CREATED_AT), + ), + SkybellSensorEntityDescription( + key=CONST.ATTR_LAST_CHECK_IN, + name="Last Check in", + icon="mdi:clock", + entity_registry_enabled_default=False, + device_class=SensorDeviceClass.TIMESTAMP, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda device: device.last_check_in, + ), + SkybellSensorEntityDescription( + key="motion_threshold", + name="Motion Threshold", + icon="mdi:walk", + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda device: device.motion_threshold, + ), + SkybellSensorEntityDescription( + key="video_profile", + name="Video Profile", + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda device: device.video_profile, + ), + SkybellSensorEntityDescription( + key=CONST.ATTR_WIFI_SSID, + name="Wifi SSID", + icon="mdi:wifi-settings", + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda device: device.wifi_ssid, + ), + SkybellSensorEntityDescription( + key=CONST.ATTR_WIFI_STATUS, + name="Wifi Status", + icon="mdi:wifi-strength-3", + entity_registry_enabled_default=False, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda device: device.wifi_status, ), ) @@ -45,13 +116,16 @@ async def async_setup_entry( SkybellSensor(coordinator, description) for coordinator in hass.data[DOMAIN][entry.entry_id] for description in SENSOR_TYPES + if coordinator.device.owner or description.key not in CONST.ATTR_OWNER_STATS ) class SkybellSensor(SkybellEntity, SensorEntity): """A sensor implementation for Skybell devices.""" + entity_description: SkybellSensorEntityDescription + @property def native_value(self) -> int: """Return the state of the sensor.""" - return self._device.outdoor_chime_level + return self.entity_description.value_fn(self._device)