Skip to content

Commit a6c2c3e

Browse files
committed
Rebuild to single data coordinator
1 parent 8f1fc62 commit a6c2c3e

File tree

16 files changed

+148
-203
lines changed

16 files changed

+148
-203
lines changed

custom_components/hon/__init__.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import logging
22
from pathlib import Path
3+
from typing import Any
34

45
import voluptuous as vol # type: ignore[import-untyped]
56
from homeassistant.config_entries import ConfigEntry
67
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
78
from homeassistant.helpers import config_validation as cv, aiohttp_client
89
from homeassistant.helpers.typing import HomeAssistantType
10+
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
911
from pyhon import Hon
1012

1113
from .const import DOMAIN, PLATFORMS, MOBILE_ID, CONF_REFRESH_TOKEN
@@ -29,23 +31,27 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
2931
session = aiohttp_client.async_get_clientsession(hass)
3032
if (config_dir := hass.config.config_dir) is None:
3133
raise ValueError("Missing Config Dir")
32-
kwargs = {
33-
"email": entry.data[CONF_EMAIL],
34-
"password": entry.data[CONF_PASSWORD],
35-
"mobile_id": MOBILE_ID,
36-
"session": session,
37-
"test_data_path": Path(config_dir),
38-
}
39-
if refresh_token := entry.data.get(CONF_REFRESH_TOKEN):
40-
kwargs["refresh_token"] = refresh_token
41-
hon = await Hon(**kwargs).create()
42-
hass.data.setdefault(DOMAIN, {})
43-
hass.data[DOMAIN][entry.unique_id] = hon
34+
hon = await Hon(
35+
email=entry.data[CONF_EMAIL],
36+
password=entry.data[CONF_PASSWORD],
37+
mobile_id=MOBILE_ID,
38+
session=session,
39+
# test_data_path=Path(config_dir),
40+
refresh_token=entry.data.get(CONF_REFRESH_TOKEN, ""),
41+
).create()
4442

43+
# Save the new refresh token
4544
hass.config_entries.async_update_entry(
4645
entry, data={**entry.data, CONF_REFRESH_TOKEN: hon.api.auth.refresh_token}
4746
)
48-
hass.data[DOMAIN]["coordinators"] = {}
47+
48+
coordinator: DataUpdateCoordinator[dict[str, Any]] = DataUpdateCoordinator(
49+
hass, _LOGGER, name=DOMAIN
50+
)
51+
hon.subscribe_updates(coordinator.async_set_updated_data)
52+
53+
hass.data.setdefault(DOMAIN, {})
54+
hass.data[DOMAIN][entry.unique_id] = {"hon": hon, "coordinator": coordinator}
4955

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

5662

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

