From 0e930fd626c4ce41e531c1c0732f89bdbc781b26 Mon Sep 17 00:00:00 2001 From: Pete Date: Sat, 3 Sep 2022 22:55:34 +0200 Subject: [PATCH] Fix setting and reading percentage for MIOT based fans (#77626) --- homeassistant/components/xiaomi_miio/const.py | 9 +++++ homeassistant/components/xiaomi_miio/fan.py | 36 ++++++++++++++----- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/xiaomi_miio/const.py b/homeassistant/components/xiaomi_miio/const.py index c0711a02a36..11922956c25 100644 --- a/homeassistant/components/xiaomi_miio/const.py +++ b/homeassistant/components/xiaomi_miio/const.py @@ -112,6 +112,15 @@ MODELS_FAN_MIOT = [ MODEL_FAN_ZA5, ] +# number of speed levels each fan has +SPEEDS_FAN_MIOT = { + MODEL_FAN_1C: 3, + MODEL_FAN_P10: 4, + MODEL_FAN_P11: 4, + MODEL_FAN_P9: 4, + MODEL_FAN_ZA5: 4, +} + MODELS_PURIFIER_MIOT = [ MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3C, diff --git a/homeassistant/components/xiaomi_miio/fan.py b/homeassistant/components/xiaomi_miio/fan.py index 39988976564..901211d1d2d 100644 --- a/homeassistant/components/xiaomi_miio/fan.py +++ b/homeassistant/components/xiaomi_miio/fan.py @@ -85,6 +85,7 @@ from .const import ( MODELS_PURIFIER_MIOT, SERVICE_RESET_FILTER, SERVICE_SET_EXTRA_FEATURES, + SPEEDS_FAN_MIOT, ) from .device import XiaomiCoordinatedMiioEntity @@ -234,9 +235,13 @@ async def async_setup_entry( elif model in MODELS_FAN_MIIO: entity = XiaomiFan(device, config_entry, unique_id, coordinator) elif model == MODEL_FAN_ZA5: - entity = XiaomiFanZA5(device, config_entry, unique_id, coordinator) + speed_count = SPEEDS_FAN_MIOT[model] + entity = XiaomiFanZA5(device, config_entry, unique_id, coordinator, speed_count) elif model in MODELS_FAN_MIOT: - entity = XiaomiFanMiot(device, config_entry, unique_id, coordinator) + speed_count = SPEEDS_FAN_MIOT[model] + entity = XiaomiFanMiot( + device, config_entry, unique_id, coordinator, speed_count + ) else: return @@ -1044,6 +1049,11 @@ class XiaomiFanP5(XiaomiGenericFan): class XiaomiFanMiot(XiaomiGenericFan): """Representation of a Xiaomi Fan Miot.""" + def __init__(self, device, entry, unique_id, coordinator, speed_count): + """Initialize MIOT fan with speed count.""" + super().__init__(device, entry, unique_id, coordinator) + self._speed_count = speed_count + @property def operation_mode_class(self): """Hold operation mode class.""" @@ -1061,7 +1071,9 @@ class XiaomiFanMiot(XiaomiGenericFan): self._preset_mode = self.coordinator.data.mode.name self._oscillating = self.coordinator.data.oscillate if self.coordinator.data.is_on: - self._percentage = self.coordinator.data.speed + self._percentage = ranged_value_to_percentage( + (1, self._speed_count), self.coordinator.data.speed + ) else: self._percentage = 0 @@ -1087,16 +1099,22 @@ class XiaomiFanMiot(XiaomiGenericFan): await self.async_turn_off() return - await self._try_command( - "Setting fan speed percentage of the miio device failed.", - self._device.set_speed, - percentage, + speed = math.ceil( + percentage_to_ranged_value((1, self._speed_count), percentage) ) - self._percentage = percentage + # if the fan is not on, we have to turn it on first if not self.is_on: await self.async_turn_on() - else: + + result = await self._try_command( + "Setting fan speed percentage of the miio device failed.", + self._device.set_speed, + speed, + ) + + if result: + self._percentage = ranged_value_to_percentage((1, self._speed_count), speed) self.async_write_ha_state()