Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to fix initialize error in some situations. #51

Merged
merged 9 commits into from
Dec 19, 2024
20 changes: 15 additions & 5 deletions custom_components/deye_dehumidifier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant, callback
Expand Down Expand Up @@ -39,6 +41,8 @@
Platform.FAN,
]

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Deye Dehumidifier from a config entry."""
Expand Down Expand Up @@ -71,12 +75,12 @@ def on_auth_token_refreshed(auth_token: str) -> None:
await cloud_api.get_device_list(),
)
)
coordinator_map = {}
for device in device_list:
coordinator = DeyeDataUpdateCoordinator(
hass, device, mqtt_client, cloud_api
)
device[DATA_COORDINATOR] = coordinator
await device[DATA_COORDINATOR].async_config_entry_first_refresh()
coordinator_map[device["device_id"]] = coordinator

except DeyeCloudApiInvalidAuthError as err:
raise ConfigEntryAuthFailed from err
Expand All @@ -88,6 +92,7 @@ def on_auth_token_refreshed(auth_token: str) -> None:
DATA_CLOUD_API: cloud_api,
DATA_MQTT_CLIENT: mqtt_client,
DATA_DEVICE_LIST: device_list,
DATA_COORDINATOR: coordinator_map,
}

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
Expand All @@ -110,13 +115,14 @@ class DeyeEntity(CoordinatorEntity, Entity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
super().__init__(coordinator)
"""Initialize the instance."""
self.coordinator = device[DATA_COORDINATOR]
super().__init__(self.coordinator)
self.coordinator = coordinator
self._device = device
self._mqtt_client = mqtt_client
self._cloud_api = cloud_api
Expand All @@ -138,10 +144,14 @@ def __init__(
self.device_state = DeyeDeviceState(
"1411000000370000000000000000003C3C0000000000" # 20°C/60%RH as the default state
)

async def async_added_to_hass(self) -> None:
"""When entity is added to Home Assistant."""
remove_handle = self.coordinator.async_add_listener(
self._handle_coordinator_update
)
self.async_on_remove(remove_handle)
await super().async_added_to_hass()

async def publish_command_async(self, attribute, value):
"""Push command to a queue and deal with them together."""
Expand All @@ -150,7 +160,7 @@ async def publish_command_async(self, attribute, value):
"call_humidifier_method",
{"device_id": self._device["device_id"], "prop": attribute, "value": value},
)
await self.coordinator.async_request_refresh()
self.coordinator.mute_subscription_for_a_while()

@property
def available(self):
Expand Down
26 changes: 20 additions & 6 deletions custom_components/deye_dehumidifier/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@
from libdeye.mqtt_client import DeyeMqttClient
from libdeye.types import DeyeApiResponseDeviceInfo

from . import DeyeEntity
from .const import DATA_CLOUD_API, DATA_DEVICE_LIST, DATA_MQTT_CLIENT, DOMAIN
from . import DeyeDataUpdateCoordinator, DeyeEntity
from .const import (
DATA_CLOUD_API,
DATA_COORDINATOR,
DATA_DEVICE_LIST,
DATA_MQTT_CLIENT,
DOMAIN,
)


async def async_setup_entry(
Expand All @@ -30,10 +36,16 @@ async def async_setup_entry(
async_add_entities(
[
DeyeWaterTankBinarySensor(
device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API]
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
),
DeyeDefrostingBinarySensor(
device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API]
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
),
]
)
Expand All @@ -48,12 +60,13 @@ class DeyeWaterTankBinarySensor(DeyeEntity, BinarySensorEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the sensor."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self._attr_unique_id += "-water-tank"
self.entity_id = f"binary_sensor.{self.entity_id_base}_water_tank"
Expand All @@ -73,12 +86,13 @@ class DeyeDefrostingBinarySensor(DeyeEntity, BinarySensorEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the sensor."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self._attr_unique_id += "-defrosting"
self.entity_id = f"binary_sensor.{self.entity_id_base}_defrosting"
Expand Down
8 changes: 4 additions & 4 deletions custom_components/deye_dehumidifier/data_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self, hass, device, mqtt_client, cloud_api):
_LOGGER,
name="deye_data_update_coordinator",
update_method=self.poll_device_state,
update_interval=timedelta(seconds=10),
update_interval=timedelta(seconds=5),
)
self._mqtt_client = mqtt_client
self._cloud_api = cloud_api
Expand Down Expand Up @@ -61,9 +61,9 @@ def update_device_state(self, state: DeyeDeviceState) -> None:
self.receive_queue.put_nowait(state)
# self.async_set_updated_data(state)

async def async_request_refresh(self) -> None:
self.mute_subscription_for_a_while()
await super().async_request_refresh()
# async def async_request_refresh(self) -> None:
# self.mute_subscription_for_a_while()
# await super().async_request_refresh()

async def poll_device_state(self) -> DeyeDeviceState:
"""
Expand Down
22 changes: 18 additions & 4 deletions custom_components/deye_dehumidifier/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@
from libdeye.types import DeyeApiResponseDeviceInfo, DeyeFanSpeed
from libdeye.utils import get_product_feature_config

