mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Add WS API for listing available statistic ids (#51984)
* Add WS API for listing available statistic ids * Update homeassistant/components/history/__init__.py Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io> Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
805ef3f90b
commit
0ca199d8d0
@ -14,7 +14,10 @@ import voluptuous as vol
|
|||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.components.recorder import history, models as history_models
|
from homeassistant.components.recorder import history, models as history_models
|
||||||
from homeassistant.components.recorder.statistics import statistics_during_period
|
from homeassistant.components.recorder.statistics import (
|
||||||
|
list_statistic_ids,
|
||||||
|
statistics_during_period,
|
||||||
|
)
|
||||||
from homeassistant.components.recorder.util import session_scope
|
from homeassistant.components.recorder.util import session_scope
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_DOMAINS,
|
CONF_DOMAINS,
|
||||||
@ -105,6 +108,7 @@ async def async_setup(hass, config):
|
|||||||
hass.components.websocket_api.async_register_command(
|
hass.components.websocket_api.async_register_command(
|
||||||
ws_get_statistics_during_period
|
ws_get_statistics_during_period
|
||||||
)
|
)
|
||||||
|
hass.components.websocket_api.async_register_command(ws_get_list_statistic_ids)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -157,6 +161,26 @@ async def ws_get_statistics_during_period(
|
|||||||
connection.send_result(msg["id"], statistics)
|
connection.send_result(msg["id"], statistics)
|
||||||
|
|
||||||
|
|
||||||
|
@websocket_api.websocket_command(
|
||||||
|
{
|
||||||
|
vol.Required("type"): "history/list_statistic_ids",
|
||||||
|
vol.Optional("statistic_type"): str,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@websocket_api.require_admin
|
||||||
|
@websocket_api.async_response
|
||||||
|
async def ws_get_list_statistic_ids(
|
||||||
|
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict
|
||||||
|
) -> None:
|
||||||
|
"""Fetch a list of available statistic_id."""
|
||||||
|
statistics = await hass.async_add_executor_job(
|
||||||
|
list_statistic_ids,
|
||||||
|
hass,
|
||||||
|
msg.get("statistic_type"),
|
||||||
|
)
|
||||||
|
connection.send_result(msg["id"], {"statistic_ids": statistics})
|
||||||
|
|
||||||
|
|
||||||
class HistoryPeriodView(HomeAssistantView):
|
class HistoryPeriodView(HomeAssistantView):
|
||||||
"""Handle history period requests."""
|
"""Handle history period requests."""
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ QUERY_STATISTICS = [
|
|||||||
Statistics.sum,
|
Statistics.sum,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
QUERY_STATISTIC_IDS = [
|
||||||
|
Statistics.statistic_id,
|
||||||
|
]
|
||||||
|
|
||||||
STATISTICS_BAKERY = "recorder_statistics_bakery"
|
STATISTICS_BAKERY = "recorder_statistics_bakery"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -74,6 +78,26 @@ def compile_statistics(instance: Recorder, start: datetime.datetime) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def list_statistic_ids(hass, statistic_type=None):
|
||||||
|
"""Return statistic_ids."""
|
||||||
|
with session_scope(hass=hass) as session:
|
||||||
|
baked_query = hass.data[STATISTICS_BAKERY](
|
||||||
|
lambda session: session.query(*QUERY_STATISTIC_IDS).distinct()
|
||||||
|
)
|
||||||
|
|
||||||
|
if statistic_type == "mean":
|
||||||
|
baked_query += lambda q: q.filter(Statistics.mean.isnot(None))
|
||||||
|
if statistic_type == "sum":
|
||||||
|
baked_query += lambda q: q.filter(Statistics.sum.isnot(None))
|
||||||
|
|
||||||
|
baked_query += lambda q: q.order_by(Statistics.statistic_id)
|
||||||
|
|
||||||
|
statistic_ids = []
|
||||||
|
result = execute(baked_query(session))
|
||||||
|
statistic_ids = [statistic_id[0] for statistic_id in result]
|
||||||
|
return statistic_ids
|
||||||
|
|
||||||
|
|
||||||
def statistics_during_period(hass, start_time, end_time=None, statistic_ids=None):
|
def statistics_during_period(hass, start_time, end_time=None, statistic_ids=None):
|
||||||
"""Return states changes during UTC period start_time - end_time."""
|
"""Return states changes during UTC period start_time - end_time."""
|
||||||
with session_scope(hass=hass) as session:
|
with session_scope(hass=hass) as session:
|
||||||
|
@ -938,3 +938,57 @@ async def test_statistics_during_period_bad_end_time(hass, hass_ws_client):
|
|||||||
response = await client.receive_json()
|
response = await client.receive_json()
|
||||||
assert not response["success"]
|
assert not response["success"]
|
||||||
assert response["error"]["code"] == "invalid_end_time"
|
assert response["error"]["code"] == "invalid_end_time"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_list_statistic_ids(hass, hass_ws_client):
|
||||||
|
"""Test list_statistic_ids."""
|
||||||
|
now = dt_util.utcnow()
|
||||||
|
|
||||||
|
await hass.async_add_executor_job(init_recorder_component, hass)
|
||||||
|
await async_setup_component(hass, "history", {"history": {}})
|
||||||
|
await async_setup_component(hass, "sensor", {})
|
||||||
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
hass.states.async_set(
|
||||||
|
"sensor.test",
|
||||||
|
10,
|
||||||
|
attributes={"device_class": "temperature", "state_class": "measurement"},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await hass.async_add_executor_job(trigger_db_commit, hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
client = await hass_ws_client()
|
||||||
|
await client.send_json({"id": 1, "type": "history/list_statistic_ids"})
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"statistic_ids": []}
|
||||||
|
|
||||||
|
hass.data[recorder.DATA_INSTANCE].do_adhoc_statistics(period="hourly", start=now)
|
||||||
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
|
await client.send_json({"id": 2, "type": "history/list_statistic_ids"})
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"statistic_ids": ["sensor.test"]}
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 3, "type": "history/list_statistic_ids", "statistic_type": "dogs"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"statistic_ids": ["sensor.test"]}
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 4, "type": "history/list_statistic_ids", "statistic_type": "mean"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"statistic_ids": ["sensor.test"]}
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{"id": 5, "type": "history/list_statistic_ids", "statistic_type": "sum"}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {"statistic_ids": []}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user