Skip to content

Commit

Permalink
Rebuild to single data coordinator
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre0512 committed Mar 29, 2024
1 parent 8f1fc62 commit a6c2c3e
Show file tree
Hide file tree
Showing 16 changed files with 148 additions and 203 deletions.
34 changes: 20 additions & 14 deletions custom_components/hon/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import logging
from pathlib import Path
from typing import Any

import voluptuous as vol # type: ignore[import-untyped]
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
from homeassistant.helpers import config_validation as cv, aiohttp_client
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from pyhon import Hon

from .const import DOMAIN, PLATFORMS, MOBILE_ID, CONF_REFRESH_TOKEN
Expand All @@ -29,23 +31,27 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
session = aiohttp_client.async_get_clientsession(hass)
if (config_dir := hass.config.config_dir) is None:
raise ValueError("Missing Config Dir")
kwargs = {
"email": entry.data[CONF_EMAIL],
"password": entry.data[CONF_PASSWORD],
"mobile_id": MOBILE_ID,
"session": session,
"test_data_path": Path(config_dir),
}
if refresh_token := entry.data.get(CONF_REFRESH_TOKEN):
kwargs["refresh_token"] = refresh_token
hon = await Hon(**kwargs).create()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.unique_id] = hon
hon = await Hon(
email=entry.data[CONF_EMAIL],
password=entry.data[CONF_PASSWORD],
mobile_id=MOBILE_ID,
session=session,
# test_data_path=Path(config_dir),
refresh_token=entry.data.get(CONF_REFRESH_TOKEN, ""),
).create()

# Save the new refresh token
hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_REFRESH_TOKEN: hon.api.auth.refresh_token}
)
hass.data[DOMAIN]["coordinators"] = {}

coordinator: DataUpdateCoordinator[dict[str, Any]] = DataUpdateCoordinator(
hass, _LOGGER, name=DOMAIN
)
hon.subscribe_updates(coordinator.async_set_updated_data)

hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.unique_id] = {"hon": hon, "coordinator": coordinator}

