Home Assistant Unofficial Reference 2024.12.1
heartbeat.py
Go to the documentation of this file.
1 """Heartbeats for Broadlink devices."""
2 
3 import datetime as dt
4 import logging
5 
6 import broadlink as blk
7 
8 from homeassistant.const import CONF_HOST
9 from homeassistant.core import CALLBACK_TYPE, HomeAssistant
10 from homeassistant.helpers import event
11 
12 from .const import DOMAIN
13 
14 _LOGGER = logging.getLogger(__name__)
15 
16 
18  """Manages heartbeats in the Broadlink integration.
19 
20  Some devices reboot when they cannot reach the cloud. This mechanism
21  feeds their watchdog timers so they can be used offline.
22  """
23 
24  HEARTBEAT_INTERVAL = dt.timedelta(minutes=2)
25 
26  def __init__(self, hass: HomeAssistant) -> None:
27  """Initialize the heartbeat."""
28  self._hass_hass = hass
29  self._unsubscribe_unsubscribe: CALLBACK_TYPE | None = None
30 
31  async def async_setup(self) -> None:
32  """Set up the heartbeat."""
33  if self._unsubscribe_unsubscribe is None:
34  await self.async_heartbeatasync_heartbeat(dt.datetime.now())
35  self._unsubscribe_unsubscribe = event.async_track_time_interval(
36  self._hass_hass, self.async_heartbeatasync_heartbeat, self.HEARTBEAT_INTERVALHEARTBEAT_INTERVAL
37  )
38 
39  async def async_unload(self) -> None:
40  """Unload the heartbeat."""
41  if self._unsubscribe_unsubscribe is not None:
42  self._unsubscribe_unsubscribe()
43  self._unsubscribe_unsubscribe = None
44 
45  async def async_heartbeat(self, _: dt.datetime) -> None:
46  """Send packets to feed watchdog timers."""
47  hass = self._hass_hass
48  config_entries = hass.config_entries.async_entries(DOMAIN)
49  hosts: set[str] = {entry.data[CONF_HOST] for entry in config_entries}
50  await hass.async_add_executor_job(self.heartbeatheartbeat, hosts)
51 
52  @staticmethod
53  def heartbeat(hosts: set[str]) -> None:
54  """Send packets to feed watchdog timers."""
55  for host in hosts:
56  try:
57  blk.ping(host)
58  except OSError as err:
59  _LOGGER.debug("Failed to send heartbeat to %s: %s", host, err)
60  else:
61  _LOGGER.debug("Heartbeat sent to %s", host)