diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index a9f31a3a410..ec462c3b993 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -6,7 +6,7 @@ from enum import IntFlag import functools as ft import logging import re -from typing import Any, final +from typing import TYPE_CHECKING, Any, final import voluptuous as vol @@ -39,6 +39,11 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType +if TYPE_CHECKING: + from functools import cached_property +else: + from homeassistant.backports.functools import cached_property + _LOGGER = logging.getLogger(__name__) ATTR_CHANGED_BY = "changed_by" @@ -113,7 +118,18 @@ class LockEntityDescription(EntityDescription, frozen_or_thawed=True): """A class that describes lock entities.""" -class LockEntity(Entity): +CACHED_PROPERTIES_WITH_ATTR_ = { + "changed_by", + "code_format", + "is_locked", + "is_locking", + "is_unlocking", + "is_jammed", + "supported_features", +} + + +class LockEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_): """Base class for lock entities.""" entity_description: LockEntityDescription @@ -143,12 +159,12 @@ class LockEntity(Entity): data[ATTR_CODE] = code return data - @property + @cached_property def changed_by(self) -> str | None: """Last change triggered by.""" return self._attr_changed_by - @property + @cached_property def code_format(self) -> str | None: """Regex for code format or None if no code is required.""" return self._attr_code_format @@ -167,22 +183,22 @@ class LockEntity(Entity): self.__code_format_cmp = re.compile(self.code_format) return self.__code_format_cmp - @property + @cached_property def is_locked(self) -> bool | None: """Return true if the lock is locked.""" return self._attr_is_locked - @property + @cached_property def is_locking(self) -> bool | None: """Return true if the lock is locking.""" return self._attr_is_locking - @property + @cached_property def is_unlocking(self) -> bool | None: """Return true if the lock is unlocking.""" return self._attr_is_unlocking - @property + @cached_property def is_jammed(self) -> bool | None: """Return true if the lock is jammed (incomplete locking).""" return self._attr_is_jammed @@ -250,7 +266,7 @@ class LockEntity(Entity): return None return STATE_LOCKED if locked else STATE_UNLOCKED - @property + @cached_property def supported_features(self) -> LockEntityFeature: """Return the list of supported features.""" return self._attr_supported_features