mirror of
				https://github.com/XiaoMi/ha_xiaomi_home.git
				synced 2025-10-31 09:22:08 +08:00 
			
		
		
		
	fix: fan speed (#464)
* fix: fan speed * fix: fan speed names map * fix: set percentage * docs: the instance code format of valuelist * fix: fan level property * fix: pylint too long line. * style: code format --------- Co-authored-by: topsworld <sworldtop@gmail.com>
This commit is contained in:
		| @@ -351,7 +351,7 @@ The instance code is the code of the MIoT-Spec-V2 instance, which is in the form | |||||||
| ``` | ``` | ||||||
| service:<siid>                  # service | service:<siid>                  # service | ||||||
| service:<siid>:property:<piid>  # property | service:<siid>:property:<piid>  # property | ||||||
| service:<siid>:property:<piid>:valuelist:<value> # the value in value-list of a property | service:<siid>:property:<piid>:valuelist:<index> # The index of a value in the value-list of a property | ||||||
| service:<siid>:event:<eiid>     # event | service:<siid>:event:<eiid>     # event | ||||||
| service:<siid>:action:<aiid>    # action | service:<siid>:action:<aiid>    # action | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -55,7 +55,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback | |||||||
| from homeassistant.components.fan import FanEntity, FanEntityFeature | from homeassistant.components.fan import FanEntity, FanEntityFeature | ||||||
| from homeassistant.util.percentage import ( | from homeassistant.util.percentage import ( | ||||||
|     percentage_to_ranged_value, |     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 | from .miot.miot_spec import MIoTSpecProperty | ||||||
| @@ -90,9 +92,11 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|     _prop_mode: Optional[MIoTSpecProperty] |     _prop_mode: Optional[MIoTSpecProperty] | ||||||
|     _prop_horizontal_swing: Optional[MIoTSpecProperty] |     _prop_horizontal_swing: Optional[MIoTSpecProperty] | ||||||
|  |  | ||||||
|     _speed_min: Optional[int] |     _speed_min: int | ||||||
|     _speed_max: Optional[int] |     _speed_max: int | ||||||
|     _speed_step: Optional[int] |     _speed_step: int | ||||||
|  |     _speed_names: Optional[list] | ||||||
|  |     _speed_name_map: Optional[dict[int, str]] | ||||||
|     _mode_list: Optional[dict[Any, Any]] |     _mode_list: Optional[dict[Any, Any]] | ||||||
|  |  | ||||||
|     def __init__( |     def __init__( | ||||||
| @@ -110,6 +114,9 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|         self._speed_min = 65535 |         self._speed_min = 65535 | ||||||
|         self._speed_max = 0 |         self._speed_max = 0 | ||||||
|         self._speed_step = 1 |         self._speed_step = 1 | ||||||
|  |         self._speed_names = [] | ||||||
|  |         self._speed_name_map = {} | ||||||
|  |  | ||||||
|         self._mode_list = None |         self._mode_list = None | ||||||
|  |  | ||||||
|         # properties |         # properties | ||||||
| @@ -124,7 +131,8 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|                     self._speed_min = prop.value_range['min'] |                     self._speed_min = prop.value_range['min'] | ||||||
|                     self._speed_max = prop.value_range['max'] |                     self._speed_max = prop.value_range['max'] | ||||||
|                     self._speed_step = prop.value_range['step'] |                     self._speed_step = prop.value_range['step'] | ||||||
|                     self._attr_speed_count = self._speed_max - self._speed_min+1 |                     self._attr_speed_count = int(( | ||||||
|  |                         self._speed_max - self._speed_min)/self._speed_step)+1 | ||||||
|                     self._attr_supported_features |= FanEntityFeature.SET_SPEED |                     self._attr_supported_features |= FanEntityFeature.SET_SPEED | ||||||
|                     self._prop_fan_level = prop |                     self._prop_fan_level = prop | ||||||
|                 elif ( |                 elif ( | ||||||
| @@ -133,10 +141,13 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|                     and prop.value_list |                     and prop.value_list | ||||||
|                 ): |                 ): | ||||||
|                     # Fan level with value-list |                     # Fan level with value-list | ||||||
|                     for item in prop.value_list: |                     # Fan level with value-range is prior to fan level with | ||||||
|                         self._speed_min = min(self._speed_min, item['value']) |                     # value-list when a fan has both fan level properties. | ||||||
|                         self._speed_max = max(self._speed_max, item['value']) |                     self._speed_name_map = { | ||||||
|                     self._attr_speed_count = self._speed_max - self._speed_min+1 |                         item['value']: item['description'] | ||||||
|  |                         for item in prop.value_list} | ||||||
|  |                     self._speed_names = list(self._speed_name_map.values()) | ||||||
|  |                     self._attr_speed_count = len(prop.value_list) | ||||||
|                     self._attr_supported_features |= FanEntityFeature.SET_SPEED |                     self._attr_supported_features |= FanEntityFeature.SET_SPEED | ||||||
|                     self._prop_fan_level = prop |                     self._prop_fan_level = prop | ||||||
|             elif prop.name == 'mode': |             elif prop.name == 'mode': | ||||||
| @@ -182,9 +193,19 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|         await self.set_property_async(prop=self._prop_on, value=True) |         await self.set_property_async(prop=self._prop_on, value=True) | ||||||
|         # percentage |         # percentage | ||||||
|         if percentage: |         if percentage: | ||||||
|  |             if self._speed_names: | ||||||
|  |                 speed = percentage_to_ordered_list_item( | ||||||
|  |                     self._speed_names, percentage) | ||||||
|  |                 speed_value = self.get_map_value( | ||||||
|  |                     map_=self._speed_name_map, description=speed) | ||||||
|  |                 await self.set_property_async( | ||||||
|  |                     prop=self._prop_fan_level, value=speed_value) | ||||||
|  |             else: | ||||||
|                 await self.set_property_async( |                 await self.set_property_async( | ||||||
|                     prop=self._prop_fan_level, |                     prop=self._prop_fan_level, | ||||||
|                 value=int(percentage*self._attr_speed_count/100)) |                     value=int(percentage_to_ranged_value( | ||||||
|  |                         low_high_range=(self._speed_min, self._speed_max), | ||||||
|  |                         percentage=percentage))) | ||||||
|         # preset_mode |         # preset_mode | ||||||
|         if preset_mode: |         if preset_mode: | ||||||
|             await self.set_property_async( |             await self.set_property_async( | ||||||
| @@ -202,6 +223,14 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|     async def async_set_percentage(self, percentage: int) -> None: |     async def async_set_percentage(self, percentage: int) -> None: | ||||||
|         """Set the percentage of the fan speed.""" |         """Set the percentage of the fan speed.""" | ||||||
|         if percentage > 0: |         if percentage > 0: | ||||||
|  |             if self._speed_names: | ||||||
|  |                 speed = percentage_to_ordered_list_item( | ||||||
|  |                     self._speed_names, percentage) | ||||||
|  |                 speed_value = self.get_map_value( | ||||||
|  |                     map_=self._speed_name_map, description=speed) | ||||||
|  |                 await self.set_property_async( | ||||||
|  |                     prop=self._prop_fan_level, value=speed_value) | ||||||
|  |             else: | ||||||
|                 await self.set_property_async( |                 await self.set_property_async( | ||||||
|                     prop=self._prop_fan_level, |                     prop=self._prop_fan_level, | ||||||
|                     value=int(percentage_to_ranged_value( |                     value=int(percentage_to_ranged_value( | ||||||
| @@ -246,9 +275,15 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|     def percentage(self) -> Optional[int]: |     def percentage(self) -> Optional[int]: | ||||||
|         """Return the current percentage of the fan speed.""" |         """Return the current percentage of the fan speed.""" | ||||||
|         fan_level = self.get_prop_value(prop=self._prop_fan_level) |         fan_level = self.get_prop_value(prop=self._prop_fan_level) | ||||||
|  |         if fan_level is None: | ||||||
|  |             return None | ||||||
|  |         if self._speed_names: | ||||||
|  |             return ordered_list_item_to_percentage( | ||||||
|  |                 self._speed_names, self._speed_name_map[fan_level]) | ||||||
|  |         else: | ||||||
|             return ranged_value_to_percentage( |             return ranged_value_to_percentage( | ||||||
|                 low_high_range=(self._speed_min, self._speed_max), |                 low_high_range=(self._speed_min, self._speed_max), | ||||||
|             value=fan_level) if fan_level else None |                 value=fan_level) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def oscillating(self) -> Optional[bool]: |     def oscillating(self) -> Optional[bool]: | ||||||
| @@ -257,8 +292,3 @@ class Fan(MIoTServiceEntity, FanEntity): | |||||||
|             self.get_prop_value( |             self.get_prop_value( | ||||||
|                 prop=self._prop_horizontal_swing) |                 prop=self._prop_horizontal_swing) | ||||||
|             if self._prop_horizontal_swing else None) |             if self._prop_horizontal_swing else None) | ||||||
|  |  | ||||||
|     @property |  | ||||||
|     def percentage_step(self) -> float: |  | ||||||
|         """Return the step of the fan speed.""" |  | ||||||
|         return self._speed_step |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user