Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Coordinator to update data from Aquacell API."""
2 
3 import asyncio
4 from datetime import datetime
5 import logging
6 
7 from aioaquacell import (
8  AquacellApi,
9  AquacellApiException,
10  AuthenticationFailed,
11  Softener,
12 )
13 
14 from homeassistant.config_entries import ConfigEntry
15 from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
16 from homeassistant.core import HomeAssistant
17 from homeassistant.exceptions import ConfigEntryError
18 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
19 
20 from .const import (
21  CONF_REFRESH_TOKEN,
22  CONF_REFRESH_TOKEN_CREATION_TIME,
23  REFRESH_TOKEN_EXPIRY_TIME,
24  UPDATE_INTERVAL,
25 )
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 
30 class AquacellCoordinator(DataUpdateCoordinator[dict[str, Softener]]):
31  """My aquacell coordinator."""
32 
33  config_entry: ConfigEntry
34 
35  def __init__(self, hass: HomeAssistant, aquacell_api: AquacellApi) -> None:
36  """Initialize coordinator."""
37  super().__init__(
38  hass,
39  _LOGGER,
40  name="Aquacell Coordinator",
41  update_interval=UPDATE_INTERVAL,
42  )
43 
44  self.refresh_tokenrefresh_token = self.config_entryconfig_entry.data[CONF_REFRESH_TOKEN]
45  self.refresh_token_creation_timerefresh_token_creation_time = self.config_entryconfig_entry.data[
46  CONF_REFRESH_TOKEN_CREATION_TIME
47  ]
48  self.emailemail = self.config_entryconfig_entry.data[CONF_EMAIL]
49  self.passwordpassword = self.config_entryconfig_entry.data[CONF_PASSWORD]
50  self.aquacell_apiaquacell_api = aquacell_api
51 
52  async def _async_update_data(self) -> dict[str, Softener]:
53  """Fetch data from API endpoint.
54 
55  This is the place to pre-process the data to lookup tables
56  so entities can quickly look up their data.
57  """
58 
59  async with asyncio.timeout(30):
60  # Check if the refresh token is expired
61  expiry_time = (
62  self.refresh_token_creation_timerefresh_token_creation_time
63  + REFRESH_TOKEN_EXPIRY_TIME.total_seconds()
64  )
65  try:
66  if datetime.now().timestamp() >= expiry_time:
67  await self._reauthenticate_reauthenticate()
68  else:
69  await self.aquacell_apiaquacell_api.authenticate_refresh(self.refresh_tokenrefresh_token)
70  _LOGGER.debug("Logged in using: %s", self.refresh_tokenrefresh_token)
71 
72  softeners = await self.aquacell_apiaquacell_api.get_all_softeners()
73  except AuthenticationFailed as err:
74  raise ConfigEntryError from err
75  except (AquacellApiException, TimeoutError) as err:
76  raise UpdateFailed(f"Error communicating with API: {err}") from err
77 
78  return {softener.dsn: softener for softener in softeners}
79 
80  async def _reauthenticate(self) -> None:
81  _LOGGER.debug("Attempting to renew refresh token")
82  refresh_token = await self.aquacell_apiaquacell_api.authenticate(self.emailemail, self.passwordpassword)
83  self.refresh_tokenrefresh_token = refresh_token
84  data = {
85  **self.config_entryconfig_entry.data,
86  CONF_REFRESH_TOKEN: self.refresh_tokenrefresh_token,
87  CONF_REFRESH_TOKEN_CREATION_TIME: datetime.now().timestamp(),
88  }
89 
90  self.hasshass.config_entries.async_update_entry(self.config_entryconfig_entry, data=data)
None __init__(self, HomeAssistant hass, AquacellApi aquacell_api)
Definition: coordinator.py:35
def authenticate(HomeAssistant hass, host, port, servers)
Definition: config_flow.py:104