Refactor hon entities
This commit is contained in:
		| @ -263,12 +263,6 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
| class HonBinarySensorEntity(HonEntity, BinarySensorEntity): | ||||
|     entity_description: HonBinarySensorEntityDescription | ||||
|  | ||||
|     def __init__(self, hass, entry, device, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|  | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|  | ||||
|     @property | ||||
|     def is_on(self) -> bool: | ||||
|         return ( | ||||
|  | ||||
| @ -53,11 +53,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|  | ||||
|  | ||||
| class HonButtonEntity(HonEntity, ButtonEntity): | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|  | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|     entity_description: ButtonEntityDescription | ||||
|  | ||||
|     async def async_press(self) -> None: | ||||
|         await self._device.commands[self.entity_description.key].send() | ||||
|  | ||||
| @ -53,9 +53,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|  | ||||
| class HonClimateEntity(HonEntity, ClimateEntity): | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}climate" | ||||
|         super().__init__(hass, entry, device, description) | ||||
|  | ||||
|         self._attr_temperature_unit = TEMP_CELSIUS | ||||
|         self._attr_target_temperature_step = PRECISION_WHOLE | ||||
|  | ||||
| @ -14,7 +14,7 @@ _LOGGER = logging.getLogger(__name__) | ||||
| class HonEntity(CoordinatorEntity): | ||||
|     _attr_has_entity_name = True | ||||
|  | ||||
|     def __init__(self, hass, entry, device: HonAppliance) -> None: | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description=None) -> None: | ||||
|         coordinator = get_coordinator(hass, device) | ||||
|         super().__init__(coordinator) | ||||
|  | ||||
| @ -23,7 +23,11 @@ class HonEntity(CoordinatorEntity): | ||||
|         self._coordinator = coordinator | ||||
|         self._device = device | ||||
|  | ||||
|         self._attr_unique_id = self._device.unique_id | ||||
|         if description is not None: | ||||
|             self.entity_description = description | ||||
|             self._attr_unique_id = f"{self._device.unique_id}{description.key}" | ||||
|         else: | ||||
|             self._attr_unique_id = self._device.unique_id | ||||
|  | ||||
|     @property | ||||
|     def device_info(self): | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| from dataclasses import dataclass | ||||
|  | ||||
| from homeassistant.components.number import ( | ||||
|     NumberEntity, | ||||
|     NumberEntityDescription, | ||||
| @ -7,143 +9,136 @@ from homeassistant.components.number import ( | ||||
| from homeassistant.config_entries import ConfigEntry | ||||
| from homeassistant.const import UnitOfTime, UnitOfTemperature | ||||
| from homeassistant.core import callback | ||||
| from homeassistant.helpers.entity import EntityCategory | ||||
| from pyhon.parameter.base import HonParameter | ||||
| from pyhon.parameter.fixed import HonParameterFixed | ||||
| from homeassistant.helpers.entity import EntityCategory, Entity | ||||
| from pyhon.parameter.range import HonParameterRange | ||||
|  | ||||
| from .const import DOMAIN | ||||
| from .hon import HonEntity, unique_entities | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonConfigNumberEntityDescription(NumberEntityDescription): | ||||
|     entity_category: EntityCategory = EntityCategory.CONFIG | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonNumberEntityDescription(NumberEntityDescription): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | ||||
|     "WM": ( | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.delayTime", | ||||
|             name="Delay Time", | ||||
|             icon="mdi:timer-plus", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.rinseIterations", | ||||
|             name="Rinse Iterations", | ||||
|             icon="mdi:rotate-right", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="rinse_iterations", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.mainWashTime", | ||||
|             name="Main Wash Time", | ||||
|             icon="mdi:clock-start", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="wash_time", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.steamLevel", | ||||
|             name="Steam Level", | ||||
|             icon="mdi:weather-dust", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="steam_level", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.waterHard", | ||||
|             name="Water hard", | ||||
|             icon="mdi:water", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="water_hard", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.lang", | ||||
|             name="lang", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|         ), | ||||
|     ), | ||||
|     "TD": ( | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.delayTime", | ||||
|             name="Delay time", | ||||
|             icon="mdi:timer-plus", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.tempLevel", | ||||
|             name="Temperature level", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:thermometer", | ||||
|             translation_key="tumbledryertemplevel", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.dryTime", | ||||
|             name="Dry Time", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="dry_time", | ||||
|         ), | ||||
|     ), | ||||
|     "OV": ( | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.delayTime", | ||||
|             name="Delay time", | ||||
|             icon="mdi:timer-plus", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.tempSel", | ||||
|             name="Target Temperature", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:thermometer", | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="target_temperature", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.prTime", | ||||
|             name="Program Duration", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timelapse", | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="program_duration", | ||||
|         ), | ||||
|     ), | ||||
|     "IH": ( | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.temp", | ||||
|             name="Temperature", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:thermometer", | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.powerManagement", | ||||
|             name="Power Management", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timelapse", | ||||
|             translation_key="power_management", | ||||
|         ), | ||||
|     ), | ||||
|     "DW": ( | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.delayTime", | ||||
|             name="Delay time", | ||||
|             icon="mdi:timer-plus", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonConfigNumberEntityDescription( | ||||
|             key="startProgram.waterHard", | ||||
|             name="Water hard", | ||||
|             icon="mdi:water", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="water_hard", | ||||
|         ), | ||||
|     ), | ||||
|     "AC": ( | ||||
|         NumberEntityDescription( | ||||
|         HonNumberEntityDescription( | ||||
|             key="settings.tempSel", | ||||
|             name="Target Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -152,14 +147,14 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "REF": ( | ||||
|         NumberEntityDescription( | ||||
|         HonNumberEntityDescription( | ||||
|             key="settings.tempSelZ1", | ||||
|             name="Fridge Temperature", | ||||
|             icon="mdi:thermometer", | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="fridge_temp_sel", | ||||
|         ), | ||||
|         NumberEntityDescription( | ||||
|         HonNumberEntityDescription( | ||||
|             key="settings.tempSelZ2", | ||||
|             name="Freezer Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -178,20 +173,24 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|         for description in NUMBERS.get(device.appliance_type, []): | ||||
|             if description.key not in device.available_settings: | ||||
|                 continue | ||||
|             entity = HonNumberEntity(hass, entry, device, description) | ||||
|             if isinstance(description, HonNumberEntityDescription): | ||||
|                 entity = HonNumberEntity(hass, entry, device, description) | ||||
|             elif isinstance(description, HonConfigNumberEntityDescription): | ||||
|                 entity = HonConfigNumberEntity(hass, entry, device, description) | ||||
|             else: | ||||
|                 continue | ||||
|             await entity.coordinator.async_config_entry_first_refresh() | ||||
|             entities.append(entity) | ||||
|     async_add_entities(entities) | ||||
|  | ||||
|  | ||||
| class HonNumberEntity(HonEntity, NumberEntity): | ||||
|     entity_description: HonNumberEntityDescription | ||||
|  | ||||
|     def __init__(self, hass, entry, device, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|         super().__init__(hass, entry, device, description) | ||||
|  | ||||
|         self._data = device.settings[description.key] | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|  | ||||
|         if isinstance(self._data, HonParameterRange): | ||||
|             self._attr_native_max_value = self._data.max | ||||
|             self._attr_native_min_value = self._data.min | ||||
| @ -203,12 +202,10 @@ class HonNumberEntity(HonEntity, NumberEntity): | ||||
|  | ||||
|     async def async_set_native_value(self, value: float) -> None: | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if not ( | ||||
|             type(setting) == HonParameter or isinstance(setting, HonParameterFixed) | ||||
|         ): | ||||
|         if isinstance(setting, HonParameterRange): | ||||
|             setting.value = value | ||||
|         if "settings." in self.entity_description.key: | ||||
|             await self._device.commands["settings"].send() | ||||
|         command = self.entity_description.key.split(".")[0] | ||||
|         await self._device.commands[command].send() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @callback | ||||
| @ -224,12 +221,23 @@ class HonNumberEntity(HonEntity, NumberEntity): | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         if self.entity_category == EntityCategory.CONFIG: | ||||
|             return super().available | ||||
|         else: | ||||
|             return ( | ||||
|                 super().available | ||||
|                 and self._device.get("remoteCtrValid", "1") == "1" | ||||
|                 and self._device.get("attributes.lastConnEvent.category") | ||||
|                 != "DISCONNECTED" | ||||
|             ) | ||||
|         return ( | ||||
|             super().available | ||||
|             and self._device.get("remoteCtrValid", "1") == "1" | ||||
|             and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED" | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class HonConfigNumberEntity(HonNumberEntity): | ||||
|     entity_description: HonConfigNumberEntityDescription | ||||
|  | ||||
|     async def async_set_native_value(self, value: str) -> None: | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if isinstance(setting, HonParameterRange): | ||||
|             setting.value = value | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         return super(NumberEntity, self).available | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| import logging | ||||
| from dataclasses import dataclass | ||||
|  | ||||
| from homeassistant.components.select import SelectEntity, SelectEntityDescription | ||||
| from homeassistant.config_entries import ConfigEntry | ||||
| from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_MINUTE | ||||
| from homeassistant.core import callback | ||||
| from homeassistant.helpers.entity import EntityCategory | ||||
| from homeassistant.helpers.entity import EntityCategory, Entity | ||||
| from pyhon.appliance import HonAppliance | ||||
| from pyhon.parameter.fixed import HonParameterFixed | ||||
|  | ||||
| @ -15,101 +16,101 @@ from .hon import HonEntity, unique_entities | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonSelectEntityDescription(SelectEntityDescription): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonConfigSelectEntityDescription(SelectEntityDescription): | ||||
|     entity_category: EntityCategory = EntityCategory.CONFIG | ||||
|  | ||||
|  | ||||
| SELECTS = { | ||||
|     "WM": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.spinSpeed", | ||||
|             name="Spin speed", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:numeric", | ||||
|             unit_of_measurement=REVOLUTIONS_PER_MINUTE, | ||||
|             translation_key="spin_speed", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.temp", | ||||
|             name="Temperature", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:thermometer", | ||||
|             unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_wm", | ||||
|         ), | ||||
|     ), | ||||
|     "TD": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_td", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.dryTimeMM", | ||||
|             name="Dry Time", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timer", | ||||
|             unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="dry_time", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.dryLevel", | ||||
|             name="Dry level", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:hair-dryer", | ||||
|             translation_key="dry_levels", | ||||
|         ), | ||||
|     ), | ||||
|     "OV": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_ov", | ||||
|         ), | ||||
|     ), | ||||
|     "IH": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_ih", | ||||
|         ), | ||||
|     ), | ||||
|     "DW": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_dw", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.temp", | ||||
|             name="Temperature", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:thermometer", | ||||
|             unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.remainingTime", | ||||
|             name="Remaining Time", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timer", | ||||
|             unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|     ), | ||||
|     "AC": ( | ||||
|         SelectEntityDescription( | ||||
|         HonSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             translation_key="programs_ac", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonSelectEntityDescription( | ||||
|             key="settings.humanSensingStatus", | ||||
|             name="Eco Pilot", | ||||
|             icon="mdi:run", | ||||
| @ -117,17 +118,15 @@ SELECTS = { | ||||
|         ), | ||||
|     ), | ||||
|     "REF": ( | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.program", | ||||
|             name="Program", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="programs_ref", | ||||
|         ), | ||||
|         SelectEntityDescription( | ||||
|         HonConfigSelectEntityDescription( | ||||
|             key="startProgram.zone", | ||||
|             name="Zone", | ||||
|             icon="mdi:radiobox-marked", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="ref_zones", | ||||
|         ), | ||||
|     ), | ||||
| @ -142,18 +141,22 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|         for description in SELECTS.get(device.appliance_type, []): | ||||
|             if description.key not in device.available_settings: | ||||
|                 continue | ||||
|             entity = HonSelectEntity(hass, entry, device, description) | ||||
|             if isinstance(description, HonSelectEntityDescription): | ||||
|                 entity = HonSelectEntity(hass, entry, device, description) | ||||
|             elif isinstance(description, HonConfigSelectEntityDescription): | ||||
|                 entity = HonConfigSelectEntity(hass, entry, device, description) | ||||
|             else: | ||||
|                 continue | ||||
|             await entity.coordinator.async_config_entry_first_refresh() | ||||
|             entities.append(entity) | ||||
|     async_add_entities(entities) | ||||
|  | ||||
|  | ||||
| class HonSelectEntity(HonEntity, SelectEntity): | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|     entity_description: HonSelectEntityDescription | ||||
|  | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         super().__init__(hass, entry, device, description) | ||||
|  | ||||
|         if not (setting := self._device.settings.get(description.key)): | ||||
|             self._attr_options: list[str] = [] | ||||
| @ -171,10 +174,8 @@ class HonSelectEntity(HonEntity, SelectEntity): | ||||
|  | ||||
|     async def async_select_option(self, option: str) -> None: | ||||
|         self._device.settings[self.entity_description.key].value = option | ||||
|         if "settings." in self.entity_description.key: | ||||
|             await self._device.commands["settings"].send() | ||||
|         elif self._device.appliance_type in ["AC"]: | ||||
|             await self._device.commands["startProgram"].send() | ||||
|         command = self.entity_description.key.split(".")[0] | ||||
|         await self._device.commands[command].send() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @callback | ||||
| @ -193,12 +194,21 @@ class HonSelectEntity(HonEntity, SelectEntity): | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         if self.entity_category == EntityCategory.CONFIG: | ||||
|             return super().available | ||||
|         else: | ||||
|             return ( | ||||
|                 super().available | ||||
|                 and self._device.get("remoteCtrValid", "1") == "1" | ||||
|                 and self._device.get("attributes.lastConnEvent.category") | ||||
|                 != "DISCONNECTED" | ||||
|             ) | ||||
|         return ( | ||||
|             super().available | ||||
|             and self._device.get("remoteCtrValid", "1") == "1" | ||||
|             and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED" | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class HonConfigSelectEntity(HonSelectEntity): | ||||
|     entity_description: HonConfigSelectEntityDescription | ||||
|  | ||||
|     async def async_select_option(self, option: str) -> None: | ||||
|         self._device.settings[self.entity_description.key].value = option | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         return super(SelectEntity, self).available | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import logging | ||||
| from dataclasses import dataclass | ||||
|  | ||||
| from homeassistant.components.sensor import ( | ||||
|     SensorEntity, | ||||
| @ -20,7 +21,6 @@ from homeassistant.const import ( | ||||
| from homeassistant.core import callback | ||||
| from homeassistant.helpers.entity import EntityCategory | ||||
| from homeassistant.helpers.typing import StateType | ||||
|  | ||||
| from . import const | ||||
| from .const import DOMAIN | ||||
| from .hon import HonEntity, unique_entities | ||||
| @ -28,9 +28,19 @@ from .hon import HonEntity, unique_entities | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonConfigSensorEntityDescription(SensorEntityDescription): | ||||
|     entity_category: EntityCategory = EntityCategory.CONFIG | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonSensorEntityDescription(SensorEntityDescription): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|     "WM": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="prPhase", | ||||
|             name="Program Phase", | ||||
|             icon="mdi:washing-machine", | ||||
| @ -38,7 +48,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="program_phases_wm", | ||||
|             options=list(const.WASHING_PR_PHASE), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="totalElectricityUsed", | ||||
|             name="Total Power", | ||||
|             device_class=SensorDeviceClass.ENERGY, | ||||
| @ -46,7 +56,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, | ||||
|             translation_key="energy_total", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="totalWaterUsed", | ||||
|             name="Total Water", | ||||
|             device_class=SensorDeviceClass.WATER, | ||||
| @ -54,14 +64,14 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfVolume.LITERS, | ||||
|             translation_key="water_total", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="totalWashCycle", | ||||
|             name="Total Wash Cycle", | ||||
|             state_class=SensorStateClass.TOTAL_INCREASING, | ||||
|             icon="mdi:counter", | ||||
|             translation_key="cycles_total", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="currentElectricityUsed", | ||||
|             name="Current Electricity Used", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
| @ -70,23 +80,22 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             icon="mdi:lightning-bolt", | ||||
|             translation_key="energy_current", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="currentWaterUsed", | ||||
|             name="Current Water Used", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             icon="mdi:water", | ||||
|             translation_key="water_current", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.weight", | ||||
|             name="Suggested weight", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, | ||||
|             icon="mdi:weight-kilogram", | ||||
|             translation_key="suggested_load", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="machMode", | ||||
|             name="Machine Status", | ||||
|             icon="mdi:information", | ||||
| @ -94,10 +103,10 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="washing_modes", | ||||
|             options=list(const.MACH_MODE), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="remainingTimeMM", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
| @ -105,7 +114,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="spinSpeed", | ||||
|             name="Spin Speed", | ||||
|             icon="mdi:speedometer", | ||||
| @ -113,53 +122,48 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=REVOLUTIONS_PER_MINUTE, | ||||
|             translation_key="spin_speed", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.energyLabel", | ||||
|             name="Energy Label", | ||||
|             icon="mdi:lightning-bolt-circle", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="energy_label", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.liquidDetergentDose", | ||||
|             name="Liquid Detergent Dose", | ||||
|             icon="mdi:cup-water", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="det_liquid", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.powderDetergentDose", | ||||
|             name="Powder Detergent Dose", | ||||
|             icon="mdi:cup", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="det_dust", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.remainingTime", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="dirtyLevel", | ||||
|             name="Dirt level", | ||||
|             icon="mdi:liquid-spot", | ||||
|             translation_key="dirt_level", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.suggestedLoadW", | ||||
|             name="Suggested Load", | ||||
|             icon="mdi:weight-kilogram", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, | ||||
|             translation_key="suggested_load", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="temp", | ||||
|             name="Current Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -169,7 +173,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "TD": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="machMode", | ||||
|             name="Machine Status", | ||||
|             icon="mdi:information", | ||||
| @ -177,10 +181,10 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="washing_modes", | ||||
|             options=list(const.MACH_MODE), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="remainingTimeMM", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
| @ -188,7 +192,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="delayTime", | ||||
|             name="Start Time", | ||||
|             icon="mdi:clock-start", | ||||
| @ -196,7 +200,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="programName", | ||||
|             name="Program", | ||||
|             icon="mdi:tumble-dryer", | ||||
| @ -204,7 +208,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="programs_td", | ||||
|             options=const.PROGRAMS_TD, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="prPhase", | ||||
|             name="Program Phase", | ||||
|             icon="mdi:washing-machine", | ||||
| @ -212,7 +216,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="program_phases_td", | ||||
|             options=list(const.TUMBLE_DRYER_PR_PHASE), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="dryLevel", | ||||
|             name="Dry level", | ||||
|             icon="mdi:hair-dryer", | ||||
| @ -220,58 +224,54 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="dry_levels", | ||||
|             options=list(const.TUMBLE_DRYER_DRY_LEVEL), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempLevel", | ||||
|             name="Temperature level", | ||||
|             icon="mdi:thermometer", | ||||
|             translation_key="tumbledryertemplevel", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.suggestedLoadD", | ||||
|             name="Suggested Load", | ||||
|             icon="mdi:weight-kilogram", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=UnitOfMass.KILOGRAMS, | ||||
|             translation_key="suggested_load", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.energyLabel", | ||||
|             name="Energy Label", | ||||
|             icon="mdi:lightning-bolt-circle", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="energy_label", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.steamLevel", | ||||
|             name="Steam level", | ||||
|             icon="mdi:smoke", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="steam_level", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="steamLevel", | ||||
|             name="Steam level", | ||||
|             icon="mdi:smoke", | ||||
|             translation_key="steam_level", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="steamType", | ||||
|             name="Steam Type", | ||||
|             icon="mdi:weather-dust", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|         ), | ||||
|     ), | ||||
|     "OV": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="remainingTimeMM", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="delayTime", | ||||
|             name="Start Time", | ||||
|             icon="mdi:clock-start", | ||||
| @ -279,13 +279,13 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="temp", | ||||
|             name="Temperature", | ||||
|             icon="mdi:thermometer", | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempSel", | ||||
|             name="Temperature Selected", | ||||
|             icon="mdi:thermometer", | ||||
| @ -293,14 +293,14 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "IH": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="remainingTimeMM", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="temp", | ||||
|             name="Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -308,10 +308,10 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="power", | ||||
|             name="Power", | ||||
|             icon="mdi:lightning-bolt", | ||||
| @ -320,57 +320,51 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "DW": ( | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.ecoIndex", | ||||
|             name="Eco Index", | ||||
|             icon="mdi:sprout", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.waterEfficiency", | ||||
|             name="Water Efficiency", | ||||
|             icon="mdi:water", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="water_efficiency", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.waterSaving", | ||||
|             name="Water Saving", | ||||
|             icon="mdi:water-percent", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=PERCENTAGE, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="water_saving", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.temp", | ||||
|             name="Temperature", | ||||
|             icon="mdi:thermometer", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="temperature", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.energyLabel", | ||||
|             name="Energy Label", | ||||
|             icon="mdi:lightning-bolt-circle", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="energy_label", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonConfigSensorEntityDescription( | ||||
|             key="startProgram.remainingTime", | ||||
|             name="Time", | ||||
|             icon="mdi:timer", | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="duration", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="machMode", | ||||
|             name="Machine Status", | ||||
|             icon="mdi:information", | ||||
| @ -378,10 +372,10 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             translation_key="washing_modes", | ||||
|             options=list(const.MACH_MODE), | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="remainingTimeMM", | ||||
|             name="Remaining Time", | ||||
|             icon="mdi:timer", | ||||
| @ -389,7 +383,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTime.MINUTES, | ||||
|             translation_key="remaining_time", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="prPhase", | ||||
|             name="Program Phase", | ||||
|             icon="mdi:washing-machine", | ||||
| @ -399,7 +393,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "AC": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempAirOutdoor", | ||||
|             name="Air Temperature Outdoor", | ||||
|             icon="mdi:thermometer", | ||||
| @ -407,7 +401,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempCoilerIndoor", | ||||
|             name="Coiler Temperature Indoor", | ||||
|             icon="mdi:thermometer", | ||||
| @ -415,7 +409,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempCoilerOutdoor", | ||||
|             name="Coiler Temperature Outside", | ||||
|             icon="mdi:thermometer", | ||||
| @ -423,7 +417,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempDefrostOutdoor", | ||||
|             name="Defrost Temperature Outdoor", | ||||
|             icon="mdi:thermometer", | ||||
| @ -431,7 +425,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempInAirOutdoor", | ||||
|             name="In Air Temperature Outdoor", | ||||
|             icon="mdi:thermometer", | ||||
| @ -439,7 +433,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempIndoor", | ||||
|             name="Indoor Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -447,7 +441,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempOutdoor", | ||||
|             name="Outdoor Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -455,7 +449,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             device_class=SensorDeviceClass.TEMPERATURE, | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempSel", | ||||
|             name="Selected Temperature", | ||||
|             icon="mdi:thermometer", | ||||
| @ -465,7 +459,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "REF": ( | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="humidityEnv", | ||||
|             name="Room Humidity", | ||||
|             icon="mdi:water-percent", | ||||
| @ -474,7 +468,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             state_class=SensorStateClass.MEASUREMENT, | ||||
|             translation_key="humidity", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempEnv", | ||||
|             name="Room Temperature", | ||||
|             icon="mdi:home-thermometer-outline", | ||||
| @ -483,7 +477,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="room_temperature", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempZ1", | ||||
|             name="Temperature Fridge", | ||||
|             icon="mdi:thermometer", | ||||
| @ -492,7 +486,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="fridge_temp", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="tempZ2", | ||||
|             name="Temperature Freezer", | ||||
|             icon="mdi:snowflake-thermometer", | ||||
| @ -501,7 +495,7 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             native_unit_of_measurement=UnitOfTemperature.CELSIUS, | ||||
|             translation_key="freezer_temp", | ||||
|         ), | ||||
|         SensorEntityDescription( | ||||
|         HonSensorEntityDescription( | ||||
|             key="errors", name="Error", icon="mdi:math-log", translation_key="errors" | ||||
|         ), | ||||
|     ), | ||||
| @ -513,11 +507,16 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|     entities = [] | ||||
|     for device in hass.data[DOMAIN][entry.unique_id].appliances: | ||||
|         for description in SENSORS.get(device.appliance_type, []): | ||||
|             if not device.get(description.key) and not device.settings.get( | ||||
|                 description.key | ||||
|             ): | ||||
|             if isinstance(description, HonSensorEntityDescription): | ||||
|                 if not device.get(description.key): | ||||
|                     continue | ||||
|                 entity = HonSensorEntity(hass, entry, device, description) | ||||
|             elif isinstance(description, HonConfigSensorEntityDescription): | ||||
|                 if description.key not in device.available_settings: | ||||
|                     continue | ||||
|                 entity = HonConfigSensorEntity(hass, entry, device, description) | ||||
|             else: | ||||
|                 continue | ||||
|             entity = HonSensorEntity(hass, entry, device, description) | ||||
|             await entity.coordinator.async_config_entry_first_refresh() | ||||
|             entities.append(entity) | ||||
|  | ||||
| @ -525,18 +524,7 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|  | ||||
|  | ||||
| class HonSensorEntity(HonEntity, SensorEntity): | ||||
|     def __init__(self, hass, entry, device, description) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|  | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|  | ||||
|     @property | ||||
|     def native_value(self) -> StateType: | ||||
|         value = self._device.get(self.entity_description.key, "") | ||||
|         if not value and self.entity_description.state_class is not None: | ||||
|             return 0 | ||||
|         return value | ||||
|     entity_description: HonSensorEntityDescription | ||||
|  | ||||
|     @callback | ||||
|     def _handle_coordinator_update(self): | ||||
| @ -545,3 +533,22 @@ class HonSensorEntity(HonEntity, SensorEntity): | ||||
|             self._attr_native_value = 0 | ||||
|         self._attr_native_value = value | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
|  | ||||
| class HonConfigSensorEntity(HonEntity, SensorEntity): | ||||
|     entity_description: HonConfigSensorEntityDescription | ||||
|  | ||||
|     @callback | ||||
|     def _handle_coordinator_update(self): | ||||
|         value = self._device.settings.get(self.entity_description.key, None) | ||||
|         if self.entity_description.state_class is not None: | ||||
|             if value and value.value: | ||||
|                 print(value.value, type(value.value)) | ||||
|                 self._attr_native_value = ( | ||||
|                     float(value.value) if "." in str(value.value) else int(value.value) | ||||
|                 ) | ||||
|             else: | ||||
|                 self._attr_native_value = 0 | ||||
|         else: | ||||
|             self._attr_native_value = value.value | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
| @ -6,7 +6,6 @@ from homeassistant.components.switch import SwitchEntityDescription, SwitchEntit | ||||
| from homeassistant.config_entries import ConfigEntry | ||||
| from homeassistant.const import EntityCategory | ||||
| from homeassistant.core import callback | ||||
| from pyhon.appliance import HonAppliance | ||||
| from pyhon.parameter.base import HonParameter | ||||
| from pyhon.parameter.range import HonParameterRange | ||||
|  | ||||
| @ -20,19 +19,27 @@ _LOGGER = logging.getLogger(__name__) | ||||
| class HonSwitchEntityDescriptionMixin: | ||||
|     turn_on_key: str = "" | ||||
|     turn_off_key: str = "" | ||||
|     status_key: str = "" | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonSwitchEntityDescription( | ||||
| class HonControlSwitchEntityDescription( | ||||
|     HonSwitchEntityDescriptionMixin, SwitchEntityDescription | ||||
| ): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class HonSwitchEntityDescription(SwitchEntityDescription): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonConfigSwitchEntityDescription(SwitchEntityDescription): | ||||
|     entity_category: EntityCategory = EntityCategory.CONFIG | ||||
|  | ||||
|  | ||||
| SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|     "WM": ( | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="active", | ||||
|             name="Washing Machine", | ||||
|             icon="mdi:washing-machine", | ||||
| @ -40,7 +47,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="stopProgram", | ||||
|             translation_key="washing_machine", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="pause", | ||||
|             name="Pause Washing Machine", | ||||
|             icon="mdi:pause", | ||||
| @ -48,79 +55,69 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="resumeProgram", | ||||
|             translation_key="pause", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.delayStatus", | ||||
|             name="Delay Status", | ||||
|             icon="mdi:timer-check", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="delay_time", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.haier_SoakPrewashSelection", | ||||
|             name="Soak Prewash Selection", | ||||
|             icon="mdi:tshirt-crew", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="prewash", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.permanentPressStatus", | ||||
|             name="Keep Fresh", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:refresh-circle", | ||||
|             translation_key="keep_fresh", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.autoSoftenerStatus", | ||||
|             name="Auto Dose Softener", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:teddy-bear", | ||||
|             translation_key="auto_dose_softener", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.autoDetergentStatus", | ||||
|             name="Auto Dose Detergent", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:cup", | ||||
|             translation_key="auto_dose_detergent", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.acquaplus", | ||||
|             name="Acqua Plus", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:water-plus", | ||||
|             translation_key="acqua_plus", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.extraRinse1", | ||||
|             name="Extra Rinse 1", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:numeric-1-box-multiple-outline", | ||||
|             translation_key="extra_rinse_1", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.extraRinse2", | ||||
|             name="Extra Rinse 2", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:numeric-2-box-multiple-outline", | ||||
|             translation_key="extra_rinse_2", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.extraRinse3", | ||||
|             name="Extra Rinse 3", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:numeric-3-box-multiple-outline", | ||||
|             translation_key="extra_rinse_3", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.goodNight", | ||||
|             name="Good Night", | ||||
|             icon="mdi:weather-night", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="good_night", | ||||
|         ), | ||||
|     ), | ||||
|     "TD": ( | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="active", | ||||
|             name="Tumble Dryer", | ||||
|             icon="mdi:tumble-dryer", | ||||
| @ -128,7 +125,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="stopProgram", | ||||
|             translation_key="tumble_dryer", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="pause", | ||||
|             name="Pause Tumble Dryer", | ||||
|             icon="mdi:pause", | ||||
| @ -136,29 +133,26 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="resumeProgram", | ||||
|             translation_key="pause", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.sterilizationStatus", | ||||
|             name="Sterilization", | ||||
|             icon="mdi:clock-start", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.antiCreaseTime", | ||||
|             name="Anti-Crease", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timer", | ||||
|             translation_key="anti_crease", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.anticrease", | ||||
|             name="Anti-Crease", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             icon="mdi:timer", | ||||
|             translation_key="anti_crease", | ||||
|         ), | ||||
|     ), | ||||
|     "OV": ( | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="active", | ||||
|             name="Oven", | ||||
|             icon="mdi:toaster-oven", | ||||
| @ -166,16 +160,15 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="stopProgram", | ||||
|             translation_key="oven", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.preheatStatus", | ||||
|             name="Preheat", | ||||
|             icon="mdi:thermometer-chevron-up", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="preheat", | ||||
|         ), | ||||
|     ), | ||||
|     "WD": ( | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="active", | ||||
|             name="Washer Dryer", | ||||
|             icon="mdi:washing-machine", | ||||
| @ -183,7 +176,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="stopProgram", | ||||
|             translation_key="washer_dryer", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="pause", | ||||
|             name="Pause Washer Dryer", | ||||
|             icon="mdi:pause", | ||||
| @ -193,7 +186,7 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "DW": ( | ||||
|         HonSwitchEntityDescription( | ||||
|         HonControlSwitchEntityDescription( | ||||
|             key="active", | ||||
|             name="Dish Washer", | ||||
|             icon="mdi:dishwasher", | ||||
| @ -201,50 +194,44 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|             turn_off_key="stopProgram", | ||||
|             translation_key="dish_washer", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.extraDry", | ||||
|             name="Extra Dry", | ||||
|             icon="mdi:hair-dryer", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="extra_dry", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.halfLoad", | ||||
|             name="Half Load", | ||||
|             icon="mdi:fraction-one-half", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="half_load", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.openDoor", | ||||
|             name="Open Door", | ||||
|             icon="mdi:door-open", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="open_door", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.threeInOne", | ||||
|             name="Three in One", | ||||
|             icon="mdi:numeric-3-box-outline", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="three_in_one", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.ecoExpress", | ||||
|             name="Eco Express", | ||||
|             icon="mdi:sprout", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="eco", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|         HonConfigSwitchEntityDescription( | ||||
|             key="startProgram.addDish", | ||||
|             name="Add Dish", | ||||
|             icon="mdi:silverware-fork-knife", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|             translation_key="add_dish", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.buzzerDisabled", | ||||
|             key="buzzerDisabled", | ||||
|             name="Buzzer Disabled", | ||||
|             icon="mdi:volume-off", | ||||
|             translation_key="buzzer", | ||||
| @ -252,65 +239,57 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|     ), | ||||
|     "AC": ( | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.10degreeHeatingStatus", | ||||
|             status_key="10degreeHeatingStatus", | ||||
|             key="10degreeHeatingStatus", | ||||
|             name="10° Heating", | ||||
|             icon="mdi:heat-wave", | ||||
|             translation_key="10_degree_heating", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.echoStatus", | ||||
|             status_key="echoStatus", | ||||
|             key="echoStatus", | ||||
|             name="Echo", | ||||
|             icon="mdi:account-voice", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.ecoMode", | ||||
|             key="ecoMode", | ||||
|             name="Eco Mode", | ||||
|             translation_key="eco_mode", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.healthMode", | ||||
|             status_key="healthMode", | ||||
|             key="healthMode", | ||||
|             name="Health Mode", | ||||
|             icon="mdi:medication-outline", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.muteStatus", | ||||
|             status_key="muteStatus", | ||||
|             key="muteStatus", | ||||
|             name="Mute", | ||||
|             icon="mdi:volume-off", | ||||
|             translation_key="mute_mode", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.rapidMode", | ||||
|             status_key="rapidMode", | ||||
|             key="rapidMode", | ||||
|             name="Rapid Mode", | ||||
|             icon="mdi:run-fast", | ||||
|             translation_key="rapid_mode", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.screenDisplayStatus", | ||||
|             status_key="screenDisplayStatus", | ||||
|             key="screenDisplayStatus", | ||||
|             name="Screen Display", | ||||
|             icon="mdi:monitor-small", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.selfCleaning56Status", | ||||
|             key="selfCleaning56Status", | ||||
|             name="Self Cleaning 56", | ||||
|             icon="mdi:air-filter", | ||||
|             translation_key="self_clean_56", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.selfCleaningStatus", | ||||
|             status_key="selfCleaningStatus", | ||||
|             key="selfCleaningStatus", | ||||
|             name="Self Cleaning", | ||||
|             icon="mdi:air-filter", | ||||
|             translation_key="self_clean", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.silentSleepStatus", | ||||
|             status_key="silentSleepStatus", | ||||
|             key="silentSleepStatus", | ||||
|             name="Silent Sleep", | ||||
|             icon="mdi:bed", | ||||
|             translation_key="silent_mode", | ||||
| @ -318,29 +297,25 @@ SWITCHES: dict[str, tuple[HonSwitchEntityDescription, ...]] = { | ||||
|     ), | ||||
|     "REF": ( | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.intelligenceMode", | ||||
|             status_key="intelligenceMode", | ||||
|             key="intelligenceMode", | ||||
|             name="Auto-Set Mode", | ||||
|             icon="mdi:thermometer-auto", | ||||
|             translation_key="auto_set", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.quickModeZ1", | ||||
|             status_key="quickModeZ1", | ||||
|             key="quickModeZ1", | ||||
|             name="Super Freeze", | ||||
|             icon="mdi:snowflake-variant", | ||||
|             translation_key="super_freeze", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.quickModeZ2", | ||||
|             status_key="quickModeZ2", | ||||
|             key="quickModeZ2", | ||||
|             name="Super Cool", | ||||
|             icon="mdi:snowflake", | ||||
|             translation_key="super_cool", | ||||
|         ), | ||||
|         HonSwitchEntityDescription( | ||||
|             key="settings.holidayMode", | ||||
|             status_key="holidayMode", | ||||
|             key="holidayMode", | ||||
|             name="Holiday Mode", | ||||
|             icon="mdi:palm-tree", | ||||
|             translation_key="holiday_mode", | ||||
| @ -356,19 +331,26 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
|     entities = [] | ||||
|     for device in hass.data[DOMAIN][entry.unique_id].appliances: | ||||
|         for description in SWITCHES.get(device.appliance_type, []): | ||||
|             if description.entity_category == EntityCategory.CONFIG: | ||||
|             if isinstance(description, HonConfigSwitchEntityDescription): | ||||
|                 if description.key not in device.available_settings: | ||||
|                     continue | ||||
|             else: | ||||
|                 if not any( | ||||
|                     [ | ||||
|                         device.get(description.key) is not None, | ||||
|                         description.turn_on_key in list(device.commands), | ||||
|                         description.turn_off_key in list(device.commands), | ||||
|                     ] | ||||
|                 entity = HonConfigSwitchEntity(hass, entry, device, description) | ||||
|             elif isinstance(description, HonControlSwitchEntityDescription): | ||||
|                 if not ( | ||||
|                     device.get(description.key) is not None | ||||
|                     or description.turn_on_key in list(device.commands) | ||||
|                     or description.turn_off_key in list(device.commands) | ||||
|                 ): | ||||
|                     continue | ||||
|             entity = HonSwitchEntity(hass, entry, device, description) | ||||
|                 entity = HonControlSwitchEntity(hass, entry, device, description) | ||||
|             elif isinstance(description, HonSwitchEntityDescription): | ||||
|                 if description.key not in device.available_settings or not device.get( | ||||
|                     description.key | ||||
|                 ): | ||||
|                     continue | ||||
|                 entity = HonSwitchEntity(hass, entry, device, description) | ||||
|             else: | ||||
|                 continue | ||||
|             await entity.coordinator.async_config_entry_first_refresh() | ||||
|             entities.append(entity) | ||||
|  | ||||
| @ -378,86 +360,100 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non | ||||
| class HonSwitchEntity(HonEntity, SwitchEntity): | ||||
|     entity_description: HonSwitchEntityDescription | ||||
|  | ||||
|     def __init__( | ||||
|         self, | ||||
|         hass, | ||||
|         entry, | ||||
|         device: HonAppliance, | ||||
|         description: HonSwitchEntityDescription, | ||||
|     ) -> None: | ||||
|         super().__init__(hass, entry, device) | ||||
|  | ||||
|         self.entity_description = description | ||||
|         self._attr_unique_id = f"{super().unique_id}{description.key}" | ||||
|  | ||||
|     @property | ||||
|     def is_on(self) -> bool | None: | ||||
|         """Return True if entity is on.""" | ||||
|         if self.entity_category == EntityCategory.CONFIG: | ||||
|             setting = self._device.settings[self.entity_description.key] | ||||
|             return ( | ||||
|                 setting.value == "1" | ||||
|                 or hasattr(setting, "min") | ||||
|                 and setting.value != setting.min | ||||
|             ) | ||||
|         elif self.entity_description.status_key: | ||||
|             return self._device.get(self.entity_description.status_key, "0") == "1" | ||||
|         return self._device.get(self.entity_description.key, False) | ||||
|         return self._device.get(self.entity_description.key, "0") == "1" | ||||
|  | ||||
|     async def async_turn_on(self, **kwargs: Any) -> None: | ||||
|         if ( | ||||
|             self.entity_category == EntityCategory.CONFIG | ||||
|             or "settings." in self.entity_description.key | ||||
|         ): | ||||
|             setting = self._device.settings[self.entity_description.key] | ||||
|             if not type(setting) == HonParameter: | ||||
|                 setting.value = ( | ||||
|                     setting.max if isinstance(setting, HonParameterRange) else "1" | ||||
|                 ) | ||||
|                 self.async_write_ha_state() | ||||
|                 await self.coordinator.async_refresh() | ||||
|                 if "settings." in self.entity_description.key: | ||||
|                     await self._device.commands["settings"].send() | ||||
|         else: | ||||
|             await self._device.commands[self.entity_description.turn_on_key].send() | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if type(setting) == HonParameter: | ||||
|             return | ||||
|         setting.value = setting.max if isinstance(setting, HonParameterRange) else "1" | ||||
|         self.async_write_ha_state() | ||||
|         await self._device.commands["settings"].send() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     async def async_turn_off(self, **kwargs: Any) -> None: | ||||
|         if ( | ||||
|             self.entity_category == EntityCategory.CONFIG | ||||
|             or "settings." in self.entity_description.key | ||||
|         ): | ||||
|             setting = self._device.settings[self.entity_description.key] | ||||
|             if not type(setting) == HonParameter: | ||||
|                 setting.value = ( | ||||
|                     setting.min if isinstance(setting, HonParameterRange) else "0" | ||||
|                 ) | ||||
|                 self.async_write_ha_state() | ||||
|                 if "settings." in self.entity_description.key: | ||||
|                     await self._device.commands["settings"].send() | ||||
|                 await self.coordinator.async_refresh() | ||||
|         else: | ||||
|             await self._device.commands[self.entity_description.turn_off_key].send() | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if type(setting) == HonParameter: | ||||
|             return | ||||
|         setting.value = setting.min if isinstance(setting, HonParameterRange) else "0" | ||||
|         self.async_write_ha_state() | ||||
|         await self._device.commands["settings"].send() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         if self.entity_category == EntityCategory.CONFIG: | ||||
|             return super().available | ||||
|         else: | ||||
|             return ( | ||||
|                 super().available | ||||
|                 and self._device.get("remoteCtrValid", "1") == "1" | ||||
|                 and self._device.get("attributes.lastConnEvent.category") | ||||
|                 != "DISCONNECTED" | ||||
|             ) | ||||
|         return ( | ||||
|             super().available | ||||
|             and self._device.get("remoteCtrValid", "1") == "1" | ||||
|             and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED" | ||||
|         ) | ||||
|  | ||||
|     @callback | ||||
|     def _handle_coordinator_update(self): | ||||
|         if self.entity_description.status_key: | ||||
|             value = self._device.get(self.entity_description.status_key, "0") | ||||
|         elif self.entity_category == EntityCategory.CONFIG: | ||||
|             value = self._device.settings.get(self.entity_description.key, "0") | ||||
|         else: | ||||
|             return | ||||
|         value = self._device.get(self.entity_description.key, "0") | ||||
|         self._attr_state = value == "1" | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
|  | ||||
| class HonControlSwitchEntity(HonEntity, SwitchEntity): | ||||
|     entity_description: HonControlSwitchEntityDescription | ||||
|  | ||||
|     @property | ||||
|     def is_on(self) -> bool | None: | ||||
|         """Return True if entity is on.""" | ||||
|         return self._device.get(self.entity_description.key, False) | ||||
|  | ||||
|     async def async_turn_on(self, **kwargs: Any) -> None: | ||||
|         await self._device.commands[self.entity_description.turn_on_key].send() | ||||
|  | ||||
|     async def async_turn_off(self, **kwargs: Any) -> None: | ||||
|         await self._device.commands[self.entity_description.turn_off_key].send() | ||||
|  | ||||
|     @property | ||||
|     def available(self) -> bool: | ||||
|         """Return True if entity is available.""" | ||||
|         return ( | ||||
|             super().available | ||||
|             and self._device.get("remoteCtrValid", "1") == "1" | ||||
|             and self._device.get("attributes.lastConnEvent.category") != "DISCONNECTED" | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class HonConfigSwitchEntity(HonEntity, SwitchEntity): | ||||
|     entity_description: HonConfigSwitchEntityDescription | ||||
|  | ||||
|     @property | ||||
|     def is_on(self) -> bool | None: | ||||
|         """Return True if entity is on.""" | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         return ( | ||||
|             setting.value == "1" | ||||
|             or hasattr(setting, "min") | ||||
|             and setting.value != setting.min | ||||
|         ) | ||||
|  | ||||
|     async def async_turn_on(self, **kwargs: Any) -> None: | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if type(setting) == HonParameter: | ||||
|             return | ||||
|         setting.value = setting.max if isinstance(setting, HonParameterRange) else "1" | ||||
|         self.async_write_ha_state() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     async def async_turn_off(self, **kwargs: Any) -> None: | ||||
|         setting = self._device.settings[self.entity_description.key] | ||||
|         if type(setting) == HonParameter: | ||||
|             return | ||||
|         setting.value = setting.min if isinstance(setting, HonParameterRange) else "0" | ||||
|         self.async_write_ha_state() | ||||
|         await self.coordinator.async_refresh() | ||||
|  | ||||
|     @callback | ||||
|     def _handle_coordinator_update(self): | ||||
|         value = self._device.settings.get(self.entity_description.key, "0") | ||||
|         self._attr_state = value == "1" | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
		Reference in New Issue
	
	Block a user