Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The IntelliFire integration."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 
7 from intellifire4py import UnifiedFireplace
8 from intellifire4py.cloud_interface import IntelliFireCloudInterface
9 from intellifire4py.model import IntelliFireCommonFireplaceData
10 
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import (
13  CONF_API_KEY,
14  CONF_HOST,
15  CONF_IP_ADDRESS,
16  CONF_PASSWORD,
17  CONF_USERNAME,
18  Platform,
19 )
20 from homeassistant.core import HomeAssistant
21 from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
22 
23 from .const import (
24  CONF_AUTH_COOKIE,
25  CONF_CONTROL_MODE,
26  CONF_READ_MODE,
27  CONF_SERIAL,
28  CONF_USER_ID,
29  CONF_WEB_CLIENT_ID,
30  DOMAIN,
31  INIT_WAIT_TIME_SECONDS,
32  LOGGER,
33  STARTUP_TIMEOUT,
34 )
35 from .coordinator import IntellifireDataUpdateCoordinator
36 
37 PLATFORMS = [
38  Platform.BINARY_SENSOR,
39  Platform.CLIMATE,
40  Platform.FAN,
41  Platform.LIGHT,
42  Platform.NUMBER,
43  Platform.SENSOR,
44  Platform.SWITCH,
45 ]
46 
47 
48 def _construct_common_data(entry: ConfigEntry) -> IntelliFireCommonFireplaceData:
49  """Convert config entry data into IntelliFireCommonFireplaceData."""
50 
51  return IntelliFireCommonFireplaceData(
52  auth_cookie=entry.data[CONF_AUTH_COOKIE],
53  user_id=entry.data[CONF_USER_ID],
54  web_client_id=entry.data[CONF_WEB_CLIENT_ID],
55  serial=entry.data[CONF_SERIAL],
56  api_key=entry.data[CONF_API_KEY],
57  ip_address=entry.data[CONF_IP_ADDRESS],
58  read_mode=entry.options[CONF_READ_MODE],
59  control_mode=entry.options[CONF_CONTROL_MODE],
60  )
61 
62 
63 async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
64  """Migrate entries."""
65  LOGGER.debug(
66  "Migrating configuration from version %s.%s",
67  config_entry.version,
68  config_entry.minor_version,
69  )
70 
71  if config_entry.version == 1:
72  new = {**config_entry.data}
73 
74  if config_entry.minor_version < 2:
75  username = config_entry.data[CONF_USERNAME]
76  password = config_entry.data[CONF_PASSWORD]
77 
78  # Create a Cloud Interface
79  async with IntelliFireCloudInterface() as cloud_interface:
80  await cloud_interface.login_with_credentials(
81  username=username, password=password
82  )
83 
84  new_data = cloud_interface.user_data.get_data_for_ip(new[CONF_HOST])
85 
86  if not new_data:
87  raise ConfigEntryAuthFailed
88  new[CONF_API_KEY] = new_data.api_key
89  new[CONF_WEB_CLIENT_ID] = new_data.web_client_id
90  new[CONF_AUTH_COOKIE] = new_data.auth_cookie
91 
92  new[CONF_IP_ADDRESS] = new_data.ip_address
93  new[CONF_SERIAL] = new_data.serial
94 
95  hass.config_entries.async_update_entry(
96  config_entry,
97  data=new,
98  options={CONF_READ_MODE: "local", CONF_CONTROL_MODE: "local"},
99  unique_id=new[CONF_SERIAL],
100  version=1,
101  minor_version=2,
102  )
103  LOGGER.debug("Pseudo Migration %s successful", config_entry.version)
104 
105  return True
106 
107 
108 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
109  """Set up IntelliFire from a config entry."""
110 
111  if CONF_USERNAME not in entry.data:
112  LOGGER.debug("Config entry without username detected: %s", entry.unique_id)
113  raise ConfigEntryAuthFailed
114 
115  try:
116  fireplace: UnifiedFireplace = (
117  await UnifiedFireplace.build_fireplace_from_common(
119  )
120  )
121  LOGGER.debug("Waiting for Fireplace to Initialize")
122  await asyncio.wait_for(
123  _async_wait_for_initialization(fireplace), timeout=STARTUP_TIMEOUT
124  )
125  except TimeoutError as err:
126  raise ConfigEntryNotReady(
127  "Initialization of fireplace timed out after 10 minutes"
128  ) from err
129 
130  # Construct coordinator
131  data_update_coordinator = IntellifireDataUpdateCoordinator(
132  hass=hass, fireplace=fireplace
133  )
134 
135  LOGGER.debug("Fireplace to Initialized - Awaiting first refresh")
136  await data_update_coordinator.async_config_entry_first_refresh()
137 
138  hass.data.setdefault(DOMAIN, {})[entry.entry_id] = data_update_coordinator
139 
140  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
141 
142  return True
143 
144 
146  fireplace: UnifiedFireplace, timeout=STARTUP_TIMEOUT
147 ):
148  """Wait for a fireplace to be initialized."""
149  while (
150  fireplace.data.ipv4_address == "127.0.0.1" and fireplace.data.serial == "unset"
151  ):
152  LOGGER.debug(f"Waiting for fireplace to initialize [{fireplace.read_mode}]")
153  await asyncio.sleep(INIT_WAIT_TIME_SECONDS)
154 
155 
156 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
157  """Unload a config entry."""
158  if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
159  hass.data[DOMAIN].pop(entry.entry_id)
160 
161  return unload_ok
def _async_wait_for_initialization(UnifiedFireplace fireplace, timeout=STARTUP_TIMEOUT)
Definition: __init__.py:147
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:156
bool async_migrate_entry(HomeAssistant hass, ConfigEntry config_entry)
Definition: __init__.py:63
IntelliFireCommonFireplaceData _construct_common_data(ConfigEntry entry)
Definition: __init__.py:48
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:108