2 Commits

Author SHA1 Message Date
sususweet
7476d6ad1d feat: add support for T0xCD 2025-11-07 01:08:38 +08:00
sususweet
883369184b feat: fix support for T0xE2 2025-11-06 22:31:08 +08:00
8 changed files with 132 additions and 28 deletions

View File

@@ -34,6 +34,7 @@ Get devices from MSmartHome/Midea Meiju homes through the network and control th
- T0xB8 Smart Robot Vacuum - T0xB8 Smart Robot Vacuum
- T0xCA French Door Refrigerator - T0xCA French Door Refrigerator
- T0xCC Central Air Conditioning (Ducted) Wi-Fi Controller - T0xCC Central Air Conditioning (Ducted) Wi-Fi Controller
- T0xCD Air Energy Water Heater
- T0xCE Fresh Air System - T0xCE Fresh Air System
- T0xCF Central Air Conditioning Heating - T0xCF Central Air Conditioning Heating
- T0xD9 Twin Tub Washing Machine - T0xD9 Twin Tub Washing Machine

View File

@@ -34,6 +34,7 @@
- T0xB8 智能扫地机器人 - T0xB8 智能扫地机器人
- T0xCA 对开门冰箱 - T0xCA 对开门冰箱
- T0xCC 中央空调(风管机)Wi-Fi线控器 - T0xCC 中央空调(风管机)Wi-Fi线控器
- T0xCD 空气能热水器
- T0xCE 新风机 - T0xCE 新风机
- T0xCF 中央空调暖家 - T0xCF 中央空调暖家
- T0xD9 复式洗衣机 - T0xD9 复式洗衣机

View File

@@ -295,19 +295,20 @@ class MiedaDevice(threading.Thread):
break break
if calculate: if calculate:
calculate_str1 = \ calculate_str1 = \
(f"{lvalue.replace('[', 'self._attributes[')} = " (f"{lvalue.replace('[', 'self._attributes[').replace("]", "\"]")} = "
f"{rvalue.replace('[', 'self._attributes[')}") \ f"{rvalue.replace('[', 'float(self._attributes[').replace(']', "\"])")}") \
.replace("[", "[\"").replace("]", "\"]") .replace("[", "[\"")
calculate_str2 = \ calculate_str2 = \
(f"{lvalue.replace('[', 'new_status[')} = " (f"{lvalue.replace('[', 'new_status[').replace("]", "\"]")} = "
f"{rvalue.replace('[', 'self._attributes[')}") \ f"{rvalue.replace('[', 'float(self._attributes[').replace(']', "\"])")}") \
.replace("[", "[\"").replace("]", "\"]") .replace("[", "[\"")
try: try:
exec(calculate_str1) exec(calculate_str1)
exec(calculate_str2) exec(calculate_str2)
except Exception: except Exception as e:
traceback.print_exc()
MideaLogger.warning( 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) self._update_all(new_status)
return ParseMessageResult.SUCCESS return ParseMessageResult.SUCCESS

View File

@@ -1,9 +1,11 @@
"""Data coordinator for Midea Auto Cloud integration.""" """Data coordinator for Midea Auto Cloud integration."""
import logging import logging
import traceback
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import NamedTuple from typing import NamedTuple
from attr import attributes
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.event import async_call_later 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: async def async_set_attribute(self, attribute: str, value) -> None:
"""Set a device attribute.""" """Set a device attribute."""
# 云端控制:构造 control 与 status携带当前状态作为上下文 attributes = {}
await self.device.set_attribute(attribute, value) attributes[attribute] = value
self.device.attributes[attribute] = value await self.async_set_attributes(attributes)
self.mute_state_update_for_a_while()
self.async_update_listeners()
async def async_set_attributes(self, attributes: dict) -> None: async def async_set_attributes(self, attributes: dict) -> None:
"""Set multiple device attributes.""" """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) await self.device.set_attributes(attributes)
self.device.attributes.update(attributes) self.device.attributes.update(attributes)
self.mute_state_update_for_a_while() self.mute_state_update_for_a_while()

View File

@@ -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
},
},
}
}
}

View File

@@ -10,12 +10,23 @@ DEVICE_MAPPING = {
"queries": [{}], "queries": [{}],
"centralized": [], "centralized": [],
"entities": { "entities": {
Platform.NUMBER: {
"water_quality": {
"min": 0,
"max": 3,
"step": 1
},
"cur_temperature": {
"device_class": SensorDeviceClass.TEMPERATURE,
"state_class": SensorStateClass.MEASUREMENT,
}
},
Platform.CLIMATE: { Platform.CLIMATE: {
"water_heater": { "water_heater": {
"power": "power", "power": "power",
"hvac_modes": { "hvac_modes": {
"off": {"power": "off"}, "off": {"power": "off"},
"on": {"power": "on"}, "heat": {"power": "on"},
}, },
"target_temperature": "temperature", "target_temperature": "temperature",
"current_temperature": "cur_temperature", "current_temperature": "cur_temperature",
@@ -52,14 +63,6 @@ DEVICE_MAPPING = {
}, },
}, },
Platform.SELECT: { Platform.SELECT: {
"water_quality": {
"options": {
"0": {"water_quality": 0},
"1": {"water_quality": 1},
"2": {"water_quality": 2},
"3": {"water_quality": 3}
}
},
"func_select": { "func_select": {
"options": { "options": {
"low": {"func_select": "low"}, "low": {"func_select": "low"},

View File

@@ -553,9 +553,6 @@
"type_select": { "type_select": {
"name": "Type Select" "name": "Type Select"
}, },
"water_quality": {
"name": "Water Quality"
},
"work_status": { "work_status": {
"name": "Work Status" "name": "Work Status"
}, },
@@ -1510,6 +1507,9 @@
} }
}, },
"number": { "number": {
"water_quality": {
"name": "Water Quality"
},
"b6_lightness": { "b6_lightness": {
"name": "Smoke Machine Lightness" "name": "Smoke Machine Lightness"
}, },
@@ -1562,6 +1562,9 @@
} }
}, },
"switch": { "switch": {
"mute": {
"name": "Mute"
},
"b6_light": { "b6_light": {
"name": "Smoke Machine Light" "name": "Smoke Machine Light"
}, },

View File

@@ -560,9 +560,6 @@
"type_select": { "type_select": {
"name": "类型选择" "name": "类型选择"
}, },
"water_quality": {
"name": "水质"
},
"work_status": { "work_status": {
"name": "工作状态" "name": "工作状态"
}, },
@@ -1514,6 +1511,9 @@
} }
}, },
"number": { "number": {
"water_quality": {
"name": "水质"
},
"b6_lightness": { "b6_lightness": {
"name": "烟机照明" "name": "烟机照明"
}, },
@@ -1566,6 +1566,9 @@
} }
}, },
"switch": { "switch": {
"mute": {
"name": "静音"
},
"b6_light": { "b6_light": {
"name": "烟机灯" "name": "烟机灯"
}, },