from . import DeyeEntity
from .const import DATA_CLOUD_API, DATA_DEVICE_LIST, DATA_MQTT_CLIENT, DOMAIN
from . import DeyeDataUpdateCoordinator, DeyeEntity
from .const import (
DATA_CLOUD_API,
DATA_COORDINATOR,
DATA_DEVICE_LIST,
DATA_MQTT_CLIENT,
DOMAIN,
)


async def async_setup_entry(
Expand All @@ -33,7 +39,14 @@ async def async_setup_entry(
feature_config = get_product_feature_config(device["product_id"])
if len(feature_config["fan_speed"]) > 0:
async_add_entities(
[DeyeFan(device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API])]
[
DeyeFan(
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
)
]
)


Expand All @@ -44,12 +57,13 @@ class DeyeFan(DeyeEntity, FanEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the fan entity."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self._attr_unique_id += "-fan"
self.entity_id = f"fan.{self.entity_id_base}_fan"
Expand Down
23 changes: 17 additions & 6 deletions custom_components/deye_dehumidifier/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from libdeye.cloud_api import DeyeCloudApi
from libdeye.device_state_command import DeyeDeviceState
from libdeye.mqtt_client import DeyeMqttClient
from libdeye.types import DeyeApiResponseDeviceInfo, DeyeDeviceMode
from libdeye.utils import get_product_feature_config

from . import DeyeEntity
from .const import DATA_CLOUD_API, DATA_DEVICE_LIST, DATA_MQTT_CLIENT, DOMAIN
from . import DeyeDataUpdateCoordinator, DeyeEntity
from .const import (
DATA_CLOUD_API,
DATA_COORDINATOR,
DATA_DEVICE_LIST,
DATA_MQTT_CLIENT,
DOMAIN,
)

MODE_MANUAL = "manual"
MODE_AIR_PURIFIER = "air_purifier"
Expand All @@ -38,7 +45,10 @@ async def async_setup_entry(

for device in data[DATA_DEVICE_LIST]:
deye_dehumidifier = DeyeDehumidifier(
device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API]
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
)
async_add_entities([deye_dehumidifier])

Expand All @@ -52,12 +62,13 @@ class DeyeDehumidifier(DeyeEntity, HumidifierEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the humidifier entity."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self.subscription_muted: CALLBACK_TYPE | None = None
self._attr_unique_id += "-dehumidifier"
Expand All @@ -81,8 +92,8 @@ async def call_method(self, event):

async def async_added_to_hass(self) -> None:
await super().async_added_to_hass()
self.hass.helpers.event.async_track_time_interval(
self.put_device_state, timedelta(seconds=5)
async_track_time_interval(
self.hass, self.put_device_state, timedelta(seconds=2)
)
self.hass.bus.async_listen("call_humidifier_method", self.call_method)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/deye_dehumidifier/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"iot_class": "cloud_push",
"issue_tracker": "https://github.com/stackia/ha-deye-dehumidifier/issues",
"requirements": ["libdeye==1.3.0"],
"version": "1.6.2"
"version": "1.6.3"
}
26 changes: 20 additions & 6 deletions custom_components/deye_dehumidifier/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
from libdeye.mqtt_client import DeyeMqttClient
from libdeye.types import DeyeApiResponseDeviceInfo

from . import DeyeEntity
from .const import DATA_CLOUD_API, DATA_DEVICE_LIST, DATA_MQTT_CLIENT, DOMAIN
from . import DeyeDataUpdateCoordinator, DeyeEntity
from .const import (
DATA_CLOUD_API,
DATA_COORDINATOR,
DATA_DEVICE_LIST,
DATA_MQTT_CLIENT,
DOMAIN,
)


async def async_setup_entry(
Expand All @@ -31,10 +37,16 @@ async def async_setup_entry(
async_add_entities(
[
DeyeHumiditySensor(
device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API]
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
),
DeyeTemperatureSensor(
device, data[DATA_MQTT_CLIENT], data[DATA_CLOUD_API]
data[DATA_COORDINATOR][device["device_id"]],
device,
data[DATA_MQTT_CLIENT],
data[DATA_CLOUD_API],
),
]
)
Expand All @@ -50,12 +62,13 @@ class DeyeHumiditySensor(DeyeEntity, SensorEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the sensor."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self._attr_unique_id += "-humidity"
self.entity_id = f"sensor.{self.entity_id_base}_humidity"
Expand All @@ -76,12 +89,13 @@ class DeyeTemperatureSensor(DeyeEntity, SensorEntity):

def __init__(
self,
coordinator: DeyeDataUpdateCoordinator,
device: DeyeApiResponseDeviceInfo,
mqtt_client: DeyeMqttClient,
cloud_api: DeyeCloudApi,
) -> None:
"""Initialize the sensor."""
super().__init__(device, mqtt_client, cloud_api)
super().__init__(coordinator, device, mqtt_client, cloud_api)
assert self._attr_unique_id is not None
self._attr_unique_id += "-temperature"
self.entity_id = f"sensor.{self.entity_id_base}_temperature"
Expand Down
Loading
Loading