Readable internal names for some selects

This commit is contained in:
Andre Basche 2023-06-12 00:20:38 +02:00
parent 52c3a861de
commit dfa5735bc2
25 changed files with 93 additions and 50 deletions

View file

@ -164,6 +164,7 @@ For every device exists a hidden button which can be used to log all infos of yo
| Filter Replacement | | `binary_sensor` | `filterChangeStatusLocal` | | Filter Replacement | | `binary_sensor` | `filterChangeStatusLocal` |
| In Air Temperature Outdoor | `thermometer` | `sensor` | `tempInAirOutdoor` | | In Air Temperature Outdoor | `thermometer` | `sensor` | `tempInAirOutdoor` |
| Indoor Temperature | `thermometer` | `sensor` | `tempIndoor` | | Indoor Temperature | `thermometer` | `sensor` | `tempIndoor` |
| Machine Status | `information` | `sensor` | `machMode` |
| Outdoor Temperature | `thermometer` | `sensor` | `tempOutdoor` | | Outdoor Temperature | `thermometer` | `sensor` | `tempOutdoor` |
| Program | | `select` | `startProgram.program` | | Program | | `select` | `startProgram.program` |
| Program | `play` | `sensor` | `programName` | | Program | `play` | `sensor` | `programName` |

View file

@ -128,6 +128,7 @@ TUMBLE_DRYER_PR_PHASE = {
} }
DIRTY_LEVEL = { DIRTY_LEVEL = {
"0": "unknown",
"1": "little", "1": "little",
"2": "normal", "2": "normal",
"3": "very", "3": "very",
@ -185,4 +186,5 @@ AC_HUMAN_SENSE = {
"0": "touch_off", "0": "touch_off",
"1": "avoid_touch", "1": "avoid_touch",
"2": "follow_touch", "2": "follow_touch",
"3": "unknown",
} }

View file

@ -11,5 +11,5 @@
"requirements": [ "requirements": [
"pyhOn==0.13.0" "pyhOn==0.13.0"
], ],
"version": "0.9.0-beta.1" "version": "0.9.0-beta.2"
} }

View file

