Home Assistant Unofficial Reference 2024.12.1
camera.py
Go to the documentation of this file.
1 """Support for viewing the camera feed from a DoorBird video doorbell."""
2 
3 from __future__ import annotations
4 
5 import datetime
6 import logging
7 
8 import aiohttp
9 
10 from homeassistant.components.camera import Camera, CameraEntityFeature
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 import homeassistant.util.dt as dt_util
14 
15 from .entity import DoorBirdEntity
16 from .models import DoorBirdConfigEntry, DoorBirdData
17 
18 _LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=2)
19 _LAST_MOTION_INTERVAL = datetime.timedelta(seconds=30)
20 _LIVE_INTERVAL = datetime.timedelta(seconds=45)
21 _LOGGER = logging.getLogger(__name__)
22 _TIMEOUT = 15 # seconds
23 
24 
26  hass: HomeAssistant,
27  config_entry: DoorBirdConfigEntry,
28  async_add_entities: AddEntitiesCallback,
29 ) -> None:
30  """Set up the DoorBird camera platform."""
31  door_bird_data = config_entry.runtime_data
32  device = door_bird_data.door_station.device
33 
35  [
37  door_bird_data,
38  device.live_image_url,
39  "live",
40  _LIVE_INTERVAL,
41  device.rtsp_live_video_url,
42  ),
44  door_bird_data,
45  device.history_image_url(1, "doorbell"),
46  "last_ring",
47  _LAST_VISITOR_INTERVAL,
48  ),
50  door_bird_data,
51  device.history_image_url(1, "motionsensor"),
52  "last_motion",
53  _LAST_MOTION_INTERVAL,
54  ),
55  ]
56  )
57 
58 
60  """The camera on a DoorBird device."""
61 
62  def __init__(
63  self,
64  door_bird_data: DoorBirdData,
65  url: str,
66  camera_id: str,
67  interval: datetime.timedelta,
68  stream_url: str | None = None,
69  ) -> None:
70  """Initialize the camera on a DoorBird device."""
71  super().__init__(door_bird_data)
72  self._url_url = url
73  self._stream_url_stream_url = stream_url
74  self._attr_translation_key_attr_translation_key = camera_id
75  self._last_image_last_image: bytes | None = None
76  if self._stream_url_stream_url:
77  self._attr_supported_features_attr_supported_features = CameraEntityFeature.STREAM
78  self._interval_interval = interval
79  self._last_update_last_update = datetime.datetime.min
80  self._attr_unique_id_attr_unique_id = f"{self._mac_addr}_{camera_id}"
81 
82  async def stream_source(self) -> str | None:
83  """Return the stream source."""
84  return self._stream_url_stream_url
85 
86  async def async_camera_image(
87  self, width: int | None = None, height: int | None = None
88  ) -> bytes | None:
89  """Pull a still image from the camera."""
90  now = dt_util.utcnow()
91 
92  if self._last_image_last_image and now - self._last_update_last_update < self._interval_interval:
93  return self._last_image_last_image
94 
95  try:
96  self._last_image_last_image = await self._door_station_door_station.device.get_image(
97  self._url_url, timeout=_TIMEOUT
98  )
99  except TimeoutError:
100  _LOGGER.error("DoorBird %s: Camera image timed out", self.namename)
101  return self._last_image_last_image
102  except aiohttp.ClientError as error:
103  _LOGGER.error(
104  "DoorBird %s: Error getting camera image: %s", self.namename, error
105  )
106  return self._last_image_last_image
107 
108  self._last_update_last_update = now
109  return self._last_image_last_image
110 
111  async def async_added_to_hass(self) -> None:
112  """Subscribe to events."""
113  await super().async_added_to_hass()
114  event_to_entity_id = self._door_bird_data_door_bird_data.event_entity_ids
115  for event in self._door_station_door_station.events:
116  event_to_entity_id[event] = self.entity_identity_id
117 
118  async def async_will_remove_from_hass(self) -> None:
119  """Unsubscribe from events."""
120  event_to_entity_id = self._door_bird_data_door_bird_data.event_entity_ids
121  for event in self._door_station_door_station.events:
122  # If the clear api was called, the events may not be in the dict
123  event_to_entity_id.pop(event, None)
124  await super().async_will_remove_from_hass()
None __init__(self, DoorBirdData door_bird_data, str url, str camera_id, datetime.timedelta interval, str|None stream_url=None)
Definition: camera.py:69
bytes|None async_camera_image(self, int|None width=None, int|None height=None)
Definition: camera.py:88
str|UndefinedType|None name(self)
Definition: entity.py:738
None async_setup_entry(HomeAssistant hass, DoorBirdConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: camera.py:29