Cache the response from config/device_registry/list (#74483)

This commit is contained in:
J. Nick Koston 2022-07-05 23:08:39 -05:00 committed by GitHub
parent df6892b908
commit 3875fc5953
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 15 deletions

View File

@ -1,12 +1,23 @@
"""HTTP views to interact with the device registry."""
from __future__ import annotations
import voluptuous as vol
from homeassistant import loader
from homeassistant.components import websocket_api
from homeassistant.components.websocket_api.decorators import require_admin
from homeassistant.core import HomeAssistant, callback
from homeassistant.components.websocket_api.messages import (
IDEN_JSON_TEMPLATE,
IDEN_TEMPLATE,
message_to_json,
)
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceEntryDisabler, async_get
from homeassistant.helpers.device_registry import (
EVENT_DEVICE_REGISTRY_UPDATED,
DeviceEntryDisabler,
async_get,
)
WS_TYPE_LIST = "config/device_registry/list"
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
@ -29,6 +40,36 @@ SCHEMA_WS_UPDATE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
async def async_setup(hass):
"""Enable the Device Registry views."""
cached_list_devices: str | None = None
@callback
def _async_clear_list_device_cache(event: Event) -> None:
nonlocal cached_list_devices
cached_list_devices = None
@callback
def websocket_list_devices(hass, connection, msg):
"""Handle list devices command."""
nonlocal cached_list_devices
if not cached_list_devices:
registry = async_get(hass)
cached_list_devices = message_to_json(
websocket_api.result_message(
IDEN_TEMPLATE,
[_entry_dict(entry) for entry in registry.devices.values()],
)
)
connection.send_message(
cached_list_devices.replace(IDEN_JSON_TEMPLATE, str(msg["id"]), 1)
)
hass.bus.async_listen(
EVENT_DEVICE_REGISTRY_UPDATED,
_async_clear_list_device_cache,
run_immediately=True,
)
websocket_api.async_register_command(
hass, WS_TYPE_LIST, websocket_list_devices, SCHEMA_WS_LIST
)
@ -41,17 +82,6 @@ async def async_setup(hass):
return True
@callback
def websocket_list_devices(hass, connection, msg):
"""Handle list devices command."""
registry = async_get(hass)
connection.send_message(
websocket_api.result_message(
msg["id"], [_entry_dict(entry) for entry in registry.devices.values()]
)
)
@require_admin
@callback
def websocket_update_device(hass, connection, msg):

View File

@ -29,14 +29,14 @@ def registry(hass):
async def test_list_devices(hass, client, registry):
"""Test list entries."""
registry.async_get_or_create(
device1 = registry.async_get_or_create(
config_entry_id="1234",
connections={("ethernet", "12:34:56:78:90:AB:CD:EF")},
identifiers={("bridgeid", "0123")},
manufacturer="manufacturer",
model="model",
)
registry.async_get_or_create(
device2 = registry.async_get_or_create(
config_entry_id="1234",
identifiers={("bridgeid", "1234")},
manufacturer="manufacturer",
@ -85,6 +85,32 @@ async def test_list_devices(hass, client, registry):
},
]
registry.async_remove_device(device2.id)
await hass.async_block_till_done()
await client.send_json({"id": 6, "type": "config/device_registry/list"})
msg = await client.receive_json()
assert msg["result"] == [
{
"area_id": None,
"config_entries": ["1234"],
"configuration_url": None,
"connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]],
"disabled_by": None,
"entry_type": None,
"hw_version": None,
"id": device1.id,
"identifiers": [["bridgeid", "0123"]],
"manufacturer": "manufacturer",
"model": "model",
"name": None,
"name_by_user": None,
"sw_version": None,
"via_device_id": None,
}
]
@pytest.mark.parametrize(
"payload_key,payload_value",