* init tedee * init tests * add config flow tests * liniting * test * undo * linting * pylint * add tests * more tests * more tests * update snapshot * more tests * typing * strict typing * cleanups * cleanups, fix tests * remove extra platforms * remove codeowner * improvements * catch tedeeclientexception * allow bridge selection in CF * allow bridge selection in CF * allow bridge selection in CF * allow bridge selection in CF * abort earlier * auto-select bridge * remove cloud token, optionsflow to remove size * remove options flow leftovers * improve coverage * defer coordinator setting to after first update * define coordinator * some improvements * remove diagnostics, webhook * remove reauth flow, freeze data classes * fix lock test * Update homeassistant/components/tedee/entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/__init__.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * requested changes * requested changes * Update lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update entity.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * requested changes * Update tests/components/tedee/test_lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/tedee/test_lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/tedee/test_lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/tedee/test_lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/tedee/conftest.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/coordinator.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update tests/components/tedee/test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/strings.json Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/strings.json Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/strings.json Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update homeassistant/components/tedee/lock.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * requested changes * requested changes * requested changes * revert load fixture * change tests * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update strings.json Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update coordinator.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * remove warning * move stuff out of try * add docstring * tedee lowercase, time.time * back to some uppercase, time.time * awaitable --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
"""Coordinator for Tedee locks."""
|
|
from collections.abc import Awaitable, Callable
|
|
from datetime import timedelta
|
|
import logging
|
|
import time
|
|
|
|
from pytedee_async import (
|
|
TedeeClient,
|
|
TedeeClientException,
|
|
TedeeDataUpdateException,
|
|
TedeeLocalAuthException,
|
|
TedeeLock,
|
|
)
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import CONF_HOST
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ConfigEntryError
|
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
|
|
|
from .const import CONF_LOCAL_ACCESS_TOKEN, DOMAIN
|
|
|
|
SCAN_INTERVAL = timedelta(seconds=20)
|
|
GET_LOCKS_INTERVAL_SECONDS = 3600
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
class TedeeApiCoordinator(DataUpdateCoordinator[dict[int, TedeeLock]]):
|
|
"""Class to handle fetching data from the tedee API centrally."""
|
|
|
|
config_entry: ConfigEntry
|
|
|
|
def __init__(self, hass: HomeAssistant) -> None:
|
|
"""Initialize coordinator."""
|
|
super().__init__(
|
|
hass,
|
|
_LOGGER,
|
|
name=DOMAIN,
|
|
update_interval=SCAN_INTERVAL,
|
|
)
|
|
|
|
self.tedee_client = TedeeClient(
|
|
local_token=self.config_entry.data[CONF_LOCAL_ACCESS_TOKEN],
|
|
local_ip=self.config_entry.data[CONF_HOST],
|
|
)
|
|
|
|
self._next_get_locks = time.time()
|
|
|
|
async def _async_update_data(self) -> dict[int, TedeeLock]:
|
|
"""Fetch data from API endpoint."""
|
|
|
|
_LOGGER.debug("Update coordinator: Getting locks from API")
|
|
# once every hours get all lock details, otherwise use the sync endpoint
|
|
if self._next_get_locks <= time.time():
|
|
_LOGGER.debug("Updating through /my/lock endpoint")
|
|
await self._async_update_locks(self.tedee_client.get_locks)
|
|
self._next_get_locks = time.time() + GET_LOCKS_INTERVAL_SECONDS
|
|
else:
|
|
_LOGGER.debug("Updating through /sync endpoint")
|
|
await self._async_update_locks(self.tedee_client.sync)
|
|
|
|
_LOGGER.debug(
|
|
"available_locks: %s",
|
|
", ".join(map(str, self.tedee_client.locks_dict.keys())),
|
|
)
|
|
|
|
return self.tedee_client.locks_dict
|
|
|
|
async def _async_update_locks(
|
|
self, update_fn: Callable[[], Awaitable[None]]
|
|
) -> None:
|
|
"""Update locks based on update function."""
|
|
try:
|
|
await update_fn()
|
|
except TedeeLocalAuthException as ex:
|
|
raise ConfigEntryError(
|
|
"Authentication failed. Local access token is invalid"
|
|
) from ex
|
|
|
|
except TedeeDataUpdateException as ex:
|
|
_LOGGER.debug("Error while updating data: %s", str(ex))
|
|
raise UpdateFailed("Error while updating data: %s" % str(ex)) from ex
|
|
except (TedeeClientException, TimeoutError) as ex:
|
|
raise UpdateFailed("Querying API failed. Error: %s" % str(ex)) from ex
|