1 """synology_dsm coordinators."""
3 from __future__
import annotations
5 from collections.abc
import Awaitable, Callable, Coroutine
6 from datetime
import timedelta
8 from typing
import Any, Concatenate
10 from synology_dsm.api.surveillance_station.camera
import SynoCamera
11 from synology_dsm.exceptions
import (
12 SynologyDSMAPIErrorException,
13 SynologyDSMNotLoggedInException,
22 from .common
import SynoApi, raise_config_entry_auth_error
24 DEFAULT_SCAN_INTERVAL,
25 SIGNAL_CAMERA_SOURCE_CHANGED,
26 SYNOLOGY_AUTH_FAILED_EXCEPTIONS,
27 SYNOLOGY_CONNECTION_EXCEPTIONS,
30 _LOGGER = logging.getLogger(__name__)
33 def async_re_login_on_expired[_T: SynologyDSMUpdateCoordinator[Any], **_P, _R](
34 func: Callable[Concatenate[_T, _P], Awaitable[_R]],
35 ) -> Callable[Concatenate[_T, _P], Coroutine[Any, Any, _R]]:
36 """Define a wrapper to re-login when expired."""
38 async
def _async_wrap(self: _T, *args: _P.args, **kwargs: _P.kwargs) -> _R:
39 for attempts
in range(2):
41 return await func(self, *args, **kwargs)
42 except SynologyDSMNotLoggedInException:
44 _LOGGER.debug(
"login is expired, try to login again")
46 await self.api.async_login()
47 except SYNOLOGY_AUTH_FAILED_EXCEPTIONS
as err:
51 except SYNOLOGY_CONNECTION_EXCEPTIONS
as err:
52 raise UpdateFailed(f
"Error communicating with API: {err}")
from err
54 raise UpdateFailed(
"Unknown error when communicating with API")
60 """DataUpdateCoordinator base class for synology_dsm."""
67 update_interval: timedelta,
69 """Initialize synology_dsm DataUpdateCoordinator."""
75 name=f
"{entry.title} {self.__class__.__name__}",
76 update_interval=update_interval,
81 SynologyDSMUpdateCoordinator[dict[str, dict[str, Any]]]
83 """DataUpdateCoordinator to gather data for a synology_dsm switch devices."""
91 """Initialize DataUpdateCoordinator for switch devices."""
93 self.
versionversion: str |
None =
None
96 """Set up the coordinator initial data."""
97 info = await self.
apiapi.dsm.surveillance_station.get_info()
98 assert info
is not None
99 self.
versionversion = info[
"data"][
"CMSMinVersion"]
101 @async_re_login_on_expired
103 """Fetch all data from api."""
104 surveillance_station = self.
apiapi.surveillance_station
105 assert surveillance_station
is not None
108 "home_mode": bool(await surveillance_station.get_home_mode_status())
114 """DataUpdateCoordinator to gather data for a synology_dsm central device."""
122 """Initialize DataUpdateCoordinator for central device."""
128 minutes=entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
132 @async_re_login_on_expired
134 """Fetch all data from api."""
139 SynologyDSMUpdateCoordinator[dict[str, dict[int, SynoCamera]]]
141 """DataUpdateCoordinator to gather data for a synology_dsm cameras."""
149 """Initialize DataUpdateCoordinator for cameras."""
152 @async_re_login_on_expired
154 """Fetch all camera data from api."""
155 surveillance_station = self.
apiapi.surveillance_station
156 assert surveillance_station
is not None
157 current_data: dict[int, SynoCamera] = {
158 camera.id: camera
for camera
in surveillance_station.get_all_cameras()
162 await surveillance_station.update()
163 except SynologyDSMAPIErrorException
as err:
164 raise UpdateFailed(f
"Error communicating with API: {err}")
from err
166 new_data: dict[int, SynoCamera] = {
167 camera.id: camera
for camera
in surveillance_station.get_all_cameras()
170 for cam_id, cam_data_new
in new_data.items():
172 (cam_data_current := current_data.get(cam_id))
is not None
173 and cam_data_current.live_view.rtsp != cam_data_new.live_view.rtsp
177 f
"{SIGNAL_CAMERA_SOURCE_CHANGED}_{self.entry.entry_id}_{cam_id}",
178 cam_data_new.live_view.rtsp,
181 return {
"cameras": new_data}
dict[str, dict[int, SynoCamera]] _async_update_data(self)
None __init__(self, HomeAssistant hass, ConfigEntry entry, SynoApi api)
None _async_update_data(self)
None __init__(self, HomeAssistant hass, ConfigEntry entry, SynoApi api)
None __init__(self, HomeAssistant hass, ConfigEntry entry, SynoApi api)
dict[str, dict[str, Any]] _async_update_data(self)
None __init__(self, HomeAssistant hass, ConfigEntry entry, SynoApi api, timedelta update_interval)
None raise_config_entry_auth_error(Exception err)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)