Add support for attribute caching to the update platform (#106261)

pull/106221/head
J. Nick Koston 2023-12-22 23:29:55 -10:00 committed by GitHub
parent 1e12c7fe12
commit 5156a93b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 12 deletions

View File

@ -5,7 +5,7 @@ from datetime import timedelta
from enum import StrEnum from enum import StrEnum
from functools import lru_cache from functools import lru_cache
import logging import logging
from typing import Any, Final, final from typing import TYPE_CHECKING, Any, Final, final
from awesomeversion import AwesomeVersion, AwesomeVersionCompareException from awesomeversion import AwesomeVersion, AwesomeVersionCompareException
import voluptuous as vol import voluptuous as vol
@ -20,7 +20,7 @@ from homeassistant.helpers.config_validation import (
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
PLATFORM_SCHEMA_BASE, PLATFORM_SCHEMA_BASE,
) )
from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.entity import ABCCachedProperties, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
@ -42,6 +42,11 @@ from .const import (
UpdateEntityFeature, UpdateEntityFeature,
) )
if TYPE_CHECKING:
from functools import cached_property
else:
from homeassistant.backports.functools import cached_property
SCAN_INTERVAL = timedelta(minutes=15) SCAN_INTERVAL = timedelta(minutes=15)
ENTITY_ID_FORMAT: Final = DOMAIN + ".{}" ENTITY_ID_FORMAT: Final = DOMAIN + ".{}"
@ -187,7 +192,24 @@ def _version_is_newer(latest_version: str, installed_version: str) -> bool:
return AwesomeVersion(latest_version) > installed_version return AwesomeVersion(latest_version) > installed_version
class UpdateEntity(RestoreEntity): CACHED_PROPERTIES_WITH_ATTR_ = {
"auto_update",
"installed_version",
"device_class",
"in_progress",
"latest_version",
"release_summary",
"release_url",
"supported_features",
"title",
}
class UpdateEntity(
RestoreEntity,
metaclass=ABCCachedProperties,
cached_properties=CACHED_PROPERTIES_WITH_ATTR_,
):
"""Representation of an update entity.""" """Representation of an update entity."""
_entity_component_unrecorded_attributes = frozenset( _entity_component_unrecorded_attributes = frozenset(
@ -208,12 +230,12 @@ class UpdateEntity(RestoreEntity):
__skipped_version: str | None = None __skipped_version: str | None = None
__in_progress: bool = False __in_progress: bool = False
@property @cached_property
def auto_update(self) -> bool: def auto_update(self) -> bool:
"""Indicate if the device or service has auto update enabled.""" """Indicate if the device or service has auto update enabled."""
return self._attr_auto_update return self._attr_auto_update
@property @cached_property
def installed_version(self) -> str | None: def installed_version(self) -> str | None:
"""Version installed and in use.""" """Version installed and in use."""
return self._attr_installed_version return self._attr_installed_version
@ -225,7 +247,7 @@ class UpdateEntity(RestoreEntity):
""" """
return self.device_class is not None return self.device_class is not None
@property @cached_property
def device_class(self) -> UpdateDeviceClass | None: def device_class(self) -> UpdateDeviceClass | None:
"""Return the class of this entity.""" """Return the class of this entity."""
if hasattr(self, "_attr_device_class"): if hasattr(self, "_attr_device_class"):
@ -256,7 +278,7 @@ class UpdateEntity(RestoreEntity):
f"https://brands.home-assistant.io/_/{self.platform.platform_name}/icon.png" f"https://brands.home-assistant.io/_/{self.platform.platform_name}/icon.png"
) )
@property @cached_property
def in_progress(self) -> bool | int | None: def in_progress(self) -> bool | int | None:
"""Update installation progress. """Update installation progress.
@ -267,12 +289,12 @@ class UpdateEntity(RestoreEntity):
""" """
return self._attr_in_progress return self._attr_in_progress
@property @cached_property
def latest_version(self) -> str | None: def latest_version(self) -> str | None:
"""Latest version available for install.""" """Latest version available for install."""
return self._attr_latest_version return self._attr_latest_version
@property @cached_property
def release_summary(self) -> str | None: def release_summary(self) -> str | None:
"""Summary of the release notes or changelog. """Summary of the release notes or changelog.
@ -281,17 +303,17 @@ class UpdateEntity(RestoreEntity):
""" """
return self._attr_release_summary return self._attr_release_summary
@property @cached_property
def release_url(self) -> str | None: def release_url(self) -> str | None:
"""URL to the full release notes of the latest version available.""" """URL to the full release notes of the latest version available."""
return self._attr_release_url return self._attr_release_url
@property @cached_property
def supported_features(self) -> UpdateEntityFeature: def supported_features(self) -> UpdateEntityFeature:
"""Flag supported features.""" """Flag supported features."""
return self._attr_supported_features return self._attr_supported_features
@property @cached_property
def title(self) -> str | None: def title(self) -> str | None:
"""Title of the software. """Title of the software.

View File

@ -128,6 +128,7 @@ async def test_update(hass: HomeAssistant) -> None:
update.entity_description = UpdateEntityDescription(key="F5 - Its very refreshing") update.entity_description = UpdateEntityDescription(key="F5 - Its very refreshing")
assert update.device_class is None assert update.device_class is None
assert update.entity_category is EntityCategory.CONFIG assert update.entity_category is EntityCategory.CONFIG
del update.device_class
update.entity_description = UpdateEntityDescription( update.entity_description = UpdateEntityDescription(
key="F5 - Its very refreshing", key="F5 - Its very refreshing",
device_class=UpdateDeviceClass.FIRMWARE, device_class=UpdateDeviceClass.FIRMWARE,