for platform in PLATFORMS:
hass.async_create_task(
Expand All @@ -55,7 +61,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool


async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool:
refresh_token = hass.data[DOMAIN][entry.unique_id].api.auth.refresh_token
refresh_token = hass.data[DOMAIN][entry.unique_id]["hon"].api.auth.refresh_token

hass.config_entries.async_update_entry(
entry, data={**entry.data, CONF_REFRESH_TOKEN: refresh_token}
Expand Down
5 changes: 3 additions & 2 deletions custom_components/hon/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from homeassistant.helpers.typing import HomeAssistantType

from .const import DOMAIN
from .hon import HonEntity, unique_entities
from .entity import HonEntity
from .util import unique_entities

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -319,7 +320,7 @@ async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
entities = []
for device in hass.data[DOMAIN][entry.unique_id].appliances:
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
for description in BINARY_SENSORS.get(device.appliance_type, []):
if device.get(description.key) is None:
continue
Expand Down
18 changes: 6 additions & 12 deletions custom_components/hon/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pyhon.appliance import HonAppliance

from .const import DOMAIN
from .hon import HonEntity
from .entity import HonEntity
from .typedefs import HonButtonType

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -59,7 +59,7 @@ async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
entities: list[HonButtonType] = []
for device in hass.data[DOMAIN][entry.unique_id].appliances:
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
for description in BUTTONS.get(device.appliance_type, []):
if not device.commands.get(description.key):
continue
Expand Down Expand Up @@ -96,19 +96,14 @@ def __init__(
self._attr_icon = "mdi:information"
self._attr_name = "Show Device Info"
self._attr_entity_category = EntityCategory.DIAGNOSTIC
if "beta" not in self.coordinator.info.hon_version:
self._attr_entity_registry_enabled_default = False
self._attr_entity_registry_enabled_default = False

async def async_press(self) -> None:
versions = "versions:\n"
versions += f" hon: {self.coordinator.info.hon_version}\n"
versions += f" pyhOn: {self.coordinator.info.pyhon_version}\n"
info = f"{self._device.diagnose}{versions}"
title = f"{self._device.nick_name} Device Info"
persistent_notification.create(
self._hass, f"````\n```\n{info}\n```\n````", title
self._hass, f"````\n```\n{self._device.diagnose}\n```\n````", title
)
_LOGGER.info(info.replace(" ", "\u200B "))
_LOGGER.info(self._device.diagnose.replace(" ", "\u200B "))


class HonDataArchive(HonEntity, ButtonEntity):
Expand All @@ -121,8 +116,7 @@ def __init__(
self._attr_icon = "mdi:archive-arrow-down"
self._attr_name = "Create Data Archive"
self._attr_entity_category = EntityCategory.DIAGNOSTIC
if "beta" not in self.coordinator.info.hon_version:
self._attr_entity_registry_enabled_default = False
self._attr_entity_registry_enabled_default = False

async def async_press(self) -> None:
if (config_dir := self._hass.config.config_dir) is None:
Expand Down
8 changes: 4 additions & 4 deletions custom_components/hon/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from pyhon.parameter.range import HonParameterRange

from .const import HON_HVAC_MODE, HON_FAN, DOMAIN, HON_HVAC_PROGRAM
from .hon import HonEntity
from .entity import HonEntity

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -108,7 +108,7 @@ async def async_setup_entry(
) -> None:
entities = []
entity: HonClimateEntity | HonACClimateEntity
for device in hass.data[DOMAIN][entry.unique_id].appliances:
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
for description in CLIMATES.get(device.appliance_type, []):
if isinstance(description, HonACClimateEntityDescription):
if description.key not in list(device.commands):
Expand Down Expand Up @@ -223,7 +223,7 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
self._device.sync_command("startProgram", "settings")
self._set_temperature_bound()
self._handle_coordinator_update(update=False)
await self.coordinator.async_refresh()
self.async_write_ha_state()
self._attr_preset_mode = preset_mode
await self._device.commands["startProgram"].send()
self.async_write_ha_state()
Expand Down Expand Up @@ -390,7 +390,7 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
self._device.sync_command(command, "settings")
self._set_temperature_bound()
self._attr_preset_mode = preset_mode
await self.coordinator.async_refresh()
self.async_write_ha_state()
await self._device.commands[command].send()
self.async_write_ha_state()

Expand Down
54 changes: 54 additions & 0 deletions custom_components/hon/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from typing import Optional, Any

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from pyhon.appliance import HonAppliance

from .const import DOMAIN
from .typedefs import HonEntityDescription


class HonEntity(CoordinatorEntity[DataUpdateCoordinator[dict[str, Any]]]):
_attr_has_entity_name = True
_attr_should_poll = False

def __init__(
self,
hass: HomeAssistantType,
entry: ConfigEntry,
device: HonAppliance,
description: Optional[HonEntityDescription] = None,
) -> None:
self.coordinator = hass.data[DOMAIN][entry.unique_id]["coordinator"]
super().__init__(self.coordinator)
self._hon = hass.data[DOMAIN][entry.unique_id]["hon"]
self._hass = hass
self._device: HonAppliance = device

if description is not None:
self.entity_description = description
self._attr_unique_id = f"{self._device.unique_id}{description.key}"
else:
self._attr_unique_id = self._device.unique_id
self._handle_coordinator_update(update=False)

@property
def device_info(self) -> DeviceInfo:
return DeviceInfo(
identifiers={(DOMAIN, self._device.unique_id)},
manufacturer=self._device.get("brand", ""),
name=self._device.nick_name,
model=self._device.model_name,
sw_version=self._device.get("fwVersion", ""),
)

@callback
def _handle_coordinator_update(self, update: bool = True) -> None:
if update:
self.async_write_ha_state()
4 changes: 2 additions & 2 deletions custom_components/hon/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from pyhon.parameter.range import HonParameterRange

from .const import DOMAIN
from .hon import HonEntity
from .entity import HonEntity

_LOGGER = logging.getLogger(__name__)

Expand All @@ -39,7 +39,7 @@ async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
entities = []
for device in hass.data[DOMAIN][entry.unique_id].appliances:
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
for description in FANS.get(device.appliance_type, []):
if (
description.key not in device.available_settings
Expand Down
142 changes: 0 additions & 142 deletions custom_components/hon/hon.py

This file was deleted.

0 comments on commit a6c2c3e

Please sign in to comment.