feat: add more device support

This commit is contained in:
sususweet
2025-09-24 18:20:58 +08:00
parent 2f88658fda
commit 39f88365e5
11 changed files with 161 additions and 23 deletions

View File

@@ -48,8 +48,8 @@ from .const import CONF_PASSWORD as CONF_PASSWORD_KEY, CONF_SERVER as CONF_SERVE
PLATFORMS: list[Platform] = [ PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR, Platform.BINARY_SENSOR,
# Platform.SENSOR, Platform.SENSOR,
# Platform.SWITCH, Platform.SWITCH,
Platform.CLIMATE, Platform.CLIMATE,
Platform.SELECT, Platform.SELECT,
Platform.WATER_HEATER, Platform.WATER_HEATER,
@@ -83,27 +83,24 @@ async def load_device_config(hass: HomeAssistant, device_type, sn8):
config_file = hass.config.path(f"{CONFIG_PATH}/{sn8}.json") config_file = hass.config.path(f"{CONFIG_PATH}/{sn8}.json")
raw = await hass.async_add_executor_job(_ensure_dir_and_load, config_dir, config_file) raw = await hass.async_add_executor_job(_ensure_dir_and_load, config_dir, config_file)
json_data = {} json_data = {}
if isinstance(raw, dict) and len(raw) > 0: # if isinstance(raw, dict) and len(raw) > 0:
# 兼容两种文件结构: # # 兼容两种文件结构:
# 1) { "<sn8>": { ...mapping... } } # # 1) { "<sn8>": { ...mapping... } }
# 2) { ...mapping... }(直接就是映射体) # # 2) { ...mapping... }(直接就是映射体)
if sn8 in raw: # if sn8 in raw:
json_data = raw.get(sn8) or {} # json_data = raw.get(sn8) or {}
else: # else:
# 如果像映射体(包含 entities/centralized 等关键字段),直接使用 # # 如果像映射体(包含 entities/centralized 等关键字段),直接使用
if any(k in raw for k in ["entities", "centralized", "queries", "manufacturer"]): # if any(k in raw for k in ["entities", "centralized", "queries", "manufacturer"]):
json_data = raw # json_data = raw
if not json_data: if not json_data:
device_path = f".device_mapping.{'T0x%02X' % device_type}" device_path = f".device_mapping.{'T0x%02X' % device_type}"
try: try:
mapping_module = import_module(device_path, __package__) mapping_module = import_module(device_path, __package__)
MideaLogger.warning(f"device_path: % {device_path}")
MideaLogger.warning(f"mapping_module.DEVICE_MAPPING: % {mapping_module.DEVICE_MAPPING}")
if sn8 in mapping_module.DEVICE_MAPPING.keys(): if sn8 in mapping_module.DEVICE_MAPPING.keys():
json_data = mapping_module.DEVICE_MAPPING[sn8] json_data = mapping_module.DEVICE_MAPPING[sn8]
elif "default" in mapping_module.DEVICE_MAPPING: elif "default" in mapping_module.DEVICE_MAPPING:
json_data = mapping_module.DEVICE_MAPPING["default"] json_data = mapping_module.DEVICE_MAPPING["default"]
MideaLogger.warning(f"json_data: % {json_data}")
except ModuleNotFoundError: except ModuleNotFoundError:
MideaLogger.warning(f"Can't load mapping file for type {'T0x%02X' % device_type}") MideaLogger.warning(f"Can't load mapping file for type {'T0x%02X' % device_type}")

View File

@@ -57,11 +57,11 @@ class MideaDeviceStatusSensorEntity(MideaEntity, BinarySensorEntity):
device.sn, device.sn,
device.sn8, device.sn8,
device.model, device.model,
entity_key
) )
self._device = device self._device = device
self._manufacturer = manufacturer self._manufacturer = manufacturer
self._rationale = rationale self._rationale = rationale
self._entity_key = entity_key
self._config = config self._config = config
@property @property
@@ -102,6 +102,7 @@ class MideaBinarySensorEntity(MideaEntity, BinarySensorEntity):
device.sn, device.sn,
device.sn8, device.sn8,
device.model, device.model,
entity_key
) )
self._device = device self._device = device
self._manufacturer = manufacturer self._manufacturer = manufacturer