@ -2,6 +2,7 @@ from __future__ import annotations
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict, List
from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -9,8 +10,8 @@ from homeassistant.const import UnitOfTemperature, UnitOfTime, REVOLUTIONS_PER_M
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from pyhon.appliance import HonAppliance from pyhon.appliance import HonAppliance
from pyhon.parameter.fixed import HonParameterFixed
from . import const
from .const import DOMAIN from .const import DOMAIN
from .hon import HonEntity, unique_entities from .hon import HonEntity, unique_entities
@ -19,12 +20,13 @@ _LOGGER = logging.getLogger(__name__)
@dataclass @dataclass
class HonSelectEntityDescription(SelectEntityDescription): class HonSelectEntityDescription(SelectEntityDescription):
pass option_list: Dict[str, str] = None
@dataclass @dataclass
class HonConfigSelectEntityDescription(SelectEntityDescription): class HonConfigSelectEntityDescription(SelectEntityDescription):
entity_category: EntityCategory = EntityCategory.CONFIG entity_category: EntityCategory = EntityCategory.CONFIG
option_list: Dict[str, str] = None
SELECTS = { SELECTS = {
@ -67,6 +69,7 @@ SELECTS = {
name="Dry level", name="Dry level",
icon="mdi:hair-dryer", icon="mdi:hair-dryer",
translation_key="dry_levels", translation_key="dry_levels",
option_list=const.TUMBLE_DRYER_DRY_LEVEL,
), ),
), ),
"OV": ( "OV": (
@ -115,6 +118,7 @@ SELECTS = {
name="Eco Pilot", name="Eco Pilot",
icon="mdi:run", icon="mdi:run",
translation_key="eco_pilot", translation_key="eco_pilot",
option_list=const.AC_HUMAN_SENSE,
), ),
), ),
"REF": ( "REF": (
@ -158,13 +162,6 @@ class HonSelectEntity(HonEntity, SelectEntity):
def __init__(self, hass, entry, device: HonAppliance, description) -> None: def __init__(self, hass, entry, device: HonAppliance, description) -> None:
super().__init__(hass, entry, device, description) super().__init__(hass, entry, device, description)
if not (setting := self._device.settings.get(description.key)):
self._attr_options: list[str] = []
elif not isinstance(setting, HonParameterFixed):
self._attr_options: list[str] = setting.values
else:
self._attr_options: list[str] = [setting.value]
@property @property
def current_option(self) -> str | None: def current_option(self) -> str | None:
value = self._device.settings.get(self.entity_description.key) value = self._device.settings.get(self.entity_description.key)
@ -183,12 +180,20 @@ class HonSelectEntity(HonEntity, SelectEntity):
setting = self._device.settings.get(self.entity_description.key) setting = self._device.settings.get(self.entity_description.key)
if setting is None: if setting is None:
self._attr_available = False self._attr_available = False
self._attr_options: list[str] = [] self._attr_options: List[str] = []
self._attr_native_value = None value = None
else: else:
self._attr_available = True self._attr_available = True
self._attr_options: list[str] = setting.values self._attr_options: List[str] = setting.values
self._attr_native_value = setting.value value = setting.value
if self.entity_description.option_list is not None:
self._attr_options = [
self.entity_description.option_list.get(k, k)
for k in self._attr_options
]
if value is not None:
value = self.entity_description.option_list.get(value, value)
self._attr_native_value = value
if update: if update:
self.async_write_ha_state() self.async_write_ha_state()

View file

@ -1,6 +1,6 @@
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from typing import List from typing import Dict
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorEntity, SensorEntity,
@ -21,7 +21,6 @@ from homeassistant.const import (
) )
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from pyhon.appliance import HonAppliance
from . import const from . import const
from .const import DOMAIN from .const import DOMAIN
@ -33,11 +32,12 @@ _LOGGER = logging.getLogger(__name__)
@dataclass @dataclass
class HonConfigSensorEntityDescription(SensorEntityDescription): class HonConfigSensorEntityDescription(SensorEntityDescription):
entity_category: EntityCategory = EntityCategory.CONFIG entity_category: EntityCategory = EntityCategory.CONFIG
option_list: Dict[str, str] = None
@dataclass @dataclass
class HonSensorEntityDescription(SensorEntityDescription): class HonSensorEntityDescription(SensorEntityDescription):
option_list: List = None option_list: Dict[str, str] = None
SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
@ -155,7 +155,9 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
key="dirtyLevel", key="dirtyLevel",
name="Dirt level", name="Dirt level",
icon="mdi:liquid-spot", icon="mdi:liquid-spot",
device_class=SensorDeviceClass.ENUM,
translation_key="dirt_level", translation_key="dirt_level",
option_list=const.DIRTY_LEVEL,
), ),
HonConfigSensorEntityDescription( HonConfigSensorEntityDescription(
key="startProgram.suggestedLoadW", key="startProgram.suggestedLoadW",
@ -256,14 +258,18 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
HonConfigSensorEntityDescription( HonConfigSensorEntityDescription(
key="startProgram.steamLevel", key="startProgram.steamLevel",
name="Steam level", name="Steam level",
device_class=SensorDeviceClass.ENUM,
icon="mdi:smoke", icon="mdi:smoke",
translation_key="steam_level", translation_key="steam_level",
option_list=const.STEAM_LEVEL,
), ),
HonSensorEntityDescription( HonSensorEntityDescription(
key="steamLevel", key="steamLevel",
name="Steam level", name="Steam level",
icon="mdi:smoke", icon="mdi:smoke",
device_class=SensorDeviceClass.ENUM,
translation_key="steam_level", translation_key="steam_level",
option_list=const.STEAM_LEVEL,
), ),
HonConfigSensorEntityDescription( HonConfigSensorEntityDescription(
key="steamType", key="steamType",
@ -494,6 +500,14 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = {
device_class=SensorDeviceClass.ENUM, device_class=SensorDeviceClass.ENUM,
translation_key="programs_ac", translation_key="programs_ac",
), ),
HonSensorEntityDescription(
key="machMode",
name="Machine Status",
icon="mdi:information",
device_class=SensorDeviceClass.ENUM,
translation_key="mach_modes_ac",
option_list=const.AC_MACH_MODE,
),
), ),
"REF": ( "REF": (
HonSensorEntityDescription( HonSensorEntityDescription(
@ -696,20 +710,16 @@ async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> Non
class HonSensorEntity(HonEntity, SensorEntity): class HonSensorEntity(HonEntity, SensorEntity):
entity_description: HonSensorEntityDescription entity_description: HonSensorEntityDescription
def __init__(self, hass, entry, device: HonAppliance, description):
super().__init__(hass, entry, device, description)
if description.key == "programName":
self._attr_options = self._device.settings.get(
"startProgram.program"
).values + ["No Program"]
elif description.option_list is not None:
self._attr_options = list(description.option_list.values())
@callback @callback
def _handle_coordinator_update(self, update=True) -> None: def _handle_coordinator_update(self, update=True) -> None:
value = self._device.get(self.entity_description.key, "") value = self._device.get(self.entity_description.key, "")
if self.entity_description.option_list is not None: if self.entity_description.key == "programName":
value = self.entity_description.option_list[value] self._attr_options = self._device.settings.get(
"startProgram.program"
).values + ["No Program"]
elif self.entity_description.option_list is not None:
self._attr_options = list(self.entity_description.option_list.values())
value = self.entity_description.option_list.get(value, value)
if not value and self.entity_description.state_class is not None: if not value and self.entity_description.state_class is not None:
self._attr_native_value = 0 self._attr_native_value = 0
self._attr_native_value = value self._attr_native_value = value
@ -725,12 +735,16 @@ class HonConfigSensorEntity(HonEntity, SensorEntity):
value = self._device.settings.get(self.entity_description.key, None) value = self._device.settings.get(self.entity_description.key, None)
if self.entity_description.state_class is not None: if self.entity_description.state_class is not None:
if value and value.value: if value and value.value:
self._attr_native_value = ( value = (
float(value.value) if "." in str(value.value) else int(value.value) float(value.value) if "." in str(value.value) else int(value.value)
) )
else: else:
self._attr_native_value = 0 value = 0
else: else:
self._attr_native_value = value.value value = value.value
if self.entity_description.option_list is not None and not value == 0:
self._attr_options = list(self.entity_description.option_list.values())
value = self.entity_description.option_list.get(value, value)
self._attr_native_value = value
if update: if update:
self.async_write_ha_state() self.async_write_ha_state()

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Vypnuto", "touch_off": "Vypnuto",
"avoid_touch": "Vyhybání", "avoid_touch": "Vyhybání",
"follow_touch": "Sledování" "follow_touch": "Sledování",
"unknown": "unknown"
}, },
"name": "Senzor osob" "name": "Senzor osob"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Aus", "touch_off": "Aus",
"avoid_touch": "Berührung vermeiden", "avoid_touch": "Berührung vermeiden",
"follow_touch": "Folgen" "follow_touch": "Folgen",
"unknown": "unknown"
}, },
"name": "Eco Pilot" "name": "Eco Pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Απενεργοποιηση", "touch_off": "Απενεργοποιηση",
"avoid_touch": "Αποφύγετε την αφή", "avoid_touch": "Αποφύγετε την αφή",
"follow_touch": "Σας ακολουθεί" "follow_touch": "Σας ακολουθεί",
"unknown": "unknown"
}, },
"name": "Οικολογικός πιλότος" "name": "Οικολογικός πιλότος"
}, },

