core/homeassistant/components/vicare/__init__.py

116 lines
3.4 KiB
Python

"""The ViCare integration."""
from __future__ import annotations
from collections.abc import Callable, Mapping
from contextlib import suppress
from dataclasses import dataclass
import logging
import os
from typing import Any
from PyViCare.PyViCare import PyViCare
from PyViCare.PyViCareDevice import Device
from PyViCare.PyViCareUtils import (
PyViCareInvalidConfigurationError,
PyViCareInvalidCredentialsError,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_CLIENT_ID, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.storage import STORAGE_DIR
from .const import (
CONF_HEATING_TYPE,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
HEATING_TYPE_TO_CREATOR_METHOD,
PLATFORMS,
VICARE_API,
VICARE_DEVICE_CONFIG,
VICARE_DEVICE_CONFIG_LIST,
HeatingType,
)
_LOGGER = logging.getLogger(__name__)
_TOKEN_FILENAME = "vicare_token.save"
@dataclass(frozen=True)
class ViCareRequiredKeysMixin:
"""Mixin for required keys."""
value_getter: Callable[[Device], Any]
@dataclass(frozen=True)
class ViCareRequiredKeysMixinWithSet(ViCareRequiredKeysMixin):
"""Mixin for required keys with setter."""
value_setter: Callable[[Device], bool]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up from config entry."""
_LOGGER.debug("Setting up ViCare component")
hass.data[DOMAIN] = {}
hass.data[DOMAIN][entry.entry_id] = {}
try:
await hass.async_add_executor_job(setup_vicare_api, hass, entry)
except (PyViCareInvalidConfigurationError, PyViCareInvalidCredentialsError) as err:
raise ConfigEntryAuthFailed("Authentication failed") from err
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
def vicare_login(hass: HomeAssistant, entry_data: Mapping[str, Any]) -> PyViCare:
"""Login via PyVicare API."""
vicare_api = PyViCare()
vicare_api.setCacheDuration(DEFAULT_SCAN_INTERVAL)
vicare_api.initWithCredentials(
entry_data[CONF_USERNAME],
entry_data[CONF_PASSWORD],
entry_data[CONF_CLIENT_ID],
hass.config.path(STORAGE_DIR, _TOKEN_FILENAME),
)
return vicare_api
def setup_vicare_api(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Set up PyVicare API."""
vicare_api = vicare_login(hass, entry.data)
for device in vicare_api.devices:
_LOGGER.info(
"Found device: %s (online: %s)", device.getModel(), str(device.isOnline())
)
# Currently we only support a single device
device_list = vicare_api.devices
device = device_list[0]
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG_LIST] = device_list
hass.data[DOMAIN][entry.entry_id][VICARE_DEVICE_CONFIG] = device
hass.data[DOMAIN][entry.entry_id][VICARE_API] = getattr(
device,
HEATING_TYPE_TO_CREATOR_METHOD[HeatingType(entry.data[CONF_HEATING_TYPE])],
)()
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload ViCare config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
with suppress(FileNotFoundError):
await hass.async_add_executor_job(
os.remove, hass.config.path(STORAGE_DIR, _TOKEN_FILENAME)
)
return unload_ok