Add support for attribute caching to the sensor platform (#106252)

pull/106301/head
J. Nick Koston 2023-12-23 00:13:02 -10:00 committed by GitHub
parent 97ed6570a7
commit ff004a1c20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 27 additions and 10 deletions

View File

@ -10,7 +10,7 @@ from decimal import Decimal, InvalidOperation as DecimalInvalidOperation
from functools import partial
import logging
from math import ceil, floor, isfinite, log10
from typing import Any, Final, Self, cast, final
from typing import TYPE_CHECKING, Any, Final, Self, cast, final
from typing_extensions import override
@ -92,6 +92,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: Final = logging.getLogger(__name__)
ENTITY_ID_FORMAT: Final = DOMAIN + ".{}"
@ -182,7 +187,19 @@ def _numeric_state_expected(
return device_class is not None
class SensorEntity(Entity):
CACHED_PROPERTIES_WITH_ATTR_ = {
"device_class",
"last_reset",
"native_unit_of_measurement",
"native_value",
"options",
"state_class",
"suggested_display_precision",
"suggested_unit_of_measurement",
}
class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
"""Base class for sensor entities."""
_entity_component_unrecorded_attributes = frozenset({ATTR_OPTIONS})
@ -302,7 +319,7 @@ class SensorEntity(Entity):
"""
return self.device_class not in (None, SensorDeviceClass.ENUM)
@property
@cached_property
@override
def device_class(self) -> SensorDeviceClass | None:
"""Return the class of this entity."""
@ -323,7 +340,7 @@ class SensorEntity(Entity):
self.suggested_display_precision,
)
@property
@cached_property
def options(self) -> list[str] | None:
"""Return a set of possible options."""
if hasattr(self, "_attr_options"):
@ -332,7 +349,7 @@ class SensorEntity(Entity):
return self.entity_description.options
return None
@property
@cached_property
def state_class(self) -> SensorStateClass | str | None:
"""Return the state class of this entity, if any."""
if hasattr(self, "_attr_state_class"):
@ -341,7 +358,7 @@ class SensorEntity(Entity):
return self.entity_description.state_class
return None
@property
@cached_property
def last_reset(self) -> datetime | None:
"""Return the time when the sensor was last reset, if any."""
if hasattr(self, "_attr_last_reset"):
@ -424,12 +441,12 @@ class SensorEntity(Entity):
return None
@property
@cached_property
def native_value(self) -> StateType | date | datetime | Decimal:
"""Return the value reported by the sensor."""
return self._attr_native_value
@property
@cached_property
def suggested_display_precision(self) -> int | None:
"""Return the suggested number of decimal digits for display."""
if hasattr(self, "_attr_suggested_display_precision"):
@ -438,7 +455,7 @@ class SensorEntity(Entity):
return self.entity_description.suggested_display_precision
return None
@property
@cached_property
def native_unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of the sensor, if any."""
if hasattr(self, "_attr_native_unit_of_measurement"):
@ -447,7 +464,7 @@ class SensorEntity(Entity):
return self.entity_description.native_unit_of_measurement
return None
@property
@cached_property
def suggested_unit_of_measurement(self) -> str | None:
"""Return the unit which should be used for the sensor's state.