102 lines
3.7 KiB
Python
102 lines
3.7 KiB
Python
"""The Rehlko integration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from aiokem import AioKem, AuthenticationError
|
|
|
|
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
from homeassistant.util import dt as dt_util
|
|
|
|
from .const import (
|
|
CONF_REFRESH_TOKEN,
|
|
CONNECTION_EXCEPTIONS,
|
|
DEVICE_DATA_DEVICES,
|
|
DEVICE_DATA_DISPLAY_NAME,
|
|
DEVICE_DATA_ID,
|
|
DOMAIN,
|
|
)
|
|
from .coordinator import RehlkoConfigEntry, RehlkoRuntimeData, RehlkoUpdateCoordinator
|
|
|
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(hass: HomeAssistant, entry: RehlkoConfigEntry) -> bool:
|
|
"""Set up Rehlko from a config entry."""
|
|
websession = async_get_clientsession(hass)
|
|
rehlko = AioKem(session=websession, home_timezone=dt_util.get_default_time_zone())
|
|
# If requests take more than 20 seconds; timeout and let the setup retry.
|
|
rehlko.set_timeout(20)
|
|
|
|
async def async_refresh_token_update(refresh_token: str) -> None:
|
|
"""Handle refresh token update."""
|
|
_LOGGER.debug("Saving refresh token")
|
|
# Update the config entry with the new refresh token
|
|
hass.config_entries.async_update_entry(
|
|
entry,
|
|
data={**entry.data, CONF_REFRESH_TOKEN: refresh_token},
|
|
)
|
|
|
|
rehlko.set_refresh_token_callback(async_refresh_token_update)
|
|
|
|
try:
|
|
await rehlko.authenticate(
|
|
entry.data[CONF_EMAIL],
|
|
entry.data[CONF_PASSWORD],
|
|
entry.data.get(CONF_REFRESH_TOKEN),
|
|
)
|
|
homes = await rehlko.get_homes()
|
|
except AuthenticationError as ex:
|
|
raise ConfigEntryAuthFailed(
|
|
translation_domain=DOMAIN,
|
|
translation_key="invalid_auth",
|
|
translation_placeholders={CONF_EMAIL: entry.data[CONF_EMAIL]},
|
|
) from ex
|
|
except CONNECTION_EXCEPTIONS as ex:
|
|
raise ConfigEntryNotReady(
|
|
translation_domain=DOMAIN,
|
|
translation_key="cannot_connect",
|
|
) from ex
|
|
coordinators: dict[int, RehlkoUpdateCoordinator] = {}
|
|
|
|
entry.runtime_data = RehlkoRuntimeData(
|
|
coordinators=coordinators,
|
|
rehlko=rehlko,
|
|
homes=homes,
|
|
)
|
|
|
|
for home_data in homes:
|
|
for device_data in home_data[DEVICE_DATA_DEVICES]:
|
|
device_id = device_data[DEVICE_DATA_ID]
|
|
coordinator = RehlkoUpdateCoordinator(
|
|
hass=hass,
|
|
logger=_LOGGER,
|
|
config_entry=entry,
|
|
home_data=home_data,
|
|
device_id=device_id,
|
|
device_data=device_data,
|
|
rehlko=rehlko,
|
|
name=f"{DOMAIN} {device_data[DEVICE_DATA_DISPLAY_NAME]}",
|
|
)
|
|
# Intentionally done in series to avoid overloading
|
|
# the Rehlko API with requests
|
|
await coordinator.async_config_entry_first_refresh()
|
|
coordinators[device_id] = coordinator
|
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
|
# Retrys enabled after successful connection to prevent blocking startup
|
|
rehlko.set_retry_policy(retry_count=3, retry_delays=[5, 10, 20])
|
|
# Rehlko service can be slow to respond, increase timeout for polls.
|
|
rehlko.set_timeout(100)
|
|
return True
|
|
|
|
|
|
async def async_unload_entry(hass: HomeAssistant, entry: RehlkoConfigEntry) -> bool:
|
|
"""Unload a config entry."""
|
|
await entry.runtime_data.rehlko.close()
|
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|