From 5d2ddcb1d2e3e0032b57cb1f84f00550e7d6c500 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 22 Dec 2023 15:22:18 -1000 Subject: [PATCH] Add support for attribute caching to the number platform (#106254) --- homeassistant/components/number/__init__.py | 34 +++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/number/__init__.py b/homeassistant/components/number/__init__.py index 631fc5fc96c..c1da287879f 100644 --- a/homeassistant/components/number/__init__.py +++ b/homeassistant/components/number/__init__.py @@ -7,7 +7,7 @@ import dataclasses from datetime import timedelta import logging from math import ceil, floor -from typing import Any, Self, final +from typing import TYPE_CHECKING, Any, Self, final import voluptuous as vol @@ -42,6 +42,11 @@ from .const import ( # noqa: F401 ) from .websocket_api import async_setup as async_setup_ws_api +if TYPE_CHECKING: + from functools import cached_property +else: + from homeassistant.backports.functools import cached_property + _LOGGER = logging.getLogger(__name__) ENTITY_ID_FORMAT = DOMAIN + ".{}" @@ -153,7 +158,18 @@ def floor_decimal(value: float, precision: float = 0) -> float: return floor(value * factor) / factor -class NumberEntity(Entity): +CACHED_PROPERTIES_WITH_ATTR_ = { + "device_class", + "native_max_value", + "native_min_value", + "native_step", + "mode", + "native_unit_of_measurement", + "native_value", +} + + +class NumberEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): """Representation of a Number entity.""" _entity_component_unrecorded_attributes = frozenset( @@ -238,7 +254,7 @@ class NumberEntity(Entity): """ return self.device_class is not None - @property + @cached_property def device_class(self) -> NumberDeviceClass | None: """Return the class of this entity.""" if hasattr(self, "_attr_device_class"): @@ -247,7 +263,7 @@ class NumberEntity(Entity): return self.entity_description.device_class return None - @property + @cached_property def native_min_value(self) -> float: """Return the minimum value.""" if hasattr(self, "_attr_native_min_value"): @@ -267,7 +283,7 @@ class NumberEntity(Entity): self.native_min_value, floor_decimal, self.device_class ) - @property + @cached_property def native_max_value(self) -> float: """Return the maximum value.""" if hasattr(self, "_attr_native_max_value"): @@ -287,7 +303,7 @@ class NumberEntity(Entity): self.native_max_value, ceil_decimal, self.device_class ) - @property + @cached_property def native_step(self) -> float | None: """Return the increment/decrement step.""" if ( @@ -316,7 +332,7 @@ class NumberEntity(Entity): step /= 10.0 return step - @property + @cached_property def mode(self) -> NumberMode: """Return the mode of the entity.""" if hasattr(self, "_attr_mode"): @@ -334,7 +350,7 @@ class NumberEntity(Entity): """Return the entity state.""" return self.value - @property + @cached_property def native_unit_of_measurement(self) -> str | None: """Return the unit of measurement of the entity, if any.""" if hasattr(self, "_attr_native_unit_of_measurement"): @@ -362,7 +378,7 @@ class NumberEntity(Entity): return native_unit_of_measurement - @property + @cached_property def native_value(self) -> float | None: """Return the value reported by the number.""" return self._attr_native_value