Refactor hon entities

This commit is contained in:
Andre Basche 2023-05-28 00:30:08 +02:00
parent 696dc136eb
commit a8762367ed
8 changed files with 382 additions and 369 deletions

View file

@ -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()