Use fan entity for wind speed
This commit is contained in:
		| @ -213,7 +213,7 @@ class HonACClimateEntity(HonEntity, ClimateEntity): | ||||
|  | ||||
|  | ||||
| class HonClimateEntity(HonEntity, ClimateEntity): | ||||
|     entity_description = HonClimateEntityDescription | ||||
|     entity_description: HonClimateEntityDescription | ||||
|  | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         super().__init__(hass, entry, device, description) | ||||
|  | ||||
| @ -17,6 +17,7 @@ PLATFORMS = [ | ||||
|     "button", | ||||
|     "binary_sensor", | ||||
|     "climate", | ||||
|     "fan", | ||||
| ] | ||||
|  | ||||
| HON_HVAC_MODE = { | ||||
|  | ||||
							
								
								
									
										122
									
								
								custom_components/hon/fan.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								custom_components/hon/fan.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | ||||
| import logging | ||||
| import math | ||||
| from dataclasses import dataclass | ||||
| from typing import Any | ||||
|  | ||||
| from homeassistant.components.fan import ( | ||||
|     FanEntityDescription, | ||||
|     FanEntity, | ||||
|     FanEntityFeature, | ||||
| ) | ||||
| from homeassistant.config_entries import ConfigEntry | ||||
| from homeassistant.core import callback | ||||
| from homeassistant.util.percentage import ( | ||||
|     percentage_to_ranged_value, | ||||
|     ranged_value_to_percentage, | ||||
| ) | ||||
| from pyhon.appliance import HonAppliance | ||||
| from pyhon.parameter.range import HonParameterRange | ||||
|  | ||||
| from .const import DOMAIN | ||||
| from .hon import HonEntity | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| @dataclass | ||||
| class HonFanEntityDescription(FanEntityDescription): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| FANS = { | ||||
|     "HO": ( | ||||
|         HonFanEntityDescription( | ||||
|             key="settings.windSpeed", | ||||
|             name="Wind Speed", | ||||
|             translation_key="air_extraction", | ||||
|         ), | ||||
|     ), | ||||
| } | ||||
|  | ||||
|  | ||||
| async def async_setup_entry(hass, entry: ConfigEntry, async_add_entities) -> None: | ||||
|     entities = [] | ||||
|     for device in hass.data[DOMAIN][entry.unique_id].appliances: | ||||
|         for description in FANS.get(device.appliance_type, []): | ||||
|             if isinstance(description, HonFanEntityDescription): | ||||
|                 if description.key not in device.available_settings or not device.get( | ||||
|                     description.key.split(".")[-1] | ||||
|                 ): | ||||
|                     continue | ||||
|                 entity = HonFanEntity(hass, entry, device, description) | ||||
|             else: | ||||
|                 continue | ||||
|             await entity.coordinator.async_config_entry_first_refresh() | ||||
|             entities.append(entity) | ||||
|     async_add_entities(entities) | ||||
|  | ||||
|  | ||||
| class HonFanEntity(HonEntity, FanEntity): | ||||
|     entity_description: HonFanEntityDescription | ||||
|  | ||||
|     def __init__(self, hass, entry, device: HonAppliance, description) -> None: | ||||
|         self._attr_supported_features = FanEntityFeature.SET_SPEED | ||||
|         self._wind_speed: HonParameterRange = device.settings.get(description.key) | ||||
|         self._speed_range = ( | ||||
|             int(self._wind_speed.values[1]), | ||||
|             int(self._wind_speed.values[-1]), | ||||
|         ) | ||||
|         self._command, self._parameter = description.key.split(".") | ||||
|  | ||||
|         super().__init__(hass, entry, device, description) | ||||
|         self._handle_coordinator_update(update=False) | ||||
|  | ||||
|     @property | ||||
|     def percentage(self) -> int | None: | ||||
|         """Return the current speed.""" | ||||
|         value = int(self._device.get(self._parameter, "0")) | ||||
|         return ranged_value_to_percentage(self._speed_range, value) | ||||
|  | ||||
|     @property | ||||
|     def speed_count(self) -> int: | ||||
|         """Return the number of speeds the fan supports.""" | ||||
|         return len(self._wind_speed.values[1:]) | ||||
|  | ||||
|     async def async_set_percentage(self, percentage: int) -> None: | ||||
|         """Set the speed percentage of the fan.""" | ||||
|         mode = math.ceil(percentage_to_ranged_value(self._speed_range, percentage)) | ||||
|         self._device.settings[self.entity_description.key].value = mode | ||||
|         await self._device.commands[self._command].send() | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
|     @property | ||||
|     def is_on(self) -> bool | None: | ||||
|         """Return true if device is on.""" | ||||
|         mode = math.ceil(percentage_to_ranged_value(self._speed_range, self.percentage)) | ||||
|         return mode > self._wind_speed.min | ||||
|  | ||||
|     async def async_turn_on( | ||||
|         self, | ||||
|         percentage: int | None = None, | ||||
|         preset_mode: str | None = None, | ||||
|         **kwargs: Any, | ||||
|     ) -> None: | ||||
|         """Turn the entity on.""" | ||||
|         if percentage is None: | ||||
|             percentage = ranged_value_to_percentage( | ||||
|                 self._speed_range, int(self._wind_speed.values[1]) | ||||
|             ) | ||||
|         await self.async_set_percentage(percentage) | ||||
|  | ||||
|     async def async_turn_off(self, **kwargs: Any) -> None: | ||||
|         """Turn the entity off.""" | ||||
|         self._device.settings[self.entity_description.key].value = 0 | ||||
|         await self._device.commands[self._command].send() | ||||
|         self.async_write_ha_state() | ||||
|  | ||||
|     @callback | ||||
|     def _handle_coordinator_update(self, update=True) -> None: | ||||
|         self._wind_speed = self._device.settings.get(self.entity_description.key) | ||||
|         self._attr_percentage = self.percentage | ||||
|         if update: | ||||
|             self.async_write_ha_state() | ||||
| @ -163,12 +163,6 @@ NUMBERS: dict[str, tuple[NumberEntityDescription, ...]] = { | ||||
|         ), | ||||
|     ), | ||||
|     "HO": ( | ||||
|         HonNumberEntityDescription( | ||||
|             key="startProgram.windSpeed", | ||||
|             name="Wind speed", | ||||
|             icon="mdi:fan", | ||||
|             entity_category=EntityCategory.CONFIG, | ||||
|         ), | ||||
|         HonNumberEntityDescription( | ||||
|             key="startProgram.lightStatus", | ||||
|             name="Light status", | ||||
|  | ||||
| @ -593,11 +593,6 @@ SENSORS: dict[str, tuple[SensorEntityDescription, ...]] = { | ||||
|             name="RGB Light Status", | ||||
|             icon="mdi:lightbulb", | ||||
|         ), | ||||
|         HonSensorEntityDescription( | ||||
|             key="windSpeed", | ||||
|             name="Wind Speed", | ||||
|             icon="mdi:fan", | ||||
|         ), | ||||
|     ), | ||||
| } | ||||
| SENSORS["WD"] = unique_entities(SENSORS["WM"], SENSORS["TD"]) | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Odsávání vzduchu" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Dunstabzug" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Εξαγωγή αέρα" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -2056,6 +2056,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Air extraction" | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Extracción de aire" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Extraction de l'air" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1065,6 +1065,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Air extraction" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Odvođenje zraka" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -2031,6 +2031,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Aspirazione aria" | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Luchtafvoer" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Wyciąg powietrza" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Extração de ar" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Extracția aerului" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Отвод воздуха" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Odsávanie vzduchu" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Odvajanje zraka" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Usisavanje vazduha" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "Hava tahliyesi" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
| @ -1979,6 +1979,11 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "fan": { | ||||
|             "air_extraction": { | ||||
|                 "name": "抽气" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "config": { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user