Add number
platform for Xiaomi Miio fan (#54977)
This commit is contained in:
parent
aa7c72a8b5
commit
4a6ca8a04e
4 changed files with 115 additions and 162 deletions
|
@ -46,7 +46,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
GATEWAY_PLATFORMS = ["alarm_control_panel", "light", "sensor", "switch"]
|
||||
SWITCH_PLATFORMS = ["switch"]
|
||||
FAN_PLATFORMS = ["fan", "select", "sensor", "switch"]
|
||||
FAN_PLATFORMS = ["fan", "number", "select", "sensor", "switch"]
|
||||
HUMIDIFIER_PLATFORMS = [
|
||||
"binary_sensor",
|
||||
"humidifier",
|
||||
|
|
|
@ -35,9 +35,6 @@ from .const import (
|
|||
FEATURE_FLAGS_AIRPURIFIER_V3,
|
||||
FEATURE_RESET_FILTER,
|
||||
FEATURE_SET_EXTRA_FEATURES,
|
||||
FEATURE_SET_FAN_LEVEL,
|
||||
FEATURE_SET_FAVORITE_LEVEL,
|
||||
FEATURE_SET_VOLUME,
|
||||
KEY_COORDINATOR,
|
||||
KEY_DEVICE,
|
||||
MODEL_AIRPURIFIER_2H,
|
||||
|
@ -48,9 +45,6 @@ from .const import (
|
|||
MODELS_PURIFIER_MIOT,
|
||||
SERVICE_RESET_FILTER,
|
||||
SERVICE_SET_EXTRA_FEATURES,
|
||||
SERVICE_SET_FAN_LEVEL,
|
||||
SERVICE_SET_FAVORITE_LEVEL,
|
||||
SERVICE_SET_VOLUME,
|
||||
)
|
||||
from .device import XiaomiCoordinatedMiioEntity
|
||||
|
||||
|
@ -64,9 +58,7 @@ CONF_MODEL = "model"
|
|||
ATTR_MODEL = "model"
|
||||
|
||||
# Air Purifier
|
||||
ATTR_FAVORITE_LEVEL = "favorite_level"
|
||||
ATTR_BRIGHTNESS = "brightness"
|
||||
ATTR_LEVEL = "level"
|
||||
ATTR_FAN_LEVEL = "fan_level"
|
||||
ATTR_SLEEP_TIME = "sleep_time"
|
||||
ATTR_SLEEP_LEARN_COUNT = "sleep_mode_learn_count"
|
||||
|
@ -74,14 +66,12 @@ ATTR_EXTRA_FEATURES = "extra_features"
|
|||
ATTR_FEATURES = "features"
|
||||
ATTR_TURBO_MODE_SUPPORTED = "turbo_mode_supported"
|
||||
ATTR_SLEEP_MODE = "sleep_mode"
|
||||
ATTR_VOLUME = "volume"
|
||||
ATTR_USE_TIME = "use_time"
|
||||
ATTR_BUTTON_PRESSED = "button_pressed"
|
||||
|
||||
# Map attributes to properties of the state object
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON = {
|
||||
ATTR_MODE: "mode",
|
||||
ATTR_FAVORITE_LEVEL: "favorite_level",
|
||||
ATTR_EXTRA_FEATURES: "extra_features",
|
||||
ATTR_TURBO_MODE_SUPPORTED: "turbo_mode_supported",
|
||||
ATTR_BUTTON_PRESSED: "button_pressed",
|
||||
|
@ -98,27 +88,20 @@ AVAILABLE_ATTRIBUTES_AIRPURIFIER = {
|
|||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_PRO = {
|
||||
**AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON,
|
||||
ATTR_USE_TIME: "use_time",
|
||||
ATTR_VOLUME: "volume",
|
||||
ATTR_SLEEP_TIME: "sleep_time",
|
||||
ATTR_SLEEP_LEARN_COUNT: "sleep_mode_learn_count",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_MIOT = {
|
||||
ATTR_MODE: "mode",
|
||||
ATTR_FAVORITE_LEVEL: "favorite_level",
|
||||
ATTR_USE_TIME: "use_time",
|
||||
ATTR_FAN_LEVEL: "fan_level",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_PRO_V7 = {
|
||||
**AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON,
|
||||
ATTR_VOLUME: "volume",
|
||||
}
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_PRO_V7 = AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_V3 = {
|
||||
# Common set isn't used here. It's a very basic version of the device.
|
||||
ATTR_MODE: "mode",
|
||||
ATTR_VOLUME: "volume",
|
||||
ATTR_SLEEP_TIME: "sleep_time",
|
||||
ATTR_SLEEP_LEARN_COUNT: "sleep_mode_learn_count",
|
||||
ATTR_EXTRA_FEATURES: "extra_features",
|
||||
|
@ -164,33 +147,12 @@ PRESET_MODES_AIRFRESH = ["Auto", "Interval"]
|
|||
|
||||
AIRPURIFIER_SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids})
|
||||
|
||||
SERVICE_SCHEMA_FAVORITE_LEVEL = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_LEVEL): vol.All(vol.Coerce(int), vol.Clamp(min=0, max=17))}
|
||||
)
|
||||
|
||||
SERVICE_SCHEMA_FAN_LEVEL = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_LEVEL): vol.All(vol.Coerce(int), vol.Clamp(min=1, max=3))}
|
||||
)
|
||||
|
||||
SERVICE_SCHEMA_VOLUME = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_VOLUME): vol.All(vol.Coerce(int), vol.Clamp(min=0, max=100))}
|
||||
)
|
||||
|
||||
SERVICE_SCHEMA_EXTRA_FEATURES = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
||||
{vol.Required(ATTR_FEATURES): cv.positive_int}
|
||||
)
|
||||
|
||||
SERVICE_TO_METHOD = {
|
||||
SERVICE_RESET_FILTER: {"method": "async_reset_filter"},
|
||||
SERVICE_SET_FAVORITE_LEVEL: {
|
||||
"method": "async_set_favorite_level",
|
||||
"schema": SERVICE_SCHEMA_FAVORITE_LEVEL,
|
||||
},
|
||||
SERVICE_SET_FAN_LEVEL: {
|
||||
"method": "async_set_fan_level",
|
||||
"schema": SERVICE_SCHEMA_FAN_LEVEL,
|
||||
},
|
||||
SERVICE_SET_VOLUME: {"method": "async_set_volume", "schema": SERVICE_SCHEMA_VOLUME},
|
||||
SERVICE_SET_EXTRA_FEATURES: {
|
||||
"method": "async_set_extra_features",
|
||||
"schema": SERVICE_SCHEMA_EXTRA_FEATURES,
|
||||
|
@ -513,39 +475,6 @@ class XiaomiAirPurifier(XiaomiGenericDevice):
|
|||
self.PRESET_MODE_MAPPING[preset_mode],
|
||||
)
|
||||
|
||||
async def async_set_favorite_level(self, level: int = 1):
|
||||
"""Set the favorite level."""
|
||||
if self._device_features & FEATURE_SET_FAVORITE_LEVEL == 0:
|
||||
return
|
||||
|
||||
await self._try_command(
|
||||
"Setting the favorite level of the miio device failed.",
|
||||
self._device.set_favorite_level,
|
||||
level,
|
||||
)
|
||||
|
||||
async def async_set_fan_level(self, level: int = 1):
|
||||
"""Set the favorite level."""
|
||||
if self._device_features & FEATURE_SET_FAN_LEVEL == 0:
|
||||
return
|
||||
|
||||
await self._try_command(
|
||||
"Setting the fan level of the miio device failed.",
|
||||
self._device.set_fan_level,
|
||||
level,
|
||||
)
|
||||
|
||||
async def async_set_volume(self, volume: int = 50):
|
||||
"""Set the sound volume."""
|
||||
if self._device_features & FEATURE_SET_VOLUME == 0:
|
||||
return
|
||||
|
||||
await self._try_command(
|
||||
"Setting the sound volume of the miio device failed.",
|
||||
self._device.set_volume,
|
||||
volume,
|
||||
)
|
||||
|
||||
async def async_set_extra_features(self, features: int = 1):
|
||||
"""Set the extra features."""
|
||||
if self._device_features & FEATURE_SET_EXTRA_FEATURES == 0:
|
||||
|
|
|
@ -12,14 +12,40 @@ from .const import (
|
|||
CONF_FLOW_TYPE,
|
||||
CONF_MODEL,
|
||||
DOMAIN,
|
||||
FEATURE_FLAGS_AIRFRESH,
|
||||
FEATURE_FLAGS_AIRHUMIDIFIER_CA4,
|
||||
FEATURE_FLAGS_AIRHUMIDIFIER_CA_AND_CB,
|
||||
FEATURE_FLAGS_AIRPURIFIER_2S,
|
||||
FEATURE_FLAGS_AIRPURIFIER_MIIO,
|
||||
FEATURE_FLAGS_AIRPURIFIER_MIOT,
|
||||
FEATURE_FLAGS_AIRPURIFIER_PRO,
|
||||
FEATURE_FLAGS_AIRPURIFIER_PRO_V7,
|
||||
FEATURE_FLAGS_AIRPURIFIER_V1,
|
||||
FEATURE_FLAGS_AIRPURIFIER_V3,
|
||||
FEATURE_SET_FAN_LEVEL,
|
||||
FEATURE_SET_FAVORITE_LEVEL,
|
||||
FEATURE_SET_MOTOR_SPEED,
|
||||
FEATURE_SET_VOLUME,
|
||||
KEY_COORDINATOR,
|
||||
KEY_DEVICE,
|
||||
MODEL_AIRFRESH_VA2,
|
||||
MODEL_AIRHUMIDIFIER_CA1,
|
||||
MODEL_AIRHUMIDIFIER_CA4,
|
||||
MODEL_AIRHUMIDIFIER_CB1,
|
||||
MODEL_AIRPURIFIER_2S,
|
||||
MODEL_AIRPURIFIER_PRO,
|
||||
MODEL_AIRPURIFIER_PRO_V7,
|
||||
MODEL_AIRPURIFIER_V1,
|
||||
MODEL_AIRPURIFIER_V3,
|
||||
MODELS_PURIFIER_MIIO,
|
||||
MODELS_PURIFIER_MIOT,
|
||||
)
|
||||
from .device import XiaomiCoordinatedMiioEntity
|
||||
|
||||
ATTR_FAN_LEVEL = "fan_level"
|
||||
ATTR_FAVORITE_LEVEL = "favorite_level"
|
||||
ATTR_MOTOR_SPEED = "motor_speed"
|
||||
ATTR_VOLUME = "volume"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -30,6 +56,7 @@ class XiaomiMiioNumberDescription(NumberEntityDescription):
|
|||
max_value: float | None = None
|
||||
step: float | None = None
|
||||
available_with_device_off: bool = True
|
||||
method: str | None = None
|
||||
|
||||
|
||||
NUMBER_TYPES = {
|
||||
|
@ -42,7 +69,47 @@ NUMBER_TYPES = {
|
|||
max_value=2000,
|
||||
step=10,
|
||||
available_with_device_off=False,
|
||||
method="async_set_motor_speed",
|
||||
),
|
||||
FEATURE_SET_FAVORITE_LEVEL: XiaomiMiioNumberDescription(
|
||||
key=ATTR_FAVORITE_LEVEL,
|
||||
name="Favorite Level",
|
||||
icon="mdi:star-cog",
|
||||
min_value=0,
|
||||
max_value=17,
|
||||
step=1,
|
||||
method="async_set_favorite_level",
|
||||
),
|
||||
FEATURE_SET_FAN_LEVEL: XiaomiMiioNumberDescription(
|
||||
key=ATTR_FAN_LEVEL,
|
||||
name="Fan Level",
|
||||
icon="mdi:fan",
|
||||
min_value=1,
|
||||
max_value=3,
|
||||
step=1,
|
||||
method="async_set_fan_level",
|
||||
),
|
||||
FEATURE_SET_VOLUME: XiaomiMiioNumberDescription(
|
||||
key=ATTR_VOLUME,
|
||||
name="Volume",
|
||||
icon="mdi:volume-high",
|
||||
min_value=1,
|
||||
max_value=100,
|
||||
step=1,
|
||||
method="async_set_volume",
|
||||
),
|
||||
}
|
||||
|
||||
MODEL_TO_FEATURES_MAP = {
|
||||
MODEL_AIRHUMIDIFIER_CA1: FEATURE_FLAGS_AIRHUMIDIFIER_CA_AND_CB,
|
||||
MODEL_AIRHUMIDIFIER_CA4: FEATURE_FLAGS_AIRHUMIDIFIER_CA4,
|
||||
MODEL_AIRHUMIDIFIER_CB1: FEATURE_FLAGS_AIRHUMIDIFIER_CA_AND_CB,
|
||||
MODEL_AIRPURIFIER_2S: FEATURE_FLAGS_AIRPURIFIER_2S,
|
||||
MODEL_AIRPURIFIER_PRO: FEATURE_FLAGS_AIRPURIFIER_PRO,
|
||||
MODEL_AIRPURIFIER_PRO_V7: FEATURE_FLAGS_AIRPURIFIER_PRO_V7,
|
||||
MODEL_AIRPURIFIER_V1: FEATURE_FLAGS_AIRPURIFIER_V1,
|
||||
MODEL_AIRPURIFIER_V3: FEATURE_FLAGS_AIRPURIFIER_V3,
|
||||
MODEL_AIRFRESH_VA2: FEATURE_FLAGS_AIRFRESH,
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,25 +121,32 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
model = config_entry.data[CONF_MODEL]
|
||||
device = hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE]
|
||||
|
||||
if model != MODEL_AIRHUMIDIFIER_CA4:
|
||||
if model in MODEL_TO_FEATURES_MAP:
|
||||
features = MODEL_TO_FEATURES_MAP[model]
|
||||
elif model in MODELS_PURIFIER_MIIO:
|
||||
features = FEATURE_FLAGS_AIRPURIFIER_MIIO
|
||||
elif model in MODELS_PURIFIER_MIOT:
|
||||
features = FEATURE_FLAGS_AIRPURIFIER_MIOT
|
||||
else:
|
||||
return
|
||||
|
||||
description = NUMBER_TYPES[FEATURE_SET_MOTOR_SPEED]
|
||||
entities.append(
|
||||
XiaomiAirHumidifierNumber(
|
||||
f"{config_entry.title} {description.name}",
|
||||
device,
|
||||
config_entry,
|
||||
f"{description.key}_{config_entry.unique_id}",
|
||||
hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
|
||||
description,
|
||||
)
|
||||
)
|
||||
for feature, description in NUMBER_TYPES.items():
|
||||
if feature & features:
|
||||
entities.append(
|
||||
XiaomiNumberEntity(
|
||||
f"{config_entry.title} {description.name}",
|
||||
device,
|
||||
config_entry,
|
||||
f"{description.key}_{config_entry.unique_id}",
|
||||
hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
|
||||
description,
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
|
||||
class XiaomiNumberEntity(XiaomiCoordinatedMiioEntity, NumberEntity):
|
||||
"""Representation of a generic Xiaomi attribute selector."""
|
||||
|
||||
def __init__(self, name, device, entry, unique_id, coordinator, description):
|
||||
|
@ -108,7 +182,8 @@ class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
|
|||
|
||||
async def async_set_value(self, value):
|
||||
"""Set an option of the miio device."""
|
||||
if await self.async_set_motor_speed(value):
|
||||
method = getattr(self, self.entity_description.method)
|
||||
if await method(value):
|
||||
self._attr_value = value
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
@ -128,3 +203,27 @@ class XiaomiAirHumidifierNumber(XiaomiCoordinatedMiioEntity, NumberEntity):
|
|||
self._device.set_speed,
|
||||
motor_speed,
|
||||
)
|
||||
|
||||
async def async_set_favorite_level(self, level: int = 1):
|
||||
"""Set the favorite level."""
|
||||
return await self._try_command(
|
||||
"Setting the favorite level of the miio device failed.",
|
||||
self._device.set_favorite_level,
|
||||
level,
|
||||
)
|
||||
|
||||
async def async_set_fan_level(self, level: int = 1):
|
||||
"""Set the fan level."""
|
||||
return await self._try_command(
|
||||
"Setting the favorite level of the miio device failed.",
|
||||
self._device.set_fan_level,
|
||||
level,
|
||||
)
|
||||
|
||||
async def async_set_volume(self, volume: int = 50):
|
||||
"""Set the volume."""
|
||||
return await self._try_command(
|
||||
"Setting the volume of the miio device failed.",
|
||||
self._device.set_volume,
|
||||
volume,
|
||||
)
|
||||
|
|
|
@ -1,58 +1,3 @@
|
|||
fan_set_favorite_level:
|
||||
name: Fan set favorite level
|
||||
description: Set the favorite level.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
selector:
|
||||
entity:
|
||||
integration: xiaomi_miio
|
||||
domain: fan
|
||||
level:
|
||||
name: Level
|
||||
description: Level.
|
||||
required: true
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 17
|
||||
|
||||
fan_set_fan_level:
|
||||
name: Fan set level
|
||||
description: Set the fan level.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
selector:
|
||||
entity:
|
||||
integration: xiaomi_miio
|
||||
domain: fan
|
||||
level:
|
||||
name: Level
|
||||
description: Level.
|
||||
selector:
|
||||
number:
|
||||
min: 1
|
||||
max: 3
|
||||
|
||||
fan_set_volume:
|
||||
name: Fan set volume
|
||||
description: Set the sound volume.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
selector:
|
||||
entity:
|
||||
integration: xiaomi_miio
|
||||
domain: fan
|
||||
volume:
|
||||
description: Volume.
|
||||
required: true
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 100
|
||||
|
||||
fan_reset_filter:
|
||||
name: Fan reset filter
|
||||
description: Reset the filter lifetime and usage.
|
||||
|
@ -83,26 +28,6 @@ fan_set_extra_features:
|
|||
min: 0
|
||||
max: 1
|
||||
|
||||
fan_set_motor_speed:
|
||||
name: Fan set motor speed
|
||||
description: Set the target motor speed.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
selector:
|
||||
entity:
|
||||
integration: xiaomi_miio
|
||||
domain: fan
|
||||
motor_speed:
|
||||
name: Motor speed
|
||||
description: Set motor speed.
|
||||
required: true
|
||||
selector:
|
||||
number:
|
||||
min: 200
|
||||
max: 2000
|
||||
unit_of_measurement: 'RPM'
|
||||
|
||||
light_set_scene:
|
||||
name: Light set scene
|
||||
description: Set a fixed scene.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue