From 266ce9e26818edb988672ee6f28fe507a07b25cd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 21 May 2024 03:03:31 -1000 Subject: [PATCH] Cache area registry JSON serialize (#117847) We already cache the entity and device registry, but since I never used area until recently I did not have enough to notice that they were not cached --- .../components/config/area_registry.py | 22 ++++--------------- homeassistant/helpers/area_registry.py | 21 +++++++++++++++++- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/config/area_registry.py b/homeassistant/components/config/area_registry.py index a499ab84784..d0725d949cc 100644 --- a/homeassistant/components/config/area_registry.py +++ b/homeassistant/components/config/area_registry.py @@ -8,7 +8,7 @@ import voluptuous as vol from homeassistant.components import websocket_api from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.area_registry import AreaEntry, async_get +from homeassistant.helpers.area_registry import async_get @callback @@ -32,7 +32,7 @@ def websocket_list_areas( registry = async_get(hass) connection.send_result( msg["id"], - [_entry_dict(entry) for entry in registry.async_list_areas()], + [entry.json_fragment for entry in registry.async_list_areas()], ) @@ -74,7 +74,7 @@ def websocket_create_area( except ValueError as err: connection.send_error(msg["id"], "invalid_info", str(err)) else: - connection.send_result(msg["id"], _entry_dict(entry)) + connection.send_result(msg["id"], entry.json_fragment) @websocket_api.websocket_command( @@ -140,18 +140,4 @@ def websocket_update_area( except ValueError as err: connection.send_error(msg["id"], "invalid_info", str(err)) else: - connection.send_result(msg["id"], _entry_dict(entry)) - - -@callback -def _entry_dict(entry: AreaEntry) -> dict[str, Any]: - """Convert entry to API format.""" - return { - "aliases": list(entry.aliases), - "area_id": entry.id, - "floor_id": entry.floor_id, - "icon": entry.icon, - "labels": list(entry.labels), - "name": entry.name, - "picture": entry.picture, - } + connection.send_result(msg["id"], entry.json_fragment) diff --git a/homeassistant/helpers/area_registry.py b/homeassistant/helpers/area_registry.py index db208990219..598eff0f70c 100644 --- a/homeassistant/helpers/area_registry.py +++ b/homeassistant/helpers/area_registry.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections.abc import Iterable import dataclasses +from functools import cached_property from typing import Any, Literal, TypedDict from homeassistant.core import HomeAssistant, callback @@ -12,6 +13,7 @@ from homeassistant.util.event_type import EventType from homeassistant.util.hass_dict import HassKey from . import device_registry as dr, entity_registry as er +from .json import json_bytes, json_fragment from .normalized_name_base_registry import ( NormalizedNameBaseRegistryEntry, NormalizedNameBaseRegistryItems, @@ -56,7 +58,7 @@ class EventAreaRegistryUpdatedData(TypedDict): area_id: str -@dataclasses.dataclass(frozen=True, kw_only=True, slots=True) +@dataclasses.dataclass(frozen=True, kw_only=True) class AreaEntry(NormalizedNameBaseRegistryEntry): """Area Registry Entry.""" @@ -67,6 +69,23 @@ class AreaEntry(NormalizedNameBaseRegistryEntry): labels: set[str] = dataclasses.field(default_factory=set) picture: str | None + @cached_property + def json_fragment(self) -> json_fragment: + """Return a JSON representation of this AreaEntry.""" + return json_fragment( + json_bytes( + { + "aliases": list(self.aliases), + "area_id": self.id, + "floor_id": self.floor_id, + "icon": self.icon, + "labels": list(self.labels), + "name": self.name, + "picture": self.picture, + } + ) + ) + class AreaRegistryStore(Store[AreasRegistryStoreData]): """Store area registry data."""