Use SelectEntityDescription for Xiaomi Miio integration (#53907)

* Use SelectEntityDescription

* Use SelectEntityDescription

* Remove service field from XiaomiMiioSelectDescription class

* Fix typo

* Use lowercase for options
This commit is contained in:
Maciej Bieniek
2021-08-03 15:58:30 +02:00
committed by Paulus Schoutsen
parent 07604e60e5
commit e4fd43ed7c
2 changed files with 40 additions and 36 deletions

View File

@@ -1,11 +1,13 @@
"""Support led_brightness for Mi Air Humidifier.""" """Support led_brightness for Mi Air Humidifier."""
from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
from miio.airhumidifier import LedBrightness as AirhumidifierLedBrightness from miio.airhumidifier import LedBrightness as AirhumidifierLedBrightness
from miio.airhumidifier_miot import LedBrightness as AirhumidifierMiotLedBrightness from miio.airhumidifier_miot import LedBrightness as AirhumidifierMiotLedBrightness
from homeassistant.components.select import SelectEntity from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.core import callback from homeassistant.core import callback
from .const import ( from .const import (
@@ -20,7 +22,6 @@ from .const import (
MODEL_AIRHUMIDIFIER_CA4, MODEL_AIRHUMIDIFIER_CA4,
MODEL_AIRHUMIDIFIER_CB1, MODEL_AIRHUMIDIFIER_CB1,
MODELS_HUMIDIFIER, MODELS_HUMIDIFIER,
SERVICE_SET_LED_BRIGHTNESS,
) )
from .device import XiaomiCoordinatedMiioEntity from .device import XiaomiCoordinatedMiioEntity
@@ -36,23 +37,19 @@ LED_BRIGHTNESS_REVERSE_MAP_MIOT = {
@dataclass @dataclass
class SelectorType: class XiaomiMiioSelectDescription(SelectEntityDescription):
"""Class that holds device specific info for a xiaomi aqara or humidifier selectors.""" """A class that describes select entities."""
name: str = None options: tuple = ()
icon: str = None
short_name: str = None
options: list = None
service: str = None
SELECTOR_TYPES = { SELECTOR_TYPES = {
FEATURE_SET_LED_BRIGHTNESS: SelectorType( FEATURE_SET_LED_BRIGHTNESS: XiaomiMiioSelectDescription(
name="Led brightness", key=ATTR_LED_BRIGHTNESS,
name="Led Brightness",
icon="mdi:brightness-6", icon="mdi:brightness-6",
short_name=ATTR_LED_BRIGHTNESS, device_class="xiaomi_miio__led_brightness",
options=["Bright", "Dim", "Off"], options=("bright", "dim", "off"),
service=SERVICE_SET_LED_BRIGHTNESS,
), ),
} }
@@ -65,7 +62,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities = [] entities = []
model = config_entry.data[CONF_MODEL] model = config_entry.data[CONF_MODEL]
device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE] device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE]
coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR]
if model in [MODEL_AIRHUMIDIFIER_CA1, MODEL_AIRHUMIDIFIER_CB1]: if model in [MODEL_AIRHUMIDIFIER_CA1, MODEL_AIRHUMIDIFIER_CB1]:
entity_class = XiaomiAirHumidifierSelector entity_class = XiaomiAirHumidifierSelector
@@ -76,15 +72,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
else: else:
return return
for selector in SELECTOR_TYPES.values(): description = SELECTOR_TYPES[FEATURE_SET_LED_BRIGHTNESS]
entities.append( entities.append(
entity_class( entity_class(
f"{config_entry.title} {selector.name}", f"{config_entry.title} {description.name}",
device, device,
config_entry, config_entry,
f"{selector.short_name}_{config_entry.unique_id}", f"{description.key}_{config_entry.unique_id}",
selector, hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
coordinator, description,
) )
) )
@@ -94,12 +90,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class XiaomiSelector(XiaomiCoordinatedMiioEntity, SelectEntity): class XiaomiSelector(XiaomiCoordinatedMiioEntity, SelectEntity):
"""Representation of a generic Xiaomi attribute selector.""" """Representation of a generic Xiaomi attribute selector."""
def __init__(self, name, device, entry, unique_id, selector, coordinator): def __init__(self, name, device, entry, unique_id, coordinator, description):
"""Initialize the generic Xiaomi attribute selector.""" """Initialize the generic Xiaomi attribute selector."""
super().__init__(name, device, entry, unique_id, coordinator) super().__init__(name, device, entry, unique_id, coordinator)
self._attr_icon = selector.icon self._attr_options = list(description.options)
self._controller = selector self.entity_description = description
self._attr_options = self._controller.options
@staticmethod @staticmethod
def _extract_value_from_attribute(state, attribute): def _extract_value_from_attribute(state, attribute):
@@ -113,33 +108,33 @@ class XiaomiSelector(XiaomiCoordinatedMiioEntity, SelectEntity):
class XiaomiAirHumidifierSelector(XiaomiSelector): class XiaomiAirHumidifierSelector(XiaomiSelector):
"""Representation of a Xiaomi Air Humidifier selector.""" """Representation of a Xiaomi Air Humidifier selector."""
def __init__(self, name, device, entry, unique_id, controller, coordinator): def __init__(self, name, device, entry, unique_id, coordinator, description):
"""Initialize the plug switch.""" """Initialize the plug switch."""
super().__init__(name, device, entry, unique_id, controller, coordinator) super().__init__(name, device, entry, unique_id, coordinator, description)
self._current_led_brightness = self._extract_value_from_attribute( self._current_led_brightness = self._extract_value_from_attribute(
self.coordinator.data, self._controller.short_name self.coordinator.data, self.entity_description.key
) )
@callback @callback
def _handle_coordinator_update(self): def _handle_coordinator_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
self._current_led_brightness = self._extract_value_from_attribute( self._current_led_brightness = self._extract_value_from_attribute(
self.coordinator.data, self._controller.short_name self.coordinator.data, self.entity_description.key
) )
self.async_write_ha_state() self.async_write_ha_state()
@property @property
def current_option(self): def current_option(self):
"""Return the current option.""" """Return the current option."""
return self.led_brightness return self.led_brightness.lower()
async def async_select_option(self, option: str) -> None: async def async_select_option(self, option: str) -> None:
"""Set an option of the miio device.""" """Set an option of the miio device."""
if option not in self.options: if option not in self.options:
raise ValueError( raise ValueError(
f"Selection '{option}' is not a valid {self._controller.name}" f"Selection '{option}' is not a valid {self.entity_description.name}"
) )
await self.async_set_led_brightness(option) await self.async_set_led_brightness(option.title())
@property @property
def led_brightness(self): def led_brightness(self):

View File

@@ -0,0 +1,9 @@
{
"state": {
"xiaomi_miio__led_brightness": {
"bright": "Bright",
"dim": "Dim",
"off": "Off"
}
}
}