fix: local buzzer control for T0xAC. Fix #102.

This commit is contained in:
sususweet
2026-02-04 23:33:42 +08:00
parent d3cfb57dc2
commit e3f0bf9dfc
4 changed files with 91 additions and 9 deletions

View File

@@ -308,6 +308,25 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
except Exception:
pass
# 提取并设置默认值
try:
default_values = {}
entities_cfg = (mapping.get("entities") or {})
for platform_cfg in entities_cfg.values():
if not isinstance(platform_cfg, dict):
continue
for entity_key, ecfg in platform_cfg.items():
if not isinstance(ecfg, dict):
continue
# 检查是否有 default_value 字段
if "default_value" in ecfg:
# 使用 entity_key 作为属性名,或者使用 attribute 字段
attr_name = ecfg.get("attribute", entity_key)
default_values[attr_name] = ecfg["default_value"]
device.set_default_values(default_values)
except Exception:
traceback.print_exc()
# 预置 attributes包含 centralized 里声明的所有键、entities 中使用到的所有属性键
try:
preset_keys = set(mapping.get("centralized", []))

View File

@@ -80,6 +80,7 @@ class MiedaDevice(threading.Thread):
self._centralized = []
self._calculate_get = []
self._calculate_set = []
self._default_values = {}
self._lua_runtime = MideaCodec(lua_file, device_type=self._attributes.get("device_type"), sn=sn, subtype=subtype) if lua_file is not None else None
self._cloud = cloud
@@ -142,6 +143,10 @@ class MiedaDevice(threading.Thread):
self._calculate_get = values_get if values_get else []
self._calculate_set = values_set if values_set else []
def set_default_values(self, default_values: dict):
"""设置属性的默认值"""
self._default_values = default_values or {}
def get_attribute(self, attribute):
return self._attributes.get(attribute)
@@ -417,6 +422,13 @@ class MiedaDevice(threading.Thread):
def _parse_cloud_message(self, status, update=True):
# MideaLogger.debug(f"Received: {decrypted}")
new_status = {}
# 对于有默认值的变量,在解析前先设置一次默认值
for attr, default_value in self._default_values.items():
# self._attributes[attr] = default_value
if attr not in self._attributes or self._attributes[attr] is None:
new_status[attr] = default_value
# 处理云端返回的状态,云端结果会覆盖默认值
for single in status.keys():
value = status.get(single)
if single not in self._attributes or self._attributes[single] != value:
@@ -439,15 +451,22 @@ class MiedaDevice(threading.Thread):
.replace("[", "[\"")
calculate_str2 = \
(f"{lvalue.replace('[', 'new_status[').replace("]", "\"]")} = "
f"{rvalue.replace('[', 'self._attributes[').replace(']', "\"]")}") \
f"{rvalue.replace('[', 'new_status[').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
)
try:
exec(calculate_str2)
except Exception as e:
traceback.print_exc()
MideaLogger.warning(
f"Calculation Error: {lvalue} = {rvalue}, calculate_str1: {calculate_str1}, calculate_str2: {calculate_str2}",
f"Calculation Error: {lvalue} = {rvalue}, calculate_str2: {calculate_str2}",
self._device_id
)
if update:

View File

@@ -193,6 +193,7 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
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")
@@ -215,7 +216,18 @@ class MideaDataUpdateCoordinator(DataUpdateCoordinator[MideaDeviceData]):
f"Calculation Error: {lvalue} = {rvalue}, calculate_str1: {calculate_str1}",
self._device_id
)
await self.device.set_attributes(attributes)
# 冻结有默认值的变量:从发送到云端的 attributes 中移除
attributes_to_send = {}
for attr, value in attributes.items():
# 如果该属性有默认值,则不发送到云端,只更新本地状态
if attr not in self.device._default_values:
attributes_to_send[attr] = value
# 只发送没有默认值的属性到云端
if attributes_to_send:
await self.device.set_attributes(attributes_to_send)
# 更新所有属性到本地状态(包括有默认值的变量)
self.device.attributes.update(attributes)
self.mute_state_update_for_a_while()
self.async_update_listeners()

View File

@@ -1128,9 +1128,17 @@ DEVICE_MAPPING = {
},
("22012369", "22040023", "22270043"): {
"rationale": ["off", "on"],
"queries": [{}, {"query_type": "run_status"}, {"query_type": "indoor_temperature"}],
"centralized": ["power", "temperature", "mode", "eco", "comfort_power_save",
"wind_swing_lr", "wind_swing_ud", "wind_speed", "ptc", "dry"],
"queries": [{}],
"centralized": ["buzzer"],
"calculate":{
"get": [
{
"lvalue": "[screen_display]",
"rvalue": "[screen_display_now]"
},
],
"set": []
},
"entities": {
Platform.CLIMATE: {
"thermostat": {
@@ -1176,6 +1184,14 @@ DEVICE_MAPPING = {
}
},
Platform.SWITCH: {
"buzzer": {
"device_class": SwitchDeviceClass.SWITCH,
"default_value": "on",
},
"screen_display": {
"device_class": SwitchDeviceClass.SWITCH,
"translation_key": "screen_close",
},
"dry": {
"device_class": SwitchDeviceClass.SWITCH,
},
@@ -1203,9 +1219,17 @@ DEVICE_MAPPING = {
},
"22251077": {
"rationale": ["off", "on"],
"queries": [{}, {"query_type": "run_status"}, {"query_type": "indoor_temperature"}],
"centralized": ["power", "temperature", "mode", "eco", "comfort_power_save",
"wind_swing_lr", "wind_swing_lr_under", "wind_swing_ud", "wind_speed", "ptc", "dry"],
"queries": [{}, {"query_type": "prevent_straight_wind"}],
"centralized": ["buzzer"],
"calculate":{
"get": [
{
"lvalue": "[screen_display]",
"rvalue": "[screen_display_now]"
},
],
"set": []
},
"entities": {
Platform.CLIMATE: {
"thermostat": {
@@ -1251,6 +1275,14 @@ DEVICE_MAPPING = {
}
},
Platform.SWITCH: {
"buzzer": {
"device_class": SwitchDeviceClass.SWITCH,
"default_value": "on",
},
"screen_display": {
"device_class": SwitchDeviceClass.SWITCH,
"translation_key": "screen_close",
},
"dry": {
"device_class": SwitchDeviceClass.SWITCH,
},