Home Assistant Unofficial Reference 2024.12.1
household_coordinator.py
Go to the documentation of this file.
1 """Class representing a Sonos household storage helper."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from collections.abc import Callable, Coroutine
7 import logging
8 from typing import Any
9 
10 from soco import SoCo
11 
12 from homeassistant.core import HomeAssistant, callback
13 from homeassistant.helpers.debounce import Debouncer
14 
15 from .const import DATA_SONOS
16 from .exception import SonosUpdateError
17 
18 _LOGGER = logging.getLogger(__name__)
19 
20 
22  """Base class for Sonos household-level storage."""
23 
24  cache_update_lock: asyncio.Lock
25 
26  def __init__(self, hass: HomeAssistant, household_id: str) -> None:
27  """Initialize the data."""
28  self.hasshass = hass
29  self.household_idhousehold_id = household_id
30  self.async_pollasync_poll: Callable[[], Coroutine[None, None, None]] | None = None
31  self.last_processed_event_id: int | None = None
32 
33  def setup(self, soco: SoCo) -> None:
34  """Set up the SonosAlarm instance."""
35  self.update_cacheupdate_cache(soco)
36  self.hasshass.add_job(self._async_setup_async_setup)
37 
38  @callback
39  def _async_setup(self) -> None:
40  """Finish setup in async context."""
41  self.cache_update_lockcache_update_lock = asyncio.Lock()
42  self.async_pollasync_poll = Debouncer[Coroutine[Any, Any, None]](
43  self.hasshass,
44  _LOGGER,
45  cooldown=3,
46  immediate=False,
47  function=self._async_poll_async_poll,
48  ).async_call
49 
50  @property
51  def class_type(self) -> str:
52  """Return the class type of this instance."""
53  return type(self).__name__
54 
55  async def _async_poll(self) -> None:
56  """Poll any known speaker."""
57  discovered = self.hasshass.data[DATA_SONOS].discovered
58 
59  for uid, speaker in discovered.items():
60  _LOGGER.debug("Polling %s using %s", self.class_typeclass_type, speaker.soco)
61  try:
62  await self.async_update_entitiesasync_update_entities(speaker.soco)
63  except SonosUpdateError as err:
64  _LOGGER.error(
65  "Could not refresh %s: %s",
66  self.class_typeclass_type,
67  err,
68  )
69  else:
70  # Prefer this SoCo instance next update
71  discovered.move_to_end(uid, last=False)
72  break
73 
75  self, soco: SoCo, update_id: int | None = None
76  ) -> None:
77  """Update the cache and update entities."""
78  raise NotImplementedError
79 
80  def update_cache(self, soco: SoCo, update_id: int | None = None) -> bool:
81  """Update the cache of the household-level feature and return if cache has changed."""
82  raise NotImplementedError