View File

@@ -44,9 +44,6 @@ async def async_setup_entry(
coordinator = coordinator_map.get(device_id) coordinator = coordinator_map.get(device_id)
device = coordinator.device if coordinator else None device = coordinator.device if coordinator else None
MideaLogger.debug(f"entities_cfg={entities_cfg} ")
for entity_key, ecfg in entities_cfg.items(): for entity_key, ecfg in entities_cfg.items():
devs.append(MideaClimateEntity( devs.append(MideaClimateEntity(
coordinator, device, manufacturer, rationale, entity_key, ecfg coordinator, device, manufacturer, rationale, entity_key, ecfg
@@ -64,11 +61,11 @@ class MideaClimateEntity(MideaEntity, ClimateEntity):
device.sn, device.sn,
device.sn8, device.sn8,
device.model, device.model,
entity_key
) )
self._device = device self._device = device
self._manufacturer = manufacturer self._manufacturer = manufacturer
self._rationale = rationale self._rationale = rationale
self._entity_key = entity_key
self._config = config self._config = config
self._key_power = self._config.get("power") self._key_power = self._config.get("power")
self._key_hvac_modes = self._config.get("hvac_modes") self._key_hvac_modes = self._config.get("hvac_modes")

View File

@@ -268,7 +268,6 @@ class MeijuCloud(MideaCloud):
"query": {} "query": {}
} }
} }
MideaLogger.error(f"get_device_status: {data}")
if response := await self._api_request( if response := await self._api_request(
endpoint="/mjl/v1/device/status/lua/get", endpoint="/mjl/v1/device/status/lua/get",
data=data data=data

View File

@@ -0,0 +1,16 @@
from homeassistant.const import Platform, UnitOfTemperature, PRECISION_HALVES
from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass
# from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.switch import SwitchDeviceClass
DEVICE_MAPPING = {
"default": {
"rationale": ["off", "on"],
"queries": [{}],
"centralized": [],
"entities": {
Platform.SWITCH: {},
Platform.SENSOR: {}
}
}
}

View File

@@ -0,0 +1,108 @@
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.const import Platform, UnitOfTemperature, PRECISION_HALVES, UnitOfTime
from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass
from homeassistant.components.switch import SwitchDeviceClass
DEVICE_MAPPING = {
"default": {
"rationale": ["off", "on"],
"queries": [{}],
"centralized": [],
"entities": {
Platform.SWITCH: {
"airswitch": {
"device_class": SwitchDeviceClass.SWITCH,
},
"waterswitch": {
"device_class": SwitchDeviceClass.SWITCH,
},
"uvswitch": {
"device_class": SwitchDeviceClass.SWITCH,
},
"doorswitch": {
"device_class": SwitchDeviceClass.SWITCH,
},
"dryswitch": {
"device_class": SwitchDeviceClass.SWITCH,
},
"dry_step_switch": {
"device_class": SwitchDeviceClass.SWITCH,
}
},
Platform.BINARY_SENSOR: {
"air_status": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"water_lack": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"softwater_lack": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"wash_stage":{
"device_class": BinarySensorDeviceClass.RUNNING,
},
"bright_lack": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"diy_flag": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"diy_main_wash": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"diy_piao_wash": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
"diy_times": {
"device_class": BinarySensorDeviceClass.RUNNING,
},
},
Platform.SELECT: {
"work_status": {
"options": {
"power_off": {"work_status": "power_off" },
}
},
},
Platform.SENSOR: {
"bright": {
"name": "亮度",
"device_class": SensorDeviceClass.ILLUMINANCE,
"unit_of_measurement": "lx",
"state_class": SensorStateClass.MEASUREMENT
},
"temperature": {
"name": "温度",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit_of_measurement": UnitOfTemperature.CELSIUS,
"state_class": SensorStateClass.MEASUREMENT
},
"softwater": {
"name": "软水",
"device_class": SensorDeviceClass.TEMPERATURE,
"unit_of_measurement": UnitOfTemperature.CELSIUS,
"state_class": SensorStateClass.MEASUREMENT
},
"left_time": {
"name": "剩余时间",
"device_class": SensorDeviceClass.DURATION,
"unit_of_measurement": UnitOfTime.HOURS,
"state_class": SensorStateClass.MEASUREMENT
},
"air_set_hour": {
"name": "空调设置时间",
"device_class": SensorDeviceClass.DURATION,
"unit_of_measurement": UnitOfTime.HOURS,
"state_class": SensorStateClass.MEASUREMENT
},
"air_left_hour": {
"name": "空调剩余时间",
"device_class": SensorDeviceClass.DURATION,
"unit_of_measurement": UnitOfTime.HOURS,
"state_class": SensorStateClass.MEASUREMENT
},
}
}
}
}

View File

@@ -0,0 +1,16 @@
from homeassistant.const import Platform, UnitOfTemperature, PRECISION_HALVES
from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass
# from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.switch import SwitchDeviceClass
DEVICE_MAPPING = {
"default": {
"rationale": ["off", "on"],
"queries": [{}],
"centralized": [],
"entities": {
Platform.SWITCH: {},
Platform.SENSOR: {}
}
}
}

View File

@@ -26,6 +26,7 @@ class MideaEntity(Entity):
self._rationale = rationale_local self._rationale = rationale_local
if self._rationale is None: if self._rationale is None:
self._rationale = ["off", "on"] self._rationale = ["off", "on"]
self._attr_name = self._config.get("name")
self._attr_native_unit_of_measurement = self._config.get("unit_of_measurement") self._attr_native_unit_of_measurement = self._config.get("unit_of_measurement")
self._attr_device_class = self._config.get("device_class") self._attr_device_class = self._config.get("device_class")
self._attr_state_class = self._config.get("state_class") self._attr_state_class = self._config.get("state_class")

View File

@@ -29,12 +29,14 @@ class MideaEntity(CoordinatorEntity[MideaDataUpdateCoordinator], Entity):
sn: str, sn: str,
sn8: str, sn8: str,
model: str, model: str,
entity_key: str
) -> None: ) -> None:
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(coordinator) super().__init__(coordinator)
self._device_id = device_id self._device_id = device_id
self._device_name = device_name self._device_name = device_name
self._device_type = device_type self._device_type = device_type
self._entity_key = entity_key
self._sn = sn self._sn = sn
self._sn8 = sn8 self._sn8 = sn8
self._model = model self._model = model

View File

@@ -5,6 +5,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN from .const import DOMAIN
from .core.logger import MideaLogger
from .midea_entity import MideaEntity from .midea_entity import MideaEntity
from . import load_device_config from . import load_device_config
@@ -51,11 +52,11 @@ class MideaSensorEntity(MideaEntity, SensorEntity):
device.sn, device.sn,
device.sn8, device.sn8,
device.model, device.model,
entity_key
) )
self._device = device self._device = device
self._manufacturer = manufacturer self._manufacturer = manufacturer
self._rationale = rationale self._rationale = rationale
self._entity_key = entity_key
self._config = config self._config = config
@property @property

View File

@@ -52,11 +52,11 @@ class MideaSwitchEntity(MideaEntity, SwitchEntity):
device.sn, device.sn,
device.sn8, device.sn8,
device.model, device.model,
entity_key
) )
self._device = device self._device = device
self._manufacturer = manufacturer self._manufacturer = manufacturer
self._rationale = rationale self._rationale = rationale
self._entity_key = entity_key
self._config = config self._config = config
@property @property