View file

@ -894,7 +894,8 @@
"state": { "state": {
"touch_off": "Off", "touch_off": "Off",
"avoid_touch": "Avoid touch", "avoid_touch": "Avoid touch",
"follow_touch": "Follow" "follow_touch": "Follow",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Apagado", "touch_off": "Apagado",
"avoid_touch": "Evitar el contacto", "avoid_touch": "Evitar el contacto",
"follow_touch": "Sígueme" "follow_touch": "Sígueme",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Désactivé", "touch_off": "Désactivé",
"avoid_touch": "Évitez de toucher", "avoid_touch": "Évitez de toucher",
"follow_touch": "Suivi" "follow_touch": "Suivi",
"unknown": "unknown"
}, },
"name": "Pilote éco" "name": "Pilote éco"
}, },

View file

@ -431,7 +431,8 @@
"state": { "state": {
"touch_off": "Off", "touch_off": "Off",
"avoid_touch": "Avoid touch", "avoid_touch": "Avoid touch",
"follow_touch": "Follow" "follow_touch": "Follow",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Isključeno", "touch_off": "Isključeno",
"avoid_touch": "Izbjegavajte dodir", "avoid_touch": "Izbjegavajte dodir",
"follow_touch": "Pratite" "follow_touch": "Pratite",
"unknown": "unknown"
}, },
"name": "Eko-pilot" "name": "Eko-pilot"
}, },

