1 """Coordinator for Tedee locks."""
3 from __future__
import annotations
5 from collections.abc
import Awaitable, Callable
6 from datetime
import timedelta
11 from aiotedee
import (
14 TedeeDataUpdateException,
15 TedeeLocalAuthException,
17 TedeeWebhookException,
19 from aiotedee.bridge
import TedeeBridge
29 from .const
import CONF_LOCAL_ACCESS_TOKEN, DOMAIN
32 GET_LOCKS_INTERVAL_SECONDS = 3600
34 _LOGGER = logging.getLogger(__name__)
36 type TedeeConfigEntry = ConfigEntry[TedeeApiCoordinator]
40 """Class to handle fetching data from the tedee API centrally."""
42 config_entry: TedeeConfigEntry
45 def __init__(self, hass: HomeAssistant, entry: TedeeConfigEntry) ->
None:
46 """Initialize coordinator."""
52 update_interval=SCAN_INTERVAL,
56 local_token=self.
config_entryconfig_entry.data[CONF_LOCAL_ACCESS_TOKEN],
63 self.new_lock_callbacks: list[Callable[[int],
None]] = []
67 """Set up the coordinator."""
69 async
def _async_get_bridge() -> None:
72 _LOGGER.debug(
"Update coordinator: Getting bridge from API")
76 """Fetch data from API endpoint."""
78 _LOGGER.debug(
"Update coordinator: Getting locks from API")
81 _LOGGER.debug(
"Updating through /my/lock endpoint")
83 self.
_next_get_locks_next_get_locks = time.time() + GET_LOCKS_INTERVAL_SECONDS
85 _LOGGER.debug(
"Updating through /sync endpoint")
89 "available_locks: %s",
90 ", ".join(map(str, self.
tedee_clienttedee_client.locks_dict.keys())),
96 async
def _async_update(self, update_fn: Callable[[], Awaitable[
None]]) ->
None:
97 """Update locks based on update function."""
100 except TedeeLocalAuthException
as ex:
102 translation_domain=DOMAIN,
103 translation_key=
"authentification_failed",
106 except TedeeDataUpdateException
as ex:
107 _LOGGER.debug(
"Error while updating data: %s",
str(ex))
109 translation_domain=DOMAIN, translation_key=
"update_failed"
111 except (TedeeClientException, TimeoutError)
as ex:
113 translation_domain=DOMAIN, translation_key=
"api_error"
117 """Handle webhook message."""
118 self.
tedee_clienttedee_client.parse_webhook_message(message)
122 """Register the webhook at the Tedee bridge."""
126 """Unregister the webhook at the Tedee bridge."""
130 except TedeeWebhookException:
131 _LOGGER.exception(
"Failed to unregister Tedee webhook from bridge")
133 _LOGGER.debug(
"Unregistered Tedee webhook")
136 """Add new locks, remove non-existing locks."""
141 current_locks := set(self.
tedee_clienttedee_client.locks_dict)
147 _LOGGER.debug(
"Removed locks: %s",
", ".join(map(str, removed_locks)))
148 device_registry = dr.async_get(self.
hasshass)
149 for lock_id
in removed_locks:
150 if device := device_registry.async_get_device(
151 identifiers={(DOMAIN,
str(lock_id))}
153 device_registry.async_update_device(
155 remove_config_entry_id=self.
config_entryconfig_entry.entry_id,
160 _LOGGER.debug(
"New locks found: %s",
", ".join(map(str, new_locks)))
161 for lock_id
in new_locks:
162 for callback
in self.new_lock_callbacks:
None webhook_received(self, dict[str, Any] message)
None _async_add_remove_locks(self)
None async_register_webhook(self, str webhook_url)
None async_unregister_webhook(self)
None _async_update(self, Callable[[], Awaitable[None]] update_fn)
None __init__(self, HomeAssistant hass, TedeeConfigEntry entry)
dict[int, TedeeLock] _async_update_data(self)
None async_set_updated_data(self, _DataT data)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)