Add websocket API to get list of recorded entities (#92640)
* Add API to get list of recorded entities * update for latest codebase * ruff * Update homeassistant/components/recorder/websocket_api.py * Update homeassistant/components/recorder/websocket_api.py * Update homeassistant/components/recorder/websocket_api.py * add suggested testpull/117476/head
parent
d29084d6fc
commit
3f053eddbd
|
@ -3,7 +3,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime as dt
|
||||
from typing import Any, Literal, cast
|
||||
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -44,7 +44,11 @@ from .statistics import (
|
|||
statistics_during_period,
|
||||
validate_statistics,
|
||||
)
|
||||
from .util import PERIOD_SCHEMA, get_instance, resolve_period
|
||||
from .util import PERIOD_SCHEMA, get_instance, resolve_period, session_scope
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .core import Recorder
|
||||
|
||||
|
||||
UNIT_SCHEMA = vol.Schema(
|
||||
{
|
||||
|
@ -81,6 +85,7 @@ def async_setup(hass: HomeAssistant) -> None:
|
|||
websocket_api.async_register_command(hass, ws_info)
|
||||
websocket_api.async_register_command(hass, ws_update_statistics_metadata)
|
||||
websocket_api.async_register_command(hass, ws_validate_statistics)
|
||||
websocket_api.async_register_command(hass, ws_get_recorded_entities)
|
||||
|
||||
|
||||
def _ws_get_statistic_during_period(
|
||||
|
@ -513,3 +518,40 @@ def ws_info(
|
|||
"thread_running": is_running,
|
||||
}
|
||||
connection.send_result(msg["id"], recorder_info)
|
||||
|
||||
|
||||
def _get_recorded_entities(
|
||||
hass: HomeAssistant, msg_id: int, instance: Recorder
|
||||
) -> bytes:
|
||||
"""Get the list of entities being recorded."""
|
||||
with session_scope(hass=hass, read_only=True) as session:
|
||||
return json_bytes(
|
||||
messages.result_message(
|
||||
msg_id,
|
||||
{
|
||||
"entity_ids": list(
|
||||
instance.states_meta_manager.get_metadata_id_to_entity_id(
|
||||
session
|
||||
).values()
|
||||
)
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "recorder/recorded_entities",
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_get_recorded_entities(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Get the list of entities being recorded."""
|
||||
instance = get_instance(hass)
|
||||
return connection.send_message(
|
||||
await instance.async_add_executor_job(
|
||||
_get_recorded_entities, hass, msg["id"], instance
|
||||
)
|
||||
)
|
||||
|
|
|
@ -23,6 +23,7 @@ from homeassistant.components.recorder.statistics import (
|
|||
from homeassistant.components.recorder.util import session_scope
|
||||
from homeassistant.components.recorder.websocket_api import UNIT_SCHEMA
|
||||
from homeassistant.components.sensor import UNIT_CONVERTERS
|
||||
from homeassistant.const import CONF_DOMAINS, CONF_EXCLUDE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import recorder as recorder_helper
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
@ -38,7 +39,7 @@ from .common import (
|
|||
)
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.typing import WebSocketGenerator
|
||||
from tests.typing import RecorderInstanceGenerator, WebSocketGenerator
|
||||
|
||||
DISTANCE_SENSOR_FT_ATTRIBUTES = {
|
||||
"device_class": "distance",
|
||||
|
@ -132,6 +133,13 @@ VOLUME_SENSOR_M3_ATTRIBUTES_TOTAL = {
|
|||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def mock_recorder_before_hass(
|
||||
async_setup_recorder_instance: RecorderInstanceGenerator,
|
||||
) -> None:
|
||||
"""Set up recorder."""
|
||||
|
||||
|
||||
def test_converters_align_with_sensor() -> None:
|
||||
"""Ensure UNIT_SCHEMA is aligned with sensor UNIT_CONVERTERS."""
|
||||
for converter in UNIT_CONVERTERS.values():
|
||||
|
@ -3177,3 +3185,64 @@ async def test_adjust_sum_statistics_errors(
|
|||
stats = statistics_during_period(hass, zero, period="hour")
|
||||
assert stats != previous_stats
|
||||
previous_stats = stats
|
||||
|
||||
|
||||
async def test_recorder_recorded_entities_no_filter(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
async_setup_recorder_instance: RecorderInstanceGenerator,
|
||||
) -> None:
|
||||
"""Test getting the list of recorded entities without a filter."""
|
||||
await async_setup_recorder_instance(hass, {recorder.CONF_COMMIT_INTERVAL: 0})
|
||||
client = await hass_ws_client()
|
||||
|
||||
await client.send_json({"id": 1, "type": "recorder/recorded_entities"})
|
||||
response = await client.receive_json()
|
||||
assert response["result"] == {"entity_ids": []}
|
||||
assert response["id"] == 1
|
||||
assert response["success"]
|
||||
assert response["type"] == "result"
|
||||
|
||||
hass.states.async_set("sensor.test", 10)
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
await client.send_json({"id": 2, "type": "recorder/recorded_entities"})
|
||||
response = await client.receive_json()
|
||||
assert response["result"] == {"entity_ids": ["sensor.test"]}
|
||||
assert response["id"] == 2
|
||||
assert response["success"]
|
||||
assert response["type"] == "result"
|
||||
|
||||
|
||||
async def test_recorder_recorded_entities_with_filter(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
async_setup_recorder_instance: RecorderInstanceGenerator,
|
||||
) -> None:
|
||||
"""Test getting the list of recorded entities with a filter."""
|
||||
await async_setup_recorder_instance(
|
||||
hass,
|
||||
{
|
||||
recorder.CONF_COMMIT_INTERVAL: 0,
|
||||
CONF_EXCLUDE: {CONF_DOMAINS: ["sensor"]},
|
||||
},
|
||||
)
|
||||
client = await hass_ws_client()
|
||||
|
||||
await client.send_json({"id": 1, "type": "recorder/recorded_entities"})
|
||||
response = await client.receive_json()
|
||||
assert response["result"] == {"entity_ids": []}
|
||||
assert response["id"] == 1
|
||||
assert response["success"]
|
||||
assert response["type"] == "result"
|
||||
|
||||
hass.states.async_set("switch.test", 10)
|
||||
hass.states.async_set("sensor.test", 10)
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
await client.send_json({"id": 2, "type": "recorder/recorded_entities"})
|
||||
response = await client.receive_json()
|
||||
assert response["result"] == {"entity_ids": ["switch.test"]}
|
||||
assert response["id"] == 2
|
||||
assert response["success"]
|
||||
assert response["type"] == "result"
|
||||
|
|
Loading…
Reference in New Issue