Add new air-humidifier device CA4 with miot protocol (#39398)
* Add new air-humidifier device CA4 with miot protocol * Update homeassistant/components/xiaomi_miio/fan.py Co-authored-by: Teemu R. <tpr@iki.fi> * xiomi_miio fan Standard speed for fan, removed static attributes * xiomi_miio fan Standard speed for fan, removed static attributes * xiomi_miio fan unnessary elif * added mode_mapping * Changed mode_mapping to constant also move reverse to constant * Removerd water_level * Return to exclude breaking changes Co-authored-by: Teemu R. <tpr@iki.fi>
This commit is contained in:
parent
f693c8a9fd
commit
d3f952f831
3 changed files with 137 additions and 2 deletions
|
@ -21,6 +21,7 @@ SERVICE_SET_EXTRA_FEATURES = "fan_set_extra_features"
|
|||
SERVICE_SET_TARGET_HUMIDITY = "fan_set_target_humidity"
|
||||
SERVICE_SET_DRY_ON = "fan_set_dry_on"
|
||||
SERVICE_SET_DRY_OFF = "fan_set_dry_off"
|
||||
SERVICE_SET_MOTOR_SPEED = "fan_set_motor_speed"
|
||||
|
||||
# Light Services
|
||||
SERVICE_SET_SCENE = "light_set_scene"
|
||||
|
|
|
@ -7,6 +7,7 @@ import logging
|
|||
from miio import ( # pylint: disable=import-error
|
||||
AirFresh,
|
||||
AirHumidifier,
|
||||
AirHumidifierMiot,
|
||||
AirPurifier,
|
||||
AirPurifierMiot,
|
||||
Device,
|
||||
|
@ -20,6 +21,11 @@ from miio.airhumidifier import ( # pylint: disable=import-error, import-error
|
|||
LedBrightness as AirhumidifierLedBrightness,
|
||||
OperationMode as AirhumidifierOperationMode,
|
||||
)
|
||||
from miio.airhumidifier_miot import ( # pylint: disable=import-error, import-error
|
||||
LedBrightness as AirhumidifierMiotLedBrightness,
|
||||
OperationMode as AirhumidifierMiotOperationMode,
|
||||
PressedButton as AirhumidifierPressedButton,
|
||||
)
|
||||
from miio.airpurifier import ( # pylint: disable=import-error, import-error
|
||||
LedBrightness as AirpurifierLedBrightness,
|
||||
OperationMode as AirpurifierOperationMode,
|
||||
|
@ -30,7 +36,14 @@ from miio.airpurifier_miot import ( # pylint: disable=import-error, import-erro
|
|||
)
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.fan import PLATFORM_SCHEMA, SUPPORT_SET_SPEED, FanEntity
|
||||
from homeassistant.components.fan import (
|
||||
PLATFORM_SCHEMA,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SUPPORT_SET_SPEED,
|
||||
FanEntity,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_MODE,
|
||||
|
@ -60,6 +73,7 @@ from .const import (
|
|||
SERVICE_SET_LEARN_MODE_OFF,
|
||||
SERVICE_SET_LEARN_MODE_ON,
|
||||
SERVICE_SET_LED_BRIGHTNESS,
|
||||
SERVICE_SET_MOTOR_SPEED,
|
||||
SERVICE_SET_TARGET_HUMIDITY,
|
||||
SERVICE_SET_VOLUME,
|
||||
)
|
||||
|
@ -88,6 +102,7 @@ MODEL_AIRPURIFIER_3H = "zhimi.airpurifier.mb3"
|
|||
|
||||
MODEL_AIRHUMIDIFIER_V1 = "zhimi.humidifier.v1"
|
||||
MODEL_AIRHUMIDIFIER_CA1 = "zhimi.humidifier.ca1"
|
||||
MODEL_AIRHUMIDIFIER_CA4 = "zhimi.humidifier.ca4"
|
||||
MODEL_AIRHUMIDIFIER_CB1 = "zhimi.humidifier.cb1"
|
||||
|
||||
MODEL_AIRFRESH_VA2 = "zhimi.airfresh.va2"
|
||||
|
@ -116,6 +131,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||
MODEL_AIRPURIFIER_3H,
|
||||
MODEL_AIRHUMIDIFIER_V1,
|
||||
MODEL_AIRHUMIDIFIER_CA1,
|
||||
MODEL_AIRHUMIDIFIER_CA4,
|
||||
MODEL_AIRHUMIDIFIER_CB1,
|
||||
MODEL_AIRFRESH_VA2,
|
||||
]
|
||||
|
@ -169,10 +185,16 @@ ATTR_HARDWARE_VERSION = "hardware_version"
|
|||
ATTR_DEPTH = "depth"
|
||||
ATTR_DRY = "dry"
|
||||
|
||||
# Air Humidifier CA4
|
||||
ATTR_ACTUAL_MOTOR_SPEED = "actual_speed"
|
||||
ATTR_FAHRENHEIT = "fahrenheit"
|
||||
ATTR_FAULT = "fault"
|
||||
|
||||
# Air Fresh
|
||||
ATTR_CO2 = "co2"
|
||||
|
||||
PURIFIER_MIOT = [MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3H]
|
||||
HUMIDIFIER_MIOT = [MODEL_AIRHUMIDIFIER_CA4]
|
||||
|
||||
# Map attributes to properties of the state object
|
||||
AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON = {
|
||||
|
@ -299,13 +321,13 @@ AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON = {
|
|||
ATTR_TARGET_HUMIDITY: "target_humidity",
|
||||
ATTR_LED_BRIGHTNESS: "led_brightness",
|
||||
ATTR_USE_TIME: "use_time",
|
||||
ATTR_HARDWARE_VERSION: "hardware_version",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER = {
|
||||
**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
|
||||
ATTR_TRANS_LEVEL: "trans_level",
|
||||
ATTR_BUTTON_PRESSED: "button_pressed",
|
||||
ATTR_HARDWARE_VERSION: "hardware_version",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA_AND_CB = {
|
||||
|
@ -313,6 +335,16 @@ AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA_AND_CB = {
|
|||
ATTR_MOTOR_SPEED: "motor_speed",
|
||||
ATTR_DEPTH: "depth",
|
||||
ATTR_DRY: "dry",
|
||||
ATTR_HARDWARE_VERSION: "hardware_version",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA4 = {
|
||||
**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
|
||||
ATTR_ACTUAL_MOTOR_SPEED: "actual_speed",
|
||||
ATTR_BUTTON_PRESSED: "button_pressed",
|
||||
ATTR_DRY: "dry",
|
||||
ATTR_FAHRENHEIT: "fahrenheit",
|
||||
ATTR_MOTOR_SPEED: "motor_speed",
|
||||
}
|
||||
|
||||
AVAILABLE_ATTRIBUTES_AIRFRESH = {
|
||||
|
@ -364,6 +396,7 @@ FEATURE_SET_EXTRA_FEATURES = 512
|
|||
FEATURE_SET_TARGET_HUMIDITY = 1024
|
||||
FEATURE_SET_DRY = 2048
|
||||
FEATURE_SET_FAN_LEVEL = 4096
|
||||
FEATURE_SET_MOTOR_SPEED = 8192
|
||||
|
||||
FEATURE_FLAGS_AIRPURIFIER = (
|
||||
FEATURE_SET_BUZZER
|
||||
|
@ -421,6 +454,15 @@ FEATURE_FLAGS_AIRHUMIDIFIER = (
|
|||
|
||||
FEATURE_FLAGS_AIRHUMIDIFIER_CA_AND_CB = FEATURE_FLAGS_AIRHUMIDIFIER | FEATURE_SET_DRY
|
||||
|
||||
FEATURE_FLAGS_AIRHUMIDIFIER_CA4 = (
|
||||
FEATURE_SET_BUZZER
|
||||
| FEATURE_SET_CHILD_LOCK
|
||||
| FEATURE_SET_LED_BRIGHTNESS
|
||||
| FEATURE_SET_TARGET_HUMIDITY
|
||||
| FEATURE_SET_DRY
|
||||
| FEATURE_SET_MOTOR_SPEED
|
||||
)
|
||||
|
||||
FEATURE_FLAGS_AIRFRESH = (
|
||||
FEATURE_SET_BUZZER
|
||||
| FEATURE_SET_CHILD_LOCK
|
||||
|
@ -460,6 +502,14 @@ SERVICE_SCHEMA_TARGET_HUMIDITY = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
|||
}
|
||||
)
|
||||
|
||||
SERVICE_SCHEMA_MOTOR_SPEED = AIRPURIFIER_SERVICE_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(ATTR_MOTOR_SPEED): vol.All(
|
||||
vol.Coerce(int), vol.Clamp(min=200, max=2000)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
SERVICE_TO_METHOD = {
|
||||
SERVICE_SET_BUZZER_ON: {"method": "async_set_buzzer_on"},
|
||||
SERVICE_SET_BUZZER_OFF: {"method": "async_set_buzzer_off"},
|
||||
|
@ -495,6 +545,10 @@ SERVICE_TO_METHOD = {
|
|||
},
|
||||
SERVICE_SET_DRY_ON: {"method": "async_set_dry_on"},
|
||||
SERVICE_SET_DRY_OFF: {"method": "async_set_dry_off"},
|
||||
SERVICE_SET_MOTOR_SPEED: {
|
||||
"method": "async_set_motor_speed",
|
||||
"schema": SERVICE_SCHEMA_MOTOR_SPEED,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -532,6 +586,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
elif model.startswith("zhimi.airpurifier."):
|
||||
air_purifier = AirPurifier(host, token)
|
||||
device = XiaomiAirPurifier(name, air_purifier, model, unique_id)
|
||||
elif model in HUMIDIFIER_MIOT:
|
||||
air_humidifier = AirHumidifierMiot(host, token)
|
||||
device = XiaomiAirHumidifierMiot(name, air_humidifier, model, unique_id)
|
||||
elif model.startswith("zhimi.humidifier."):
|
||||
air_humidifier = AirHumidifier(host, token, model=model)
|
||||
device = XiaomiAirHumidifier(name, air_humidifier, model, unique_id)
|
||||
|
@ -998,6 +1055,10 @@ class XiaomiAirHumidifier(XiaomiGenericDevice):
|
|||
for mode in AirhumidifierOperationMode
|
||||
if mode is not AirhumidifierOperationMode.Strong
|
||||
]
|
||||
elif self._model in [MODEL_AIRHUMIDIFIER_CA4]:
|
||||
self._device_features = FEATURE_FLAGS_AIRHUMIDIFIER_CA4
|
||||
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA4
|
||||
self._speed_list = [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||
else:
|
||||
self._device_features = FEATURE_FLAGS_AIRHUMIDIFIER
|
||||
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER
|
||||
|
@ -1107,6 +1168,69 @@ class XiaomiAirHumidifier(XiaomiGenericDevice):
|
|||
)
|
||||
|
||||
|
||||
class XiaomiAirHumidifierMiot(XiaomiAirHumidifier):
|
||||
"""Representation of a Xiaomi Air Humidifier (MiOT protocol)."""
|
||||
|
||||
MODE_MAPPING = {
|
||||
AirhumidifierMiotOperationMode.Low: SPEED_LOW,
|
||||
AirhumidifierMiotOperationMode.Mid: SPEED_MEDIUM,
|
||||
AirhumidifierMiotOperationMode.High: SPEED_HIGH,
|
||||
}
|
||||
|
||||
REVERSE_MODE_MAPPING = {v: k for k, v in MODE_MAPPING.items()}
|
||||
|
||||
@property
|
||||
def speed(self):
|
||||
"""Return the current speed."""
|
||||
if self._state:
|
||||
return self.MODE_MAPPING.get(
|
||||
AirhumidifierMiotOperationMode(self._state_attrs[ATTR_MODE])
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def button_pressed(self):
|
||||
"""Return the last button pressed."""
|
||||
if self._state:
|
||||
return AirhumidifierPressedButton(
|
||||
self._state_attrs[ATTR_BUTTON_PRESSED]
|
||||
).name
|
||||
|
||||
return None
|
||||
|
||||
async def async_set_speed(self, speed: str) -> None:
|
||||
"""Set the speed of the fan."""
|
||||
|
||||
await self._try_command(
|
||||
"Setting operation mode of the miio device failed.",
|
||||
self._device.set_mode,
|
||||
self.REVERSE_MODE_MAPPING[speed],
|
||||
)
|
||||
|
||||
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,
|
||||
AirhumidifierMiotLedBrightness(brightness),
|
||||
)
|
||||
|
||||
async def async_set_motor_speed(self, motor_speed: int = 400):
|
||||
"""Set the target motor speed."""
|
||||
if self._device_features & FEATURE_SET_MOTOR_SPEED == 0:
|
||||
return
|
||||
|
||||
await self._try_command(
|
||||
"Setting the target motor speed of the miio device failed.",
|
||||
self._device.set_speed,
|
||||
motor_speed,
|
||||
)
|
||||
|
||||
|
||||
class XiaomiAirFresh(XiaomiGenericDevice):
|
||||
"""Representation of a Xiaomi Air Fresh."""
|
||||
|
||||
|
|
|
@ -149,6 +149,16 @@ fan_set_dry_off:
|
|||
description: Name of the xiaomi miio entity.
|
||||
example: "fan.xiaomi_miio_device"
|
||||
|
||||
fan_set_motor_speed:
|
||||
description: Set the target motor speed.
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of the xiaomi miio entity.
|
||||
example: 'fan.xiaomi_miio_device'
|
||||
motor_speed:
|
||||
description: Set RPM of motor speed, between 200 and 2000.
|
||||
example: 1100
|
||||
|
||||
light_set_scene:
|
||||
description: Set a fixed scene.
|
||||
fields:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue