645 lines
26 KiB
Python
645 lines
26 KiB
Python
"""Spook - Your homie."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
from homeassistant.components import (
|
|
automation,
|
|
input_boolean,
|
|
input_button,
|
|
input_datetime,
|
|
input_number,
|
|
input_select,
|
|
input_text,
|
|
persistent_notification,
|
|
person,
|
|
script,
|
|
sun,
|
|
zone,
|
|
)
|
|
from homeassistant.components.sensor import (
|
|
SensorEntity,
|
|
SensorEntityDescription,
|
|
SensorStateClass,
|
|
)
|
|
from homeassistant.const import (
|
|
EVENT_COMPONENT_LOADED,
|
|
EVENT_HOMEASSISTANT_STARTED,
|
|
EntityCategory,
|
|
Platform,
|
|
)
|
|
from homeassistant.core import Event, HomeAssistant, callback
|
|
from homeassistant.helpers import (
|
|
area_registry as ar,
|
|
device_registry as dr,
|
|
entity_registry as er,
|
|
)
|
|
from homeassistant.helpers.event import async_call_later
|
|
|
|
from ...entity import SpookEntityDescription
|
|
from ...listeners import async_listen_once_tracked
|
|
from .entity import HomeAssistantSpookEntity
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Callable
|
|
from datetime import datetime # Moved datetime here
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.util.event_type import EventType
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class HomeAssistantSpookSensorEntityDescription(
|
|
SpookEntityDescription,
|
|
SensorEntityDescription,
|
|
):
|
|
"""Class describing Spook Home Assistant sensor entities."""
|
|
|
|
value_fn: Callable[[HomeAssistant], int | None]
|
|
update_events: set[EventType[Any] | str] = field(default_factory=set)
|
|
|
|
|
|
@callback
|
|
def _count_active_domain_entities(hass: HomeAssistant, domain: str) -> int:
|
|
"""Count domain entities that are not restored placeholders."""
|
|
return sum(
|
|
(state := hass.states.get(entity_id)) is not None
|
|
and not state.attributes.get("restored", False)
|
|
for entity_id in hass.states.async_entity_ids(domain)
|
|
)
|
|
|
|
|
|
SENSORS: tuple[HomeAssistantSpookSensorEntityDescription, ...] = (
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.AIR_QUALITY,
|
|
translation_key="homeassistant_air_quality",
|
|
entity_id="sensor.air_quality",
|
|
icon="mdi:air-filter",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.AIR_QUALITY)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.ALARM_CONTROL_PANEL,
|
|
translation_key="homeassistant_alarm_control_panel",
|
|
entity_id="sensor.alarm_control_panels",
|
|
icon="mdi:alarm-panel",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(
|
|
hass.states.async_entity_ids(Platform.ALARM_CONTROL_PANEL),
|
|
),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="area",
|
|
translation_key="homeassistant_area",
|
|
entity_id="sensor.areas",
|
|
icon="mdi:texture-box",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, ar.EVENT_AREA_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(list(ar.async_get(hass).async_list_areas())),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=automation.DOMAIN,
|
|
translation_key="homeassistant_automation",
|
|
entity_id="sensor.automations",
|
|
icon="mdi:robot",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={automation.EVENT_AUTOMATION_RELOADED},
|
|
value_fn=lambda hass: _count_active_domain_entities(hass, automation.DOMAIN),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.BINARY_SENSOR,
|
|
translation_key="homeassistant_binary_sensor",
|
|
entity_id="sensor.binary_sensors",
|
|
icon="mdi:numeric-10",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.BINARY_SENSOR)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.BUTTON,
|
|
translation_key="homeassistant_button",
|
|
entity_id="sensor.buttons",
|
|
icon="mdi:gesture-tap",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.BUTTON)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.CALENDAR,
|
|
translation_key="homeassistant_calendar",
|
|
entity_id="sensor.calendars",
|
|
icon="mdi:calendar",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CALENDAR)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.CAMERA,
|
|
translation_key="homeassistant_camera",
|
|
entity_id="sensor.cameras",
|
|
icon="mdi:cctv",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CAMERA)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.CLIMATE,
|
|
translation_key="homeassistant_climate",
|
|
entity_id="sensor.climate",
|
|
icon="mdi:thermostat",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.CLIMATE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.COVER,
|
|
translation_key="homeassistant_cover",
|
|
entity_id="sensor.covers",
|
|
icon="mdi:blinds",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.COVER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.DATE,
|
|
translation_key="homeassistant_date",
|
|
entity_id="sensor.dates",
|
|
icon="mdi:calendar-month-outline",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.DATE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.DATETIME,
|
|
translation_key="homeassistant_datetime",
|
|
entity_id="sensor.datetimes",
|
|
icon="mdi:calendar-clock",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.DATETIME)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="device",
|
|
translation_key="homeassistant_device",
|
|
entity_id="sensor.devices",
|
|
icon="mdi:cellphone",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, dr.EVENT_DEVICE_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(dr.async_get(hass).devices),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.DEVICE_TRACKER,
|
|
translation_key="homeassistant_device_tracker",
|
|
entity_id="sensor.device_trackers",
|
|
icon="mdi:cellphone-marker",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(
|
|
hass.states.async_entity_ids(Platform.DEVICE_TRACKER),
|
|
),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="entities",
|
|
translation_key="homeassistant_entities",
|
|
entity_id="sensor.entities",
|
|
icon="mdi:counter",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids()),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.FAN,
|
|
translation_key="homeassistant_fan",
|
|
entity_id="sensor.fans",
|
|
icon="mdi:fan",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.FAN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.HUMIDIFIER,
|
|
translation_key="homeassistant_humidifier",
|
|
entity_id="sensor.humidifiers",
|
|
icon="mdi:air-humidifier",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.HUMIDIFIER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="integration",
|
|
translation_key="homeassistant_integration",
|
|
entity_id="sensor.integrations",
|
|
icon="mdi:package-variant-closed",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED},
|
|
value_fn=lambda hass: len(hass.data["entity_platform"]),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="custom_component",
|
|
translation_key="homeassistant_custom_component",
|
|
entity_id="sensor.custom_integrations",
|
|
icon="mdi:package-variant-closed",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED},
|
|
value_fn=lambda hass: len(hass.data["custom_components"]),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_boolean.DOMAIN,
|
|
translation_key="homeassistant_input_boolean",
|
|
entity_id="sensor.input_booleans",
|
|
icon="mdi:toggle-switch-outline",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_boolean.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_button.DOMAIN,
|
|
translation_key="homeassistant_input_button",
|
|
entity_id="sensor.input_buttons",
|
|
icon="mdi:gesture-tap-button",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_button.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_datetime.DOMAIN,
|
|
translation_key="homeassistant_input_datetime",
|
|
entity_id="sensor.input_datetimes",
|
|
icon="mdi:clock",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_datetime.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_number.DOMAIN,
|
|
translation_key="homeassistant_input_number",
|
|
entity_id="sensor.input_numbers",
|
|
icon="mdi:ray-vertex",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_number.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_select.DOMAIN,
|
|
translation_key="homeassistant_input_select",
|
|
entity_id="sensor.input_selects",
|
|
icon="mdi:form-dropdown",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_select.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=input_text.DOMAIN,
|
|
translation_key="homeassistant_input_text",
|
|
entity_id="sensor.input_texts",
|
|
icon="mdi:form-textbox",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(input_text.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.IMAGE,
|
|
translation_key="homeassistant_image",
|
|
entity_id="sensor.images",
|
|
icon="mdi:image",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.IMAGE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.LIGHT,
|
|
translation_key="homeassistant_light",
|
|
entity_id="sensor.lights",
|
|
icon="mdi:lightbulb",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.LIGHT)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.LOCK,
|
|
translation_key="homeassistant_lock",
|
|
entity_id="sensor.locks",
|
|
icon="mdi:lock",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.LOCK)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.MEDIA_PLAYER,
|
|
translation_key="homeassistant_media_player",
|
|
entity_id="sensor.media_players",
|
|
icon="mdi:record-player",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.MEDIA_PLAYER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.NUMBER,
|
|
translation_key="homeassistant_number",
|
|
entity_id="sensor.numbers",
|
|
icon="mdi:ray-vertex",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.NUMBER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key="persistent_notification",
|
|
translation_key="homeassistant_persistent_notification",
|
|
entity_id="sensor.persistent_notifications",
|
|
icon="mdi:bell-ring-outline",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={
|
|
"persistent_notifications_updated",
|
|
},
|
|
value_fn=lambda hass: len(
|
|
# pylint: disable-next=protected-access
|
|
persistent_notification._async_get_or_create_notifications( # noqa: SLF001
|
|
hass,
|
|
),
|
|
),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=person.DOMAIN,
|
|
translation_key="homeassistant_person",
|
|
entity_id="sensor.persons",
|
|
icon="mdi:account-group",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(person.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.REMOTE,
|
|
translation_key="homeassistant_remote",
|
|
entity_id="sensor.remotes",
|
|
icon="mdi:remote",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.REMOTE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.SCENE,
|
|
translation_key="homeassistant_scene",
|
|
entity_id="sensor.scenes",
|
|
icon="mdi:palette",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SCENE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=script.DOMAIN,
|
|
translation_key="homeassistant_script",
|
|
entity_id="sensor.scripts",
|
|
icon="mdi:script-text",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: _count_active_domain_entities(hass, script.DOMAIN),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.SELECT,
|
|
translation_key="homeassistant_select",
|
|
entity_id="sensor.selects",
|
|
icon="mdi:format-list-bulleted",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SELECT)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.SENSOR,
|
|
translation_key="homeassistant_sensor",
|
|
entity_id="sensor.sensors",
|
|
icon="mdi:eye",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SENSOR)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.SIREN,
|
|
translation_key="homeassistant_siren",
|
|
entity_id="sensor.sirens",
|
|
icon="mdi:bullhorn",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SIREN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=sun.DOMAIN,
|
|
translation_key="homeassistant_sun",
|
|
entity_id="sensor.suns",
|
|
icon="mdi:emoticon-cool",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(sun.DOMAIN)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.STT,
|
|
translation_key="homeassistant_stt",
|
|
entity_id="sensor.stt",
|
|
icon="mdi:microphone-message",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.STT)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.SWITCH,
|
|
translation_key="homeassistant_switch",
|
|
entity_id="sensor.switches",
|
|
icon="mdi:toggle-switch",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.SWITCH)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.TEXT,
|
|
translation_key="homeassistant_text",
|
|
entity_id="sensor.texts",
|
|
icon="mdi:form-textbox",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TEXT)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.TIME,
|
|
translation_key="homeassistant_time",
|
|
entity_id="sensor.times",
|
|
icon="mdi:clock-time-eight-outline",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TIME)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.TODO,
|
|
translation_key="homeassistant_todo",
|
|
entity_id="sensor.todos",
|
|
icon="mdi:clipboard-list",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TODO)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.TTS,
|
|
translation_key="homeassistant_tts",
|
|
entity_id="sensor.tts",
|
|
icon="mdi:speaker-message",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.TTS)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.VACUUM,
|
|
translation_key="homeassistant_vacuum",
|
|
entity_id="sensor.vacuums",
|
|
icon="mdi:vacuum",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.VACUUM)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.UPDATE,
|
|
translation_key="homeassistant_update",
|
|
entity_id="sensor.update",
|
|
icon="mdi:cellphone-arrow-down",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.UPDATE)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.WATER_HEATER,
|
|
translation_key="homeassistant_water_heater",
|
|
entity_id="sensor.water_heaters",
|
|
icon="mdi:water-boiler",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.WATER_HEATER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=Platform.WEATHER,
|
|
translation_key="homeassistant_weather",
|
|
entity_id="sensor.weather",
|
|
icon="mdi:weather-cloudy",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(Platform.WEATHER)),
|
|
),
|
|
HomeAssistantSpookSensorEntityDescription(
|
|
key=zone.DOMAIN,
|
|
translation_key="homeassistant_zone",
|
|
entity_id="sensor.zones",
|
|
icon="mdi:selection-marker",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
state_class=SensorStateClass.TOTAL,
|
|
update_events={EVENT_COMPONENT_LOADED, er.EVENT_ENTITY_REGISTRY_UPDATED},
|
|
value_fn=lambda hass: len(hass.states.async_entity_ids(zone.DOMAIN)),
|
|
),
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
_hass: HomeAssistant,
|
|
_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up Spook sensor."""
|
|
async_add_entities(
|
|
HomeAssistantSpookSensorEntity(description) for description in SENSORS
|
|
)
|
|
|
|
|
|
class HomeAssistantSpookSensorEntity(HomeAssistantSpookEntity, SensorEntity):
|
|
"""Spook sensor providig Home Asistant information."""
|
|
|
|
entity_description: HomeAssistantSpookSensorEntityDescription
|
|
_unsub_debouncer: Callable[[], None] | None = None
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Register for sensor updates."""
|
|
|
|
@callback
|
|
def _debounced_update(
|
|
_now: datetime | None = None,
|
|
) -> None:
|
|
"""Update state after debounce."""
|
|
self._unsub_debouncer = None
|
|
self.async_schedule_update_ha_state()
|
|
|
|
@callback
|
|
def _update_state(_: Event) -> None:
|
|
"""Update state."""
|
|
if self._unsub_debouncer:
|
|
self._unsub_debouncer()
|
|
self._unsub_debouncer = async_call_later(self.hass, 5, _debounced_update)
|
|
|
|
for event in self.entity_description.update_events:
|
|
self.async_on_remove(self.hass.bus.async_listen(event, _update_state))
|
|
|
|
self.async_on_remove(
|
|
async_listen_once_tracked(
|
|
self.hass, EVENT_HOMEASSISTANT_STARTED, _update_state
|
|
),
|
|
)
|
|
|
|
async def async_will_remove_from_hass(self) -> None:
|
|
"""Clean up debounce timer."""
|
|
if self._unsub_debouncer:
|
|
self._unsub_debouncer()
|
|
self._unsub_debouncer = None
|
|
await super().async_will_remove_from_hass()
|
|
|
|
@property
|
|
def native_value(self) -> int | None:
|
|
"""Return the sensor value."""
|
|
return self.entity_description.value_fn(self.hass)
|