Include end time of statistics data points in API response (#56063)

* Include end time of statistics data points in API response

* Correct typing

* Update tests
pull/56170/head
Erik Montnemery 2021-09-13 10:02:24 +02:00 committed by GitHub
parent 7472fb2049
commit d2a9f7904a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 19 deletions

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from datetime import datetime from datetime import datetime
import json import json
import logging import logging
from typing import TypedDict from typing import TypedDict, overload
from sqlalchemy import ( from sqlalchemy import (
Boolean, Boolean,
@ -391,6 +391,16 @@ class StatisticsRuns(Base): # type: ignore
) )
@overload
def process_timestamp(ts: None) -> None:
...
@overload
def process_timestamp(ts: datetime) -> datetime:
...
def process_timestamp(ts): def process_timestamp(ts):
"""Process a timestamp into datetime object.""" """Process a timestamp into datetime object."""
if ts is None: if ts is None:
@ -401,6 +411,16 @@ def process_timestamp(ts):
return dt_util.as_utc(ts) return dt_util.as_utc(ts)
@overload
def process_timestamp_to_utc_isoformat(ts: None) -> None:
...
@overload
def process_timestamp_to_utc_isoformat(ts: datetime) -> str:
...
def process_timestamp_to_utc_isoformat(ts: datetime | None) -> str | None: def process_timestamp_to_utc_isoformat(ts: datetime | None) -> str | None:
"""Process a timestamp into UTC isotime.""" """Process a timestamp into UTC isotime."""
if ts is None: if ts is None:

View File

@ -32,6 +32,7 @@ from .models import (
Statistics, Statistics,
StatisticsMeta, StatisticsMeta,
StatisticsRuns, StatisticsRuns,
process_timestamp,
process_timestamp_to_utc_isoformat, process_timestamp_to_utc_isoformat,
) )
from .util import execute, retryable_database_job, session_scope from .util import execute, retryable_database_job, session_scope
@ -437,9 +438,6 @@ def _sorted_statistics_to_dict(
for stat_id in statistic_ids: for stat_id in statistic_ids:
result[stat_id] = [] result[stat_id] = []
# Called in a tight loop so cache the function here
_process_timestamp_to_utc_isoformat = process_timestamp_to_utc_isoformat
# Append all statistic entries, and do unit conversion # Append all statistic entries, and do unit conversion
for meta_id, group in groupby(stats, lambda stat: stat.metadata_id): # type: ignore for meta_id, group in groupby(stats, lambda stat: stat.metadata_id): # type: ignore
unit = metadata[meta_id]["unit_of_measurement"] unit = metadata[meta_id]["unit_of_measurement"]
@ -450,20 +448,25 @@ def _sorted_statistics_to_dict(
else: else:
convert = no_conversion convert = no_conversion
ent_results = result[meta_id] ent_results = result[meta_id]
ent_results.extend( for db_state in group:
start = process_timestamp(db_state.start)
end = start + timedelta(hours=1)
ent_results.append(
{ {
"statistic_id": statistic_id, "statistic_id": statistic_id,
"start": _process_timestamp_to_utc_isoformat(db_state.start), "start": start.isoformat(),
"end": end.isoformat(),
"mean": convert(db_state.mean, units), "mean": convert(db_state.mean, units),
"min": convert(db_state.min, units), "min": convert(db_state.min, units),
"max": convert(db_state.max, units), "max": convert(db_state.max, units),
"last_reset": _process_timestamp_to_utc_isoformat(db_state.last_reset), "last_reset": process_timestamp_to_utc_isoformat(
db_state.last_reset
),
"state": convert(db_state.state, units), "state": convert(db_state.state, units),
"sum": (_sum := convert(db_state.sum, units)), "sum": (_sum := convert(db_state.sum, units)),
"sum_increase": (inc := convert(db_state.sum_increase, units)), "sum_increase": (inc := convert(db_state.sum_increase, units)),
"sum_decrease": None if _sum is None or inc is None else inc - _sum, "sum_decrease": None if _sum is None or inc is None else inc - _sum,
} }
for db_state in group
) )
# Filter out the empty lists if some states had 0 results. # Filter out the empty lists if some states had 0 results.

View File

@ -908,6 +908,7 @@ async def test_statistics_during_period(
{ {
"statistic_id": "sensor.test", "statistic_id": "sensor.test",
"start": now.isoformat(), "start": now.isoformat(),
"end": (now + timedelta(hours=1)).isoformat(),
"mean": approx(value), "mean": approx(value),
"min": approx(value), "min": approx(value),
"max": approx(value), "max": approx(value),

View File

@ -45,6 +45,7 @@ def test_compile_hourly_statistics(hass_recorder):
expected_1 = { expected_1 = {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(14.915254237288135), "mean": approx(14.915254237288135),
"min": approx(10.0), "min": approx(10.0),
"max": approx(20.0), "max": approx(20.0),
@ -57,6 +58,7 @@ def test_compile_hourly_statistics(hass_recorder):
expected_2 = { expected_2 = {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(four), "start": process_timestamp_to_utc_isoformat(four),
"end": process_timestamp_to_utc_isoformat(four + timedelta(hours=1)),
"mean": approx(20.0), "mean": approx(20.0),
"min": approx(20.0), "min": approx(20.0),
"max": approx(20.0), "max": approx(20.0),
@ -164,6 +166,7 @@ def test_compile_hourly_statistics_exception(
expected_1 = { expected_1 = {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(now), "start": process_timestamp_to_utc_isoformat(now),
"end": process_timestamp_to_utc_isoformat(now + timedelta(hours=1)),
"mean": None, "mean": None,
"min": None, "min": None,
"max": None, "max": None,
@ -176,6 +179,7 @@ def test_compile_hourly_statistics_exception(
expected_2 = { expected_2 = {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(now + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(now + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(now + timedelta(hours=2)),
"mean": None, "mean": None,
"min": None, "min": None,
"max": None, "max": None,
@ -235,6 +239,7 @@ def test_rename_entity(hass_recorder):
expected_1 = { expected_1 = {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(14.915254237288135), "mean": approx(14.915254237288135),
"min": approx(10.0), "min": approx(10.0),
"max": approx(20.0), "max": approx(20.0),

View File

@ -95,6 +95,7 @@ def test_compile_hourly_statistics(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -159,6 +160,7 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(13.050847), "mean": approx(13.050847),
"min": approx(-10.0), "min": approx(-10.0),
"max": approx(30.0), "max": approx(30.0),
@ -173,6 +175,7 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
{ {
"statistic_id": "sensor.test6", "statistic_id": "sensor.test6",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(13.050847), "mean": approx(13.050847),
"min": approx(-10.0), "min": approx(-10.0),
"max": approx(30.0), "max": approx(30.0),
@ -187,6 +190,7 @@ def test_compile_hourly_statistics_unsupported(hass_recorder, caplog, attributes
{ {
"statistic_id": "sensor.test7", "statistic_id": "sensor.test7",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(13.050847), "mean": approx(13.050847),
"min": approx(-10.0), "min": approx(-10.0),
"max": approx(30.0), "max": approx(30.0),
@ -260,6 +264,7 @@ def test_compile_hourly_sum_statistics_amount(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -272,6 +277,7 @@ def test_compile_hourly_sum_statistics_amount(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -284,6 +290,7 @@ def test_compile_hourly_sum_statistics_amount(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -360,6 +367,7 @@ def test_compile_hourly_sum_statistics_amount_reset_every_state_change(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -426,6 +434,7 @@ def test_compile_hourly_sum_statistics_nan_inf_state(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -492,6 +501,7 @@ def test_compile_hourly_sum_statistics_total_no_reset(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -504,6 +514,7 @@ def test_compile_hourly_sum_statistics_total_no_reset(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -516,6 +527,7 @@ def test_compile_hourly_sum_statistics_total_no_reset(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -578,6 +590,7 @@ def test_compile_hourly_sum_statistics_total_increasing(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -590,6 +603,7 @@ def test_compile_hourly_sum_statistics_total_increasing(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -602,6 +616,7 @@ def test_compile_hourly_sum_statistics_total_increasing(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -675,6 +690,7 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
"last_reset": None, "last_reset": None,
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -687,6 +703,7 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
"last_reset": None, "last_reset": None,
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -699,6 +716,7 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
"last_reset": None, "last_reset": None,
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -767,6 +785,7 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -779,6 +798,7 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -791,6 +811,7 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -856,6 +877,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -868,6 +890,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -880,6 +903,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -894,6 +918,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test2", "statistic_id": "sensor.test2",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -906,6 +931,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test2", "statistic_id": "sensor.test2",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -918,6 +944,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test2", "statistic_id": "sensor.test2",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -932,6 +959,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test3", "statistic_id": "sensor.test3",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -944,6 +972,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test3", "statistic_id": "sensor.test3",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -956,6 +985,7 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test3", "statistic_id": "sensor.test3",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=3)),
"max": None, "max": None,
"mean": None, "mean": None,
"min": None, "min": None,
@ -1011,6 +1041,7 @@ def test_compile_hourly_statistics_unchanged(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(four), "start": process_timestamp_to_utc_isoformat(four),
"end": process_timestamp_to_utc_isoformat(four + timedelta(hours=1)),
"mean": approx(value), "mean": approx(value),
"min": approx(value), "min": approx(value),
"max": approx(value), "max": approx(value),
@ -1045,6 +1076,7 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog):
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(21.1864406779661), "mean": approx(21.1864406779661),
"min": approx(10.0), "min": approx(10.0),
"max": approx(25.0), "max": approx(25.0),
@ -1104,6 +1136,7 @@ def test_compile_hourly_statistics_unavailable(
{ {
"statistic_id": "sensor.test2", "statistic_id": "sensor.test2",
"start": process_timestamp_to_utc_isoformat(four), "start": process_timestamp_to_utc_isoformat(four),
"end": process_timestamp_to_utc_isoformat(four + timedelta(hours=1)),
"mean": approx(value), "mean": approx(value),
"min": approx(value), "min": approx(value),
"max": approx(value), "max": approx(value),
@ -1256,6 +1289,7 @@ def test_compile_hourly_statistics_changing_units_1(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -1284,6 +1318,7 @@ def test_compile_hourly_statistics_changing_units_1(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -1391,6 +1426,7 @@ def test_compile_hourly_statistics_changing_units_3(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -1417,6 +1453,7 @@ def test_compile_hourly_statistics_changing_units_3(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -1497,6 +1534,7 @@ def test_compile_hourly_statistics_changing_statistics(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero), "start": process_timestamp_to_utc_isoformat(zero),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"mean": approx(mean), "mean": approx(mean),
"min": approx(min), "min": approx(min),
"max": approx(max), "max": approx(max),
@ -1509,6 +1547,7 @@ def test_compile_hourly_statistics_changing_statistics(
{ {
"statistic_id": "sensor.test1", "statistic_id": "sensor.test1",
"start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)), "start": process_timestamp_to_utc_isoformat(zero + timedelta(hours=1)),
"end": process_timestamp_to_utc_isoformat(zero + timedelta(hours=2)),
"mean": None, "mean": None,
"min": None, "min": None,
"max": None, "max": None,