Skip to content

Commit

Permalink
Try to fix initialize error in some situations. (#51)
Browse files Browse the repository at this point in the history
* fix: Change the name of "Fresh" mode to "Purification" synchronized with the official app

* fix: command sent to wrong device when multiple device available.

* feat: add continuous switch according to official app only available when manual mode is on.

* fix: try to fix initialize error in some situations.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* feat: bump version to 1.6.3

* fix: optimize refresh interval.

* fix: change direct access to hass.helpers.event, which should be updated to import functions used from event directly to adapt HA 2025.5.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
sususweet and pre-commit-ci[bot] authored Dec 19, 2024
1 parent ba234cb commit c38cd2c
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 42 deletions.
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

0 comments on commit c38cd2c

Please sign in to comment.