1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00
ha-core/homeassistant/components/econet/__init__.py
epenet 04e8e84058
Add init type hints [e] (#63102)
Co-authored-by: epenet <epenet@users.noreply.github.com>
2021-12-31 11:05:44 +01:00

168 lines
5.1 KiB
Python

"""Support for EcoNet products."""
from datetime import timedelta
import logging
from aiohttp.client_exceptions import ClientError
from pyeconet import EcoNetApiInterface
from pyeconet.equipment import EquipmentType
from pyeconet.errors import (
GenericHTTPError,
InvalidCredentialsError,
InvalidResponseFormat,
PyeconetError,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, TEMP_FAHRENHEIT, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType
from .const import API_CLIENT, DOMAIN, EQUIPMENT
_LOGGER = logging.getLogger(__name__)
PLATFORMS = [
Platform.CLIMATE,
Platform.BINARY_SENSOR,
Platform.SENSOR,
Platform.WATER_HEATER,
]
PUSH_UPDATE = "econet.push_update"
INTERVAL = timedelta(minutes=60)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the EcoNet component."""
hass.data[DOMAIN] = {}
hass.data[DOMAIN][API_CLIENT] = {}
hass.data[DOMAIN][EQUIPMENT] = {}
return True
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up EcoNet as config entry."""
email = config_entry.data[CONF_EMAIL]
password = config_entry.data[CONF_PASSWORD]
try:
api = await EcoNetApiInterface.login(email, password=password)
except InvalidCredentialsError:
_LOGGER.error("Invalid credentials provided")
return False
except PyeconetError as err:
_LOGGER.error("Config entry failed: %s", err)
raise ConfigEntryNotReady from err
try:
equipment = await api.get_equipment_by_type(
[EquipmentType.WATER_HEATER, EquipmentType.THERMOSTAT]
)
except (ClientError, GenericHTTPError, InvalidResponseFormat) as err:
raise ConfigEntryNotReady from err
hass.data[DOMAIN][API_CLIENT][config_entry.entry_id] = api
hass.data[DOMAIN][EQUIPMENT][config_entry.entry_id] = equipment
hass.config_entries.async_setup_platforms(config_entry, PLATFORMS)
api.subscribe()
def update_published():
"""Handle a push update."""
dispatcher_send(hass, PUSH_UPDATE)
for _eqip in equipment[EquipmentType.WATER_HEATER]:
_eqip.set_update_callback(update_published)
for _eqip in equipment[EquipmentType.THERMOSTAT]:
_eqip.set_update_callback(update_published)
async def resubscribe(now):
"""Resubscribe to the MQTT updates."""
await hass.async_add_executor_job(api.unsubscribe)
api.subscribe()
async def fetch_update(now):
"""Fetch the latest changes from the API."""
await api.refresh_equipment()
config_entry.async_on_unload(async_track_time_interval(hass, resubscribe, INTERVAL))
config_entry.async_on_unload(
async_track_time_interval(hass, fetch_update, INTERVAL + timedelta(minutes=1))
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a EcoNet config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN][API_CLIENT].pop(entry.entry_id)
hass.data[DOMAIN][EQUIPMENT].pop(entry.entry_id)
return unload_ok
class EcoNetEntity(Entity):
"""Define a base EcoNet entity."""
def __init__(self, econet):
"""Initialize."""
self._econet = econet
async def async_added_to_hass(self):
"""Subscribe to device events."""
await super().async_added_to_hass()
self.async_on_remove(
self.hass.helpers.dispatcher.async_dispatcher_connect(
PUSH_UPDATE, self.on_update_received
)
)
@callback
def on_update_received(self):
"""Update was pushed from the ecoent API."""
self.async_write_ha_state()
@property
def available(self):
"""Return if the the device is online or not."""
return self._econet.connected
@property
def device_info(self) -> DeviceInfo:
"""Return device registry information for this entity."""
return DeviceInfo(
identifiers={(DOMAIN, self._econet.device_id)},
manufacturer="Rheem",
name=self._econet.device_name,
)
@property
def name(self):
"""Return the name of the entity."""
return self._econet.device_name
@property
def unique_id(self):
"""Return the unique ID of the entity."""
return f"{self._econet.device_id}_{self._econet.device_name}"
@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_FAHRENHEIT
@property
def should_poll(self) -> bool:
"""Return True if entity has to be polled for state.
False if entity pushes its state to HA.
"""
return False