From ecf93e09e8f6bb8a0a8898243ef0091402700aa4 Mon Sep 17 00:00:00 2001 From: Jim Ekman Date: Wed, 17 Mar 2021 08:50:34 +0100 Subject: [PATCH] Add support for percentage based fan model in esphome (#46712) --- homeassistant/components/esphome/fan.py | 37 +++++++++++++++---- .../components/esphome/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/esphome/fan.py b/homeassistant/components/esphome/fan.py index 8cf28d6b2aa..bac35fdb93f 100644 --- a/homeassistant/components/esphome/fan.py +++ b/homeassistant/components/esphome/fan.py @@ -1,4 +1,5 @@ """Support for ESPHome fans.""" +import math from typing import Optional from aioesphomeapi import FanDirection, FanInfo, FanSpeed, FanState @@ -16,6 +17,8 @@ from homeassistant.helpers.typing import HomeAssistantType from homeassistant.util.percentage import ( ordered_list_item_to_percentage, percentage_to_ordered_list_item, + percentage_to_ranged_value, + ranged_value_to_percentage, ) from . import ( @@ -62,6 +65,11 @@ class EsphomeFan(EsphomeEntity, FanEntity): def _state(self) -> Optional[FanState]: return super()._state + @property + def _supports_speed_levels(self) -> bool: + api_version = self._client.api_version + return api_version.major == 1 and api_version.minor > 3 + async def async_set_percentage(self, percentage: int) -> None: """Set the speed percentage of the fan.""" if percentage == 0: @@ -70,10 +78,17 @@ class EsphomeFan(EsphomeEntity, FanEntity): data = {"key": self._static_info.key, "state": True} if percentage is not None: - named_speed = percentage_to_ordered_list_item( - ORDERED_NAMED_FAN_SPEEDS, percentage - ) - data["speed"] = named_speed + if self._supports_speed_levels: + data["speed_level"] = math.ceil( + percentage_to_ranged_value( + (1, self._static_info.supported_speed_levels), percentage + ) + ) + else: + named_speed = percentage_to_ordered_list_item( + ORDERED_NAMED_FAN_SPEEDS, percentage + ) + data["speed"] = named_speed await self._client.fan_command(**data) async def async_turn_on( @@ -115,14 +130,22 @@ class EsphomeFan(EsphomeEntity, FanEntity): """Return the current speed percentage.""" if not self._static_info.supports_speed: return None - return ordered_list_item_to_percentage( - ORDERED_NAMED_FAN_SPEEDS, self._state.speed + + if not self._supports_speed_levels: + return ordered_list_item_to_percentage( + ORDERED_NAMED_FAN_SPEEDS, self._state.speed + ) + + return ranged_value_to_percentage( + (1, self._static_info.supported_speed_levels), self._state.speed_level ) @property def speed_count(self) -> int: """Return the number of speeds the fan supports.""" - return len(ORDERED_NAMED_FAN_SPEEDS) + if not self._supports_speed_levels: + return len(ORDERED_NAMED_FAN_SPEEDS) + return self._static_info.supported_speed_levels @esphome_state_property def oscillating(self) -> None: diff --git a/homeassistant/components/esphome/manifest.json b/homeassistant/components/esphome/manifest.json index 17ff2ca96ba..e3c609c9fad 100644 --- a/homeassistant/components/esphome/manifest.json +++ b/homeassistant/components/esphome/manifest.json @@ -3,7 +3,7 @@ "name": "ESPHome", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/esphome", - "requirements": ["aioesphomeapi==2.6.5"], + "requirements": ["aioesphomeapi==2.6.6"], "zeroconf": ["_esphomelib._tcp.local."], "codeowners": ["@OttoWinter"], "after_dependencies": ["zeroconf", "tag"] diff --git a/requirements_all.txt b/requirements_all.txt index e685876c09d..0398f053ec3 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -154,7 +154,7 @@ aiodns==2.0.0 aioeafm==0.1.2 # homeassistant.components.esphome -aioesphomeapi==2.6.5 +aioesphomeapi==2.6.6 # homeassistant.components.flo aioflo==0.4.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 00e6121b485..47c10b5700c 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -91,7 +91,7 @@ aiodns==2.0.0 aioeafm==0.1.2 # homeassistant.components.esphome -aioesphomeapi==2.6.5 +aioesphomeapi==2.6.6 # homeassistant.components.flo aioflo==0.4.1