1 """Support for Synology DSM cameras."""
3 from __future__
import annotations
5 from dataclasses
import dataclass
8 from synology_dsm.api.surveillance_station
import SynoCamera, SynoSurveillanceStation
9 from synology_dsm.exceptions
import (
10 SynologyDSMAPIErrorException,
11 SynologyDSMRequestException,
16 CameraEntityDescription,
27 CONF_SNAPSHOT_QUALITY,
28 DEFAULT_SNAPSHOT_QUALITY,
30 SIGNAL_CAMERA_SOURCE_CHANGED,
32 from .coordinator
import SynologyDSMCameraUpdateCoordinator
33 from .entity
import SynologyDSMBaseEntity, SynologyDSMEntityDescription
34 from .models
import SynologyDSMData
36 _LOGGER = logging.getLogger(__name__)
39 @dataclass(frozen=True, kw_only=True)
41 CameraEntityDescription, SynologyDSMEntityDescription
43 """Describes Synology DSM camera entity."""
49 hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
51 """Set up the Synology NAS cameras."""
52 data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
53 if coordinator := data.coordinator_cameras:
56 for camera_id
in coordinator.data[
"cameras"]
61 """Representation a Synology camera."""
63 _attr_supported_features = CameraEntityFeature.STREAM
64 entity_description: SynologyDSMCameraEntityDescription
69 coordinator: SynologyDSMCameraUpdateCoordinator,
72 """Initialize a Synology camera."""
74 api_key=SynoSurveillanceStation.CAMERA_API_KEY,
78 entity_registry_enabled_default=coordinator.data[
"cameras"][
83 CONF_SNAPSHOT_QUALITY, DEFAULT_SNAPSHOT_QUALITY
85 super().
__init__(api, coordinator, description)
91 return self.coordinator.data[
"cameras"][self.entity_description.camera_id]
95 """Return the device information."""
96 information = self._api.information
97 assert information
is not None
99 identifiers={(DOMAIN, f
"{information.serial}_{self.camera_data.id}")},
104 f
"{information.serial}_{SynoSurveillanceStation.INFO_API_KEY}",
110 """Return the availability of the camera."""
111 return self.
camera_datacamera_data.is_enabled
and super().available
115 """Return true if the device is recording."""
120 """Return the camera motion detection status."""
124 """Listen for camera source changed events."""
127 def _handle_signal(url: str) ->
None:
129 _LOGGER.debug(
"Update stream URL for camera %s", self.
camera_datacamera_data.name)
130 self.
streamstream.update_source(url)
132 assert self.
platformplatform.config_entry
136 f
"{SIGNAL_CAMERA_SOURCE_CHANGED}_{self.platform.config_entry.entry_id}_{self.camera_data.id}",
142 """Subscribe to signal."""
147 self, width: int |
None =
None, height: int |
None =
None
149 """Return bytes of camera image."""
151 "SynoDSMCamera.camera_image(%s)",
156 assert self._api.surveillance_station
is not None
158 return await self._api.surveillance_station.get_camera_image(
162 SynologyDSMAPIErrorException,
163 SynologyDSMRequestException,
164 ConnectionRefusedError,
167 "SynoDSMCamera.camera_image(%s) - Exception:%s",
174 """Return the source of the stream."""
176 "SynoDSMCamera.stream_source(%s)",
185 """Enable motion detection in the camera."""
187 "SynoDSMCamera.enable_motion_detection(%s)",
190 assert self._api.surveillance_station
is not None
191 await self._api.surveillance_station.enable_motion_detection(
192 self.entity_description.camera_id
196 """Disable motion detection in camera."""
198 "SynoDSMCamera.disable_motion_detection(%s)",
201 assert self._api.surveillance_station
is not None
202 await self._api.surveillance_station.disable_motion_detection(
203 self.entity_description.camera_id
None async_disable_motion_detection(self)
None async_enable_motion_detection(self)
str|None stream_source(self)
SynoCamera camera_data(self)
bytes|None async_camera_image(self, int|None width=None, int|None height=None)
None async_added_to_hass(self)
DeviceInfo device_info(self)
bool motion_detection_enabled(self)
None __init__(self, SynoApi api, SynologyDSMCameraUpdateCoordinator coordinator, int camera_id)
None _listen_source_updates(self)
None async_on_remove(self, CALLBACK_TYPE func)
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)