Add cloud control.

This commit is contained in:
sususweet
2025-09-17 22:46:38 +08:00
parent 85365338f4
commit 2bfc2b9fbe
4 changed files with 174 additions and 15 deletions

View File

@@ -10,6 +10,8 @@ from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .core.device import MiedaDevice
from .const import DOMAIN
from .core.logger import MideaLogger
_LOGGER = logging.getLogger(__name__)
@@ -46,11 +48,8 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
async def _async_setup(self) -> None:
"""Set up the coordinator."""
self.data = MideaDeviceData(
attributes=self.device.attributes,
available=self.device.connected,
connected=self.device.connected,
)
# Immediate first refresh to avoid waiting for the interval
self.data = await self.poll_device_state()
# Register for device updates
self.device.register_update(self._device_update_callback)
@@ -71,10 +70,9 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
if self.state_update_muted:
return
# Update device attributes
# Update device attributes (allow new keys to be added)
for key, value in status.items():
if key in self.device.attributes:
self.device.attributes[key] = value
self.device.attributes[key] = value
# Update coordinator data
self.async_set_updated_data(
@@ -91,12 +89,26 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
return self.data
try:
# The device handles its own polling, so we just return current state
return MideaDeviceData(
# 尝试账号模式下的云端轮询(如果 cloud 存在且支持)
account_bucket = self.hass.data.get(DOMAIN, {}).get("accounts", {}).get(self.config_entry.entry_id)
cloud = account_bucket.get("cloud") if account_bucket else None
if cloud and hasattr(cloud, "get_device_status"):
try:
status = await cloud.get_device_status(self._device_id)
if isinstance(status, dict) and len(status) > 0:
for k, v in status.items():
self.device.attributes[k] = v
except Exception as e:
MideaLogger.debug(f"Cloud status fetch failed: {e}")
# 返回并推送当前状态
updated = MideaDeviceData(
attributes=self.device.attributes,
available=self.device.connected,
connected=self.device.connected,
)
self.async_set_updated_data(updated)
return updated
except Exception as e:
_LOGGER.error(f"Error polling device state: {e}")
return MideaDeviceData(
@@ -107,13 +119,29 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
async def async_set_attribute(self, attribute: str, value) -> None:
"""Set a device attribute."""
self.device.set_attribute(attribute, value)
# 云端控制:构造 control 与 status携带当前状态作为上下文
account_bucket = self.hass.data.get(DOMAIN, {}).get("accounts", {}).get(self.config_entry.entry_id)
cloud = account_bucket.get("cloud") if account_bucket else None
control = {attribute: value}
status = dict(self.device.attributes)
if cloud and hasattr(cloud, "send_device_control"):
ok = await cloud.send_device_control(self._device_id, control=control, status=status)
if ok:
# 本地先行更新,随后依赖轮询或设备事件校正
self.device.attributes[attribute] = value
self.mute_state_update_for_a_while()
self.async_update_listeners()
async def async_set_attributes(self, attributes: dict) -> None:
"""Set multiple device attributes."""
self.device.set_attributes(attributes)
account_bucket = self.hass.data.get(DOMAIN, {}).get("accounts", {}).get(self.config_entry.entry_id)
cloud = account_bucket.get("cloud") if account_bucket else None
control = dict(attributes)
status = dict(self.device.attributes)
if cloud and hasattr(cloud, "send_device_control"):
ok = await cloud.send_device_control(self._device_id, control=control, status=status)
if ok:
self.device.attributes.update(attributes)
self.mute_state_update_for_a_while()
self.async_update_listeners()