From 466fe2d8f93b33d28db94f0103d65126c2617c85 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 22 Dec 2023 09:58:17 -1000 Subject: [PATCH] Add support for attribute caching to the fan platform Builds on https://github.com/home-assistant/core/pull/100601 --- homeassistant/components/fan/__init__.py | 35 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/fan/__init__.py b/homeassistant/components/fan/__init__.py index ec6fc1aad7e0aa..c53be415b8e86a 100644 --- a/homeassistant/components/fan/__init__.py +++ b/homeassistant/components/fan/__init__.py @@ -6,7 +6,7 @@ import functools as ft import logging import math -from typing import Any, final +from typing import TYPE_CHECKING, Any, final import voluptuous as vol @@ -38,6 +38,12 @@ ranged_value_to_percentage, ) +if TYPE_CHECKING: + from functools import cached_property +else: + from homeassistant.backports.functools import cached_property + + _LOGGER = logging.getLogger(__name__) DOMAIN = "fan" @@ -207,7 +213,18 @@ class FanEntityDescription(ToggleEntityDescription, frozen_or_thawed=True): """A class that describes fan entities.""" -class FanEntity(ToggleEntity): +CACHED_PROPERTIES_WITH_ATTR_ = { + "percentage", + "speed_count", + "current_direction", + "oscillating", + "supported_features", + "preset_mode", + "preset_modes", +} + + +class FanEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): """Base class for fan entities.""" _entity_component_unrecorded_attributes = frozenset({ATTR_PRESET_MODES}) @@ -350,14 +367,14 @@ def is_on(self) -> bool | None: self.percentage is not None and self.percentage > 0 ) or self.preset_mode is not None - @property + @cached_property def percentage(self) -> int | None: """Return the current speed as a percentage.""" if hasattr(self, "_attr_percentage"): return self._attr_percentage return 0 - @property + @cached_property def speed_count(self) -> int: """Return the number of speeds the fan supports.""" if hasattr(self, "_attr_speed_count"): @@ -369,12 +386,12 @@ def percentage_step(self) -> float: """Return the step size for percentage.""" return 100 / self.speed_count - @property + @cached_property def current_direction(self) -> str | None: """Return the current direction of the fan.""" return self._attr_current_direction - @property + @cached_property def oscillating(self) -> bool | None: """Return whether or not the fan is currently oscillating.""" return self._attr_oscillating @@ -417,12 +434,12 @@ def state_attributes(self) -> dict[str, float | str | None]: return data - @property + @cached_property def supported_features(self) -> FanEntityFeature: """Flag supported features.""" return self._attr_supported_features - @property + @cached_property def preset_mode(self) -> str | None: """Return the current preset mode, e.g., auto, smart, interval, favorite. @@ -432,7 +449,7 @@ def preset_mode(self) -> str | None: return self._attr_preset_mode return None - @property + @cached_property def preset_modes(self) -> list[str] | None: """Return a list of available preset modes.