Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Data update coordinator for shark iq vacuums."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from datetime import datetime, timedelta
7 
8 from sharkiq import (
9  AylaApi,
10  SharkIqAuthError,
11  SharkIqAuthExpiringError,
12  SharkIqNotAuthedError,
13  SharkIqVacuum,
14 )
15 
16 from homeassistant.config_entries import ConfigEntry
17 from homeassistant.core import HomeAssistant
18 from homeassistant.exceptions import ConfigEntryAuthFailed
19 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
20 
21 from .const import API_TIMEOUT, DOMAIN, LOGGER, UPDATE_INTERVAL
22 
23 
25  """Define a wrapper class to update Shark IQ data."""
26 
27  def __init__(
28  self,
29  hass: HomeAssistant,
30  config_entry: ConfigEntry,
31  ayla_api: AylaApi,
32  shark_vacs: list[SharkIqVacuum],
33  ) -> None:
34  """Set up the SharkIqUpdateCoordinator class."""
35  self.ayla_apiayla_api = ayla_api
36  self.shark_vacs: dict[str, SharkIqVacuum] = {
37  sharkiq.serial_number: sharkiq for sharkiq in shark_vacs
38  }
39  self._config_entry_config_entry = config_entry
40  self._online_dsns_online_dsns: set[str] = set()
41 
42  super().__init__(hass, LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL)
43 
44  @property
45  def online_dsns(self) -> set[str]:
46  """Get the set of all online DSNs."""
47  return self._online_dsns_online_dsns
48 
49  def device_is_online(self, dsn: str) -> bool:
50  """Return the online state of a given vacuum dsn."""
51  return dsn in self._online_dsns_online_dsns
52 
53  @staticmethod
54  async def _async_update_vacuum(sharkiq: SharkIqVacuum) -> None:
55  """Asynchronously update the data for a single vacuum."""
56  dsn = sharkiq.serial_number
57  LOGGER.debug("Updating sharkiq data for device DSN %s", dsn)
58  async with asyncio.timeout(API_TIMEOUT):
59  await sharkiq.async_update()
60 
61  async def _async_update_data(self) -> bool:
62  """Update data device by device."""
63  try:
64  if (
65  self.ayla_apiayla_api.token_expiring_soon
66  or datetime.now()
67  > self.ayla_apiayla_api.auth_expiration - timedelta(seconds=600)
68  ):
69  await self.ayla_apiayla_api.async_refresh_auth()
70 
71  all_vacuums = await self.ayla_apiayla_api.async_list_devices()
72  self._online_dsns_online_dsns = {
73  v["dsn"]
74  for v in all_vacuums
75  if v["connection_status"] == "Online" and v["dsn"] in self.shark_vacs
76  }
77 
78  LOGGER.debug("Updating sharkiq data")
79  online_vacs = (self.shark_vacs[dsn] for dsn in self.online_dsnsonline_dsns)
80  await asyncio.gather(*(self._async_update_vacuum_async_update_vacuum(v) for v in online_vacs))
81  except (
82  SharkIqAuthError,
83  SharkIqNotAuthedError,
84  SharkIqAuthExpiringError,
85  ) as err:
86  LOGGER.debug("Bad auth state. Attempting re-auth", exc_info=err)
87  raise ConfigEntryAuthFailed from err
88  except Exception as err:
89  LOGGER.exception("Unexpected error updating SharkIQ. Attempting re-auth")
90  raise UpdateFailed(err) from err
91 
92  return True
None __init__(self, HomeAssistant hass, ConfigEntry config_entry, AylaApi ayla_api, list[SharkIqVacuum] shark_vacs)
Definition: coordinator.py:33