hass-core/homeassistant/components/anova/__init__.py
Luke Lashley 22bc11f397
Convert Anova to cloud push (#109508)
* current state

* finish refactor

* Apply suggestions from code review

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* address MR comments

* Change to sensor setup to be listener based.

* remove assert for websocket handler

* added assert for log

* remove mixin

* fix linting

* fix merge change

* Add clarifying comment

* Apply suggestions from code review

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Address MR comments

* bump version and fix typing check

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-05-08 14:53:44 +02:00

78 lines
2.7 KiB
Python

"""The Anova integration."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from anova_wifi import (
AnovaApi,
APCWifiDevice,
InvalidLogin,
NoDevicesFound,
WebsocketFailure,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from .const import DOMAIN
from .coordinator import AnovaCoordinator
from .models import AnovaData
PLATFORMS = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Anova from a config entry."""
api = AnovaApi(
aiohttp_client.async_get_clientsession(hass),
entry.data[CONF_USERNAME],
entry.data[CONF_PASSWORD],
)
try:
await api.authenticate()
except InvalidLogin as err:
_LOGGER.error(
"Login was incorrect - please log back in through the config flow. %s", err
)
return False
assert api.jwt
try:
await api.create_websocket()
except NoDevicesFound as err:
# Can later setup successfully and spawn a repair.
raise ConfigEntryNotReady(
"No devices were found on the websocket, perhaps you don't have any devices on this account?"
) from err
except WebsocketFailure as err:
raise ConfigEntryNotReady("Failed connecting to the websocket.") from err
# Create a coordinator per device, if the device is offline, no data will be on the
# websocket, and the coordinator should auto mark as unavailable. But as long as
# the websocket successfully connected, config entry should setup.
devices: list[APCWifiDevice] = []
if TYPE_CHECKING:
# api.websocket_handler can't be None after successfully creating the
# websocket client
assert api.websocket_handler is not None
devices = list(api.websocket_handler.devices.values())
coordinators = [AnovaCoordinator(hass, device) for device in devices]
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = AnovaData(
api_jwt=api.jwt, coordinators=coordinators, api=api
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
anova_data: AnovaData = hass.data[DOMAIN].pop(entry.entry_id)
# Disconnect from WS
await anova_data.api.disconnect_websocket()
return unload_ok