Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fan speed #464

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 37 additions & 21 deletions custom_components/xiaomi_home/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.util.percentage import (
percentage_to_ranged_value,
ranged_value_to_percentage
ranged_value_to_percentage,
ordered_list_item_to_percentage,
percentage_to_ordered_list_item
)

from .miot.miot_spec import MIoTSpecProperty
Expand Down Expand Up @@ -93,6 +95,8 @@ class Fan(MIoTServiceEntity, FanEntity):
_speed_min: Optional[int]
_speed_max: Optional[int]
_speed_step: Optional[int]
_speed_names: Optional[list]
_speed_name_value: Optional[list]
_mode_list: Optional[dict[Any, Any]]

def __init__(
Expand All @@ -110,6 +114,9 @@ def __init__(
self._speed_min = 65535
self._speed_max = 0
self._speed_step = 1
self._speed_names = []
self._speed_name_value = []

self._mode_list = None

# properties
Expand All @@ -124,19 +131,16 @@ def __init__(
self._speed_min = prop.value_range['min']
self._speed_max = prop.value_range['max']
self._speed_step = prop.value_range['step']
self._attr_speed_count = self._speed_max - self._speed_min+1
self._attr_speed_count = (self._speed_max - self._speed_min
)/self._speed_step+1
self._attr_supported_features |= FanEntityFeature.SET_SPEED
self._prop_fan_level = prop
elif (
self._prop_fan_level is None
and isinstance(prop.value_list, list)
and prop.value_list
):
elif isinstance(prop.value_list, list) and prop.value_list:
# Fan level with value-list
for item in prop.value_list:
self._speed_min = min(self._speed_min, item['value'])
self._speed_max = max(self._speed_max, item['value'])
self._attr_speed_count = self._speed_max - self._speed_min+1
self._speed_names.append(item['description'])
self._speed_name_value.append(item['value'])
self._attr_speed_count = len(prop.value_list)
self._attr_supported_features |= FanEntityFeature.SET_SPEED
self._prop_fan_level = prop
elif prop.name == 'mode':
Expand Down Expand Up @@ -182,9 +186,19 @@ async def async_turn_on(
await self.set_property_async(prop=self._prop_on, value=True)
# percentage
if percentage:
await self.set_property_async(
prop=self._prop_fan_level,
value=int(percentage*self._attr_speed_count/100))
if self._speed_names:
speed = percentage_to_ordered_list_item(self._speed_names,
percentage)
order = self._speed_names.index(speed)
await self.set_property_async(prop=self._prop_fan_level,
value=self._speed_name_value[order])
else:
speed = int((self._speed_max - self._speed_min)*percentage/100
)+self._speed_min
step_cnt = int((speed - self._speed_min)/self._speed_step)
speed = self._speed_min+step_cnt*self._speed_step
await self.set_property_async(prop=self._prop_fan_level,
value=speed)
# preset_mode
if preset_mode:
await self.set_property_async(
Expand Down Expand Up @@ -246,9 +260,16 @@ def preset_mode(self) -> Optional[str]:
def percentage(self) -> Optional[int]:
"""Return the current percentage of the fan speed."""
fan_level = self.get_prop_value(prop=self._prop_fan_level)
return ranged_value_to_percentage(
low_high_range=(self._speed_min, self._speed_max),
value=fan_level) if fan_level else None
if fan_level is None:
return None
if self._speed_names:
order = self._speed_name_value.index(fan_level)
return ordered_list_item_to_percentage(self._speed_names,
self._speed_names[order])
else:
return ranged_value_to_percentage(
low_high_range=(self._speed_min, self._speed_max),
value=fan_level)

@property
def oscillating(self) -> Optional[bool]:
Expand All @@ -257,8 +278,3 @@ def oscillating(self) -> Optional[bool]:
self.get_prop_value(
prop=self._prop_horizontal_swing)
if self._prop_horizontal_swing else None)

@property
def percentage_step(self) -> float:
"""Return the step of the fan speed."""
return self._speed_step
Loading