From 7476d6ad1d308fae8269c8eec377036a59ed9608 Mon Sep 17 00:00:00 2001 From: sususweet Date: Fri, 7 Nov 2025 01:08:38 +0800 Subject: [PATCH] feat: add support for T0xCD --- README.md | 1 + README_hans.md | 1 + .../midea_auto_cloud/core/device.py | 17 ++--- .../midea_auto_cloud/data_coordinator.py | 33 +++++++-- .../midea_auto_cloud/device_mapping/T0xCD.py | 69 +++++++++++++++++++ .../midea_auto_cloud/translations/en.json | 3 + .../translations/zh-Hans.json | 3 + 7 files changed, 114 insertions(+), 13 deletions(-) create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xCD.py diff --git a/README.md b/README.md index de86904..f92b1f2 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Get devices from MSmartHome/Midea Meiju homes through the network and control th - T0xB8 Smart Robot Vacuum - T0xCA French Door Refrigerator - T0xCC Central Air Conditioning (Ducted) Wi-Fi Controller +- T0xCD Air Energy Water Heater - T0xCE Fresh Air System - T0xCF Central Air Conditioning Heating - T0xD9 Twin Tub Washing Machine diff --git a/README_hans.md b/README_hans.md index 40278da..77b927d 100644 --- a/README_hans.md +++ b/README_hans.md @@ -34,6 +34,7 @@ - T0xB8 智能扫地机器人 - T0xCA 对开门冰箱 - T0xCC 中央空调(风管机)Wi-Fi线控器 +- T0xCD 空气能热水器 - T0xCE 新风机 - T0xCF 中央空调暖家 - T0xD9 复式洗衣机 diff --git a/custom_components/midea_auto_cloud/core/device.py b/custom_components/midea_auto_cloud/core/device.py index 0c47139..70f3246 100644 --- a/custom_components/midea_auto_cloud/core/device.py +++ b/custom_components/midea_auto_cloud/core/device.py @@ -295,19 +295,20 @@ class MiedaDevice(threading.Thread): break if calculate: calculate_str1 = \ - (f"{lvalue.replace('[', 'self._attributes[')} = " - f"{rvalue.replace('[', 'self._attributes[')}") \ - .replace("[", "[\"").replace("]", "\"]") + (f"{lvalue.replace('[', 'self._attributes[').replace("]", "\"]")} = " + f"{rvalue.replace('[', 'float(self._attributes[').replace(']', "\"])")}") \ + .replace("[", "[\"") calculate_str2 = \ - (f"{lvalue.replace('[', 'new_status[')} = " - f"{rvalue.replace('[', 'self._attributes[')}") \ - .replace("[", "[\"").replace("]", "\"]") + (f"{lvalue.replace('[', 'new_status[').replace("]", "\"]")} = " + f"{rvalue.replace('[', 'float(self._attributes[').replace(']', "\"])")}") \ + .replace("[", "[\"") try: exec(calculate_str1) exec(calculate_str2) - except Exception: + except Exception as e: + traceback.print_exc() MideaLogger.warning( - f"Calculation Error: {lvalue} = {rvalue}", self._device_id + f"Calculation Error: {lvalue} = {rvalue}, calculate_str1: {calculate_str1}, calculate_str2: {calculate_str2}", self._device_id ) self._update_all(new_status) return ParseMessageResult.SUCCESS diff --git a/custom_components/midea_auto_cloud/data_coordinator.py b/custom_components/midea_auto_cloud/data_coordinator.py index 43bd6ba..e317573 100644 --- a/custom_components/midea_auto_cloud/data_coordinator.py +++ b/custom_components/midea_auto_cloud/data_coordinator.py @@ -1,9 +1,11 @@ """Data coordinator for Midea Auto Cloud integration.""" import logging +import traceback from datetime import datetime, timedelta from typing import NamedTuple +from attr import attributes from homeassistant.config_entries import ConfigEntry from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.helpers.event import async_call_later @@ -184,14 +186,35 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]): async def async_set_attribute(self, attribute: str, value) -> None: """Set a device attribute.""" - # 云端控制:构造 control 与 status(携带当前状态作为上下文) - await self.device.set_attribute(attribute, value) - self.device.attributes[attribute] = value - self.mute_state_update_for_a_while() - self.async_update_listeners() + attributes = {} + attributes[attribute] = value + await self.async_set_attributes(attributes) async def async_set_attributes(self, attributes: dict) -> None: """Set multiple device attributes.""" + # 云端控制:构造 control 与 status(携带当前状态作为上下文) + for c in self.device._calculate_set: + lvalue = c.get("lvalue") + rvalue = c.get("rvalue") + if lvalue and rvalue: + calculate = False + for s, v in attributes.items(): + if rvalue.find(f"[{s}]") >= 0: + calculate = True + break + if calculate: + calculate_str1 = \ + (f"{lvalue.replace('[', 'attributes[').replace("]", "\"]")} = " + f"{rvalue.replace('[', 'float(attributes[').replace(']', "\"])")}") \ + .replace("[", "[\"") + try: + exec(calculate_str1) + except Exception as e: + traceback.print_exc() + MideaLogger.warning( + f"Calculation Error: {lvalue} = {rvalue}, calculate_str1: {calculate_str1}", + self._device_id + ) await self.device.set_attributes(attributes) self.device.attributes.update(attributes) self.mute_state_update_for_a_while() diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xCD.py b/custom_components/midea_auto_cloud/device_mapping/T0xCD.py new file mode 100644 index 0000000..e483c9c --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xCD.py @@ -0,0 +1,69 @@ +from homeassistant.const import Platform, UnitOfTemperature, UnitOfTime, PERCENTAGE, PRECISION_HALVES, PRECISION_WHOLE +from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass +from homeassistant.components.binary_sensor import BinarySensorDeviceClass +from homeassistant.components.switch import SwitchDeviceClass + +DEVICE_MAPPING = { + "default": { + "manufacturer": "美的", + "rationale": ["off", "on"], + "queries": [{}], + "calculate": { + "get": [ + { + "lvalue": "[temperature]", + "rvalue": "([set_temperature] - 106) / 74 * 37 + 38" + }, + { + "lvalue": "[cur_temperature]", + "rvalue": "([water_box_temperature] - 106) / 74 * 37 + 38" + } + ], + "set": [ + { + "lvalue": "[set_temperature]", + "rvalue": "([temperature] - 38) / 37 * 74 + 106" + }, + ] + }, + "centralized": [], + "entities": { + Platform.CLIMATE: { + "water_heater": { + "power": "power", + "hvac_modes": { + "off": {"power": "off"}, + "heat": {"power": "on"}, + }, + "preset_modes": { + "标准": {"mode": "standard"}, + "节能": {"mode": "energy"}, + "速热": {"mode": "compatibilizing"}, + }, + "target_temperature": "temperature", + "current_temperature": "cur_temperature", + "min_temp": 38, + "max_temp": 75, + "temperature_unit": UnitOfTemperature.CELSIUS, + "precision": PRECISION_WHOLE, + } + }, + Platform.SWITCH: { + "power": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "mute": { + "device_class": SwitchDeviceClass.SWITCH, + }, + }, + Platform.SENSOR: { + "cur_temperature": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + }, + } + } +} + diff --git a/custom_components/midea_auto_cloud/translations/en.json b/custom_components/midea_auto_cloud/translations/en.json index 1c86c29..7fd51f0 100644 --- a/custom_components/midea_auto_cloud/translations/en.json +++ b/custom_components/midea_auto_cloud/translations/en.json @@ -1562,6 +1562,9 @@ } }, "switch": { + "mute": { + "name": "Mute" + }, "b6_light": { "name": "Smoke Machine Light" }, diff --git a/custom_components/midea_auto_cloud/translations/zh-Hans.json b/custom_components/midea_auto_cloud/translations/zh-Hans.json index 7222b09..25df9fd 100644 --- a/custom_components/midea_auto_cloud/translations/zh-Hans.json +++ b/custom_components/midea_auto_cloud/translations/zh-Hans.json @@ -1566,6 +1566,9 @@ } }, "switch": { + "mute": { + "name": "静音" + }, "b6_light": { "name": "烟机灯" },