diff --git a/.coveragerc b/.coveragerc index 7980a9c5cdf..27001654d72 100644 --- a/.coveragerc +++ b/.coveragerc @@ -245,6 +245,7 @@ omit = homeassistant/components/doorbird/camera.py homeassistant/components/doorbird/device.py homeassistant/components/doorbird/entity.py + homeassistant/components/doorbird/event.py homeassistant/components/doorbird/util.py homeassistant/components/doorbird/view.py homeassistant/components/dormakaba_dkey/__init__.py diff --git a/homeassistant/components/doorbird/const.py b/homeassistant/components/doorbird/const.py index 1bd13496e3a..4985b9ac9ea 100644 --- a/homeassistant/components/doorbird/const.py +++ b/homeassistant/components/doorbird/const.py @@ -3,7 +3,7 @@ from homeassistant.const import Platform DOMAIN = "doorbird" -PLATFORMS = [Platform.BUTTON, Platform.CAMERA] +PLATFORMS = [Platform.BUTTON, Platform.CAMERA, Platform.EVENT] DOOR_STATION = "door_station" DOOR_STATION_INFO = "door_station_info" DOOR_STATION_EVENT_ENTITY_IDS = "door_station_event_entity_ids" diff --git a/homeassistant/components/doorbird/device.py b/homeassistant/components/doorbird/device.py index e0fb02fcb8d..23c0055cbe0 100644 --- a/homeassistant/components/doorbird/device.py +++ b/homeassistant/components/doorbird/device.py @@ -2,10 +2,12 @@ from __future__ import annotations +from dataclasses import dataclass +from functools import cached_property import logging from typing import Any, cast -from doorbirdpy import DoorBird +from doorbirdpy import DoorBird, DoorBirdScheduleEntry from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant @@ -17,6 +19,14 @@ from .const import API_URL _LOGGER = logging.getLogger(__name__) +@dataclass(slots=True) +class DoorbirdEvent: + """Describes a doorbird event.""" + + event: str + event_type: str + + class ConfiguredDoorBird: """Attach additional information to pass along with configured device.""" @@ -36,6 +46,7 @@ class ConfiguredDoorBird: self._event_entity_ids = event_entity_ids self.events: list[str] = [] self.door_station_events: list[str] = [] + self.event_descriptions: list[DoorbirdEvent] = [] def update_events(self, events: list[str]) -> None: """Update the doorbird events.""" @@ -84,7 +95,27 @@ class ConfiguredDoorBird: "Successfully registered URL for %s on %s", event, self.name ) - @property + schedule: list[DoorBirdScheduleEntry] = self.device.schedule() + http_fav: dict[str, dict[str, Any]] = favorites.get("http") or {} + events: list[DoorbirdEvent] = [] + favorite_input_type: dict[str, str] = {} + for entry in schedule: + input_type = entry.input + for output in entry.output: + if output.event == "http": + favorite_input_type[output.param] = input_type + + for identifier, data in http_fav.items(): + title: str | None = data.get("title") + if not title or not title.startswith("Home Assistant"): + continue + event = title.split("(")[1].strip(")") + if input_type := favorite_input_type.get(identifier): + events.append(DoorbirdEvent(event, input_type)) + + self.event_descriptions = events + + @cached_property def slug(self) -> str: """Get device slug.""" return slugify(self._name) diff --git a/homeassistant/components/doorbird/event.py b/homeassistant/components/doorbird/event.py new file mode 100644 index 00000000000..082ddb6d487 --- /dev/null +++ b/homeassistant/components/doorbird/event.py @@ -0,0 +1,88 @@ +"""Support for doorbird events.""" + +from typing import TYPE_CHECKING + +from homeassistant.components.event import ( + EventDeviceClass, + EventEntity, + EventEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .device import DoorbirdEvent +from .entity import DoorBirdEntity +from .models import DoorBirdData + +EVENT_DESCRIPTIONS = { + "doorbell": EventEntityDescription( + key="doorbell", + translation_key="doorbell", + device_class=EventDeviceClass.DOORBELL, + event_types=["ring"], + ), + "motion": EventEntityDescription( + key="motion", + translation_key="motion", + device_class=EventDeviceClass.MOTION, + event_types=["motion"], + ), +} + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the DoorBird event platform.""" + config_entry_id = config_entry.entry_id + door_bird_data: DoorBirdData = hass.data[DOMAIN][config_entry_id] + async_add_entities( + DoorBirdEventEntity(door_bird_data, doorbird_event, description) + for doorbird_event in door_bird_data.door_station.event_descriptions + if (description := EVENT_DESCRIPTIONS.get(doorbird_event.event_type)) + ) + + +class DoorBirdEventEntity(DoorBirdEntity, EventEntity): + """A relay in a DoorBird device.""" + + entity_description: EventEntityDescription + _attr_has_entity_name = True + + def __init__( + self, + door_bird_data: DoorBirdData, + doorbird_event: DoorbirdEvent, + entity_description: EventEntityDescription, + ) -> None: + """Initialize an event for a doorbird device.""" + super().__init__(door_bird_data) + self._doorbird_event = doorbird_event + self.entity_description = entity_description + event = doorbird_event.event + self._attr_unique_id = f"{self._mac_addr}_{event}" + slug_name = event.removeprefix(self._door_station.slug).strip("_") + friendly_name = slug_name.replace("_", " ") + self._attr_name = friendly_name[0:1].upper() + friendly_name[1:].lower() + + async def async_added_to_hass(self) -> None: + """Subscribe to device events.""" + self.async_on_remove( + self.hass.bus.async_listen( + f"{DOMAIN}_{self._doorbird_event.event}", + self._async_handle_event, + ) + ) + + @callback + def _async_handle_event(self, event: Event) -> None: + """Handle a device event.""" + event_types = self.entity_description.event_types + if TYPE_CHECKING: + assert event_types is not None + self._trigger_event(event_type=event_types[0]) + self.async_write_ha_state() diff --git a/homeassistant/components/doorbird/strings.json b/homeassistant/components/doorbird/strings.json index c851de379d4..7bb55739fcf 100644 --- a/homeassistant/components/doorbird/strings.json +++ b/homeassistant/components/doorbird/strings.json @@ -48,6 +48,26 @@ "last_motion": { "name": "Last motion" } + }, + "event": { + "doorbell": { + "state_attributes": { + "event_type": { + "state": { + "ring": "Ring" + } + } + } + }, + "motion": { + "state_attributes": { + "event_type": { + "state": { + "motion": "Motion" + } + } + } + } } } }