From f99019bdcaeec747a5099ef81673ff2f14fc80d3 Mon Sep 17 00:00:00 2001 From: sususweet Date: Wed, 24 Sep 2025 23:31:31 +0800 Subject: [PATCH] feat: support more devices. --- README.md | 15 + .../midea_auto_cloud/__init__.py | 3 +- .../midea_auto_cloud/device_mapping/T0xB3.py | 199 +++++++++ .../midea_auto_cloud/device_mapping/T0xCE.py | 187 ++++++++ .../midea_auto_cloud/device_mapping/T0xCF.py | 168 ++++++++ .../midea_auto_cloud/device_mapping/T0xD9.py | 186 ++++++++ .../midea_auto_cloud/device_mapping/T0xDB.py | 399 ++++++++++++++++++ .../midea_auto_cloud/device_mapping/T0xDC.py | 153 +++++++ .../midea_auto_cloud/device_mapping/T0xFD.py | 158 +++++++ .../midea_auto_cloud/humidifier.py | 151 +++++++ .../midea_auto_cloud/manifest.json | 2 +- .../midea_auto_cloud/translations/en.json | 278 +++++++++++- .../translations/zh-Hans.json | 278 +++++++++++- img.png | Bin 0 -> 6899 bytes img_1.png | Bin 0 -> 41925 bytes 15 files changed, 2169 insertions(+), 8 deletions(-) create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xB3.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xCE.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xCF.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xD9.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xDB.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xDC.py create mode 100644 custom_components/midea_auto_cloud/device_mapping/T0xFD.py create mode 100644 custom_components/midea_auto_cloud/humidifier.py create mode 100644 img.png create mode 100644 img_1.png diff --git a/README.md b/README.md index 26bc522..3aafb53 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,28 @@ ## 目前支持的设备类型 - T0xAC 空调 +- T0xB3 消毒碗柜 - T0xB8 智能扫地机器人 +- T0xCE 新风机 +- T0xCF 中央空调暖家 +- T0xD9 复式洗衣机 +- T0xDB 滚筒洗衣机 +- T0xDC 干衣机 - T0xE1 洗碗机 - T0xEA 电饭锅 - T0xED 软水机 +- T0xFD 加湿器 欢迎合作开发添加更多设备支持。 +合作开发方法:添加本插件后,找到未能正确识别的设备,点击对应设备`传感器`分类下的`连通性`: + +![img.png](img.png) + +展开下面的`属性`卡片,把里面这些字段复制给我或随issue提交,等待适配就可以了。 + +![img_1.png](img_1.png) + ## 实体映射 映射文件位于`device_mapping`下, 每个大的品类一个映射文件,目前支持映射的实体类型如下: diff --git a/custom_components/midea_auto_cloud/__init__.py b/custom_components/midea_auto_cloud/__init__.py index ba02ced..4ecd64d 100644 --- a/custom_components/midea_auto_cloud/__init__.py +++ b/custom_components/midea_auto_cloud/__init__.py @@ -53,7 +53,8 @@ PLATFORMS: list[Platform] = [ Platform.CLIMATE, Platform.SELECT, Platform.WATER_HEATER, - Platform.FAN + Platform.FAN, + Platform.HUMIDIFIER ] diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xB3.py b/custom_components/midea_auto_cloud/device_mapping/T0xB3.py new file mode 100644 index 0000000..1653f68 --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xB3.py @@ -0,0 +1,199 @@ +from homeassistant.const import Platform, UnitOfTemperature, UnitOfTime +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": [ + "upstair_work_status", "downstair_work_status", "middlestair_work_status", + "upstair_mode", "downstair_mode", "middlestair_mode", + "upstair_temp", "downstair_temp", "middlestair_temp" + ], + "entities": { + Platform.BINARY_SENSOR: { + "door_middlestair": { + "device_class": BinarySensorDeviceClass.DOOR, + }, + "door_upstair": { + "device_class": BinarySensorDeviceClass.DOOR, + }, + "door_downstair": { + "device_class": BinarySensorDeviceClass.DOOR, + }, + "downstair_ispreheat": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "upstair_ispreheat": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "downstair_iscooling": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "upstair_iscooling": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "middlestair_ispreheat": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "middlestair_iscooling": { + "device_class": BinarySensorDeviceClass.RUNNING, + }, + "lock": { + "device_class": BinarySensorDeviceClass.LOCK, + }, + "is_error": { + "device_class": BinarySensorDeviceClass.PROBLEM, + }, + "uv_disinfect": { + "device_class": BinarySensorDeviceClass.RUNNING, + } + }, + Platform.SELECT: { + "upstair_work_status": { + "options": { + "power_off": {"upstair_work_status": "power_off"}, + "power_on": {"upstair_work_status": "power_on"}, + "working": {"upstair_work_status": "working"}, + "pause": {"upstair_work_status": "pause"}, + "finish": {"upstair_work_status": "finish"}, + "error": {"upstair_work_status": "error"} + } + }, + "downstair_work_status": { + "options": { + "power_off": {"downstair_work_status": "power_off"}, + "power_on": {"downstair_work_status": "power_on"}, + "working": {"downstair_work_status": "working"}, + "pause": {"downstair_work_status": "pause"}, + "finish": {"downstair_work_status": "finish"}, + "error": {"downstair_work_status": "error"} + } + }, + "middlestair_work_status": { + "options": { + "power_off": {"middlestair_work_status": "power_off"}, + "power_on": {"middlestair_work_status": "power_on"}, + "working": {"middlestair_work_status": "working"}, + "pause": {"middlestair_work_status": "pause"}, + "finish": {"middlestair_work_status": "finish"}, + "error": {"middlestair_work_status": "error"} + } + }, + "upstair_mode": { + "options": { + "off": {"upstair_mode": "0"}, + "bake": {"upstair_mode": "1"}, + "roast": {"upstair_mode": "2"}, + "grill": {"upstair_mode": "3"}, + "convection": {"upstair_mode": "4"}, + "defrost": {"upstair_mode": "5"} + } + }, + "downstair_mode": { + "options": { + "off": {"downstair_mode": "0"}, + "bake": {"downstair_mode": "1"}, + "roast": {"downstair_mode": "2"}, + "grill": {"downstair_mode": "3"}, + "convection": {"downstair_mode": "4"}, + "defrost": {"downstair_mode": "5"} + } + }, + "middlestair_mode": { + "options": { + "off": {"middlestair_mode": "0"}, + "bake": {"middlestair_mode": "1"}, + "roast": {"middlestair_mode": "2"}, + "grill": {"middlestair_mode": "3"}, + "convection": {"middlestair_mode": "4"}, + "defrost": {"middlestair_mode": "5"} + } + } + }, + Platform.SENSOR: { + "upstair_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "downstair_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "middlestair_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "upstair_hour": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "upstair_min": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "upstair_sec": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.SECONDS, + "state_class": SensorStateClass.MEASUREMENT + }, + "middlestair_hour": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "middlestair_min": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "middlestair_sec": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.SECONDS, + "state_class": SensorStateClass.MEASUREMENT + }, + "downstair_hour": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "downstair_min": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "downstair_sec": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.SECONDS, + "state_class": SensorStateClass.MEASUREMENT + }, + "order_hour": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "order_min": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "order_sec": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.SECONDS, + "state_class": SensorStateClass.MEASUREMENT + }, + "version": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xCE.py b/custom_components/midea_auto_cloud/device_mapping/T0xCE.py new file mode 100644 index 0000000..ecb8bdb --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xCE.py @@ -0,0 +1,187 @@ +from homeassistant.const import Platform, UnitOfTemperature, UnitOfTime +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": [ + "power", "mode_state", "fan_set", "room_temp_value", "humidity_set" + ], + "entities": { + Platform.SWITCH: { + "lock_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "esp_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "passby_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "preheat_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "remain_able": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "hcho_check_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "co2_check_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "function_set_link": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "function_set_sleep": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "function_set_energy_save": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "function_set_prheat": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "function_set_ultimate": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "clean_net_clean_flg": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "change_net_change_flg": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "condensation_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "humidity_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "preheat_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "esp_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "pm25_check_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "timer_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "freeze_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "humidity_check_enable": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.SELECT: { + "mode_state": { + "options": { + "passby": {"mode_state": "passby"}, + "auto": {"mode_state": "auto"}, + "manual": {"mode_state": "manual"}, + "sleep": {"mode_state": "sleep"}, + "energy_save": {"mode_state": "energy_save"}, + "ultimate": {"mode_state": "ultimate"} + } + }, + "fan_set": { + "options": { + "off": {"fan_set": "0"}, + "low": {"fan_set": "1"}, + "medium": {"fan_set": "2"}, + "high": {"fan_set": "3"}, + "auto": {"fan_set": "4"} + } + } + }, + Platform.SENSOR: { + "room_temp_value": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "clean_net_used_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "change_net_used_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "tvoc_value": { + "device_class": SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, + "unit_of_measurement": "mg/m³", + "state_class": SensorStateClass.MEASUREMENT + }, + "change_set_real_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "clean_set_real_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "humidity_set": { + "device_class": SensorDeviceClass.HUMIDITY, + "unit_of_measurement": "%", + "state_class": SensorStateClass.MEASUREMENT + }, + "room_aqi_value": { + "device_class": SensorDeviceClass.AQI, + "state_class": SensorStateClass.MEASUREMENT + }, + "change_net_set_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "clean_net_set_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.HOURS, + "state_class": SensorStateClass.MEASUREMENT + }, + "humidity_value": { + "device_class": SensorDeviceClass.HUMIDITY, + "unit_of_measurement": "%", + "state_class": SensorStateClass.MEASUREMENT + }, + "hcho_value": { + "device_class": SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, + "unit_of_measurement": "mg/m³", + "state_class": SensorStateClass.MEASUREMENT + }, + "pm25_value": { + "device_class": SensorDeviceClass.PM25, + "unit_of_measurement": "µg/m³", + "state_class": SensorStateClass.MEASUREMENT + }, + "co2_value": { + "device_class": SensorDeviceClass.CO2, + "unit_of_measurement": "ppm", + "state_class": SensorStateClass.MEASUREMENT + }, + "machine_type": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xCF.py b/custom_components/midea_auto_cloud/device_mapping/T0xCF.py new file mode 100644 index 0000000..330e6c3 --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xCF.py @@ -0,0 +1,168 @@ +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": [ + "power_state", "run_mode", "temp_set", "heat_enable", "cool_enable" + ], + "entities": { + Platform.CLIMATE: { + "thermostat": { + "power": "power_state", + "hvac_modes": { + "off": {"power_state": "off"}, + "heat": {"power_state": "on", "run_mode": "heat", "heat_enable": "on"}, + "cool": {"power_state": "on", "run_mode": "cool", "cool_enable": "on"}, + "auto": {"power_state": "on", "run_mode": "auto", "heat_enable": "on", "cool_enable": "on"} + }, + "target_temperature": "temp_set", + "current_temperature": "cur_temp", + "min_temp": 5, + "max_temp": 70, + "temperature_unit": UnitOfTemperature.CELSIUS, + "precision": PRECISION_HALVES, + } + }, + Platform.SWITCH: { + "freeze_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "heat_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "cool_enable": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "silence_set_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "time_set_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "silence_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "holiday_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "holiday_set_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "holiday_on_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "room_temp_ctrl": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "room_temp_set": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "comp_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "day_time_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "week_time_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "warn_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "defrost_state": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "pre_heat": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.SELECT: { + "run_mode": { + "options": { + "heat": {"run_mode": "heat"}, + "cool": {"run_mode": "cool"}, + "auto": {"run_mode": "auto"}, + "fan": {"run_mode": "fan"}, + "dry": {"run_mode": "dry"} + } + }, + "temp_type": { + "options": { + "water_temperature": {"temp_type": "water_temperature"}, + "room_temperature": {"temp_type": "room_temperature"}, + "outdoor_temperature": {"temp_type": "outdoor_temperature"} + } + } + }, + Platform.SENSOR: { + "cur_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "heat_max_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "heat_min_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "cool_max_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "cool_min_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "auto_max_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "auto_min_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "preheat_on_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "preheat_max_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "preheat_min_set_temp": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "temp_set": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xD9.py b/custom_components/midea_auto_cloud/device_mapping/T0xD9.py new file mode 100644 index 0000000..c14c7c2 --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xD9.py @@ -0,0 +1,186 @@ +from homeassistant.const import Platform, UnitOfElectricPotential, UnitOfTemperature, UnitOfTime +from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass +from homeassistant.components.binary_sensor import BinarySensorDeviceClass +from homeassistant.components.switch import SwitchDeviceClass + +DEVICE_MAPPING = { + "default": { + "rationale": [0, 1], + "calculate": { + "get": [ + { + "lvalue": "[remaining_time]", + "rvalue": "[db_remain_time]" + } + ], + "set": { + } + }, + "entities": { + Platform.SWITCH: { + "db_power": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_clean_notification": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_softener_needed": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_detergent_needed": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_nightly_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_baby_lock": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_light": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_steam_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_fast_clean_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "db_wash_dry_link": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.SELECT: { + "db_running_status": { + "options": { + "stop": {"db_running_status": "stop"}, + "start": {"db_running_status": "start"}, + "pause": {"db_running_status": "pause"}, + "finish": {"db_running_status": "finish"}, + "error": {"db_running_status": "error"} + } + }, + "db_program": { + "options": { + "fast_wash_30": {"db_program": "fast_wash_30"}, + "normal_wash": {"db_program": "normal_wash"}, + "heavy_wash": {"db_program": "heavy_wash"}, + "delicate_wash": {"db_program": "delicate_wash"}, + "quick_wash": {"db_program": "quick_wash"}, + "eco_wash": {"db_program": "eco_wash"} + } + }, + "db_water_level": { + "options": { + "low": {"db_water_level": "1"}, + "medium": {"db_water_level": "2"}, + "high": {"db_water_level": "3"}, + "extra_high": {"db_water_level": "4"} + } + }, + "db_temperature": { + "options": { + "cold": {"db_temperature": "1"}, + "warm": {"db_temperature": "2"}, + "hot": {"db_temperature": "3"}, + "extra_hot": {"db_temperature": "4"} + } + }, + "dehydration_speed": { + "options": { + "low": {"dehydration_speed": "1"}, + "medium": {"dehydration_speed": "2"}, + "high": {"dehydration_speed": "3"}, + "extra_high": {"dehydration_speed": "4"} + } + }, + "db_detergent": { + "options": { + "none": {"db_detergent": "1"}, + "little": {"db_detergent": "2"}, + "normal": {"db_detergent": "3"}, + "more": {"db_detergent": "4"} + } + }, + "db_softener": { + "options": { + "none": {"db_softener": "1"}, + "little": {"db_softener": "2"}, + "normal": {"db_softener": "3"}, + "more": {"db_softener": "4"} + } + }, + "db_position": { + "options": { + "position_1": {"db_position": "1"}, + "position_2": {"db_position": "2"}, + "position_3": {"db_position": "3"} + } + }, + "db_location": { + "options": { + "location_1": {"db_location": "1"}, + "location_2": {"db_location": "2"}, + "location_3": {"db_location": "3"} + } + } + }, + Platform.SENSOR: { + "db_remain_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_progress": { + "device_class": SensorDeviceClass.BATTERY, + "unit_of_measurement": "%", + "state_class": SensorStateClass.MEASUREMENT + }, + "db_error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_set_dewater_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_set_wash_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_device_software_version": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_rinse_count": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_wash_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_appointment_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_appointment": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_dehydration_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "db_cycle_memory": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xDB.py b/custom_components/midea_auto_cloud/device_mapping/T0xDB.py new file mode 100644 index 0000000..192e90d --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xDB.py @@ -0,0 +1,399 @@ +from homeassistant.const import Platform, UnitOfElectricPotential, UnitOfTemperature, UnitOfTime +from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass +from homeassistant.components.binary_sensor import BinarySensorDeviceClass +from homeassistant.components.switch import SwitchDeviceClass + +DEVICE_MAPPING = { + "default": { + "rationale": [0, 1], + "calculate": { + "get": [ + { + "lvalue": "[remaining_time]", + "rvalue": "[remain_time]" + } + ], + "set": { + } + }, + "entities": { + Platform.SWITCH: { + "power": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "softener_lack": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "detergent_lack": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "door_opened": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "bucket_water_overheating": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "memory": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "appointment": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "spray_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "old_speedy": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "nightly": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "down_light": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "easy_ironing": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "super_clean_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "intelligent_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "strong_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "silent": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "speedy": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "lock": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "flocks_switcher": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "fresh_anion_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "dry_weighing_already": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "keep_fresh_status": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "drying_tunnel_overheating": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "fast_clean_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "steam_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "beforehand_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "ai_flag": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "water_plus": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "soak": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "ultraviolet_lamp": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "eye_wash": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "microbubble": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "wind_dispel": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "cycle_memory": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.SELECT: { + "running_status": { + "options": { + "standby": {"running_status": "standby"}, + "running": {"running_status": "running"}, + "pause": {"running_status": "pause"}, + "finish": {"running_status": "finish"}, + "error": {"running_status": "error"} + } + }, + "db_dehydration_speed": { + "options": { + "low": {"db_dehydration_speed": "1"}, + "medium": {"db_dehydration_speed": "2"}, + "high": {"db_dehydration_speed": "3"}, + "extra_high": {"db_dehydration_speed": "4"} + } + }, + "mode": { + "options": { + "normal": {"mode": "normal"}, + "eco": {"mode": "eco"}, + "quick": {"mode": "quick"}, + "heavy": {"mode": "heavy"}, + "delicate": {"mode": "delicate"} + } + }, + "water_level": { + "options": { + "low": {"water_level": "low"}, + "medium": {"water_level": "medium"}, + "high": {"water_level": "high"}, + "extra_high": {"water_level": "extra_high"} + } + }, + "program": { + "options": { + "ssp": {"program": "ssp"}, + "cotton": {"program": "cotton"}, + "synthetic": {"program": "synthetic"}, + "wool": {"program": "wool"}, + "delicate": {"program": "delicate"}, + "quick": {"program": "quick"} + } + }, + "temperature": { + "options": { + "cold": {"temperature": "cold"}, + "warm": {"temperature": "warm"}, + "hot": {"temperature": "hot"}, + "extra_hot": {"temperature": "extra_hot"} + } + }, + "detergent_density": { + "options": { + "low": {"detergent_density": "low"}, + "medium": {"detergent_density": "medium"}, + "high": {"detergent_density": "high"}, + "extra_high": {"detergent_density": "extra_high"} + } + }, + "softener_density": { + "options": { + "low": {"softener_density": "low"}, + "medium": {"softener_density": "medium"}, + "high": {"softener_density": "high"}, + "extra_high": {"softener_density": "extra_high"} + } + }, + "detergent": { + "options": { + "none": {"detergent": "none"}, + "little": {"detergent": "little"}, + "normal": {"detergent": "normal"}, + "more": {"detergent": "more"} + } + }, + "softener": { + "options": { + "none": {"softener": "none"}, + "little": {"softener": "little"}, + "normal": {"softener": "normal"}, + "more": {"softener": "more"} + } + }, + "season": { + "options": { + "spring": {"season": "spring"}, + "summer": {"season": "summer"}, + "autumn": {"season": "autumn"}, + "winter": {"season": "winter"} + } + }, + "disinfectant": { + "options": { + "none": {"disinfectant": "none"}, + "light": {"disinfectant": "light"}, + "medium": {"disinfectant": "medium"}, + "strong": {"disinfectant": "strong"} + } + }, + "dirty_degree": { + "options": { + "light": {"dirty_degree": "light"}, + "medium": {"dirty_degree": "medium"}, + "heavy": {"dirty_degree": "heavy"}, + "extra_heavy": {"dirty_degree": "extra_heavy"} + } + }, + "stains": { + "options": { + "none": {"stains": "none"}, + "light": {"stains": "light"}, + "medium": {"stains": "medium"}, + "heavy": {"stains": "heavy"} + } + }, + "add_rinse": { + "options": { + "none": {"add_rinse": "none"}, + "one": {"add_rinse": "one"}, + "two": {"add_rinse": "two"}, + "three": {"add_rinse": "three"} + } + }, + "soak_count": { + "options": { + "none": {"soak_count": "none"}, + "one": {"soak_count": "one"}, + "two": {"soak_count": "two"}, + "three": {"soak_count": "three"} + } + } + }, + Platform.SENSOR: { + "wash_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "appointment_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "remain_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "dryer": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "remote_control_flag": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "progress": { + "device_class": SensorDeviceClass.BATTERY, + "unit_of_measurement": "%", + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_low": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_high": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai1": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai2": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai3": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai4": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai_time1": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "dehydration_time_value": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai_time3": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai_time4": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "customize_machine_cycle": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "detergent_global": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "softener_global": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "detergent_density_global": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "softener_density_global": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "fresh_air_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "flocks_remind_period": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "device_software_version": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "expert_step": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "flocks_wash_count": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "active_oxygen": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "dehydration_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "cloud_cycle_jiepai_time2": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "wash_time_value": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xDC.py b/custom_components/midea_auto_cloud/device_mapping/T0xDC.py new file mode 100644 index 0000000..5d6e5bd --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xDC.py @@ -0,0 +1,153 @@ +from homeassistant.const import Platform, UnitOfTime +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": [ + "power", "ai_switch", "light", "appointment", "prevent_wrinkle_switch", + "steam_switch", "damp_dry_signal", "eco_dry_switch", "bucket_clean_switch", + "water_box", "baby_lock", "remind_sound", "steam", "prevent_wrinkle", + "material", "sterilize", "dryness_level", "dry_temp", "intensity", "program" + ], + "entities": { + Platform.SWITCH: { + "ai_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "light": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "appointment": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "prevent_wrinkle_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "steam_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "damp_dry_signal": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "eco_dry_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "bucket_clean_switch": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "water_box": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "baby_lock": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "remind_sound": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "steam": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.BINARY_SENSOR: { + "door_warn": { + "device_class": BinarySensorDeviceClass.PROBLEM, + } + }, + Platform.SELECT: { + "prevent_wrinkle": { + "options": { + "off": {"prevent_wrinkle": "0"}, + "low": {"prevent_wrinkle": "1"}, + "medium": {"prevent_wrinkle": "2"}, + "high": {"prevent_wrinkle": "3"} + } + }, + "material": { + "options": { + "cotton": {"material": "0"}, + "synthetic": {"material": "1"}, + "wool": {"material": "2"}, + "delicate": {"material": "3"}, + "mixed": {"material": "4"} + } + }, + "sterilize": { + "options": { + "off": {"sterilize": "0"}, + "on": {"sterilize": "1"} + } + }, + "dryness_level": { + "options": { + "extra_dry": {"dryness_level": "0"}, + "dry": {"dryness_level": "1"}, + "normal": {"dryness_level": "2"}, + "damp": {"dryness_level": "3"} + } + }, + "dry_temp": { + "options": { + "low": {"dry_temp": "0"}, + "medium": {"dry_temp": "1"}, + "high": {"dry_temp": "2"}, + "extra_high": {"dry_temp": "3"} + } + }, + "intensity": { + "options": { + "low": {"intensity": "0"}, + "medium": {"intensity": "1"}, + "high": {"intensity": "2"} + } + }, + "program": { + "options": { + "mixed_wash": {"program": "mixed_wash"}, + "cotton": {"program": "cotton"}, + "synthetic": {"program": "synthetic"}, + "wool": {"program": "wool"}, + "delicate": {"program": "delicate"}, + "quick": {"program": "quick"}, + "eco": {"program": "eco"} + } + } + }, + Platform.SENSOR: { + "appointment_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "remain_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "progress": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "version": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "dry_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/device_mapping/T0xFD.py b/custom_components/midea_auto_cloud/device_mapping/T0xFD.py new file mode 100644 index 0000000..8422d2b --- /dev/null +++ b/custom_components/midea_auto_cloud/device_mapping/T0xFD.py @@ -0,0 +1,158 @@ +from homeassistant.const import Platform, UnitOfTemperature, UnitOfTime, PERCENTAGE +from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass +from homeassistant.components.binary_sensor import BinarySensorDeviceClass +from homeassistant.components.switch import SwitchDeviceClass +from homeassistant.components.humidifier import HumidifierDeviceClass + +DEVICE_MAPPING = { + "default": { + "rationale": ["off", "on"], + "queries": [{}], + "centralized": [ + "power", "disinfect_on_off", "netions_on_off", "airdry_on_off", + "wind_gear", "wind_speed", "light_color", "bright_led", + "humidity_mode", "tank_status", "humidity", "cur_humidity" + ], + "entities": { + Platform.SWITCH: { + "disinfect_on_off": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "netions_on_off": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "airdry_on_off": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "buzzer": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power_on_timer": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "power_off_timer": { + "device_class": SwitchDeviceClass.SWITCH, + }, + "display_on_off": { + "device_class": SwitchDeviceClass.SWITCH, + } + }, + Platform.BINARY_SENSOR: { + "add_water_flag": { + "device_class": BinarySensorDeviceClass.PROBLEM, + } + }, + Platform.HUMIDIFIER: { + "humidifier": { + "device_class": HumidifierDeviceClass.HUMIDIFIER, + "power": "power", + "target_humidity": "humidity", + "current_humidity": "cur_humidity", + "min_humidity": 30, + "max_humidity": 80, + "mode": "humidity_mode", + "modes": { + "manual": {"humidity_mode": "manual"}, + "auto": {"humidity_mode": "auto"}, + "sleep": {"humidity_mode": "sleep"}, + "baby": {"humidity_mode": "baby"} + } + } + }, + Platform.SELECT: { + "wind_gear": { + "options": { + "low": {"wind_gear": "low"}, + "medium": {"wind_gear": "medium"}, + "high": {"wind_gear": "high"}, + "auto": {"wind_gear": "auto"}, + "invalid": {"wind_gear": "invalid"} + } + }, + "wind_speed": { + "options": { + "low": {"wind_speed": "low"}, + "medium": {"wind_speed": "medium"}, + "high": {"wind_speed": "high"}, + "auto": {"wind_speed": "auto"} + } + }, + "light_color": { + "options": { + "warm": {"light_color": "warm"}, + "cool": {"light_color": "cool"}, + "white": {"light_color": "white"}, + "blue": {"light_color": "blue"}, + "green": {"light_color": "green"}, + "red": {"light_color": "red"}, + "off": {"light_color": "off"} + } + }, + "bright_led": { + "options": { + "light": {"bright_led": "light"}, + "dim": {"bright_led": "dim"}, + "off": {"bright_led": "off"} + } + }, + "tank_status": { + "options": { + "normal": {"tank_status": "0"}, + "low": {"tank_status": "1"}, + "empty": {"tank_status": "2"}, + "error": {"tank_status": "3"} + } + } + }, + Platform.SENSOR: { + "running_percent": { + "device_class": SensorDeviceClass.POWER_FACTOR, + "unit_of_measurement": PERCENTAGE, + "state_class": SensorStateClass.MEASUREMENT + }, + "error_code": { + "device_class": SensorDeviceClass.ENUM, + "state_class": SensorStateClass.MEASUREMENT + }, + "cur_temperature": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "sensor_battery": { + "device_class": SensorDeviceClass.BATTERY, + "unit_of_measurement": PERCENTAGE, + "state_class": SensorStateClass.MEASUREMENT + }, + "sensor_humidify": { + "device_class": SensorDeviceClass.HUMIDITY, + "unit_of_measurement": PERCENTAGE, + "state_class": SensorStateClass.MEASUREMENT + }, + "sensor_temperature": { + "device_class": SensorDeviceClass.TEMPERATURE, + "unit_of_measurement": UnitOfTemperature.CELSIUS, + "state_class": SensorStateClass.MEASUREMENT + }, + "air_dry_left_time": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "time_on": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + }, + "time_off": { + "device_class": SensorDeviceClass.DURATION, + "unit_of_measurement": UnitOfTime.MINUTES, + "state_class": SensorStateClass.MEASUREMENT + } + } + } + } +} diff --git a/custom_components/midea_auto_cloud/humidifier.py b/custom_components/midea_auto_cloud/humidifier.py new file mode 100644 index 0000000..dbd4483 --- /dev/null +++ b/custom_components/midea_auto_cloud/humidifier.py @@ -0,0 +1,151 @@ +from homeassistant.components.humidifier import ( + HumidifierEntity, + HumidifierDeviceClass +) +from homeassistant.const import Platform +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .midea_entity import MideaEntity +from . import load_device_config + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up humidifier entities for Midea devices.""" + account_bucket = hass.data.get(DOMAIN, {}).get("accounts", {}).get(config_entry.entry_id) + if not account_bucket: + async_add_entities([]) + return + device_list = account_bucket.get("device_list", {}) + coordinator_map = account_bucket.get("coordinator_map", {}) + + devs = [] + for device_id, info in device_list.items(): + device_type = info.get("type") + sn8 = info.get("sn8") + config = await load_device_config(hass, device_type, sn8) or {} + entities_cfg = (config.get("entities") or {}).get(Platform.HUMIDIFIER, {}) + manufacturer = config.get("manufacturer") + rationale = config.get("rationale") + coordinator = coordinator_map.get(device_id) + device = coordinator.device if coordinator else None + + for entity_key, ecfg in entities_cfg.items(): + devs.append(MideaHumidifierEntity( + coordinator, device, manufacturer, rationale, entity_key, ecfg + )) + async_add_entities(devs) + + +class MideaHumidifierEntity(MideaEntity, HumidifierEntity): + """Generic humidifier entity.""" + + def __init__(self, coordinator, device, manufacturer, rationale, entity_key, config): + super().__init__( + coordinator, + device.device_id, + device.device_name, + f"T0x{device.device_type:02X}", + device.sn, + device.sn8, + device.model, + entity_key, + device=device, + manufacturer=manufacturer, + rationale=rationale, + config=config, + ) + self._device = device + self._manufacturer = manufacturer + self._rationale = rationale + self._entity_key = entity_key + self._config = config + + @property + def device_class(self): + """Return the device class.""" + return self._config.get("device_class", HumidifierDeviceClass.HUMIDIFIER) + + @property + def is_on(self): + """Return if the humidifier is on.""" + power_key = self._config.get("power") + if power_key: + value = self.device_attributes.get(power_key) + if isinstance(value, bool): + return value + return value == 1 or value == "on" or value == "true" + return False + + @property + def target_humidity(self): + """Return the target humidity.""" + target_humidity_key = self._config.get("target_humidity") + if target_humidity_key: + return self.device_attributes.get(target_humidity_key, 0) + return 0 + + @property + def current_humidity(self): + """Return the current humidity.""" + current_humidity_key = self._config.get("current_humidity") + if current_humidity_key: + return self.device_attributes.get(current_humidity_key, 0) + return 0 + + @property + def min_humidity(self): + """Return the minimum humidity.""" + return self._config.get("min_humidity", 30) + + @property + def max_humidity(self): + """Return the maximum humidity.""" + return self._config.get("max_humidity", 80) + + @property + def mode(self): + """Return the current mode.""" + mode_key = self._config.get("mode") + if mode_key: + return self.device_attributes.get(mode_key, "manual") + return "manual" + + @property + def available_modes(self): + """Return the available modes.""" + modes = self._config.get("modes", {}) + return list(modes.keys()) + + async def async_turn_on(self, **kwargs): + """Turn the humidifier on.""" + power_key = self._config.get("power") + if power_key: + await self._device.set_attribute(power_key, True) + + async def async_turn_off(self, **kwargs): + """Turn the humidifier off.""" + power_key = self._config.get("power") + if power_key: + await self._device.set_attribute(power_key, False) + + async def async_set_humidity(self, humidity: int): + """Set the target humidity.""" + target_humidity_key = self._config.get("target_humidity") + if target_humidity_key: + await self._device.set_attribute(target_humidity_key, humidity) + + async def async_set_mode(self, mode: str): + """Set the mode.""" + mode_key = self._config.get("mode") + modes = self._config.get("modes", {}) + if mode_key and mode in modes: + mode_config = modes[mode] + for attr_key, attr_value in mode_config.items(): + await self._device.set_attribute(attr_key, attr_value) diff --git a/custom_components/midea_auto_cloud/manifest.json b/custom_components/midea_auto_cloud/manifest.json index 222a2b1..9394ff5 100644 --- a/custom_components/midea_auto_cloud/manifest.json +++ b/custom_components/midea_auto_cloud/manifest.json @@ -7,5 +7,5 @@ "iot_class": "cloud_push", "issue_tracker": "https://github.com/sususweet/midea-meiju-codec/issues", "requirements": [], - "version": "v0.0.3" + "version": "v0.0.4" } \ No newline at end of file diff --git a/custom_components/midea_auto_cloud/translations/en.json b/custom_components/midea_auto_cloud/translations/en.json index 50b092c..e60c0a8 100644 --- a/custom_components/midea_auto_cloud/translations/en.json +++ b/custom_components/midea_auto_cloud/translations/en.json @@ -118,7 +118,50 @@ "error_type": { "name": "Error Type" }, "control_type": { "name": "Control Type" }, "mode": { "name": "Mode" }, - "rice_type": { "name": "Rice Type" } + "rice_type": { "name": "Rice Type" }, + "db_running_status": { "name": "DB Running Status" }, + "db_program": { "name": "DB Program" }, + "db_water_level": { "name": "DB Water Level" }, + "db_temperature": { "name": "DB Temperature" }, + "db_dehydration_speed": { "name": "DB Dehydration Speed" }, + "db_detergent": { "name": "DB Detergent" }, + "db_softener": { "name": "DB Softener" }, + "db_position": { "name": "DB Position" }, + "db_location": { "name": "DB Location" }, + "running_status": { "name": "Running Status" }, + "mode": { "name": "Mode" }, + "program": { "name": "Program" }, + "detergent_density": { "name": "Detergent Density" }, + "softener_density": { "name": "Softener Density" }, + "season": { "name": "Season" }, + "disinfectant": { "name": "Disinfectant" }, + "dirty_degree": { "name": "Dirty Degree" }, + "stains": { "name": "Stains" }, + "add_rinse": { "name": "Add Rinse" }, + "soak_count": { "name": "Soak Count" }, + "run_mode": { "name": "Run Mode" }, + "temp_type": { "name": "Temp Type" }, + "mode_state": { "name": "Mode State" }, + "fan_set": { "name": "Fan Set" }, + "upstair_work_status": { "name": "Up Stair Work Status" }, + "downstair_work_status": { "name": "Down Stair Work Status" }, + "middlestair_work_status": { "name": "Middle Stair Work Status" }, + "upstair_mode": { "name": "Up Stair Mode" }, + "downstair_mode": { "name": "Down Stair Mode" }, + "middlestair_mode": { "name": "Middle Stair Mode" }, + "prevent_wrinkle": { "name": "Prevent Wrinkle" }, + "material": { "name": "Material" }, + "sterilize": { "name": "Sterilize" }, + "dryness_level": { "name": "Dryness Level" }, + "dry_temp": { "name": "Dry Temperature" }, + "intensity": { "name": "Intensity" }, + "program": { "name": "Program" }, + "wind_gear": { "name": "Wind Gear" }, + "wind_speed": { "name": "Wind Speed" }, + "light_color": { "name": "Light Color" }, + "bright_led": { "name": "Bright LED" }, + "humidity_mode": { "name": "Humidity Mode" }, + "tank_status": { "name": "Tank Status" } }, "sensor": { "bright": { "name": "Brightness" }, @@ -186,7 +229,115 @@ "warming_time": { "name": "Warming Time" }, "delay_time": { "name": "Delay Time" }, "indoor_temperature": { "name": "Indoor Temperature" }, - "outdoor_temperature": { "name": "Outdoor Temperature" } + "outdoor_temperature": { "name": "Outdoor Temperature" }, + "db_remain_time": { "name": "DB Remain Time" }, + "db_progress": { "name": "DB Progress" }, + "db_error_code": { "name": "DB Error Code" }, + "db_set_dewater_time": { "name": "DB Set Dewater Time" }, + "db_set_wash_time": { "name": "DB Set Wash Time" }, + "db_project_no": { "name": "DB Project No" }, + "db_device_software_version": { "name": "DB Device Software Version" }, + "db_rinse_count": { "name": "DB Rinse Count" }, + "db_wash_time": { "name": "DB Wash Time" }, + "db_appointment_time": { "name": "DB Appointment Time" }, + "db_appointment": { "name": "DB Appointment" }, + "db_dehydration_time": { "name": "DB Dehydration Time" }, + "db_cycle_memory": { "name": "DB Cycle Memory" }, + "dehydration_speed": { "name": "Dehydration Speed" }, + "wash_time": { "name": "Wash Time" }, + "appointment_time": { "name": "Appointment Time" }, + "remain_time": { "name": "Remain Time" }, + "project_no": { "name": "Project No" }, + "dryer": { "name": "Dryer" }, + "remote_control_flag": { "name": "Remote Control Flag" }, + "progress": { "name": "Progress" }, + "cloud_cycle_low": { "name": "Cloud Cycle Low" }, + "cloud_cycle_high": { "name": "Cloud Cycle High" }, + "cloud_cycle_jiepai1": { "name": "Cloud Cycle Jiepai1" }, + "cloud_cycle_jiepai2": { "name": "Cloud Cycle Jiepai2" }, + "cloud_cycle_jiepai3": { "name": "Cloud Cycle Jiepai3" }, + "cloud_cycle_jiepai4": { "name": "Cloud Cycle Jiepai4" }, + "cloud_cycle_jiepai_time1": { "name": "Cloud Cycle Jiepai Time1" }, + "dehydration_time_value": { "name": "Dehydration Time Value" }, + "cloud_cycle_jiepai_time3": { "name": "Cloud Cycle Jiepai Time3" }, + "cloud_cycle_jiepai_time4": { "name": "Cloud Cycle Jiepai Time4" }, + "customize_machine_cycle": { "name": "Customize Machine Cycle" }, + "detergent_global": { "name": "Detergent Global" }, + "softener_global": { "name": "Softener Global" }, + "detergent_density_global": { "name": "Detergent Density Global" }, + "softener_density_global": { "name": "Softener Density Global" }, + "fresh_air_time": { "name": "Fresh Air Time" }, + "flocks_remind_period": { "name": "Flocks Remind Period" }, + "device_software_version": { "name": "Device Software Version" }, + "expert_step": { "name": "Expert Step" }, + "error_code": { "name": "Error Code" }, + "flocks_wash_count": { "name": "Flocks Wash Count" }, + "active_oxygen": { "name": "Active Oxygen" }, + "version": { "name": "Version" }, + "dehydration_time": { "name": "Dehydration Time" }, + "cloud_cycle_jiepai_time2": { "name": "Cloud Cycle Jiepai Time2" }, + "wash_time_value": { "name": "Wash Time Value" }, + "cur_temp": { "name": "Current Temperature" }, + "error_code": { "name": "Error Code" }, + "heat_max_set_temp": { "name": "Heat Max Set Temp" }, + "heat_min_set_temp": { "name": "Heat Min Set Temp" }, + "cool_max_set_temp": { "name": "Cool Max Set Temp" }, + "cool_min_set_temp": { "name": "Cool Min Set Temp" }, + "auto_max_set_temp": { "name": "Auto Max Set Temp" }, + "auto_min_set_temp": { "name": "Auto Min Set Temp" }, + "preheat_on_set_temp": { "name": "Preheat On Set Temp" }, + "preheat_max_set_temp": { "name": "Preheat Max Set Temp" }, + "preheat_min_set_temp": { "name": "Preheat Min Set Temp" }, + "version": { "name": "Version" }, + "temp_set": { "name": "Temperature Set" }, + "room_temp_value": { "name": "Room Temperature Value" }, + "clean_net_used_time": { "name": "Clean Net Used Time" }, + "change_net_used_time": { "name": "Change Net Used Time" }, + "tvoc_value": { "name": "TVOC Value" }, + "change_set_real_time": { "name": "Change Set Real Time" }, + "clean_set_real_time": { "name": "Clean Set Real Time" }, + "humidity_set": { "name": "Humidity Set" }, + "room_aqi_value": { "name": "Room AQI Value" }, + "change_net_set_time": { "name": "Change Net Set Time" }, + "clean_net_set_time": { "name": "Clean Net Set Time" }, + "humidity_value": { "name": "Humidity Value" }, + "hcho_value": { "name": "HCHO Value" }, + "pm25_value": { "name": "PM2.5 Value" }, + "co2_value": { "name": "CO2 Value" }, + "machine_type": { "name": "Machine Type" }, + "upstair_temp": { "name": "Up Stair Temperature" }, + "downstair_temp": { "name": "Down Stair Temperature" }, + "middlestair_temp": { "name": "Middle Stair Temperature" }, + "upstair_hour": { "name": "Up Stair Hour" }, + "upstair_min": { "name": "Up Stair Min" }, + "upstair_sec": { "name": "Up Stair Sec" }, + "middlestair_hour": { "name": "Middle Stair Hour" }, + "middlestair_min": { "name": "Middle Stair Min" }, + "middlestair_sec": { "name": "Middle Stair Sec" }, + "downstair_hour": { "name": "Down Stair Hour" }, + "downstair_min": { "name": "Down Stair Min" }, + "downstair_sec": { "name": "Down Stair Sec" }, + "order_hour": { "name": "Order Hour" }, + "order_min": { "name": "Order Min" }, + "order_sec": { "name": "Order Sec" }, + "appointment_time": { "name": "Appointment Time" }, + "project_no": { "name": "Project Number" }, + "remain_time": { "name": "Remain Time" }, + "progress": { "name": "Progress" }, + "version": { "name": "Version" }, + "error_code": { "name": "Error Code" }, + "dry_time": { "name": "Dry Time" }, + "version": { "name": "Version" }, + "time_off": { "name": "Time Off" }, + "humidity": { "name": "Humidity" }, + "cur_temperature": { "name": "Current Temperature" }, + "cur_humidity": { "name": "Current Humidity" }, + "time_on": { "name": "Time On" }, + "air_dry_left_time": { "name": "Air Dry Left Time" }, + "sensor_battery": { "name": "Sensor Battery" }, + "running_percent": { "name": "Running Percent" }, + "sensor_humidify": { "name": "Sensor Humidify" }, + "sensor_temperature": { "name": "Sensor Temperature" } }, "binary_sensor": { "air_status": { "name": "Air Running" }, @@ -210,6 +361,9 @@ "climate": { "thermostat": { "name": "Thermostat" } }, + "humidifier": { + "humidifier": { "name": "Humidifier" } + }, "switch": { "airswitch": { "name": "AC Switch" }, "waterswitch": { "name": "Water Switch" }, @@ -236,7 +390,125 @@ "pre_regeneration": { "name": "Pre Regeneration" }, "dry": { "name": "Dry" }, "prevent_straight_wind": { "name": "Prevent Straight Wind" }, - "aux_heat": { "name": "Aux Heat" } + "aux_heat": { "name": "Aux Heat" }, + "db_power": { "name": "DB Power" }, + "db_clean_notification": { "name": "DB Clean Notification" }, + "db_softener_needed": { "name": "DB Softener Needed" }, + "db_detergent_needed": { "name": "DB Detergent Needed" }, + "db_nightly_wash": { "name": "DB Nightly Wash" }, + "db_baby_lock": { "name": "DB Baby Lock" }, + "db_light": { "name": "DB Light" }, + "db_steam_wash": { "name": "DB Steam Wash" }, + "db_fast_clean_wash": { "name": "DB Fast Clean Wash" }, + "db_wash_dry_link": { "name": "DB Wash Dry Link" }, + "power": { "name": "Power" }, + "softener_lack": { "name": "Softener Lack" }, + "detergent_lack": { "name": "Detergent Lack" }, + "door_opened": { "name": "Door Opened" }, + "bucket_water_overheating": { "name": "Bucket Water Overheating" }, + "memory": { "name": "Memory" }, + "appointment": { "name": "Appointment" }, + "spray_wash": { "name": "Spray Wash" }, + "old_speedy": { "name": "Old Speedy" }, + "nightly": { "name": "Nightly" }, + "down_light": { "name": "Down Light" }, + "easy_ironing": { "name": "Easy Ironing" }, + "super_clean_wash": { "name": "Super Clean Wash" }, + "intelligent_wash": { "name": "Intelligent Wash" }, + "strong_wash": { "name": "Strong Wash" }, + "silent": { "name": "Silent" }, + "speedy": { "name": "Speedy" }, + "lock": { "name": "Lock" }, + "flocks_switcher": { "name": "Flocks Switcher" }, + "fresh_anion_switch": { "name": "Fresh Anion Switch" }, + "dry_weighing_already": { "name": "Dry Weighing Already" }, + "keep_fresh_status": { "name": "Keep Fresh Status" }, + "drying_tunnel_overheating": { "name": "Drying Tunnel Overheating" }, + "fast_clean_wash": { "name": "Fast Clean Wash" }, + "steam_wash": { "name": "Steam Wash" }, + "beforehand_wash": { "name": "Beforehand Wash" }, + "ai_flag": { "name": "AI Flag" }, + "water_plus": { "name": "Water Plus" }, + "soak": { "name": "Soak" }, + "ultraviolet_lamp": { "name": "Ultraviolet Lamp" }, + "eye_wash": { "name": "Eye Wash" }, + "microbubble": { "name": "Microbubble" }, + "wind_dispel": { "name": "Wind Dispel" }, + "cycle_memory": { "name": "Cycle Memory" }, + "freeze_state": { "name": "Freeze State" }, + "power_state": { "name": "Power State" }, + "heat_enable": { "name": "Heat Enable" }, + "cool_enable": { "name": "Cool Enable" }, + "silence_set_state": { "name": "Silence Set State" }, + "time_set_state": { "name": "Time Set State" }, + "silence_state": { "name": "Silence State" }, + "holiday_state": { "name": "Holiday State" }, + "holiday_set_state": { "name": "Holiday Set State" }, + "holiday_on_state": { "name": "Holiday On State" }, + "room_temp_ctrl": { "name": "Room Temp Ctrl" }, + "room_temp_set": { "name": "Room Temp Set" }, + "comp_state": { "name": "Comp State" }, + "day_time_state": { "name": "Day Time State" }, + "week_time_state": { "name": "Week Time State" }, + "warn_state": { "name": "Warn State" }, + "defrost_state": { "name": "Defrost State" }, + "pre_heat": { "name": "Pre Heat" }, + "lock_state": { "name": "Lock State" }, + "esp_state": { "name": "ESP State" }, + "passby_enable": { "name": "Passby Enable" }, + "preheat_enable": { "name": "Preheat Enable" }, + "remain_able": { "name": "Remain Able" }, + "hcho_check_enable": { "name": "HCHO Check Enable" }, + "co2_check_enable": { "name": "CO2 Check Enable" }, + "function_set_link": { "name": "Function Set Link" }, + "function_set_sleep": { "name": "Function Set Sleep" }, + "function_set_energy_save": { "name": "Function Set Energy Save" }, + "function_set_prheat": { "name": "Function Set Preheat" }, + "function_set_ultimate": { "name": "Function Set Ultimate" }, + "clean_net_clean_flg": { "name": "Clean Net Clean Flag" }, + "change_net_change_flg": { "name": "Change Net Change Flag" }, + "condensation_state": { "name": "Condensation State" }, + "humidity_state": { "name": "Humidity State" }, + "preheat_state": { "name": "Preheat State" }, + "esp_enable": { "name": "ESP Enable" }, + "pm25_check_enable": { "name": "PM2.5 Check Enable" }, + "timer_state": { "name": "Timer State" }, + "humidity_check_enable": { "name": "Humidity Check Enable" }, + "door_middlestair": { "name": "Door Middle Stair" }, + "door_upstair": { "name": "Door Up Stair" }, + "door_downstair": { "name": "Door Down Stair" }, + "downstair_ispreheat": { "name": "Down Stair Is Preheat" }, + "upstair_ispreheat": { "name": "Up Stair Is Preheat" }, + "downstair_iscooling": { "name": "Down Stair Is Cooling" }, + "upstair_iscooling": { "name": "Up Stair Is Cooling" }, + "middlestair_ispreheat": { "name": "Middle Stair Is Preheat" }, + "middlestair_iscooling": { "name": "Middle Stair Is Cooling" }, + "lock": { "name": "Lock" }, + "is_error": { "name": "Is Error" }, + "uv_disinfect": { "name": "UV Disinfect" }, + "ai_switch": { "name": "AI Switch" }, + "light": { "name": "Light" }, + "appointment": { "name": "Appointment" }, + "prevent_wrinkle_switch": { "name": "Prevent Wrinkle Switch" }, + "steam_switch": { "name": "Steam Switch" }, + "damp_dry_signal": { "name": "Damp Dry Signal" }, + "eco_dry_switch": { "name": "Eco Dry Switch" }, + "bucket_clean_switch": { "name": "Bucket Clean Switch" }, + "water_box": { "name": "Water Box" }, + "baby_lock": { "name": "Baby Lock" }, + "remind_sound": { "name": "Remind Sound" }, + "steam": { "name": "Steam" }, + "power": { "name": "Power" }, + "door_warn": { "name": "Door Warning" }, + "disinfect_on_off": { "name": "Disinfect On Off" }, + "power_on_timer": { "name": "Power On Timer" }, + "power": { "name": "Power" }, + "buzzer": { "name": "Buzzer" }, + "power_off_timer": { "name": "Power Off Timer" }, + "display_on_off": { "name": "Display On Off" }, + "netions_on_off": { "name": "Net Ions On Off" }, + "airdry_on_off": { "name": "Air Dry On Off" }, + "add_water_flag": { "name": "Add Water Flag" } } } } \ No newline at end of file diff --git a/custom_components/midea_auto_cloud/translations/zh-Hans.json b/custom_components/midea_auto_cloud/translations/zh-Hans.json index ac7af27..0c69168 100644 --- a/custom_components/midea_auto_cloud/translations/zh-Hans.json +++ b/custom_components/midea_auto_cloud/translations/zh-Hans.json @@ -118,7 +118,50 @@ "error_type": { "name": "错误类型" }, "control_type": { "name": "控制类型" }, "mode": { "name": "模式" }, - "rice_type": { "name": "米种类型" } + "rice_type": { "name": "米种类型" }, + "db_running_status": { "name": "运行状态" }, + "db_program": { "name": "洗涤程序" }, + "db_water_level": { "name": "水位" }, + "db_temperature": { "name": "温度" }, + "db_dehydration_speed": { "name": "脱水转速" }, + "db_detergent": { "name": "洗涤剂" }, + "db_softener": { "name": "柔顺剂" }, + "db_position": { "name": "位置" }, + "db_location": { "name": "地点" }, + "running_status": { "name": "运行状态" }, + "mode": { "name": "模式" }, + "program": { "name": "程序" }, + "detergent_density": { "name": "洗涤剂浓度" }, + "softener_density": { "name": "柔顺剂浓度" }, + "season": { "name": "季节" }, + "disinfectant": { "name": "消毒剂" }, + "dirty_degree": { "name": "脏污程度" }, + "stains": { "name": "污渍" }, + "add_rinse": { "name": "加漂洗" }, + "soak_count": { "name": "浸泡次数" }, + "run_mode": { "name": "运行模式" }, + "temp_type": { "name": "温度类型" }, + "mode_state": { "name": "模式状态" }, + "fan_set": { "name": "风扇设置" }, + "upstair_work_status": { "name": "上层工作状态" }, + "downstair_work_status": { "name": "下层工作状态" }, + "middlestair_work_status": { "name": "中层工作状态" }, + "upstair_mode": { "name": "上层模式" }, + "downstair_mode": { "name": "下层模式" }, + "middlestair_mode": { "name": "中层模式" }, + "prevent_wrinkle": { "name": "防皱" }, + "material": { "name": "材质" }, + "sterilize": { "name": "杀菌" }, + "dryness_level": { "name": "干燥程度" }, + "dry_temp": { "name": "烘干温度" }, + "intensity": { "name": "强度" }, + "program": { "name": "程序" }, + "wind_gear": { "name": "风档" }, + "wind_speed": { "name": "风速" }, + "light_color": { "name": "灯光颜色" }, + "bright_led": { "name": "亮度LED" }, + "humidity_mode": { "name": "湿度模式" }, + "tank_status": { "name": "水箱状态" } }, "sensor": { "bright": { "name": "亮度" }, @@ -186,7 +229,115 @@ "warming_time": { "name": "保温时间" }, "delay_time": { "name": "预约时间" }, "indoor_temperature": { "name": "室内温度" }, - "outdoor_temperature": { "name": "室外温度" } + "outdoor_temperature": { "name": "室外温度" }, + "db_remain_time": { "name": "剩余时间" }, + "db_progress": { "name": "进度" }, + "db_error_code": { "name": "错误代码" }, + "db_set_dewater_time": { "name": "设置脱水时间" }, + "db_set_wash_time": { "name": "设置洗涤时间" }, + "db_project_no": { "name": "项目编号" }, + "db_device_software_version": { "name": "设备软件版本" }, + "db_rinse_count": { "name": "漂洗次数" }, + "db_wash_time": { "name": "洗涤时间" }, + "db_appointment_time": { "name": "预约时间" }, + "db_appointment": { "name": "预约" }, + "db_dehydration_time": { "name": "脱水时间" }, + "db_cycle_memory": { "name": "循环记忆" }, + "dehydration_speed": { "name": "脱水转速" }, + "wash_time": { "name": "洗涤时间" }, + "appointment_time": { "name": "预约时间" }, + "remain_time": { "name": "剩余时间" }, + "project_no": { "name": "项目编号" }, + "dryer": { "name": "烘干机" }, + "remote_control_flag": { "name": "遥控标志" }, + "progress": { "name": "进度" }, + "cloud_cycle_low": { "name": "云循环低" }, + "cloud_cycle_high": { "name": "云循环高" }, + "cloud_cycle_jiepai1": { "name": "云循环节拍1" }, + "cloud_cycle_jiepai2": { "name": "云循环节拍2" }, + "cloud_cycle_jiepai3": { "name": "云循环节拍3" }, + "cloud_cycle_jiepai4": { "name": "云循环节拍4" }, + "cloud_cycle_jiepai_time1": { "name": "云循环节拍时间1" }, + "dehydration_time_value": { "name": "脱水时间值" }, + "cloud_cycle_jiepai_time3": { "name": "云循环节拍时间3" }, + "cloud_cycle_jiepai_time4": { "name": "云循环节拍时间4" }, + "customize_machine_cycle": { "name": "自定义机器循环" }, + "detergent_global": { "name": "洗涤剂全局" }, + "softener_global": { "name": "柔顺剂全局" }, + "detergent_density_global": { "name": "洗涤剂浓度全局" }, + "softener_density_global": { "name": "柔顺剂浓度全局" }, + "fresh_air_time": { "name": "新风时间" }, + "flocks_remind_period": { "name": "毛绒提醒周期" }, + "device_software_version": { "name": "设备软件版本" }, + "expert_step": { "name": "专家步骤" }, + "error_code": { "name": "错误代码" }, + "flocks_wash_count": { "name": "毛绒洗涤次数" }, + "active_oxygen": { "name": "活性氧" }, + "version": { "name": "版本" }, + "dehydration_time": { "name": "脱水时间" }, + "cloud_cycle_jiepai_time2": { "name": "云循环节拍时间2" }, + "wash_time_value": { "name": "洗涤时间值" }, + "cur_temp": { "name": "当前温度" }, + "error_code": { "name": "错误代码" }, + "heat_max_set_temp": { "name": "制热最大设定温度" }, + "heat_min_set_temp": { "name": "制热最小设定温度" }, + "cool_max_set_temp": { "name": "制冷最大设定温度" }, + "cool_min_set_temp": { "name": "制冷最小设定温度" }, + "auto_max_set_temp": { "name": "自动最大设定温度" }, + "auto_min_set_temp": { "name": "自动最小设定温度" }, + "preheat_on_set_temp": { "name": "预热开启设定温度" }, + "preheat_max_set_temp": { "name": "预热最大设定温度" }, + "preheat_min_set_temp": { "name": "预热最小设定温度" }, + "version": { "name": "版本" }, + "temp_set": { "name": "设定温度" }, + "room_temp_value": { "name": "室温值" }, + "clean_net_used_time": { "name": "清洁网使用时间" }, + "change_net_used_time": { "name": "更换网使用时间" }, + "tvoc_value": { "name": "TVOC值" }, + "change_set_real_time": { "name": "更换设定实际时间" }, + "clean_set_real_time": { "name": "清洁设定实际时间" }, + "humidity_set": { "name": "湿度设置" }, + "room_aqi_value": { "name": "室内AQI值" }, + "change_net_set_time": { "name": "更换网设定时间" }, + "clean_net_set_time": { "name": "清洁网设定时间" }, + "humidity_value": { "name": "湿度值" }, + "hcho_value": { "name": "甲醛值" }, + "pm25_value": { "name": "PM2.5值" }, + "co2_value": { "name": "CO2值" }, + "machine_type": { "name": "机器类型" }, + "upstair_temp": { "name": "上层温度" }, + "downstair_temp": { "name": "下层温度" }, + "middlestair_temp": { "name": "中层温度" }, + "upstair_hour": { "name": "上层小时" }, + "upstair_min": { "name": "上层分钟" }, + "upstair_sec": { "name": "上层秒" }, + "middlestair_hour": { "name": "中层小时" }, + "middlestair_min": { "name": "中层分钟" }, + "middlestair_sec": { "name": "中层秒" }, + "downstair_hour": { "name": "下层小时" }, + "downstair_min": { "name": "下层分钟" }, + "downstair_sec": { "name": "下层秒" }, + "order_hour": { "name": "预约小时" }, + "order_min": { "name": "预约分钟" }, + "order_sec": { "name": "预约秒" }, + "appointment_time": { "name": "预约时间" }, + "project_no": { "name": "项目编号" }, + "remain_time": { "name": "剩余时间" }, + "progress": { "name": "进度" }, + "version": { "name": "版本" }, + "error_code": { "name": "错误代码" }, + "dry_time": { "name": "烘干时间" }, + "version": { "name": "版本" }, + "time_off": { "name": "关机时间" }, + "humidity": { "name": "湿度" }, + "cur_temperature": { "name": "当前温度" }, + "cur_humidity": { "name": "当前湿度" }, + "time_on": { "name": "开机时间" }, + "air_dry_left_time": { "name": "风干剩余时间" }, + "sensor_battery": { "name": "传感器电池" }, + "running_percent": { "name": "运行百分比" }, + "sensor_humidify": { "name": "传感器湿度" }, + "sensor_temperature": { "name": "传感器温度" } }, "binary_sensor": { "air_status": { "name": "空气运行" }, @@ -210,6 +361,9 @@ "climate": { "thermostat": { "name": "温控器" } }, + "humidifier": { + "humidifier": { "name": "加湿器" } + }, "switch": { "airswitch": { "name": "空调开关" }, "waterswitch": { "name": "热水开关" }, @@ -236,7 +390,125 @@ "pre_regeneration": { "name": "预再生" }, "dry": { "name": "干燥" }, "prevent_straight_wind": { "name": "防直吹" }, - "aux_heat": { "name": "电辅热" } + "aux_heat": { "name": "电辅热" }, + "db_power": { "name": "洗衣机电源" }, + "db_clean_notification": { "name": "清洁提醒" }, + "db_softener_needed": { "name": "需要柔顺剂" }, + "db_detergent_needed": { "name": "需要洗涤剂" }, + "db_nightly_wash": { "name": "夜间洗涤" }, + "db_baby_lock": { "name": "童锁" }, + "db_light": { "name": "照明" }, + "db_steam_wash": { "name": "蒸汽洗涤" }, + "db_fast_clean_wash": { "name": "快速清洁洗涤" }, + "db_wash_dry_link": { "name": "洗烘联动" }, + "power": { "name": "电源" }, + "softener_lack": { "name": "柔顺剂不足" }, + "detergent_lack": { "name": "洗涤剂不足" }, + "door_opened": { "name": "门已打开" }, + "bucket_water_overheating": { "name": "桶内水温过热" }, + "memory": { "name": "记忆" }, + "appointment": { "name": "预约" }, + "spray_wash": { "name": "喷淋洗涤" }, + "old_speedy": { "name": "老式快速" }, + "nightly": { "name": "夜间" }, + "down_light": { "name": "下灯" }, + "easy_ironing": { "name": "易熨烫" }, + "super_clean_wash": { "name": "超净洗涤" }, + "intelligent_wash": { "name": "智能洗涤" }, + "strong_wash": { "name": "强力洗涤" }, + "silent": { "name": "静音" }, + "speedy": { "name": "快速" }, + "lock": { "name": "锁定" }, + "flocks_switcher": { "name": "毛绒切换器" }, + "fresh_anion_switch": { "name": "负离子开关" }, + "dry_weighing_already": { "name": "已称重" }, + "keep_fresh_status": { "name": "保持新鲜状态" }, + "drying_tunnel_overheating": { "name": "烘干通道过热" }, + "fast_clean_wash": { "name": "快速清洁洗涤" }, + "steam_wash": { "name": "蒸汽洗涤" }, + "beforehand_wash": { "name": "预洗" }, + "ai_flag": { "name": "AI标志" }, + "water_plus": { "name": "加水" }, + "soak": { "name": "浸泡" }, + "ultraviolet_lamp": { "name": "紫外线灯" }, + "eye_wash": { "name": "护眼洗涤" }, + "microbubble": { "name": "微气泡" }, + "wind_dispel": { "name": "风干" }, + "cycle_memory": { "name": "循环记忆" }, + "freeze_state": { "name": "防冻状态" }, + "power_state": { "name": "电源状态" }, + "heat_enable": { "name": "制热启用" }, + "cool_enable": { "name": "制冷启用" }, + "silence_set_state": { "name": "静音设置状态" }, + "time_set_state": { "name": "时间设置状态" }, + "silence_state": { "name": "静音状态" }, + "holiday_state": { "name": "假日状态" }, + "holiday_set_state": { "name": "假日设置状态" }, + "holiday_on_state": { "name": "假日开启状态" }, + "room_temp_ctrl": { "name": "室温控制" }, + "room_temp_set": { "name": "室温设置" }, + "comp_state": { "name": "压缩机状态" }, + "day_time_state": { "name": "日间状态" }, + "week_time_state": { "name": "周时间状态" }, + "warn_state": { "name": "警告状态" }, + "defrost_state": { "name": "除霜状态" }, + "pre_heat": { "name": "预热" }, + "lock_state": { "name": "锁定状态" }, + "esp_state": { "name": "ESP状态" }, + "passby_enable": { "name": "旁通启用" }, + "preheat_enable": { "name": "预热启用" }, + "remain_able": { "name": "保持可用" }, + "hcho_check_enable": { "name": "甲醛检测启用" }, + "co2_check_enable": { "name": "CO2检测启用" }, + "function_set_link": { "name": "功能设置联动" }, + "function_set_sleep": { "name": "功能设置睡眠" }, + "function_set_energy_save": { "name": "功能设置节能" }, + "function_set_prheat": { "name": "功能设置预热" }, + "function_set_ultimate": { "name": "功能设置终极" }, + "clean_net_clean_flg": { "name": "清洁网清洁标志" }, + "change_net_change_flg": { "name": "更换网更换标志" }, + "condensation_state": { "name": "冷凝状态" }, + "humidity_state": { "name": "湿度状态" }, + "preheat_state": { "name": "预热状态" }, + "esp_enable": { "name": "ESP启用" }, + "pm25_check_enable": { "name": "PM2.5检测启用" }, + "timer_state": { "name": "定时器状态" }, + "humidity_check_enable": { "name": "湿度检测启用" }, + "door_middlestair": { "name": "中层门" }, + "door_upstair": { "name": "上层门" }, + "door_downstair": { "name": "下层门" }, + "downstair_ispreheat": { "name": "下层预热" }, + "upstair_ispreheat": { "name": "上层预热" }, + "downstair_iscooling": { "name": "下层冷却" }, + "upstair_iscooling": { "name": "上层冷却" }, + "middlestair_ispreheat": { "name": "中层预热" }, + "middlestair_iscooling": { "name": "中层冷却" }, + "lock": { "name": "锁定" }, + "is_error": { "name": "错误状态" }, + "uv_disinfect": { "name": "紫外线消毒" }, + "ai_switch": { "name": "AI开关" }, + "light": { "name": "灯光" }, + "appointment": { "name": "预约" }, + "prevent_wrinkle_switch": { "name": "防皱开关" }, + "steam_switch": { "name": "蒸汽开关" }, + "damp_dry_signal": { "name": "湿干信号" }, + "eco_dry_switch": { "name": "节能烘干开关" }, + "bucket_clean_switch": { "name": "桶清洁开关" }, + "water_box": { "name": "水箱" }, + "baby_lock": { "name": "童锁" }, + "remind_sound": { "name": "提醒声音" }, + "steam": { "name": "蒸汽" }, + "power": { "name": "电源" }, + "door_warn": { "name": "门警告" }, + "disinfect_on_off": { "name": "消毒开关" }, + "power_on_timer": { "name": "开机定时器" }, + "power": { "name": "电源" }, + "buzzer": { "name": "蜂鸣器" }, + "power_off_timer": { "name": "关机定时器" }, + "display_on_off": { "name": "显示开关" }, + "netions_on_off": { "name": "负离子开关" }, + "airdry_on_off": { "name": "风干开关" }, + "add_water_flag": { "name": "加水标志" } } } } diff --git a/img.png b/img.png new file mode 100644 index 0000000000000000000000000000000000000000..e0323a4a7acc58a35020576de9b112d61fafc4a6 GIT binary patch literal 6899 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 LNkvXXu0mjf_nWpH literal 0 HcmV?d00001