1 """Support for DoorBird devices."""
3 from __future__
import annotations
5 from collections
import defaultdict
6 from dataclasses
import dataclass
7 from http
import HTTPStatus
11 from aiohttp
import ClientResponseError
12 from doorbirdpy
import (
14 DoorBirdScheduleEntry,
15 DoorBirdScheduleEntryOutput,
16 DoorBirdScheduleEntrySchedule,
18 from propcache
import cached_property
33 _LOGGER = logging.getLogger(__name__)
36 @dataclass(slots=True)
38 """Describes a doorbird event."""
44 @dataclass(slots=True)
46 """Describes the configuration of doorbird events."""
48 events: list[DoorbirdEvent]
49 schedule: list[DoorBirdScheduleEntry]
50 unconfigured_favorites: defaultdict[str, list[str]]
54 """Attach additional information to pass along with configured device."""
61 custom_url: str |
None,
63 event_entity_ids: dict[str, str],
65 """Initialize configured device."""
73 self.
eventsevents: list[str] = []
79 """Update the doorbird events."""
86 def name(self) -> str | None:
87 """Get custom device name."""
88 return self.
_name_name
92 """Get the configured device."""
97 """Get custom url for device."""
102 """Get token for device."""
106 """Register events on device."""
112 _LOGGER.debug(
"%s: Event config: %s", self.
namename, event_config)
113 if event_config.unconfigured_favorites:
119 self, event_config: DoorbirdEventConfig
121 """Configure unconfigured favorites."""
122 for entry
in event_config.schedule:
123 modified_schedule =
False
124 for identifier
in event_config.unconfigured_favorites.get(entry.input, ()):
125 schedule = DoorBirdScheduleEntrySchedule()
126 schedule.add_weekday(MIN_WEEKDAY, MAX_WEEKDAY)
128 DoorBirdScheduleEntryOutput(
130 event=HTTP_EVENT_TYPE,
135 modified_schedule =
True
137 if modified_schedule:
138 update_ok, code = await self.
devicedevice.change_schedule(entry)
141 "Unable to update schedule entry %s to %s. Error code: %s",
148 """Register events on device."""
151 hass_url = custom_url
154 hass_url =
get_url(self.
_hass_hass, prefer_external=
False)
171 self, http_fav: dict[str, dict[str, Any]]
172 ) -> DoorbirdEventConfig:
173 """Get events and unconfigured favorites from http favorites."""
174 device = self.
devicedevice
175 events: list[DoorbirdEvent] = []
176 unconfigured_favorites: defaultdict[str, list[str]] = defaultdict(list)
178 schedule = await device.schedule()
179 except ClientResponseError
as ex:
180 if ex.status == HTTPStatus.NOT_FOUND:
184 favorite_input_type = {
185 output.param: entry.input
186 for entry
in schedule
187 for output
in entry.output
188 if output.event == HTTP_EVENT_TYPE
190 default_event_types = {
192 for event, event_type
in DEFAULT_EVENT_TYPES
194 for identifier, data
in http_fav.items():
195 title: str |
None = data.get(
"title")
196 if not title
or not title.startswith(
"Home Assistant"):
198 event = title.partition(
"(")[2].strip(
")")
199 if input_type := favorite_input_type.get(identifier):
201 elif input_type := default_event_types.get(event):
202 unconfigured_favorites[input_type].append(identifier)
208 """Get device slug."""
212 return f
"{self.slug}_{event}"
215 """Get the HTTP favorites from the device."""
216 return (await self.
devicedevice.favorites()).
get(HTTP_EVENT_TYPE)
or {}
219 self, hass_url: str, event: str, http_fav: dict[str, dict[str, Any]]
221 """Register an event.
223 Returns True if the event was registered, False if
224 the event was already registered or registration failed.
226 url = f
"{hass_url}{API_URL}/{event}?token={self._token}"
227 _LOGGER.debug(
"Registering URL %s for event %s", url, event)
229 if any(fav[
"value"] == url
for fav
in http_fav.values()):
230 _LOGGER.debug(
"URL already registered for %s", event)
233 if not await self.
devicedevice.change_favorite(
234 HTTP_EVENT_TYPE, f
"Home Assistant ({event})", url
237 'Unable to set favorite URL "%s". Event "%s" will not fire',
243 _LOGGER.debug(
"Successfully registered URL for %s on %s", event, self.
namename)
247 """Get data to pass along with HA event."""
249 "timestamp": dt_util.utcnow().isoformat(),
250 "live_video_url": self.
_device_device.live_video_url,
251 "live_image_url": self.
_device_device.live_image_url,
252 "rtsp_live_video_url": self.
_device_device.rtsp_live_video_url,
253 "html5_viewer_url": self.
_device_device.html5_viewer_url,
259 """Handle clearing favorites on device."""
260 door_bird = door_station.device
261 favorites = await door_bird.favorites()
262 for favorite_type, favorite_ids
in favorites.items():
263 for favorite_id
in favorite_ids:
264 await door_bird.delete_favorite(favorite_type, favorite_id)
265 await door_station.async_register_events()
web.Response get(self, web.Request request, str config_key)
None async_reset_device_favorites(ConfiguredDoorBird door_station)
str get_url(HomeAssistant hass, *bool require_current_request=False, bool require_ssl=False, bool require_standard_port=False, bool require_cloud=False, bool allow_internal=True, bool allow_external=True, bool allow_cloud=True, bool|None allow_ip=None, bool|None prefer_external=None, bool prefer_cloud=False)