Add event platform to doorbird (#121114)

This commit is contained in:
J. Nick Koston 2024-07-04 04:41:56 -05:00 committed by GitHub
parent a6f6221f16
commit 0be1f773a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 143 additions and 3 deletions

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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()

View File

@ -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"
}
}
}
}
}
}
}