6066
hass.config_entries.async_update_entry(
6167
entry, data={**entry.data, CONF_REFRESH_TOKEN: refresh_token}

custom_components/hon/binary_sensor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
from homeassistant.helpers.typing import HomeAssistantType
1313

1414
from .const import DOMAIN
15-
from .hon import HonEntity, unique_entities
15+
from .entity import HonEntity
16+
from .util import unique_entities
1617

1718
_LOGGER = logging.getLogger(__name__)
1819

@@ -319,7 +320,7 @@ async def async_setup_entry(
319320
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
320321
) -> None:
321322
entities = []
322-
for device in hass.data[DOMAIN][entry.unique_id].appliances:
323+
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
323324
for description in BINARY_SENSORS.get(device.appliance_type, []):
324325
if device.get(description.key) is None:
325326
continue

custom_components/hon/button.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pyhon.appliance import HonAppliance
1111

1212
from .const import DOMAIN
13-
from .hon import HonEntity
13+
from .entity import HonEntity
1414
from .typedefs import HonButtonType
1515

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

102101
async def async_press(self) -> None:
103-
versions = "versions:\n"
104-
versions += f" hon: {self.coordinator.info.hon_version}\n"
105-
versions += f" pyhOn: {self.coordinator.info.pyhon_version}\n"
106-
info = f"{self._device.diagnose}{versions}"
107102
title = f"{self._device.nick_name} Device Info"
108103
persistent_notification.create(
109-
self._hass, f"````\n```\n{info}\n```\n````", title
104+
self._hass, f"````\n```\n{self._device.diagnose}\n```\n````", title
110105
)
111-
_LOGGER.info(info.replace(" ", "\u200B "))
106+
_LOGGER.info(self._device.diagnose.replace(" ", "\u200B "))
112107

113108

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

127121
async def async_press(self) -> None:
128122
if (config_dir := self._hass.config.config_dir) is None:

custom_components/hon/climate.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from pyhon.parameter.range import HonParameterRange
2727

2828
from .const import HON_HVAC_MODE, HON_FAN, DOMAIN, HON_HVAC_PROGRAM
29-
from .hon import HonEntity
29+
from .entity import HonEntity
3030

3131
_LOGGER = logging.getLogger(__name__)
3232

@@ -108,7 +108,7 @@ async def async_setup_entry(
108108
) -> None:
109109
entities = []
110110
entity: HonClimateEntity | HonACClimateEntity
111-
for device in hass.data[DOMAIN][entry.unique_id].appliances:
111+
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
112112
for description in CLIMATES.get(device.appliance_type, []):
113113
if isinstance(description, HonACClimateEntityDescription):
114114
if description.key not in list(device.commands):
@@ -223,7 +223,7 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
223223
self._device.sync_command("startProgram", "settings")
224224
self._set_temperature_bound()
225225
self._handle_coordinator_update(update=False)
226-
await self.coordinator.async_refresh()
226+
self.async_write_ha_state()
227227
self._attr_preset_mode = preset_mode
228228
await self._device.commands["startProgram"].send()
229229
self.async_write_ha_state()
@@ -390,7 +390,7 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
390390
self._device.sync_command(command, "settings")
391391
self._set_temperature_bound()
392392
self._attr_preset_mode = preset_mode
393-
await self.coordinator.async_refresh()
393+
self.async_write_ha_state()
394394
await self._device.commands[command].send()
395395
self.async_write_ha_state()
396396

custom_components/hon/entity.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from typing import Optional, Any
2+
3+
from homeassistant.config_entries import ConfigEntry
4+
from homeassistant.core import callback
5+
from homeassistant.helpers.entity import DeviceInfo
6+
from homeassistant.helpers.typing import HomeAssistantType
7+
from homeassistant.helpers.update_coordinator import (
8+
CoordinatorEntity,
9+
)
10+
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
11+
from pyhon.appliance import HonAppliance
12+
13+
from .const import DOMAIN
14+
from .typedefs import HonEntityDescription
15+
16+
17+
class HonEntity(CoordinatorEntity[DataUpdateCoordinator[dict[str, Any]]]):
18+
_attr_has_entity_name = True
19+
_attr_should_poll = False
20+
21+
def __init__(
22+
self,
23+
hass: HomeAssistantType,
24+
entry: ConfigEntry,
25+
device: HonAppliance,
26+
description: Optional[HonEntityDescription] = None,
27+
) -> None:
28+
self.coordinator = hass.data[DOMAIN][entry.unique_id]["coordinator"]
29+
super().__init__(self.coordinator)
30+
self._hon = hass.data[DOMAIN][entry.unique_id]["hon"]
31+
self._hass = hass
32+
self._device: HonAppliance = device
33+
34+
if description is not None:
35+
self.entity_description = description
36+
self._attr_unique_id = f"{self._device.unique_id}{description.key}"
37+
else:
38+
self._attr_unique_id = self._device.unique_id
39+
self._handle_coordinator_update(update=False)
40+
41+
@property
42+
def device_info(self) -> DeviceInfo:
43+
return DeviceInfo(
44+
identifiers={(DOMAIN, self._device.unique_id)},
45+
manufacturer=self._device.get("brand", ""),
46+
name=self._device.nick_name,
47+
model=self._device.model_name,
48+
sw_version=self._device.get("fwVersion", ""),
49+
)
50+
51+
@callback
52+
def _handle_coordinator_update(self, update: bool = True) -> None:
53+
if update:
54+
self.async_write_ha_state()

custom_components/hon/fan.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from pyhon.parameter.range import HonParameterRange
2020

2121
from .const import DOMAIN
22-
from .hon import HonEntity
22+
from .entity import HonEntity
2323

2424
_LOGGER = logging.getLogger(__name__)
2525

@@ -39,7 +39,7 @@ async def async_setup_entry(
3939
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
4040
) -> None:
4141
entities = []
42-
for device in hass.data[DOMAIN][entry.unique_id].appliances:
42+
for device in hass.data[DOMAIN][entry.unique_id]["hon"].appliances:
4343
for description in FANS.get(device.appliance_type, []):
4444
if (
4545
description.key not in device.available_settings

custom_components/hon/hon.py

Lines changed: 0 additions & 142 deletions
This file was deleted.

0 commit comments

Comments
 (0)