Use NumberEntityDescription for Xiaomi Miio (#53911)

This commit is contained in:
Maciej Bieniek 2021-08-04 12:03:18 +02:00 committed by GitHub
parent 8f014361d4
commit 3b212b9109
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,8 +1,10 @@
"""Motor speed support for Xiaomi Mi Air Humidifier.""" """Motor speed support for Xiaomi Mi Air Humidifier."""
from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
from homeassistant.components.number import NumberEntity from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.core import callback from homeassistant.core import callback
from .const import ( from .const import (
@ -21,28 +23,23 @@ ATTR_MOTOR_SPEED = "motor_speed"
@dataclass @dataclass
class NumberType: class XiaomiMiioNumberDescription(NumberEntityDescription):
"""Class that holds device specific info for a xiaomi aqara or humidifier number controller types.""" """A class that describes number entities."""
name: str = None min_value: float | None = None
short_name: str = None max_value: float | None = None
unit_of_measurement: str = None step: float | None = None
icon: str = None
device_class: str = None
min: float = None
max: float = None
step: float = None
available_with_device_off: bool = True available_with_device_off: bool = True
NUMBER_TYPES = { NUMBER_TYPES = {
FEATURE_SET_MOTOR_SPEED: NumberType( FEATURE_SET_MOTOR_SPEED: XiaomiMiioNumberDescription(
key=ATTR_MOTOR_SPEED,
name="Motor Speed", name="Motor Speed",
icon="mdi:fast-forward-outline", icon="mdi:fast-forward-outline",
short_name=ATTR_MOTOR_SPEED,
unit_of_measurement="rpm", unit_of_measurement="rpm",
min=200, min_value=200,
max=2000, max_value=2000,
step=10, step=10,
available_with_device_off=False, available_with_device_off=False,
), ),
@ -56,22 +53,21 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
return return
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 not in [MODEL_AIRHUMIDIFIER_CA4]: if model != MODEL_AIRHUMIDIFIER_CA4:
return return
for number in NUMBER_TYPES.values(): description = NUMBER_TYPES[FEATURE_SET_MOTOR_SPEED]
entities.append( entities.append(
XiaomiAirHumidifierNumber( XiaomiAirHumidifierNumber(
f"{config_entry.title} {number.name}", f"{config_entry.title} {description.name}",
device, device,
config_entry, config_entry,
f"{number.short_name}_{config_entry.unique_id}", f"{description.key}_{config_entry.unique_id}",
number, hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
coordinator, description,
)
) )
)
async_add_entities(entities) async_add_entities(entities)
@ -79,18 +75,17 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity): class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
"""Representation of a generic Xiaomi attribute selector.""" """Representation of a generic Xiaomi attribute selector."""
def __init__(self, name, device, entry, unique_id, number, 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 = number.icon
self._attr_unit_of_measurement = number.unit_of_measurement self._attr_min_value = description.min_value
self._attr_min_value = number.min self._attr_max_value = description.max_value
self._attr_max_value = number.max self._attr_step = description.step
self._attr_step = number.step
self._controller = number
self._attr_value = self._extract_value_from_attribute( self._attr_value = self._extract_value_from_attribute(
self.coordinator.data, self._controller.short_name coordinator.data, description.key
) )
self.entity_description = description
@property @property
def available(self): def available(self):
@ -98,7 +93,7 @@ class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
if ( if (
super().available super().available
and not self.coordinator.data.is_on and not self.coordinator.data.is_on
and not self._controller.available_with_device_off and not self.entity_description.available_with_device_off
): ):
return False return False
return super().available return super().available
@ -131,7 +126,7 @@ class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
"""Fetch state from the device.""" """Fetch state from the device."""
# On state change the device doesn't provide the new state immediately. # On state change the device doesn't provide the new state immediately.
self._attr_value = self._extract_value_from_attribute( self._attr_value = 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()