diff --git a/custom_components/ds_air/climate.py b/custom_components/ds_air/climate.py index c6074a0..c092dd0 100644 --- a/custom_components/ds_air/climate.py +++ b/custom_components/ds_air/climate.py @@ -6,16 +6,11 @@ """ import logging -from typing import List, Optional import voluptuous as vol from homeassistant.components.climate import ( ClimateEntity, ClimateEntityFeature, - FAN_AUTO, - FAN_HIGH, - FAN_LOW, - FAN_MEDIUM, HVACAction, HVACMode, PLATFORM_SCHEMA, @@ -30,7 +25,7 @@ CONF_PORT, MAJOR_VERSION, MINOR_VERSION, - UnitOfTemperature, + PRECISION_TENTHS, UnitOfTemperature, ) from homeassistant.core import Event, HomeAssistant from homeassistant.helpers import config_validation as cv @@ -38,9 +33,20 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_track_state_change_event -from .const import DOMAIN, MANUFACTURER +from .const import ( + AIR_FLOW_NAME_LIST, + DOMAIN, + FAN_DIRECTION_LIST, + MANUFACTURER, + get_action_name, + get_air_flow_enum, get_air_flow_name, + get_fan_direction_enum, + get_fan_direction_name, + get_mode_name, +) from .ds_air_service import AirCon, AirConStatus, Config, EnumControl, display, Service + _SUPPORT_FLAGS = ( ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE @@ -49,9 +55,6 @@ if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2): _SUPPORT_FLAGS |= ClimateEntityFeature.TURN_ON | ClimateEntityFeature.TURN_OFF -FAN_LIST = [FAN_LOW, "稍弱", FAN_MEDIUM, "稍强", FAN_HIGH, FAN_AUTO] -SWING_LIST = ["➡️", "↘️", "⬇️", "↙️", "⬅️", "↔️", "🔄"] - PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( {vol.Optional(CONF_HOST): cv.string, vol.Optional(CONF_PORT): cv.port} ) @@ -106,14 +109,19 @@ async def listener(event: Event): class DsAir(ClimateEntity): """Representation of a Daikin climate device.""" + # Entity Properties + _attr_has_entity_name: bool = True + _attr_name: str | None = None _attr_should_poll: bool = False - _attr_fan_modes: list[str] | None = FAN_LIST + # Climate Properties + _attr_fan_modes: list[str] | None = AIR_FLOW_NAME_LIST # _attr_max_humidity: float = 3 _attr_max_temp: float = 32 # _attr_min_humidity: float = 1 _attr_min_temp: float = 16 - _attr_swing_modes: list[str] | None = SWING_LIST + _attr_precision: float = PRECISION_TENTHS + _attr_swing_modes: list[str] | None = FAN_DIRECTION_LIST[1:] _attr_target_temperature_high: float | None = None _attr_target_temperature_low: float | None = None _attr_target_temperature_step: float | None = 0.5 @@ -126,21 +134,17 @@ def __init__(self, aircon: AirCon): _log(str(aircon.__dict__)) _log(str(aircon.status.__dict__)) """Initialize the climate device.""" - self._attr_name = aircon.alias self._device_info = aircon self._attr_unique_id = aircon.unique_id self.linked_temp_entity_id: str | None = None self.linked_humi_entity_id: str | None = None self._link_cur_temp = False - self._link_cur_humi = False - self._cur_temp = None - self._cur_humi = None Service.register_status_hook(aircon, self._status_change_hook) self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, self.unique_id)}, - name=f"空调{self._attr_name}", + name=aircon.alias, manufacturer=MANUFACTURER, ) @@ -184,20 +188,19 @@ def _status_change_hook(self, **kwargs): _log(display(self._device_info.status)) self.schedule_update_ha_state() - def update_cur_temp(self, value): + def update_cur_temp(self, value: str | None) -> None: self._link_cur_temp = value is not None try: - self._cur_temp = float(value) + self._attr_current_temperature = float(value) except ValueError: - """Ignore""" + self._attr_current_temperature = None self.schedule_update_ha_state() - def update_cur_humi(self, value): - self._link_cur_humi = value is not None + def update_cur_humi(self, value: str | None) -> None: try: - self._cur_humi = int(float(value)) + self._attr_current_humidity = int(float(value)) except ValueError: - """Ignore""" + self._attr_current_humidity = None self.schedule_update_ha_state() @property @@ -207,26 +210,21 @@ def target_humidity(self) -> float | None: @property def hvac_action(self) -> HVACAction | None: - """Return current operation ie. heat, cool, idle.""" + """Return the current running hvac operation if supported.""" if self._device_info.status.switch == EnumControl.Switch.OFF: return HVACAction.OFF - else: - return EnumControl.get_action_name(self._device_info.status.mode.value) + return get_action_name(self._device_info.status.mode.value) @property def hvac_mode(self) -> HVACMode | None: - """Return hvac operation ie. heat, cool mode. - - Need to be one of HVAC_MODE_*. - """ + """Return hvac operation ie. heat, cool mode.""" if self._device_info.status.switch == EnumControl.Switch.OFF: return HVACMode.OFF - else: - return EnumControl.get_mode_name(self._device_info.status.mode.value) + return get_mode_name(self._device_info.status.mode.value) @property def hvac_modes(self) -> list[HVACMode]: - """Return the list of supported features.""" + """Return the list of available hvac operation modes.""" li = [] aircon = self._device_info if aircon.cool_mode: @@ -246,7 +244,7 @@ def hvac_modes(self) -> list[HVACMode]: def current_temperature(self) -> float | None: """Return the current temperature.""" if self._link_cur_temp: - return self._cur_temp + return self._attr_current_temperature else: if Config.is_c611: return None @@ -258,14 +256,6 @@ def target_temperature(self) -> float | None: """Return the temperature we try to reach.""" return self._device_info.status.setted_temp / 10 - @property - def current_humidity(self) -> float | None: - """Return the current humidity.""" - if self._link_cur_humi: - return self._cur_humi - else: - return None - @property def preset_mode(self) -> str | None: """Return the current preset mode, e.g., home, away, temp. @@ -274,10 +264,9 @@ def preset_mode(self) -> str | None: """ if self._device_info.status.mode == EnumControl.Mode.SLEEP: return PRESET_SLEEP - elif self._device_info.status.mode == EnumControl.Mode.RELAX: + if self._device_info.status.mode == EnumControl.Mode.RELAX: return PRESET_COMFORT - else: - return PRESET_NONE + return PRESET_NONE @property def preset_modes(self) -> list[str] | None: @@ -300,7 +289,7 @@ def fan_mode(self) -> str | None: Requires ClimateEntityFeature.FAN_MODE. """ - return EnumControl.get_air_flow_name(self._device_info.status.air_flow.value) + return get_air_flow_name(self._device_info.status.air_flow.value) @property def swing_mode(self) -> str | None: @@ -308,51 +297,49 @@ def swing_mode(self) -> str | None: Requires ClimateEntityFeature.SWING_MODE. """ - return EnumControl.get_fan_direction_name( - self._device_info.status.fan_direction1.value - ) + return get_fan_direction_name(self._device_info.status.fan_direction1.value) def set_temperature(self, **kwargs) -> None: """Set new target temperatures.""" if (temperate := kwargs.get(ATTR_TEMPERATURE)) is not None: status = self._device_info.status - new_status = AirConStatus() if status.switch == EnumControl.Switch.ON and status.mode not in [ EnumControl.Mode.VENTILATION, EnumControl.Mode.MOREDRY, ]: + new_status = AirConStatus() status.setted_temp = round(temperate * 10.0) new_status.setted_temp = round(temperate * 10.0) Service.control(self._device_info, new_status) - self.schedule_update_ha_state() + self.schedule_update_ha_state() - def set_humidity(self, humidity) -> None: + def set_humidity(self, humidity: int) -> None: """Set new humidity level.""" status = self._device_info.status - new_status = AirConStatus() if status.switch == EnumControl.Switch.ON and status.mode in [ EnumControl.Mode.RELAX, EnumControl.Mode.SLEEP, ]: + new_status = AirConStatus() status.humidity = EnumControl.Humidity(humidity) new_status.humidity = EnumControl.Humidity(humidity) Service.control(self._device_info, new_status) - self.schedule_update_ha_state() + self.schedule_update_ha_state() def set_fan_mode(self, fan_mode: str) -> None: - """Set new fan mode.""" + """Set new target fan mode.""" status = self._device_info.status - new_status = AirConStatus() if status.switch == EnumControl.Switch.ON and status.mode not in [ EnumControl.Mode.MOREDRY, EnumControl.Mode.SLEEP, ]: - status.air_flow = EnumControl.get_air_flow_enum(fan_mode) - new_status.air_flow = EnumControl.get_air_flow_enum(fan_mode) + new_status = AirConStatus() + status.air_flow = get_air_flow_enum(fan_mode) + new_status.air_flow = get_air_flow_enum(fan_mode) Service.control(self._device_info, new_status) - self.schedule_update_ha_state() + self.schedule_update_ha_state() - def set_hvac_mode(self, hvac_mode: str) -> None: + def set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set new target hvac mode.""" aircon = self._device_info status = aircon.status @@ -397,16 +384,17 @@ def set_hvac_mode(self, hvac_mode: str) -> None: def set_swing_mode(self, swing_mode: str) -> None: """Set new swing mode.""" status = self._device_info.status - new_status = AirConStatus() if status.switch == EnumControl.Switch.ON: + new_status = AirConStatus() status.fan_direction1 = self._device_info.status.fan_direction1 new_status.fan_direction1 = self._device_info.status.fan_direction1 - status.fan_direction2 = EnumControl.get_fan_direction_enum(swing_mode) - new_status.fan_direction2 = EnumControl.get_fan_direction_enum(swing_mode) + status.fan_direction2 = get_fan_direction_enum(swing_mode) + new_status.fan_direction2 = get_fan_direction_enum(swing_mode) Service.control(self._device_info, new_status) - self.schedule_update_ha_state() + self.schedule_update_ha_state() def set_preset_mode(self, preset_mode: str) -> None: + """Set new preset mode.""" aircon = self._device_info status = aircon.status new_status = AirConStatus() @@ -435,7 +423,7 @@ def supported_features(self) -> ClimateEntityFeature: flags = _SUPPORT_FLAGS aircon = self._device_info if aircon.status.fan_direction1.value > 0: - flags = flags | ClimateEntityFeature.SWING_MODE + flags |= ClimateEntityFeature.SWING_MODE if aircon.relax_mode: - flags = flags | ClimateEntityFeature.TARGET_HUMIDITY + flags |= ClimateEntityFeature.TARGET_HUMIDITY return flags diff --git a/custom_components/ds_air/config_flow.py b/custom_components/ds_air/config_flow.py index 657a830..de42514 100644 --- a/custom_components/ds_air/config_flow.py +++ b/custom_components/ds_air/config_flow.py @@ -5,7 +5,12 @@ import voluptuous as vol from homeassistant.components.sensor import SensorDeviceClass -from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow +from homeassistant.config_entries import ( + ConfigEntry, + ConfigFlow, + ConfigFlowResult, + OptionsFlow, +) from homeassistant.const import ( ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, @@ -37,17 +42,14 @@ def __init__(self): async def async_step_user( self, user_input: dict[str, Any] | None = None - ) -> FlowResult: + ) -> ConfigFlowResult: if self._async_current_entries(): return self.async_abort(reason="single_instance_allowed") errors = {} if user_input is not None: self.user_input.update(user_input) - if ( - not user_input.get(CONF_SENSORS) - or user_input.get("temp") is not None - ): + if not user_input.get(CONF_SENSORS) or user_input.get("temp") is not None: return self.async_create_entry(title="金制空气", data=self.user_input) else: return self.async_show_form( @@ -107,20 +109,21 @@ async def async_step_init( """Manage the options.""" sensors = self.hass.states.async_all("sensor") self._sensors_temp = { - None: 'None', + None: "None", **{ state.entity_id: f"{state.attributes.get(ATTR_FRIENDLY_NAME, state.entity_id)} ({state.entity_id})" for state in sensors - if state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TEMPERATURE - } + if state.attributes.get(ATTR_DEVICE_CLASS) + == SensorDeviceClass.TEMPERATURE + }, } self._sensors_humi = { - None: 'None', + None: "None", **{ state.entity_id: f"{state.attributes.get(ATTR_FRIENDLY_NAME, state.entity_id)} ({state.entity_id})" for state in sensors if state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.HUMIDITY - } + }, } return self.async_show_menu( @@ -229,7 +232,9 @@ async def async_step_bind_sensors( return self.async_create_entry(title="", data={"link": self._config_data}) cur_climate: str = self._climates[self._cur] cur_links = self.config_entry.options.get("link", []) - cur_link = next((link for link in cur_links if link["climate"] == cur_climate), None) + cur_link = next( + (link for link in cur_links if link["climate"] == cur_climate), None + ) cur_sensor_temp = cur_link.get("sensor_temp") if cur_link else None cur_sensor_humi = cur_link.get("sensor_humi") if cur_link else None return self.async_show_form( diff --git a/custom_components/ds_air/const.py b/custom_components/ds_air/const.py index 4499611..ef6519f 100644 --- a/custom_components/ds_air/const.py +++ b/custom_components/ds_air/const.py @@ -1,21 +1,15 @@ -from collections.abc import Callable -from dataclasses import dataclass -from typing import Any - -from homeassistant.components.sensor import ( - SensorDeviceClass, - SensorEntityDescription, - SensorStateClass, -) -from homeassistant.const import ( - CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, - CONCENTRATION_PARTS_PER_MILLION, - MAJOR_VERSION, - PERCENTAGE, - UnitOfTemperature, +from homeassistant.components.climate import ( + FAN_AUTO, + FAN_HIGH, + FAN_LOW, + FAN_MEDIUM, + HVACAction, + HVACMode, ) +from .ds_air_service import EnumControl + + DOMAIN = "ds_air" CONF_GW = "gw" DEFAULT_HOST = "192.168.1." @@ -25,56 +19,60 @@ MANUFACTURER = "Daikin Industries, Ltd." -FROZEN = MAJOR_VERSION >= 2024 - - -@dataclass(frozen=FROZEN, kw_only=True) -class DsSensorEntityDescription(SensorEntityDescription): - has_entity_name: bool = True - state_class: SensorStateClass = SensorStateClass.MEASUREMENT - value_fn: Callable[[Any], Any] | None = lambda x: x - - -SENSOR_DESCRIPTORS = { - "temp": DsSensorEntityDescription( - key="temp", - native_unit_of_measurement=UnitOfTemperature.CELSIUS, - device_class=SensorDeviceClass.TEMPERATURE, - value_fn=lambda x: x / 10, - ), - "humidity": DsSensorEntityDescription( - key="humidity", - native_unit_of_measurement=PERCENTAGE, - device_class=SensorDeviceClass.HUMIDITY, - value_fn=lambda x: x / 10, - ), - "pm25": DsSensorEntityDescription( - key="pm25", - native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - device_class=SensorDeviceClass.PM25, - ), - "co2": DsSensorEntityDescription( - key="co2", - native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, - device_class=SensorDeviceClass.CO2, - ), - "tvoc": DsSensorEntityDescription( - key="tvoc", - name="TVOC", - native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, - suggested_display_precision=0, - value_fn=lambda x: x * 10, - ), - "voc": DsSensorEntityDescription( - key="voc", - device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS, - value_fn=lambda x: str(x), # EnumSensor.Voc - ), - "hcho": DsSensorEntityDescription( - key="hcho", - name="HCHO", - native_unit_of_measurement=CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, - value_fn=lambda x: x / 100, - ), -} + +_MODE_NAME_LIST = [ + HVACMode.COOL, + HVACMode.DRY, + HVACMode.FAN_ONLY, + HVACMode.AUTO, + HVACMode.HEAT, + HVACMode.DRY, + HVACMode.AUTO, + HVACMode.AUTO, + HVACMode.HEAT, + HVACMode.DRY, +] + + +def get_mode_name(idx: int) -> HVACMode: + return _MODE_NAME_LIST[idx] + + +_MODE_ACTION_LIST = [ + HVACAction.COOLING, + HVACAction.DRYING, + HVACAction.FAN, + None, + HVACAction.HEATING, + HVACAction.DRYING, + None, + None, + HVACAction.PREHEATING, + HVACAction.DRYING, +] + + +def get_action_name(idx: int) -> HVACAction | None: + return _MODE_ACTION_LIST[idx] + + +AIR_FLOW_NAME_LIST = [FAN_LOW, "稍弱", FAN_MEDIUM, "稍强", FAN_HIGH, FAN_AUTO] + + +def get_air_flow_name(idx: int) -> str: + return AIR_FLOW_NAME_LIST[idx] + + +def get_air_flow_enum(name: str) -> EnumControl.AirFlow: + return EnumControl.AirFlow(AIR_FLOW_NAME_LIST.index(name)) + + +FAN_DIRECTION_LIST = [None, "➡️", "↘️", "⬇️", "↙️", "⬅️", "↔️", "🔄"] + + +def get_fan_direction_name(idx: int) -> str: + return FAN_DIRECTION_LIST[idx] + + +def get_fan_direction_enum(name: str) -> EnumControl.FanDirection: + return EnumControl.FanDirection(FAN_DIRECTION_LIST.index(name)) diff --git a/custom_components/ds_air/descriptions.py b/custom_components/ds_air/descriptions.py new file mode 100644 index 0000000..8e78678 --- /dev/null +++ b/custom_components/ds_air/descriptions.py @@ -0,0 +1,70 @@ +from dataclasses import dataclass +from typing import Any, Callable + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntityDescription, + SensorStateClass, +) +from homeassistant.const import ( + CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, + CONCENTRATION_PARTS_PER_MILLION, + MAJOR_VERSION, + PERCENTAGE, + UnitOfTemperature, +) + +FROZEN = MAJOR_VERSION >= 2024 + + +@dataclass(frozen=FROZEN, kw_only=True) +class DsSensorEntityDescription(SensorEntityDescription): + has_entity_name: bool = True + state_class: SensorStateClass = SensorStateClass.MEASUREMENT + value_fn: Callable[[Any], Any] | None = lambda x: x + + +SENSOR_DESCRIPTORS = { + "temp": DsSensorEntityDescription( + key="temp", + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + device_class=SensorDeviceClass.TEMPERATURE, + value_fn=lambda x: x / 10, + ), + "humidity": DsSensorEntityDescription( + key="humidity", + native_unit_of_measurement=PERCENTAGE, + device_class=SensorDeviceClass.HUMIDITY, + value_fn=lambda x: x / 10, + ), + "pm25": DsSensorEntityDescription( + key="pm25", + native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + device_class=SensorDeviceClass.PM25, + ), + "co2": DsSensorEntityDescription( + key="co2", + native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + device_class=SensorDeviceClass.CO2, + ), + "tvoc": DsSensorEntityDescription( + key="tvoc", + name="TVOC", + native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, + suggested_display_precision=0, + value_fn=lambda x: x * 10, + ), + "voc": DsSensorEntityDescription( + key="voc", + device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS, + value_fn=lambda x: str(x), # EnumSensor.Voc + ), + "hcho": DsSensorEntityDescription( + key="hcho", + name="HCHO", + native_unit_of_measurement=CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, + value_fn=lambda x: x / 100, + ), +} diff --git a/custom_components/ds_air/ds_air_service/ctrl_enum.py b/custom_components/ds_air/ds_air_service/ctrl_enum.py index 4487390..9dc6a08 100644 --- a/custom_components/ds_air/ds_air_service/ctrl_enum.py +++ b/custom_components/ds_air/ds_air_service/ctrl_enum.py @@ -1,14 +1,5 @@ from enum import Enum, IntEnum -from homeassistant.components.climate.const import ( - FAN_AUTO, - FAN_HIGH, - FAN_LOW, - FAN_MEDIUM, - HVACAction, - HVACMode, -) - class EnumCmdType(IntEnum): # 返回指令 @@ -229,49 +220,6 @@ class EnumSwitch(IntEnum): OFF = 2 -"""EnumControl""" - - -class AirFlow(IntEnum): - SUPER_WEAK = 0 - WEAK = 1 - MIDDLE = 2 - STRONG = 3 - SUPER_STRONG = 4 - AUTO = 5 - - -# _AIR_FLOW_NAME_LIST = ['最弱', '稍弱', '中等', '稍强', '最强', '自动'] -_AIR_FLOW_NAME_LIST = [FAN_LOW, "稍弱", FAN_MEDIUM, "稍强", FAN_HIGH, FAN_AUTO] - - -class Breathe(IntEnum): - CLOSE = 0 - WEAK = 1 - STRONG = 2 - - -class FanDirection(IntEnum): - INVALID = 0 - P0 = 1 # 最右 最上 - P1 = 2 - P2 = 3 - P3 = 4 - P4 = 5 # 最左 最下 - AUTO = 6 - SWING = 7 - - -_FAN_DIRECTION_LIST = ["INVALID", "➡️", "↘️", "⬇️", "↙️", "⬅️", "↔️", "🔄"] - - -class Humidity(IntEnum): - CLOSE = 0 - STEP1 = 1 - STEP2 = 2 - STEP3 = 3 - - class FreshAirHumidification(IntEnum): OFF = 0 FRESH_AIR = 1 @@ -285,112 +233,68 @@ class ThreeDFresh(IntEnum): AUTO = 3 -class Mode(IntEnum): - COLD = 0 - DRY = 1 - VENTILATION = 2 - AUTO = 3 - HEAT = 4 - AUTODRY = 5 - RELAX = 6 - SLEEP = 7 - PREHEAT = 8 - MOREDRY = 9 - - -# Legacy Mode Mapping -# _MODE_NAME_LIST = [HVACMode.COOL, HVACMode.DRY, HVACMode.FAN_ONLY, HVACMode.AUTO, HVACMode.HEAT, -# HVACMode.DRY, HVACMode.AUTO, HVACMode.HEAT_COOL, HVACMode.HEAT, HVACMode.DRY] - -_MODE_NAME_LIST = [ - HVACMode.COOL, - HVACMode.DRY, - HVACMode.FAN_ONLY, - HVACMode.AUTO, - HVACMode.HEAT, - HVACMode.DRY, - HVACMode.AUTO, - HVACMode.AUTO, - HVACMode.HEAT, - HVACMode.DRY, -] -_MODE_ACTION_LIST = [ - HVACAction.COOLING, - HVACAction.DRYING, - HVACAction.FAN, - None, - HVACAction.HEATING, - HVACAction.DRYING, - None, - None, - HVACAction.PREHEATING, - HVACAction.DRYING, -] - - -class Switch(IntEnum): - OFF = 0 - ON = 1 - - -class Type(IntEnum): - SWITCH = 1 # 0 - MODE = 2 # 1 - AIR_FLOW = 4 # 2 - CURRENT_TEMP = 8 - FRESH_AIR_HUMIDIFICATION = 8 # 3 - SETTED_TEMP = 16 # 4 - FAN_DIRECTION = 32 # 5 - HUMIDITY = 64 # 6 - BREATHE = 128 # 7 - FAN_DIRECTION_FB = 254 # 8 - FAN_DIRECTION_LR = 255 # 9 - SCENE_STATE = 253 # 10 - - class EnumControl: - Switch = Switch - AirFlow = AirFlow - Breathe = Breathe - FanDirection = FanDirection - Humidity = Humidity - Mode = Mode - Type = Type - - @staticmethod - def get_mode_name(idx): - return _MODE_NAME_LIST[idx] - - @staticmethod - def get_action_name(idx): - return _MODE_ACTION_LIST[idx] - - @staticmethod - def get_mode_enum(name): - return Mode(_MODE_NAME_LIST.index(name)) - - @staticmethod - def get_air_flow_name(idx): - return _AIR_FLOW_NAME_LIST[idx] - - @staticmethod - def get_air_flow_enum(name): - return AirFlow(_AIR_FLOW_NAME_LIST.index(name)) - - @staticmethod - def get_fan_direction_name(idx): - return _FAN_DIRECTION_LIST[idx] - - @staticmethod - def get_fan_direction_enum(name): - return FanDirection(_FAN_DIRECTION_LIST.index(name)) + class Switch(IntEnum): + OFF = 0 + ON = 1 + + class AirFlow(IntEnum): + SUPER_WEAK = 0 + WEAK = 1 + MIDDLE = 2 + STRONG = 3 + SUPER_STRONG = 4 + AUTO = 5 + + class Breathe(IntEnum): + CLOSE = 0 + WEAK = 1 + STRONG = 2 + + class FanDirection(IntEnum): + INVALID = 0 + P0 = 1 # 最右 最上 + P1 = 2 + P2 = 3 + P3 = 4 + P4 = 5 # 最左 最下 + AUTO = 6 + SWING = 7 + + class Humidity(IntEnum): + CLOSE = 0 + STEP1 = 1 + STEP2 = 2 + STEP3 = 3 + + class Mode(IntEnum): + COLD = 0 + DRY = 1 + VENTILATION = 2 + AUTO = 3 + HEAT = 4 + AUTODRY = 5 + RELAX = 6 + SLEEP = 7 + PREHEAT = 8 + MOREDRY = 9 + + class Type(IntEnum): + SWITCH = 1 # 0 + MODE = 2 # 1 + AIR_FLOW = 4 # 2 + CURRENT_TEMP = 8 + FRESH_AIR_HUMIDIFICATION = 8 # 3 + SETTED_TEMP = 16 # 4 + FAN_DIRECTION = 32 # 5 + HUMIDITY = 64 # 6 + BREATHE = 128 # 7 + FAN_DIRECTION_FB = 254 # 8 + FAN_DIRECTION_LR = 255 # 9 + SCENE_STATE = 253 # 10 class EnumSensor: - class LinkState(IntEnum): - NO_LINKED = 0 - YES_LINKED = 1 - class Voc(IntEnum): STEP_1 = 1 STEP_2 = 2 diff --git a/custom_components/ds_air/sensor.py b/custom_components/ds_air/sensor.py index dcdf1c6..3d80a1e 100644 --- a/custom_components/ds_air/sensor.py +++ b/custom_components/ds_air/sensor.py @@ -6,7 +6,8 @@ from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import DOMAIN, DsSensorEntityDescription, MANUFACTURER, SENSOR_DESCRIPTORS +from .const import DOMAIN, MANUFACTURER +from .descriptions import DsSensorEntityDescription, SENSOR_DESCRIPTORS from .ds_air_service import Sensor, Service, UNINITIALIZED_VALUE