feat: fan entity support direction ctrl (#556)

* feat: fan entity support direction

* fix: fix value judgement logic
This commit is contained in:
Paul Shawn 2025-01-07 20:21:24 +08:00 committed by GitHub
parent ce7ce7af4b
commit c0d100ce2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 1 deletions

View File

@ -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 @@ class Fan(MIoTServiceEntity, FanEntity):
"""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 @@ class Fan(MIoTServiceEntity, FanEntity):
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 @@ class Fan(MIoTServiceEntity, FanEntity):
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 @@ class Fan(MIoTServiceEntity, FanEntity):
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."""

View File

@ -289,7 +289,7 @@ SPEC_SERVICE_TRANS_MAP: dict[str, dict | str] = {
}
},
'optional': {
'properties': {'mode', 'horizontal-swing'}
'properties': {'mode', 'horizontal-swing', 'wind-reverse'}
},
'entity': 'fan'
},