Add support for Mi AirPurifier 3 (#31729)
* Adding support for Mi AirPurifier 3 * Adding support for Mi AirPurifier 3H * Enabled setting fan level for AirPurifier 3/3H * Get rid of isinstance for MIOT AirPurifier * Bumping xiaomi-miio dependency * Fixed lint error * Update manifest.json * Fixed requirements files for 0.5.0.1 Co-authored-by: Piotr Król <Piotr@gorszyportal.pl>pull/33586/head
parent
c0315e32bd
commit
912eb321d9
|
@ -10,6 +10,7 @@ SERVICE_SET_CHILD_LOCK_ON = "fan_set_child_lock_on"
|
|||
SERVICE_SET_CHILD_LOCK_OFF = "fan_set_child_lock_off"
|
||||
SERVICE_SET_LED_BRIGHTNESS = "fan_set_led_brightness"
|
||||
SERVICE_SET_FAVORITE_LEVEL = "fan_set_favorite_level"
|
||||
SERVICE_SET_FAN_LEVEL = "fan_set_fan_level"
|
||||
SERVICE_SET_AUTO_DETECT_ON = "fan_set_auto_detect_on"
|
||||
SERVICE_SET_AUTO_DETECT_OFF = "fan_set_auto_detect_off"
|
||||
SERVICE_SET_LEARN_MODE_ON = "fan_set_learn_mode_on"
|
||||
|
|
|
@ -8,6 +8,7 @@ from miio import ( # pylint: disable=import-error
|
|||
AirFresh,
|
||||
AirHumidifier,
|
||||
AirPurifier,
|
||||
AirPurifierMiot,
|
||||
Device,
|
||||
DeviceException,
|
||||
)
|
||||
|
@ -23,6 +24,10 @@ from miio.airpurifier import ( # pylint: disable=import-error, import-error
|
|||
LedBrightness as AirpurifierLedBrightness,
|
||||
OperationMode as AirpurifierOperationMode,
|
||||
)
|
||||
from miio.airpurifier_miot import ( # pylint: disable=import-error, import-error
|
||||
LedBrightness as AirpurifierMiotLedBrightness,
|
||||
OperationMode as AirpurifierMiotOperationMode,
|
||||
)
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.fan import PLATFORM_SCHEMA, SUPPORT_SET_SPEED, FanEntity
|
||||
|
@ -48,6 +53,7 @@ from .const import (
|
|||
SERVICE_SET_DRY_OFF,
|
||||
SERVICE_SET_DRY_ON,
|
||||
SERVICE_SET_EXTRA_FEATURES,
|
||||
SERVICE_SET_FAN_LEVEL,
|
||||
SERVICE_SET_FAVORITE_LEVEL,
|
||||
SERVICE_SET_LEARN_MODE_OFF,
|
||||
SERVICE_SET_LEARN_MODE_ON,
|
||||
|
@ -77,6 +83,8 @@ MODEL_AIRPURIFIER_MA2 = "zhimi.airpurifier.ma2"
|
|||
MODEL_AIRPURIFIER_SA1 = "zhimi.airpurifier.sa1"
|
||||
MODEL_AIRPURIFIER_SA2 = "zhimi.airpurifier.sa2"
|
||||
MODEL_AIRPURIFIER_2S = "zhimi.airpurifier.mc1"
|
||||
MODEL_AIRPURIFIER_3 = "zhimi.airpurifier.ma4"
|
||||
MODEL_AIRPURIFIER_3H = "zhimi.airpurifier.mb3"
|
||||
|
||||
MODEL_AIRHUMIDIFIER_V1 = "zhimi.humidifier.v1"
|
||||
MODEL_AIRHUMIDIFIER_CA1 = "zhimi.humidifier.ca1"
|
||||
|
@ -104,6 +112,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
MODEL_AIRPURIFIER_SA1,
|
||||
MODEL_AIRPURIFIER_SA2,
|
||||
MODEL_AIRPURIFIER_2S,
|
||||
MODEL_AIRPURIFIER_3,
|
||||
MODEL_AIRPURIFIER_3H,
|
||||
MODEL_AIRHUMIDIFIER_V1,
|
||||
MODEL_AIRHUMIDIFIER_CA1,
|
||||
MODEL_AIRHUMIDIFIER_CB1,
|
||||
|
@ -131,6 +141,7 @@ ATTR_AVERAGE_AIR_QUALITY_INDEX = "average_aqi"
|
|||
ATTR_PURIFY_VOLUME = "purify_volume"
|
||||
ATTR_BRIGHTNESS = "brightness"
|
||||
ATTR_LEVEL = "level"
|
||||
ATTR_FAN_LEVEL = "fan_level"
|
||||
ATTR_MOTOR2_SPEED = "motor2_speed"
|
||||
ATTR_ILLUMINANCE = "illuminance"
|
||||
ATTR_FILTER_RFID_PRODUCT_ID = "filter_rfid_product_id"
|
||||
|
@ -154,13 +165,15 @@ ATTR_TRANS_LEVEL = "trans_level"
|
|||
ATTR_HARDWARE_VERSION = "hardware_version"
|
||||
|
||||
# Air Humidifier CA
|
||||
ATTR_MOTOR_SPEED = "motor_speed"
|
||||
# ATTR_MOTOR_SPEED = "motor_speed"
|
||||
ATTR_DEPTH = "depth"
|
||||
ATTR_DRY = "dry"
|
||||
|
||||
# Air Fresh
|
||||
ATTR_CO2 = "co2"
|
||||
|
||||
PURIFIER_MIOT = [MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3H]
|
||||
|
||||
# Map attributes to properties of the state object
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON = {
|
||||
ATTR_TEMPERATURE: "temperature",
|
||||
|
@ -227,6 +240,28 @@ AVAILABLE_ATTRIBUTES_AIRPURIFIER_2S = {
|
|||
ATTR_ILLUMINANCE: "illuminance",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_3 = {
|
||||
ATTR_TEMPERATURE: "temperature",
|
||||
ATTR_HUMIDITY: "humidity",
|
||||
ATTR_AIR_QUALITY_INDEX: "aqi",
|
||||
ATTR_MODE: "mode",
|
||||
ATTR_FILTER_HOURS_USED: "filter_hours_used",
|
||||
ATTR_FILTER_LIFE: "filter_life_remaining",
|
||||
ATTR_FAVORITE_LEVEL: "favorite_level",
|
||||
ATTR_CHILD_LOCK: "child_lock",
|
||||
ATTR_LED: "led",
|
||||
ATTR_MOTOR_SPEED: "motor_speed",
|
||||
ATTR_AVERAGE_AIR_QUALITY_INDEX: "average_aqi",
|
||||
ATTR_PURIFY_VOLUME: "purify_volume",
|
||||
ATTR_USE_TIME: "use_time",
|
||||
ATTR_BUZZER: "buzzer",
|
||||
ATTR_LED_BRIGHTNESS: "led_brightness",
|
||||
ATTR_FILTER_RFID_PRODUCT_ID: "filter_rfid_product_id",
|
||||
ATTR_FILTER_RFID_TAG: "filter_rfid_tag",
|
||||
ATTR_FILTER_TYPE: "filter_type",
|
||||
ATTR_FAN_LEVEL: "fan_level",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_V3 = {
|
||||
# Common set isn't used here. It's a very basic version of the device.
|
||||
ATTR_AIR_QUALITY_INDEX: "aqi",
|
||||
|
@ -302,6 +337,7 @@ OPERATION_MODES_AIRPURIFIER = ["Auto", "Silent", "Favorite", "Idle"]
|
|||
OPERATION_MODES_AIRPURIFIER_PRO = ["Auto", "Silent", "Favorite"]
|
||||
OPERATION_MODES_AIRPURIFIER_PRO_V7 = OPERATION_MODES_AIRPURIFIER_PRO
|
||||
OPERATION_MODES_AIRPURIFIER_2S = ["Auto", "Silent", "Favorite"]
|
||||
OPERATION_MODES_AIRPURIFIER_3 = ["Auto", "Silent", "Favorite", "Fan"]
|
||||
OPERATION_MODES_AIRPURIFIER_V3 = [
|
||||
"Auto",
|
||||
"Silent",
|
||||
|
@ -327,6 +363,7 @@ FEATURE_RESET_FILTER = 256
|
|||
FEATURE_SET_EXTRA_FEATURES = 512
|
||||
FEATURE_SET_TARGET_HUMIDITY = 1024
|
||||
FEATURE_SET_DRY = 2048
|
||||
FEATURE_SET_FAN_LEVEL = 4096
|
||||
|
||||
FEATURE_FLAGS_AIRPURIFIER = (
|
||||
FEATURE_SET_BUZZER
|
||||
|
@ -361,6 +398,15 @@ FEATURE_FLAGS_AIRPURIFIER_2S = (
|
|||
| FEATURE_SET_FAVORITE_LEVEL
|
||||
)
|
||||
|
||||
FEATURE_FLAGS_AIRPURIFIER_3 = (
|
||||
FEATURE_SET_BUZZER
|
||||
| FEATURE_SET_CHILD_LOCK
|
||||
| FEATURE_SET_LED
|
||||
| FEATURE_SET_FAVORITE_LEVEL
|
||||
| FEATURE_SET_FAN_LEVEL
|
||||
| FEATURE_SET_LED_BRIGHTNESS
|
||||
)
|
||||
|
||||
FEATURE_FLAGS_AIRPURIFIER_V3 = (
|
||||
FEATURE_SET_BUZZER | FEATURE_SET_CHILD_LOCK | FEATURE_SET_LED
|
||||
)
|
||||
|
@ -394,6 +440,10 @@ 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))}
|
||||
)
|
||||
|
@ -430,6 +480,10 @@ SERVICE_TO_METHOD = {
|
|||
"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",
|
||||
|
@ -472,7 +526,10 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
except DeviceException:
|
||||
raise PlatformNotReady
|
||||
|
||||
if model.startswith("zhimi.airpurifier."):
|
||||
if model in PURIFIER_MIOT:
|
||||
air_purifier = AirPurifierMiot(host, token)
|
||||
device = XiaomiAirPurifierMiot(name, air_purifier, model, unique_id)
|
||||
elif model.startswith("zhimi.airpurifier."):
|
||||
air_purifier = AirPurifier(host, token)
|
||||
device = XiaomiAirPurifier(name, air_purifier, model, unique_id)
|
||||
elif model.startswith("zhimi.humidifier."):
|
||||
|
@ -690,6 +747,10 @@ class XiaomiAirPurifier(XiaomiGenericDevice):
|
|||
self._device_features = FEATURE_FLAGS_AIRPURIFIER_2S
|
||||
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_2S
|
||||
self._speed_list = OPERATION_MODES_AIRPURIFIER_2S
|
||||
elif self._model == MODEL_AIRPURIFIER_3 or self._model == MODEL_AIRPURIFIER_3H:
|
||||
self._device_features = FEATURE_FLAGS_AIRPURIFIER_3
|
||||
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_3
|
||||
self._speed_list = OPERATION_MODES_AIRPURIFIER_3
|
||||
elif self._model == MODEL_AIRPURIFIER_V3:
|
||||
self._device_features = FEATURE_FLAGS_AIRPURIFIER_V3
|
||||
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_V3
|
||||
|
@ -795,6 +856,17 @@ class XiaomiAirPurifier(XiaomiGenericDevice):
|
|||
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_auto_detect_on(self):
|
||||
"""Turn the auto detect on."""
|
||||
if self._device_features & FEATURE_SET_AUTO_DETECT == 0:
|
||||
|
@ -872,6 +944,42 @@ class XiaomiAirPurifier(XiaomiGenericDevice):
|
|||
)
|
||||
|
||||
|
||||
class XiaomiAirPurifierMiot(XiaomiAirPurifier):
|
||||
"""Representation of a Xiaomi Air Purifier (MiOT protocol)."""
|
||||
|
||||
@property
|
||||
def speed(self):
|
||||
"""Return the current speed."""
|
||||
if self._state:
|
||||
return AirpurifierMiotOperationMode(self._state_attrs[ATTR_MODE]).name
|
||||
|
||||
return None
|
||||
|
||||
async def async_set_speed(self, speed: str) -> None:
|
||||
"""Set the speed of the fan."""
|
||||
if self.supported_features & SUPPORT_SET_SPEED == 0:
|
||||
return
|
||||
|
||||
_LOGGER.debug("Setting the operation mode to: %s", speed)
|
||||
|
||||
await self._try_command(
|
||||
"Setting operation mode of the miio device failed.",
|
||||
self._device.set_mode,
|
||||
AirpurifierMiotOperationMode[speed.title()],
|
||||
)
|
||||
|
||||
async def async_set_led_brightness(self, brightness: int = 2):
|
||||
"""Set the led brightness."""
|
||||
if self._device_features & FEATURE_SET_LED_BRIGHTNESS == 0:
|
||||
return
|
||||
|
||||
await self._try_command(
|
||||
"Setting the led brightness of the miio device failed.",
|
||||
self._device.set_led_brightness,
|
||||
AirpurifierMiotLedBrightness(brightness),
|
||||
)
|
||||
|
||||
|
||||
class XiaomiAirHumidifier(XiaomiGenericDevice):
|
||||
"""Representation of a Xiaomi Air Humidifier."""
|
||||
|
||||
|
|
|
@ -50,6 +50,16 @@ fan_set_favorite_level:
|
|||
description: Level, between 0 and 16.
|
||||
example: 1
|
||||
|
||||
fan_set_fan_level:
|
||||
description: Set the fan level.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
example: 'fan.xiaomi_miio_device'
|
||||
level:
|
||||
description: Level, between 1 and 3.
|
||||
example: 1
|
||||
|
||||
fan_set_led_brightness:
|
||||
description: Set the led brightness.
|
||||
fields:
|
||||
|
|
Loading…
Reference in New Issue