diff --git a/custom_components/xiaomi_home/fan.py b/custom_components/xiaomi_home/fan.py index caf67cb..90220db 100644 --- a/custom_components/xiaomi_home/fan.py +++ b/custom_components/xiaomi_home/fan.py @@ -91,6 +91,9 @@ class Fan(MIoTServiceEntity, FanEntity): _prop_fan_level: Optional[MIoTSpecProperty] _prop_mode: Optional[MIoTSpecProperty] _prop_horizontal_swing: Optional[MIoTSpecProperty] + _prop_wind_reverse: Optional[MIoTSpecProperty] + _prop_wind_reverse_forward: Any + _prop_wind_reverse_reverse: Any _speed_min: int _speed_max: int @@ -105,12 +108,16 @@ def __init__( """Initialize the Fan.""" super().__init__(miot_device=miot_device, entity_data=entity_data) self._attr_preset_modes = [] + self._attr_current_direction = None self._attr_supported_features = FanEntityFeature(0) self._prop_on = None self._prop_fan_level = None self._prop_mode = None self._prop_horizontal_swing = None + self._prop_wind_reverse = None + self._prop_wind_reverse_forward = None + self._prop_wind_reverse_reverse = None self._speed_min = 65535 self._speed_max = 0 self._speed_step = 1 @@ -167,6 +174,30 @@ def __init__( elif prop.name == 'horizontal-swing': self._attr_supported_features |= FanEntityFeature.OSCILLATE self._prop_horizontal_swing = prop + elif prop.name == 'wind-reverse': + if prop.format_ == 'bool': + self._prop_wind_reverse_forward = False + self._prop_wind_reverse_reverse = True + elif ( + isinstance(prop.value_list, list) + and prop.value_list + ): + for item in prop.value_list: + if item['name'].lower() in {'foreward'}: + self._prop_wind_reverse_forward = item['value'] + elif item['name'].lower() in { + 'reversal', 'reverse'}: + self._prop_wind_reverse_reverse = item['value'] + if ( + self._prop_wind_reverse_forward is None + or self._prop_wind_reverse_reverse is None + ): + # NOTICE: Value may be 0 or False + _LOGGER.info( + 'invalid wind-reverse, %s', self.entity_id) + continue + self._attr_supported_features |= FanEntityFeature.DIRECTION + self._prop_wind_reverse = prop def __get_mode_description(self, key: int) -> Optional[str]: if self._mode_list is None: @@ -250,6 +281,14 @@ async def async_set_preset_mode(self, preset_mode: str) -> None: async def async_set_direction(self, direction: str) -> None: """Set the direction of the fan.""" + if not self._prop_wind_reverse: + return + await self.set_property_async( + prop=self._prop_wind_reverse, + value=( + self._prop_wind_reverse_reverse + if self.current_direction == 'reverse' + else self._prop_wind_reverse_forward)) async def async_oscillate(self, oscillating: bool) -> None: """Oscillate the fan.""" @@ -271,6 +310,15 @@ def preset_mode(self) -> Optional[str]: key=self.get_prop_value(prop=self._prop_mode)) if self._prop_mode else None) + @property + def current_direction(self) -> Optional[str]: + """Return the current direction of the fan.""" + if not self._prop_wind_reverse: + return None + return 'reverse' if self.get_prop_value( + prop=self._prop_wind_reverse + ) == self._prop_wind_reverse_reverse else 'forward' + @property def percentage(self) -> Optional[int]: """Return the current percentage of the fan speed.""" diff --git a/custom_components/xiaomi_home/miot/specs/specv2entity.py b/custom_components/xiaomi_home/miot/specs/specv2entity.py index 9763970..9e36011 100644 --- a/custom_components/xiaomi_home/miot/specs/specv2entity.py +++ b/custom_components/xiaomi_home/miot/specs/specv2entity.py @@ -289,7 +289,7 @@ } }, 'optional': { - 'properties': {'mode', 'horizontal-swing'} + 'properties': {'mode', 'horizontal-swing', 'wind-reverse'} }, 'entity': 'fan' },