Skip to content

Commit

Permalink
feat: fan entity support direction ctrl (#556)
Browse files Browse the repository at this point in the history
* feat: fan entity support direction

* fix: fix value judgement logic
  • Loading branch information
topsworld authored Jan 7, 2025
1 parent ce7ce7a commit c0d100c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
48 changes: 48 additions & 0 deletions custom_components/xiaomi_home/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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."""
Expand All @@ -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."""
Expand Down
2 changes: 1 addition & 1 deletion custom_components/xiaomi_home/miot/specs/specv2entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
}
},
'optional': {
'properties': {'mode', 'horizontal-swing'}
'properties': {'mode', 'horizontal-swing', 'wind-reverse'}
},
'entity': 'fan'
},
Expand Down

0 comments on commit c0d100c

Please sign in to comment.