From 62d7fe3b83d2b2263046782ddbdc3b0529c06c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Skrzypon=CC=81?= Date: Thu, 9 Jul 2026 23:40:47 +0200 Subject: [PATCH 1/2] Add fan direction controls --- custom_components/xiaomi_miot/fan.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/custom_components/xiaomi_miot/fan.py b/custom_components/xiaomi_miot/fan.py index 74c1a54e1..96658e4be 100644 --- a/custom_components/xiaomi_miot/fan.py +++ b/custom_components/xiaomi_miot/fan.py @@ -4,6 +4,8 @@ from homeassistant.components.fan import ( DOMAIN as ENTITY_DOMAIN, + DIRECTION_FORWARD, + DIRECTION_REVERSE, FanEntity as BaseEntity, FanEntityFeature, ) @@ -67,6 +69,8 @@ class FanEntity(XEntity, BaseEntity): _speed_list = None _speed_range = None _conv_oscillate = None + _act_turn_left = None + _act_turn_right = None _prop_speed = None _prop_percentage = None @@ -100,6 +104,16 @@ def on_init(self): self._conv_oscillate = conv self._attr_supported_features |= FanEntityFeature.OSCILLATE + if self._miot_service: + self._act_turn_left = self._miot_service.get_action('turn_left') + self._act_turn_right = self._miot_service.get_action('turn_right') + direction_actions = (self._act_turn_left, self._act_turn_right) + if all(action and not action.ins for action in direction_actions): + self._attr_supported_features |= FanEntityFeature.DIRECTION + else: + self._act_turn_left = None + self._act_turn_right = None + # issues/617 if self.custom_config_bool('disable_preset_modes'): self._attr_supported_features &= ~FanEntityFeature.PRESET_MODE @@ -224,6 +238,19 @@ async def async_oscillate(self, oscillating: bool): return await self.device.async_write({self._conv_oscillate.full_name: oscillating}) + async def async_set_direction(self, direction: str): + action = { + DIRECTION_REVERSE: self._act_turn_left, + DIRECTION_FORWARD: self._act_turn_right, + 'left': self._act_turn_left, + 'right': self._act_turn_right, + }.get(direction) + if not action: + return + if self._conv_oscillate and self._attr_oscillating: + await self.async_oscillate(False) + return await self.async_call_action(action) + XEntity.CLS[ENTITY_DOMAIN] = FanEntity From 6f2f65aca3d74b2f798ce64d2ad9b4e914a8b48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dariusz=20Skrzypon=CC=81?= Date: Thu, 9 Jul 2026 23:57:51 +0200 Subject: [PATCH 2/2] Support motor-control fan direction --- custom_components/xiaomi_miot/fan.py | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/custom_components/xiaomi_miot/fan.py b/custom_components/xiaomi_miot/fan.py index 96658e4be..ada6d2e3b 100644 --- a/custom_components/xiaomi_miot/fan.py +++ b/custom_components/xiaomi_miot/fan.py @@ -71,6 +71,9 @@ class FanEntity(XEntity, BaseEntity): _conv_oscillate = None _act_turn_left = None _act_turn_right = None + _prop_direction = None + _direction_left = None + _direction_right = None _prop_speed = None _prop_percentage = None @@ -113,6 +116,16 @@ def on_init(self): else: self._act_turn_left = None self._act_turn_right = None + for prop in self._miot_service.spec.get_properties('motor_control'): + left = prop.list_first('left') + right = prop.list_first('right') + if not prop.writeable or left is None or right is None: + continue + self._prop_direction = prop + self._direction_left = left + self._direction_right = right + self._attr_supported_features |= FanEntityFeature.DIRECTION + break # issues/617 if self.custom_config_bool('disable_preset_modes'): @@ -239,17 +252,20 @@ async def async_oscillate(self, oscillating: bool): await self.device.async_write({self._conv_oscillate.full_name: oscillating}) async def async_set_direction(self, direction: str): - action = { - DIRECTION_REVERSE: self._act_turn_left, - DIRECTION_FORWARD: self._act_turn_right, - 'left': self._act_turn_left, - 'right': self._act_turn_right, - }.get(direction) - if not action: + if direction in [DIRECTION_REVERSE, 'left']: + action = self._act_turn_left + value = self._direction_left + elif direction in [DIRECTION_FORWARD, 'right']: + action = self._act_turn_right + value = self._direction_right + else: return if self._conv_oscillate and self._attr_oscillating: await self.async_oscillate(False) - return await self.async_call_action(action) + if action: + return await self.async_call_action(action) + if self._prop_direction: + return await self.async_set_property(self._prop_direction, value) XEntity.CLS[ENTITY_DOMAIN] = FanEntity