View file

@ -878,7 +878,8 @@
"state": { "state": {
"touch_off": "Spento", "touch_off": "Spento",
"avoid_touch": "Avoid touch", "avoid_touch": "Avoid touch",
"follow_touch": "Segui" "follow_touch": "Segui",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Uit", "touch_off": "Uit",
"avoid_touch": "Voorkom aanraking", "avoid_touch": "Voorkom aanraking",
"follow_touch": "Volgen" "follow_touch": "Volgen",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Wyłącz", "touch_off": "Wyłącz",
"avoid_touch": "Unikanie kontaktu", "avoid_touch": "Unikanie kontaktu",
"follow_touch": "Podążanie" "follow_touch": "Podążanie",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Off", "touch_off": "Off",
"avoid_touch": "Evitar o toque", "avoid_touch": "Evitar o toque",
"follow_touch": "Seguir" "follow_touch": "Seguir",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Oprit", "touch_off": "Oprit",
"avoid_touch": "Evitați atingerea", "avoid_touch": "Evitați atingerea",
"follow_touch": "Urmărire" "follow_touch": "Urmărire",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "ВЫКЛ", "touch_off": "ВЫКЛ",
"avoid_touch": "Не прикасайтесь", "avoid_touch": "Не прикасайтесь",
"follow_touch": "Следование" "follow_touch": "Следование",
"unknown": "unknown"
}, },
"name": "Eco pilot" "name": "Eco pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Off (Vypnúť)", "touch_off": "Off (Vypnúť)",
"avoid_touch": "Nedotýkať sa", "avoid_touch": "Nedotýkať sa",
"follow_touch": "Nasledovať" "follow_touch": "Nasledovať",
"unknown": "unknown"
}, },
"name": "Ekologický pilot" "name": "Ekologický pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Izklop", "touch_off": "Izklop",
"avoid_touch": "Brez dotika", "avoid_touch": "Brez dotika",
"follow_touch": "Sledenje" "follow_touch": "Sledenje",
"unknown": "unknown"
}, },
"name": "Eko pilot" "name": "Eko pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Isključeno", "touch_off": "Isključeno",
"avoid_touch": "Izbegavajte dodir", "avoid_touch": "Izbegavajte dodir",
"follow_touch": "Pratiti" "follow_touch": "Pratiti",
"unknown": "unknown"
}, },
"name": "Eko pilot" "name": "Eko pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "Kapali", "touch_off": "Kapali",
"avoid_touch": "Dokunmaktan kaçının", "avoid_touch": "Dokunmaktan kaçının",
"follow_touch": "Takip et" "follow_touch": "Takip et",
"unknown": "unknown"
}, },
"name": "Eko pilot" "name": "Eko pilot"
}, },

View file

@ -873,7 +873,8 @@
"state": { "state": {
"touch_off": "关闭", "touch_off": "关闭",
"avoid_touch": "避免触摸", "avoid_touch": "避免触摸",
"follow_touch": "跟随" "follow_touch": "跟随",
"unknown": "unknown"
}, },
"name": "节能模式" "name": "节能模式"
}, },

View file

@ -35,6 +35,7 @@ DIRTY_LEVEL = {
"little": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.LITTLE", "little": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.LITTLE",
"normal": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NORMAL", "normal": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.NORMAL",
"very": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.VERY", "very": "WASHING_CMD&CTRL.PROGRAM_CYCLE_DETAIL_OPTIONS_VALUES_DESCRIPTION.VERY",
"unknown": "unknown",
} }
STEAM_LEVEL = { STEAM_LEVEL = {
@ -81,6 +82,7 @@ AC_HUMAN_SENSE = {
"touch_off": "AC.PROGRAM_DETAIL.TOUCH_OFF", "touch_off": "AC.PROGRAM_DETAIL.TOUCH_OFF",
"avoid_touch": "AC.PROGRAM_DETAIL.AVOID_TOUCH", "avoid_touch": "AC.PROGRAM_DETAIL.AVOID_TOUCH",
"follow_touch": "AC.PROGRAM_DETAIL.FOLLOW_TOUCH", "follow_touch": "AC.PROGRAM_DETAIL.FOLLOW_TOUCH",
"unknown": "unknown",
} }
REF_ZONES = { REF_ZONES = {