hass-core/homeassistant/components/tedee/coordinator.py
Josef Zweck 02b863e968
Add tedee integration (#102846)
* 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>
2023-12-29 14:55:41 +01:00

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