Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The Balboa Spa Client integration."""
2 
3 from __future__ import annotations
4 
5 from datetime import datetime, timedelta
6 import logging
7 
8 from pybalboa import SpaClient
9 
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.const import CONF_HOST, Platform
12 from homeassistant.core import HomeAssistant
13 from homeassistant.exceptions import ConfigEntryNotReady
14 from homeassistant.helpers.event import async_track_time_interval
15 import homeassistant.util.dt as dt_util
16 
17 from .const import CONF_SYNC_TIME, DEFAULT_SYNC_TIME
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 PLATFORMS = [
22  Platform.BINARY_SENSOR,
23  Platform.CLIMATE,
24  Platform.FAN,
25  Platform.LIGHT,
26  Platform.SELECT,
27 ]
28 
29 
30 KEEP_ALIVE_INTERVAL = timedelta(minutes=1)
31 SYNC_TIME_INTERVAL = timedelta(hours=1)
32 
33 type BalboaConfigEntry = ConfigEntry[SpaClient]
34 
35 
36 async def async_setup_entry(hass: HomeAssistant, entry: BalboaConfigEntry) -> bool:
37  """Set up Balboa Spa from a config entry."""
38  host = entry.data[CONF_HOST]
39 
40  _LOGGER.debug("Attempting to connect to %s", host)
41  spa = SpaClient(host)
42  if not await spa.connect():
43  _LOGGER.error("Failed to connect to spa at %s", host)
44  raise ConfigEntryNotReady("Unable to connect")
45  if not await spa.async_configuration_loaded():
46  _LOGGER.error("Failed to get spa info at %s", host)
47  raise ConfigEntryNotReady("Unable to configure")
48 
49  entry.runtime_data = spa
50 
51  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
52 
53  await async_setup_time_sync(hass, entry)
54  entry.async_on_unload(entry.add_update_listener(update_listener))
55  entry.async_on_unload(spa.disconnect)
56 
57  return True
58 
59 
60 async def async_unload_entry(hass: HomeAssistant, entry: BalboaConfigEntry) -> bool:
61  """Unload a config entry."""
62  return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
63 
64 
65 async def update_listener(hass: HomeAssistant, entry: BalboaConfigEntry) -> None:
66  """Handle options update."""
67  await hass.config_entries.async_reload(entry.entry_id)
68 
69 
70 async def async_setup_time_sync(hass: HomeAssistant, entry: BalboaConfigEntry) -> None:
71  """Set up the time sync."""
72  if not entry.options.get(CONF_SYNC_TIME, DEFAULT_SYNC_TIME):
73  return
74 
75  _LOGGER.debug("Setting up daily time sync")
76  spa = entry.runtime_data
77 
78  async def sync_time(now: datetime) -> None:
79  now = dt_util.as_local(now)
80  if (now.hour, now.minute) != (spa.time_hour, spa.time_minute):
81  _LOGGER.debug("Syncing time with Home Assistant")
82  await spa.set_time(now.hour, now.minute)
83 
84  await sync_time(dt_util.utcnow())
85  entry.async_on_unload(
86  async_track_time_interval(hass, sync_time, SYNC_TIME_INTERVAL)
87  )
None async_setup_time_sync(HomeAssistant hass, BalboaConfigEntry entry)
Definition: __init__.py:70
None update_listener(HomeAssistant hass, BalboaConfigEntry entry)
Definition: __init__.py:65
bool async_unload_entry(HomeAssistant hass, BalboaConfigEntry entry)
Definition: __init__.py:60
bool async_setup_entry(HomeAssistant hass, BalboaConfigEntry entry)
Definition: __init__.py:36
CALLBACK_TYPE async_track_time_interval(HomeAssistant hass, Callable[[datetime], Coroutine[Any, Any, None]|None] action, timedelta interval, *str|None name=None, bool|None cancel_on_shutdown=None)
Definition: event.py:1679