Reduce size of get_statistics_during_period WS API response (#82131)
This commit is contained in:
parent
bb64b39d0e
commit
607a0e7697
12 changed files with 588 additions and 591 deletions
|
@ -267,7 +267,7 @@ async def _insert_sum_statistics(
|
||||||
statistic_id = metadata["statistic_id"]
|
statistic_id = metadata["statistic_id"]
|
||||||
|
|
||||||
last_stats = await get_instance(hass).async_add_executor_job(
|
last_stats = await get_instance(hass).async_add_executor_job(
|
||||||
get_last_statistics, hass, 1, statistic_id, False
|
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
||||||
)
|
)
|
||||||
if statistic_id in last_stats:
|
if statistic_id in last_stats:
|
||||||
sum_ = last_stats[statistic_id][0]["sum"] or 0
|
sum_ = last_stats[statistic_id][0]["sum"] or 0
|
||||||
|
|
|
@ -272,8 +272,8 @@ async def ws_get_fossil_energy_consumption(
|
||||||
end_time,
|
end_time,
|
||||||
statistic_ids,
|
statistic_ids,
|
||||||
"hour",
|
"hour",
|
||||||
True,
|
|
||||||
{"energy": UnitOfEnergy.KILO_WATT_HOUR},
|
{"energy": UnitOfEnergy.KILO_WATT_HOUR},
|
||||||
|
{"mean", "sum"},
|
||||||
)
|
)
|
||||||
|
|
||||||
def _combine_sum_statistics(
|
def _combine_sum_statistics(
|
||||||
|
|
|
@ -53,13 +53,7 @@ from .db_schema import (
|
||||||
StatisticsRuns,
|
StatisticsRuns,
|
||||||
StatisticsShortTerm,
|
StatisticsShortTerm,
|
||||||
)
|
)
|
||||||
from .models import (
|
from .models import StatisticData, StatisticMetaData, StatisticResult, process_timestamp
|
||||||
StatisticData,
|
|
||||||
StatisticMetaData,
|
|
||||||
StatisticResult,
|
|
||||||
process_timestamp,
|
|
||||||
process_timestamp_to_utc_isoformat,
|
|
||||||
)
|
|
||||||
from .util import (
|
from .util import (
|
||||||
execute,
|
execute,
|
||||||
execute_stmt_lambda_element,
|
execute_stmt_lambda_element,
|
||||||
|
@ -947,6 +941,7 @@ def _reduce_statistics(
|
||||||
same_period: Callable[[datetime, datetime], bool],
|
same_period: Callable[[datetime, datetime], bool],
|
||||||
period_start_end: Callable[[datetime], tuple[datetime, datetime]],
|
period_start_end: Callable[[datetime], tuple[datetime, datetime]],
|
||||||
period: timedelta,
|
period: timedelta,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict[str, Any]]]:
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
"""Reduce hourly statistics to daily or monthly statistics."""
|
"""Reduce hourly statistics to daily or monthly statistics."""
|
||||||
result: dict[str, list[dict[str, Any]]] = defaultdict(list)
|
result: dict[str, list[dict[str, Any]]] = defaultdict(list)
|
||||||
|
@ -963,19 +958,24 @@ def _reduce_statistics(
|
||||||
if not same_period(prev_stat["start"], statistic["start"]):
|
if not same_period(prev_stat["start"], statistic["start"]):
|
||||||
start, end = period_start_end(prev_stat["start"])
|
start, end = period_start_end(prev_stat["start"])
|
||||||
# The previous statistic was the last entry of the period
|
# The previous statistic was the last entry of the period
|
||||||
result[statistic_id].append(
|
row: dict[str, Any] = {
|
||||||
{
|
"start": start,
|
||||||
"statistic_id": statistic_id,
|
"end": end,
|
||||||
"start": start.isoformat(),
|
}
|
||||||
"end": end.isoformat(),
|
if "mean" in types:
|
||||||
"mean": mean(mean_values) if mean_values else None,
|
row["mean"] = mean(mean_values) if mean_values else None
|
||||||
"min": min(min_values) if min_values else None,
|
if "min" in types:
|
||||||
"max": max(max_values) if max_values else None,
|
row["min"] = min(min_values) if min_values else None
|
||||||
"last_reset": prev_stat.get("last_reset"),
|
if "max" in types:
|
||||||
"state": prev_stat.get("state"),
|
row["max"] = max(max_values) if max_values else None
|
||||||
"sum": prev_stat["sum"],
|
if "last_reset" in types:
|
||||||
}
|
row["last_reset"] = prev_stat.get("last_reset")
|
||||||
)
|
if "state" in types:
|
||||||
|
row["state"] = prev_stat.get("state")
|
||||||
|
if "sum" in types:
|
||||||
|
row["sum"] = prev_stat["sum"]
|
||||||
|
result[statistic_id].append(row)
|
||||||
|
|
||||||
max_values = []
|
max_values = []
|
||||||
mean_values = []
|
mean_values = []
|
||||||
min_values = []
|
min_values = []
|
||||||
|
@ -1007,11 +1007,12 @@ def day_start_end(time: datetime) -> tuple[datetime, datetime]:
|
||||||
|
|
||||||
|
|
||||||
def _reduce_statistics_per_day(
|
def _reduce_statistics_per_day(
|
||||||
stats: dict[str, list[dict[str, Any]]]
|
stats: dict[str, list[dict[str, Any]]],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict[str, Any]]]:
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
"""Reduce hourly statistics to daily statistics."""
|
"""Reduce hourly statistics to daily statistics."""
|
||||||
|
|
||||||
return _reduce_statistics(stats, same_day, day_start_end, timedelta(days=1))
|
return _reduce_statistics(stats, same_day, day_start_end, timedelta(days=1), types)
|
||||||
|
|
||||||
|
|
||||||
def same_week(time1: datetime, time2: datetime) -> bool:
|
def same_week(time1: datetime, time2: datetime) -> bool:
|
||||||
|
@ -1037,10 +1038,13 @@ def week_start_end(time: datetime) -> tuple[datetime, datetime]:
|
||||||
|
|
||||||
def _reduce_statistics_per_week(
|
def _reduce_statistics_per_week(
|
||||||
stats: dict[str, list[dict[str, Any]]],
|
stats: dict[str, list[dict[str, Any]]],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict[str, Any]]]:
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
"""Reduce hourly statistics to weekly statistics."""
|
"""Reduce hourly statistics to weekly statistics."""
|
||||||
|
|
||||||
return _reduce_statistics(stats, same_week, week_start_end, timedelta(days=7))
|
return _reduce_statistics(
|
||||||
|
stats, same_week, week_start_end, timedelta(days=7), types
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def same_month(time1: datetime, time2: datetime) -> bool:
|
def same_month(time1: datetime, time2: datetime) -> bool:
|
||||||
|
@ -1063,53 +1067,47 @@ def month_start_end(time: datetime) -> tuple[datetime, datetime]:
|
||||||
|
|
||||||
def _reduce_statistics_per_month(
|
def _reduce_statistics_per_month(
|
||||||
stats: dict[str, list[dict[str, Any]]],
|
stats: dict[str, list[dict[str, Any]]],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict[str, Any]]]:
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
"""Reduce hourly statistics to monthly statistics."""
|
"""Reduce hourly statistics to monthly statistics."""
|
||||||
|
|
||||||
return _reduce_statistics(stats, same_month, month_start_end, timedelta(days=31))
|
return _reduce_statistics(
|
||||||
|
stats, same_month, month_start_end, timedelta(days=31), types
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _statistics_during_period_stmt(
|
def _statistics_during_period_stmt(
|
||||||
start_time: datetime,
|
start_time: datetime,
|
||||||
end_time: datetime | None,
|
end_time: datetime | None,
|
||||||
metadata_ids: list[int] | None,
|
metadata_ids: list[int] | None,
|
||||||
|
table: type[Statistics | StatisticsShortTerm],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> StatementLambdaElement:
|
) -> StatementLambdaElement:
|
||||||
"""Prepare a database query for statistics during a given period.
|
"""Prepare a database query for statistics during a given period.
|
||||||
|
|
||||||
This prepares a lambda_stmt query, so we don't insert the parameters yet.
|
This prepares a lambda_stmt query, so we don't insert the parameters yet.
|
||||||
"""
|
"""
|
||||||
stmt = lambda_stmt(
|
|
||||||
lambda: select(*QUERY_STATISTICS).filter(Statistics.start >= start_time)
|
columns = [table.metadata_id, table.start]
|
||||||
)
|
if "last_reset" in types:
|
||||||
|
columns.append(table.last_reset)
|
||||||
|
if "max" in types:
|
||||||
|
columns.append(table.max)
|
||||||
|
if "mean" in types:
|
||||||
|
columns.append(table.mean)
|
||||||
|
if "min" in types:
|
||||||
|
columns.append(table.min)
|
||||||
|
if "state" in types:
|
||||||
|
columns.append(table.state)
|
||||||
|
if "sum" in types:
|
||||||
|
columns.append(table.sum)
|
||||||
|
|
||||||
|
stmt = lambda_stmt(lambda: select(columns).filter(table.start >= start_time))
|
||||||
if end_time is not None:
|
if end_time is not None:
|
||||||
stmt += lambda q: q.filter(Statistics.start < end_time)
|
stmt += lambda q: q.filter(table.start < end_time)
|
||||||
if metadata_ids:
|
if metadata_ids:
|
||||||
stmt += lambda q: q.filter(Statistics.metadata_id.in_(metadata_ids))
|
stmt += lambda q: q.filter(table.metadata_id.in_(metadata_ids))
|
||||||
stmt += lambda q: q.order_by(Statistics.metadata_id, Statistics.start)
|
stmt += lambda q: q.order_by(table.metadata_id, table.start)
|
||||||
return stmt
|
|
||||||
|
|
||||||
|
|
||||||
def _statistics_during_period_stmt_short_term(
|
|
||||||
start_time: datetime,
|
|
||||||
end_time: datetime | None,
|
|
||||||
metadata_ids: list[int] | None,
|
|
||||||
) -> StatementLambdaElement:
|
|
||||||
"""Prepare a database query for short term statistics during a given period.
|
|
||||||
|
|
||||||
This prepares a lambda_stmt query, so we don't insert the parameters yet.
|
|
||||||
"""
|
|
||||||
stmt = lambda_stmt(
|
|
||||||
lambda: select(*QUERY_STATISTICS_SHORT_TERM).filter(
|
|
||||||
StatisticsShortTerm.start >= start_time
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if end_time is not None:
|
|
||||||
stmt += lambda q: q.filter(StatisticsShortTerm.start < end_time)
|
|
||||||
if metadata_ids:
|
|
||||||
stmt += lambda q: q.filter(StatisticsShortTerm.metadata_id.in_(metadata_ids))
|
|
||||||
stmt += lambda q: q.order_by(
|
|
||||||
StatisticsShortTerm.metadata_id, StatisticsShortTerm.start
|
|
||||||
)
|
|
||||||
return stmt
|
return stmt
|
||||||
|
|
||||||
|
|
||||||
|
@ -1119,7 +1117,7 @@ def _get_max_mean_min_statistic_in_sub_period(
|
||||||
start_time: datetime | None,
|
start_time: datetime | None,
|
||||||
end_time: datetime | None,
|
end_time: datetime | None,
|
||||||
table: type[Statistics | StatisticsShortTerm],
|
table: type[Statistics | StatisticsShortTerm],
|
||||||
types: set[str],
|
types: set[Literal["max", "mean", "min", "change"]],
|
||||||
metadata_id: int,
|
metadata_id: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Return max, mean and min during the period."""
|
"""Return max, mean and min during the period."""
|
||||||
|
@ -1160,7 +1158,7 @@ def _get_max_mean_min_statistic(
|
||||||
tail_end_time: datetime | None,
|
tail_end_time: datetime | None,
|
||||||
tail_only: bool,
|
tail_only: bool,
|
||||||
metadata_id: int,
|
metadata_id: int,
|
||||||
types: set[str],
|
types: set[Literal["max", "mean", "min", "change"]],
|
||||||
) -> dict[str, float | None]:
|
) -> dict[str, float | None]:
|
||||||
"""Return max, mean and min during the period.
|
"""Return max, mean and min during the period.
|
||||||
|
|
||||||
|
@ -1380,7 +1378,7 @@ def statistic_during_period(
|
||||||
start_time: datetime | None,
|
start_time: datetime | None,
|
||||||
end_time: datetime | None,
|
end_time: datetime | None,
|
||||||
statistic_id: str,
|
statistic_id: str,
|
||||||
types: set[str] | None,
|
types: set[Literal["max", "mean", "min", "change"]] | None,
|
||||||
units: dict[str, str] | None,
|
units: dict[str, str] | None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Return a statistic data point for the UTC period start_time - end_time."""
|
"""Return a statistic data point for the UTC period start_time - end_time."""
|
||||||
|
@ -1534,11 +1532,11 @@ def statistic_during_period(
|
||||||
def statistics_during_period(
|
def statistics_during_period(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
start_time: datetime,
|
start_time: datetime,
|
||||||
end_time: datetime | None = None,
|
end_time: datetime | None,
|
||||||
statistic_ids: list[str] | None = None,
|
statistic_ids: list[str] | None,
|
||||||
period: Literal["5minute", "day", "hour", "week", "month"] = "hour",
|
period: Literal["5minute", "day", "hour", "week", "month"],
|
||||||
start_time_as_datetime: bool = False,
|
units: dict[str, str] | None,
|
||||||
units: dict[str, str] | None = None,
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict[str, Any]]]:
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
"""Return statistic data points during UTC period start_time - end_time.
|
"""Return statistic data points during UTC period start_time - end_time.
|
||||||
|
|
||||||
|
@ -1556,14 +1554,12 @@ def statistics_during_period(
|
||||||
if statistic_ids is not None:
|
if statistic_ids is not None:
|
||||||
metadata_ids = [metadata_id for metadata_id, _ in metadata.values()]
|
metadata_ids = [metadata_id for metadata_id, _ in metadata.values()]
|
||||||
|
|
||||||
if period == "5minute":
|
table: type[Statistics | StatisticsShortTerm] = (
|
||||||
table = StatisticsShortTerm
|
Statistics if period != "5minute" else StatisticsShortTerm
|
||||||
stmt = _statistics_during_period_stmt_short_term(
|
)
|
||||||
start_time, end_time, metadata_ids
|
stmt = _statistics_during_period_stmt(
|
||||||
)
|
start_time, end_time, metadata_ids, table, types
|
||||||
else:
|
)
|
||||||
table = Statistics
|
|
||||||
stmt = _statistics_during_period_stmt(start_time, end_time, metadata_ids)
|
|
||||||
stats = execute_stmt_lambda_element(session, stmt)
|
stats = execute_stmt_lambda_element(session, stmt)
|
||||||
|
|
||||||
if not stats:
|
if not stats:
|
||||||
|
@ -1579,8 +1575,8 @@ def statistics_during_period(
|
||||||
True,
|
True,
|
||||||
table,
|
table,
|
||||||
start_time,
|
start_time,
|
||||||
start_time_as_datetime,
|
|
||||||
units,
|
units,
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = _sorted_statistics_to_dict(
|
result = _sorted_statistics_to_dict(
|
||||||
|
@ -1592,17 +1588,17 @@ def statistics_during_period(
|
||||||
True,
|
True,
|
||||||
table,
|
table,
|
||||||
start_time,
|
start_time,
|
||||||
True,
|
|
||||||
units,
|
units,
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
|
|
||||||
if period == "day":
|
if period == "day":
|
||||||
return _reduce_statistics_per_day(result)
|
return _reduce_statistics_per_day(result, types)
|
||||||
|
|
||||||
if period == "week":
|
if period == "week":
|
||||||
return _reduce_statistics_per_week(result)
|
return _reduce_statistics_per_week(result, types)
|
||||||
|
|
||||||
return _reduce_statistics_per_month(result)
|
return _reduce_statistics_per_month(result, types)
|
||||||
|
|
||||||
|
|
||||||
def _get_last_statistics_stmt(
|
def _get_last_statistics_stmt(
|
||||||
|
@ -1637,6 +1633,7 @@ def _get_last_statistics(
|
||||||
statistic_id: str,
|
statistic_id: str,
|
||||||
convert_units: bool,
|
convert_units: bool,
|
||||||
table: type[Statistics | StatisticsShortTerm],
|
table: type[Statistics | StatisticsShortTerm],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict]]:
|
) -> dict[str, list[dict]]:
|
||||||
"""Return the last number_of_stats statistics for a given statistic_id."""
|
"""Return the last number_of_stats statistics for a given statistic_id."""
|
||||||
statistic_ids = [statistic_id]
|
statistic_ids = [statistic_id]
|
||||||
|
@ -1665,26 +1662,34 @@ def _get_last_statistics(
|
||||||
convert_units,
|
convert_units,
|
||||||
table,
|
table,
|
||||||
None,
|
None,
|
||||||
False,
|
|
||||||
None,
|
None,
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_last_statistics(
|
def get_last_statistics(
|
||||||
hass: HomeAssistant, number_of_stats: int, statistic_id: str, convert_units: bool
|
hass: HomeAssistant,
|
||||||
|
number_of_stats: int,
|
||||||
|
statistic_id: str,
|
||||||
|
convert_units: bool,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict]]:
|
) -> dict[str, list[dict]]:
|
||||||
"""Return the last number_of_stats statistics for a statistic_id."""
|
"""Return the last number_of_stats statistics for a statistic_id."""
|
||||||
return _get_last_statistics(
|
return _get_last_statistics(
|
||||||
hass, number_of_stats, statistic_id, convert_units, Statistics
|
hass, number_of_stats, statistic_id, convert_units, Statistics, types
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_last_short_term_statistics(
|
def get_last_short_term_statistics(
|
||||||
hass: HomeAssistant, number_of_stats: int, statistic_id: str, convert_units: bool
|
hass: HomeAssistant,
|
||||||
|
number_of_stats: int,
|
||||||
|
statistic_id: str,
|
||||||
|
convert_units: bool,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict]]:
|
) -> dict[str, list[dict]]:
|
||||||
"""Return the last number_of_stats short term statistics for a statistic_id."""
|
"""Return the last number_of_stats short term statistics for a statistic_id."""
|
||||||
return _get_last_statistics(
|
return _get_last_statistics(
|
||||||
hass, number_of_stats, statistic_id, convert_units, StatisticsShortTerm
|
hass, number_of_stats, statistic_id, convert_units, StatisticsShortTerm, types
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1720,6 +1725,7 @@ def _latest_short_term_statistics_stmt(
|
||||||
def get_latest_short_term_statistics(
|
def get_latest_short_term_statistics(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
statistic_ids: list[str],
|
statistic_ids: list[str],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
metadata: dict[str, tuple[int, StatisticMetaData]] | None = None,
|
metadata: dict[str, tuple[int, StatisticMetaData]] | None = None,
|
||||||
) -> dict[str, list[dict]]:
|
) -> dict[str, list[dict]]:
|
||||||
"""Return the latest short term statistics for a list of statistic_ids."""
|
"""Return the latest short term statistics for a list of statistic_ids."""
|
||||||
|
@ -1749,8 +1755,8 @@ def get_latest_short_term_statistics(
|
||||||
False,
|
False,
|
||||||
StatisticsShortTerm,
|
StatisticsShortTerm,
|
||||||
None,
|
None,
|
||||||
False,
|
|
||||||
None,
|
None,
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1759,31 +1765,38 @@ def _statistics_at_time(
|
||||||
metadata_ids: set[int],
|
metadata_ids: set[int],
|
||||||
table: type[Statistics | StatisticsShortTerm],
|
table: type[Statistics | StatisticsShortTerm],
|
||||||
start_time: datetime,
|
start_time: datetime,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> list | None:
|
) -> list | None:
|
||||||
"""Return last known statistics, earlier than start_time, for the metadata_ids."""
|
"""Return last known statistics, earlier than start_time, for the metadata_ids."""
|
||||||
# Fetch metadata for the given (or all) statistic_ids
|
columns = [table.metadata_id, table.start]
|
||||||
if table == StatisticsShortTerm:
|
if "last_reset" in types:
|
||||||
base_query = QUERY_STATISTICS_SHORT_TERM
|
columns.append(table.last_reset)
|
||||||
else:
|
if "max" in types:
|
||||||
base_query = QUERY_STATISTICS
|
columns.append(table.max)
|
||||||
|
if "mean" in types:
|
||||||
|
columns.append(table.mean)
|
||||||
|
if "min" in types:
|
||||||
|
columns.append(table.min)
|
||||||
|
if "state" in types:
|
||||||
|
columns.append(table.state)
|
||||||
|
if "sum" in types:
|
||||||
|
columns.append(table.sum)
|
||||||
|
|
||||||
query = session.query(*base_query)
|
stmt = lambda_stmt(lambda: select(columns))
|
||||||
|
|
||||||
most_recent_statistic_ids = (
|
most_recent_statistic_ids = (
|
||||||
session.query(
|
lambda_stmt(lambda: select(func.max(table.id).label("max_id")))
|
||||||
func.max(table.id).label("max_id"),
|
|
||||||
)
|
|
||||||
.filter(table.start < start_time)
|
.filter(table.start < start_time)
|
||||||
.filter(table.metadata_id.in_(metadata_ids))
|
.filter(table.metadata_id.in_(metadata_ids))
|
||||||
|
.group_by(table.metadata_id)
|
||||||
|
.subquery()
|
||||||
)
|
)
|
||||||
most_recent_statistic_ids = most_recent_statistic_ids.group_by(table.metadata_id)
|
|
||||||
most_recent_statistic_ids = most_recent_statistic_ids.subquery()
|
stmt += lambda q: q.join(
|
||||||
query = query.join(
|
|
||||||
most_recent_statistic_ids,
|
most_recent_statistic_ids,
|
||||||
table.id == most_recent_statistic_ids.c.max_id,
|
table.id == most_recent_statistic_ids.c.max_id,
|
||||||
)
|
)
|
||||||
|
return execute_stmt_lambda_element(session, stmt)
|
||||||
return execute(query)
|
|
||||||
|
|
||||||
|
|
||||||
def _sorted_statistics_to_dict(
|
def _sorted_statistics_to_dict(
|
||||||
|
@ -1795,8 +1808,8 @@ def _sorted_statistics_to_dict(
|
||||||
convert_units: bool,
|
convert_units: bool,
|
||||||
table: type[Statistics | StatisticsShortTerm],
|
table: type[Statistics | StatisticsShortTerm],
|
||||||
start_time: datetime | None,
|
start_time: datetime | None,
|
||||||
start_time_as_datetime: bool,
|
|
||||||
units: dict[str, str] | None,
|
units: dict[str, str] | None,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> dict[str, list[dict]]:
|
) -> dict[str, list[dict]]:
|
||||||
"""Convert SQL results into JSON friendly data structure."""
|
"""Convert SQL results into JSON friendly data structure."""
|
||||||
result: dict = defaultdict(list)
|
result: dict = defaultdict(list)
|
||||||
|
@ -1822,7 +1835,9 @@ def _sorted_statistics_to_dict(
|
||||||
# Fetch last known statistics for the needed metadata IDs
|
# Fetch last known statistics for the needed metadata IDs
|
||||||
if need_stat_at_start_time:
|
if need_stat_at_start_time:
|
||||||
assert start_time # Can not be None if need_stat_at_start_time is not empty
|
assert start_time # Can not be None if need_stat_at_start_time is not empty
|
||||||
tmp = _statistics_at_time(session, need_stat_at_start_time, table, start_time)
|
tmp = _statistics_at_time(
|
||||||
|
session, need_stat_at_start_time, table, start_time, types
|
||||||
|
)
|
||||||
if tmp:
|
if tmp:
|
||||||
for stat in tmp:
|
for stat in tmp:
|
||||||
stats_at_start_time[stat.metadata_id] = (stat,)
|
stats_at_start_time[stat.metadata_id] = (stat,)
|
||||||
|
@ -1841,21 +1856,24 @@ def _sorted_statistics_to_dict(
|
||||||
for db_state in chain(stats_at_start_time.get(meta_id, ()), group):
|
for db_state in chain(stats_at_start_time.get(meta_id, ()), group):
|
||||||
start = process_timestamp(db_state.start)
|
start = process_timestamp(db_state.start)
|
||||||
end = start + table.duration
|
end = start + table.duration
|
||||||
ent_results.append(
|
row = {
|
||||||
{
|
"start": start,
|
||||||
"statistic_id": statistic_id,
|
"end": end,
|
||||||
"start": start if start_time_as_datetime else start.isoformat(),
|
}
|
||||||
"end": end.isoformat(),
|
if "mean" in types:
|
||||||
"mean": convert(db_state.mean),
|
row["mean"] = convert(db_state.mean)
|
||||||
"min": convert(db_state.min),
|
if "min" in types:
|
||||||
"max": convert(db_state.max),
|
row["min"] = convert(db_state.min)
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(
|
if "max" in types:
|
||||||
db_state.last_reset
|
row["max"] = convert(db_state.max)
|
||||||
),
|
if "last_reset" in types:
|
||||||
"state": convert(db_state.state),
|
row["last_reset"] = process_timestamp(db_state.last_reset)
|
||||||
"sum": convert(db_state.sum),
|
if "state" in types:
|
||||||
}
|
row["state"] = convert(db_state.state)
|
||||||
)
|
if "sum" in types:
|
||||||
|
row["sum"] = convert(db_state.sum)
|
||||||
|
|
||||||
|
ent_results.append(row)
|
||||||
|
|
||||||
# Filter out the empty lists if some states had 0 results.
|
# Filter out the empty lists if some states had 0 results.
|
||||||
return {metadata[key]["statistic_id"]: val for key, val in result.items() if val}
|
return {metadata[key]["statistic_id"]: val for key, val in result.items() if val}
|
||||||
|
|
|
@ -65,7 +65,7 @@ def _ws_get_statistic_during_period(
|
||||||
start_time: dt | None,
|
start_time: dt | None,
|
||||||
end_time: dt | None,
|
end_time: dt | None,
|
||||||
statistic_id: str,
|
statistic_id: str,
|
||||||
types: set[str] | None,
|
types: set[Literal["max", "mean", "min", "change"]] | None,
|
||||||
units: dict[str, str],
|
units: dict[str, str],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Fetch statistics and convert them to json in the executor."""
|
"""Fetch statistics and convert them to json in the executor."""
|
||||||
|
@ -101,7 +101,9 @@ def _ws_get_statistic_during_period(
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
vol.Optional("statistic_id"): str,
|
vol.Optional("statistic_id"): str,
|
||||||
vol.Optional("types"): vol.All([str], vol.Coerce(set)),
|
vol.Optional("types"): vol.All(
|
||||||
|
[vol.Any("max", "mean", "min", "change")], vol.Coerce(set)
|
||||||
|
),
|
||||||
vol.Optional("units"): vol.Schema(
|
vol.Optional("units"): vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),
|
vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),
|
||||||
|
@ -210,16 +212,27 @@ def _ws_get_statistics_during_period(
|
||||||
statistic_ids: list[str] | None,
|
statistic_ids: list[str] | None,
|
||||||
period: Literal["5minute", "day", "hour", "week", "month"],
|
period: Literal["5minute", "day", "hour", "week", "month"],
|
||||||
units: dict[str, str],
|
units: dict[str, str],
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Fetch statistics and convert them to json in the executor."""
|
"""Fetch statistics and convert them to json in the executor."""
|
||||||
return JSON_DUMP(
|
result = statistics_during_period(
|
||||||
messages.result_message(
|
hass,
|
||||||
msg_id,
|
start_time,
|
||||||
statistics_during_period(
|
end_time,
|
||||||
hass, start_time, end_time, statistic_ids, period, units=units
|
statistic_ids,
|
||||||
),
|
period,
|
||||||
)
|
units,
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
|
for statistic_id in result:
|
||||||
|
for item in result[statistic_id]:
|
||||||
|
if (start := item.get("start")) is not None:
|
||||||
|
item["start"] = int(start.timestamp() * 1000)
|
||||||
|
if (end := item.get("end")) is not None:
|
||||||
|
item["end"] = int(end.timestamp() * 1000)
|
||||||
|
if (last_reset := item.get("last_reset")) is not None:
|
||||||
|
item["last_reset"] = int(last_reset.timestamp() * 1000)
|
||||||
|
return JSON_DUMP(messages.result_message(msg_id, result))
|
||||||
|
|
||||||
|
|
||||||
async def ws_handle_get_statistics_during_period(
|
async def ws_handle_get_statistics_during_period(
|
||||||
|
@ -244,6 +257,8 @@ async def ws_handle_get_statistics_during_period(
|
||||||
else:
|
else:
|
||||||
end_time = None
|
end_time = None
|
||||||
|
|
||||||
|
if (types := msg.get("types")) is None:
|
||||||
|
types = {"last_reset", "max", "mean", "min", "state", "sum"}
|
||||||
connection.send_message(
|
connection.send_message(
|
||||||
await get_instance(hass).async_add_executor_job(
|
await get_instance(hass).async_add_executor_job(
|
||||||
_ws_get_statistics_during_period,
|
_ws_get_statistics_during_period,
|
||||||
|
@ -254,6 +269,7 @@ async def ws_handle_get_statistics_during_period(
|
||||||
msg.get("statistic_ids"),
|
msg.get("statistic_ids"),
|
||||||
msg.get("period"),
|
msg.get("period"),
|
||||||
msg.get("units"),
|
msg.get("units"),
|
||||||
|
types,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -277,6 +293,10 @@ async def ws_handle_get_statistics_during_period(
|
||||||
vol.Optional("volume"): vol.In(VolumeConverter.VALID_UNITS),
|
vol.Optional("volume"): vol.In(VolumeConverter.VALID_UNITS),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
vol.Optional("types"): vol.All(
|
||||||
|
[vol.Any("last_reset", "max", "mean", "min", "state", "sum")],
|
||||||
|
vol.Coerce(set),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
|
|
|
@ -450,7 +450,7 @@ def _compile_statistics( # noqa: C901
|
||||||
to_query.append(entity_id)
|
to_query.append(entity_id)
|
||||||
|
|
||||||
last_stats = statistics.get_latest_short_term_statistics(
|
last_stats = statistics.get_latest_short_term_statistics(
|
||||||
hass, to_query, metadata=old_metadatas
|
hass, to_query, {"last_reset", "state", "sum"}, metadata=old_metadatas
|
||||||
)
|
)
|
||||||
for ( # pylint: disable=too-many-nested-blocks
|
for ( # pylint: disable=too-many-nested-blocks
|
||||||
entity_id,
|
entity_id,
|
||||||
|
@ -508,6 +508,8 @@ def _compile_statistics( # noqa: C901
|
||||||
if entity_id in last_stats:
|
if entity_id in last_stats:
|
||||||
# We have compiled history for this sensor before, use that as a starting point
|
# We have compiled history for this sensor before, use that as a starting point
|
||||||
last_reset = old_last_reset = last_stats[entity_id][0]["last_reset"]
|
last_reset = old_last_reset = last_stats[entity_id][0]["last_reset"]
|
||||||
|
if old_last_reset is not None:
|
||||||
|
last_reset = old_last_reset = old_last_reset.isoformat()
|
||||||
new_state = old_state = last_stats[entity_id][0]["state"]
|
new_state = old_state = last_stats[entity_id][0]["state"]
|
||||||
_sum = last_stats[entity_id][0]["sum"] or 0.0
|
_sum = last_stats[entity_id][0]["sum"] or 0.0
|
||||||
|
|
||||||
|
|
|
@ -591,7 +591,7 @@ class TibberDataCoordinator(DataUpdateCoordinator):
|
||||||
)
|
)
|
||||||
|
|
||||||
last_stats = await get_instance(self.hass).async_add_executor_job(
|
last_stats = await get_instance(self.hass).async_add_executor_job(
|
||||||
get_last_statistics, self.hass, 1, statistic_id, True
|
get_last_statistics, self.hass, 1, statistic_id, True, {}
|
||||||
)
|
)
|
||||||
|
|
||||||
if not last_stats:
|
if not last_stats:
|
||||||
|
@ -613,7 +613,7 @@ class TibberDataCoordinator(DataUpdateCoordinator):
|
||||||
else home.hourly_consumption_data
|
else home.hourly_consumption_data
|
||||||
)
|
)
|
||||||
|
|
||||||
from_time = dt_util.parse_datetime(hourly_data[0]["from"])
|
from_time = hourly_data[0]["from"]
|
||||||
if from_time is None:
|
if from_time is None:
|
||||||
continue
|
continue
|
||||||
start = from_time - timedelta(hours=1)
|
start = from_time - timedelta(hours=1)
|
||||||
|
@ -624,7 +624,8 @@ class TibberDataCoordinator(DataUpdateCoordinator):
|
||||||
None,
|
None,
|
||||||
[statistic_id],
|
[statistic_id],
|
||||||
"hour",
|
"hour",
|
||||||
True,
|
None,
|
||||||
|
{"sum"},
|
||||||
)
|
)
|
||||||
_sum = stat[statistic_id][0]["sum"]
|
_sum = stat[statistic_id][0]["sum"]
|
||||||
last_stats_time = stat[statistic_id][0]["start"]
|
last_stats_time = stat[statistic_id][0]["start"]
|
||||||
|
|
|
@ -114,7 +114,7 @@ async def test_demo_statistics_growth(recorder_mock, mock_history, hass):
|
||||||
await async_wait_recording_done(hass)
|
await async_wait_recording_done(hass)
|
||||||
|
|
||||||
statistics = await get_instance(hass).async_add_executor_job(
|
statistics = await get_instance(hass).async_add_executor_job(
|
||||||
get_last_statistics, hass, 1, statistic_id, False
|
get_last_statistics, hass, 1, statistic_id, False, {"sum"}
|
||||||
)
|
)
|
||||||
assert statistics[statistic_id][0]["sum"] > 2**20
|
assert statistics[statistic_id][0]["sum"] > 2**20
|
||||||
assert statistics[statistic_id][0]["sum"] <= (2**20 + 24)
|
assert statistics[statistic_id][0]["sum"] <= (2**20 + 24)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import asyncio
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import time
|
import time
|
||||||
from typing import Any, cast
|
from typing import Any, Literal, cast
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
@ -137,3 +137,21 @@ def run_information_with_session(
|
||||||
session.expunge(res)
|
session.expunge(res)
|
||||||
return cast(RecorderRuns, res)
|
return cast(RecorderRuns, res)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def statistics_during_period(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
start_time: datetime,
|
||||||
|
end_time: datetime | None = None,
|
||||||
|
statistic_ids: list[str] | None = None,
|
||||||
|
period: Literal["5minute", "day", "hour", "week", "month"] = "hour",
|
||||||
|
units: dict[str, str] | None = None,
|
||||||
|
types: set[Literal["last_reset", "max", "mean", "min", "state", "sum"]]
|
||||||
|
| None = None,
|
||||||
|
) -> dict[str, list[dict[str, Any]]]:
|
||||||
|
"""Call statistics_during_period with defaults for simpler tests."""
|
||||||
|
if types is None:
|
||||||
|
types = {"last_reset", "max", "mean", "min", "state", "sum"}
|
||||||
|
return statistics.statistics_during_period(
|
||||||
|
hass, start_time, end_time, statistic_ids, period, units, types
|
||||||
|
)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.components import recorder
|
||||||
from homeassistant.components.recorder import history, statistics
|
from homeassistant.components.recorder import history, statistics
|
||||||
from homeassistant.components.recorder.const import SQLITE_URL_PREFIX
|
from homeassistant.components.recorder.const import SQLITE_URL_PREFIX
|
||||||
from homeassistant.components.recorder.db_schema import StatisticsShortTerm
|
from homeassistant.components.recorder.db_schema import StatisticsShortTerm
|
||||||
from homeassistant.components.recorder.models import process_timestamp_to_utc_isoformat
|
from homeassistant.components.recorder.models import process_timestamp
|
||||||
from homeassistant.components.recorder.statistics import (
|
from homeassistant.components.recorder.statistics import (
|
||||||
async_add_external_statistics,
|
async_add_external_statistics,
|
||||||
async_import_statistics,
|
async_import_statistics,
|
||||||
|
@ -25,7 +25,6 @@ from homeassistant.components.recorder.statistics import (
|
||||||
get_latest_short_term_statistics,
|
get_latest_short_term_statistics,
|
||||||
get_metadata,
|
get_metadata,
|
||||||
list_statistic_ids,
|
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 TEMP_CELSIUS
|
from homeassistant.const import TEMP_CELSIUS
|
||||||
|
@ -35,7 +34,12 @@ from homeassistant.helpers import recorder as recorder_helper
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from .common import async_wait_recording_done, do_adhoc_statistics, wait_recording_done
|
from .common import (
|
||||||
|
async_wait_recording_done,
|
||||||
|
do_adhoc_statistics,
|
||||||
|
statistics_during_period,
|
||||||
|
wait_recording_done,
|
||||||
|
)
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant, mock_registry
|
from tests.common import get_test_home_assistant, mock_registry
|
||||||
|
|
||||||
|
@ -52,22 +56,29 @@ def test_compile_hourly_statistics(hass_recorder):
|
||||||
assert dict(states) == dict(hist)
|
assert dict(states) == dict(hist)
|
||||||
|
|
||||||
# Should not fail if there is nothing there yet
|
# Should not fail if there is nothing there yet
|
||||||
stats = get_latest_short_term_statistics(hass, ["sensor.test1"])
|
stats = get_latest_short_term_statistics(
|
||||||
|
hass, ["sensor.test1"], {"last_reset", "max", "mean", "min", "state", "sum"}
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
||||||
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
stats = get_last_short_term_statistics(hass, 0, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
0,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
do_adhoc_statistics(hass, start=zero)
|
do_adhoc_statistics(hass, start=zero)
|
||||||
do_adhoc_statistics(hass, start=four)
|
do_adhoc_statistics(hass, start=four)
|
||||||
wait_recording_done(hass)
|
wait_recording_done(hass)
|
||||||
expected_1 = {
|
expected_1 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(14.915254237288135),
|
"mean": approx(14.915254237288135),
|
||||||
"min": approx(10.0),
|
"min": approx(10.0),
|
||||||
"max": approx(20.0),
|
"max": approx(20.0),
|
||||||
|
@ -76,9 +87,8 @@ def test_compile_hourly_statistics(hass_recorder):
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_2 = {
|
expected_2 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(four),
|
||||||
"start": process_timestamp_to_utc_isoformat(four),
|
"end": process_timestamp(four + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(four + timedelta(minutes=5)),
|
|
||||||
"mean": approx(20.0),
|
"mean": approx(20.0),
|
||||||
"min": approx(20.0),
|
"min": approx(20.0),
|
||||||
"max": approx(20.0),
|
"max": approx(20.0),
|
||||||
|
@ -86,14 +96,8 @@ def test_compile_hourly_statistics(hass_recorder):
|
||||||
"state": None,
|
"state": None,
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_stats1 = [
|
expected_stats1 = [expected_1, expected_2]
|
||||||
{**expected_1, "statistic_id": "sensor.test1"},
|
expected_stats2 = [expected_1, expected_2]
|
||||||
{**expected_2, "statistic_id": "sensor.test1"},
|
|
||||||
]
|
|
||||||
expected_stats2 = [
|
|
||||||
{**expected_1, "statistic_id": "sensor.test2"},
|
|
||||||
{**expected_2, "statistic_id": "sensor.test2"},
|
|
||||||
]
|
|
||||||
|
|
||||||
# Test statistics_during_period
|
# Test statistics_during_period
|
||||||
stats = statistics_during_period(hass, zero, period="5minute")
|
stats = statistics_during_period(hass, zero, period="5minute")
|
||||||
|
@ -119,32 +123,71 @@ def test_compile_hourly_statistics(hass_recorder):
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
# Test get_last_short_term_statistics and get_latest_short_term_statistics
|
# Test get_last_short_term_statistics and get_latest_short_term_statistics
|
||||||
stats = get_last_short_term_statistics(hass, 0, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
0,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
stats = get_last_short_term_statistics(hass, 1, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
assert stats == {"sensor.test1": [{**expected_2, "statistic_id": "sensor.test1"}]}
|
hass,
|
||||||
|
1,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
|
assert stats == {"sensor.test1": [expected_2]}
|
||||||
|
|
||||||
stats = get_latest_short_term_statistics(hass, ["sensor.test1"])
|
stats = get_latest_short_term_statistics(
|
||||||
assert stats == {"sensor.test1": [{**expected_2, "statistic_id": "sensor.test1"}]}
|
hass, ["sensor.test1"], {"last_reset", "max", "mean", "min", "state", "sum"}
|
||||||
|
)
|
||||||
|
assert stats == {"sensor.test1": [expected_2]}
|
||||||
|
|
||||||
metadata = get_metadata(hass, statistic_ids=['sensor.test1"'])
|
metadata = get_metadata(hass, statistic_ids=['sensor.test1"'])
|
||||||
|
|
||||||
stats = get_latest_short_term_statistics(hass, ["sensor.test1"], metadata=metadata)
|
stats = get_latest_short_term_statistics(
|
||||||
assert stats == {"sensor.test1": [{**expected_2, "statistic_id": "sensor.test1"}]}
|
hass,
|
||||||
|
["sensor.test1"],
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
metadata=metadata,
|
||||||
|
)
|
||||||
|
assert stats == {"sensor.test1": [expected_2]}
|
||||||
|
|
||||||
stats = get_last_short_term_statistics(hass, 2, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
2,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {"sensor.test1": expected_stats1[::-1]}
|
assert stats == {"sensor.test1": expected_stats1[::-1]}
|
||||||
|
|
||||||
stats = get_last_short_term_statistics(hass, 3, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
3,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {"sensor.test1": expected_stats1[::-1]}
|
assert stats == {"sensor.test1": expected_stats1[::-1]}
|
||||||
|
|
||||||
stats = get_last_short_term_statistics(hass, 1, "sensor.test3", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
1,
|
||||||
|
"sensor.test3",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
instance.get_session().query(StatisticsShortTerm).delete()
|
instance.get_session().query(StatisticsShortTerm).delete()
|
||||||
# Should not fail there is nothing in the table
|
# Should not fail there is nothing in the table
|
||||||
stats = get_latest_short_term_statistics(hass, ["sensor.test1"])
|
stats = get_latest_short_term_statistics(
|
||||||
|
hass, ["sensor.test1"], {"last_reset", "max", "mean", "min", "state", "sum"}
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,9 +261,8 @@ def test_compile_periodic_statistics_exception(
|
||||||
do_adhoc_statistics(hass, start=now + timedelta(minutes=5))
|
do_adhoc_statistics(hass, start=now + timedelta(minutes=5))
|
||||||
wait_recording_done(hass)
|
wait_recording_done(hass)
|
||||||
expected_1 = {
|
expected_1 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(now),
|
||||||
"start": process_timestamp_to_utc_isoformat(now),
|
"end": process_timestamp(now + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(now + timedelta(minutes=5)),
|
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"max": None,
|
"max": None,
|
||||||
|
@ -229,9 +271,8 @@ def test_compile_periodic_statistics_exception(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_2 = {
|
expected_2 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(now + timedelta(minutes=5)),
|
||||||
"start": process_timestamp_to_utc_isoformat(now + timedelta(minutes=5)),
|
"end": process_timestamp(now + timedelta(minutes=10)),
|
||||||
"end": process_timestamp_to_utc_isoformat(now + timedelta(minutes=10)),
|
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"max": None,
|
"max": None,
|
||||||
|
@ -239,17 +280,9 @@ def test_compile_periodic_statistics_exception(
|
||||||
"state": None,
|
"state": None,
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_stats1 = [
|
expected_stats1 = [expected_1, expected_2]
|
||||||
{**expected_1, "statistic_id": "sensor.test1"},
|
expected_stats2 = [expected_2]
|
||||||
{**expected_2, "statistic_id": "sensor.test1"},
|
expected_stats3 = [expected_1, expected_2]
|
||||||
]
|
|
||||||
expected_stats2 = [
|
|
||||||
{**expected_2, "statistic_id": "sensor.test2"},
|
|
||||||
]
|
|
||||||
expected_stats3 = [
|
|
||||||
{**expected_1, "statistic_id": "sensor.test3"},
|
|
||||||
{**expected_2, "statistic_id": "sensor.test3"},
|
|
||||||
]
|
|
||||||
|
|
||||||
stats = statistics_during_period(hass, now, period="5minute")
|
stats = statistics_during_period(hass, now, period="5minute")
|
||||||
assert stats == {
|
assert stats == {
|
||||||
|
@ -286,15 +319,20 @@ def test_rename_entity(hass_recorder):
|
||||||
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
||||||
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
stats = get_last_short_term_statistics(hass, 0, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
0,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
do_adhoc_statistics(hass, start=zero)
|
do_adhoc_statistics(hass, start=zero)
|
||||||
wait_recording_done(hass)
|
wait_recording_done(hass)
|
||||||
expected_1 = {
|
expected_1 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(14.915254237288135),
|
"mean": approx(14.915254237288135),
|
||||||
"min": approx(10.0),
|
"min": approx(10.0),
|
||||||
"max": approx(20.0),
|
"max": approx(20.0),
|
||||||
|
@ -302,15 +340,9 @@ def test_rename_entity(hass_recorder):
|
||||||
"state": None,
|
"state": None,
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_stats1 = [
|
expected_stats1 = [expected_1]
|
||||||
{**expected_1, "statistic_id": "sensor.test1"},
|
expected_stats2 = [expected_1]
|
||||||
]
|
expected_stats99 = [expected_1]
|
||||||
expected_stats2 = [
|
|
||||||
{**expected_1, "statistic_id": "sensor.test2"},
|
|
||||||
]
|
|
||||||
expected_stats99 = [
|
|
||||||
{**expected_1, "statistic_id": "sensor.test99"},
|
|
||||||
]
|
|
||||||
|
|
||||||
stats = statistics_during_period(hass, zero, period="5minute")
|
stats = statistics_during_period(hass, zero, period="5minute")
|
||||||
assert stats == {"sensor.test1": expected_stats1, "sensor.test2": expected_stats2}
|
assert stats == {"sensor.test1": expected_stats1, "sensor.test2": expected_stats2}
|
||||||
|
@ -353,15 +385,20 @@ def test_rename_entity_collision(hass_recorder, caplog):
|
||||||
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
for kwargs in ({}, {"statistic_ids": ["sensor.test1"]}):
|
||||||
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
stats = statistics_during_period(hass, zero, period="5minute", **kwargs)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
stats = get_last_short_term_statistics(hass, 0, "sensor.test1", True)
|
stats = get_last_short_term_statistics(
|
||||||
|
hass,
|
||||||
|
0,
|
||||||
|
"sensor.test1",
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert stats == {}
|
assert stats == {}
|
||||||
|
|
||||||
do_adhoc_statistics(hass, start=zero)
|
do_adhoc_statistics(hass, start=zero)
|
||||||
wait_recording_done(hass)
|
wait_recording_done(hass)
|
||||||
expected_1 = {
|
expected_1 = {
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(14.915254237288135),
|
"mean": approx(14.915254237288135),
|
||||||
"min": approx(10.0),
|
"min": approx(10.0),
|
||||||
"max": approx(20.0),
|
"max": approx(20.0),
|
||||||
|
@ -369,12 +406,8 @@ def test_rename_entity_collision(hass_recorder, caplog):
|
||||||
"state": None,
|
"state": None,
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
expected_stats1 = [
|
expected_stats1 = [expected_1]
|
||||||
{**expected_1, "statistic_id": "sensor.test1"},
|
expected_stats2 = [expected_1]
|
||||||
]
|
|
||||||
expected_stats2 = [
|
|
||||||
{**expected_1, "statistic_id": "sensor.test2"},
|
|
||||||
]
|
|
||||||
|
|
||||||
stats = statistics_during_period(hass, zero, period="5minute")
|
stats = statistics_during_period(hass, zero, period="5minute")
|
||||||
assert stats == {"sensor.test1": expected_stats1, "sensor.test2": expected_stats2}
|
assert stats == {"sensor.test1": expected_stats1, "sensor.test2": expected_stats2}
|
||||||
|
@ -465,7 +498,7 @@ async def test_import_statistics(
|
||||||
|
|
||||||
zero = dt_util.utcnow()
|
zero = dt_util.utcnow()
|
||||||
last_reset = dt_util.parse_datetime(last_reset_str) if last_reset_str else None
|
last_reset = dt_util.parse_datetime(last_reset_str) if last_reset_str else None
|
||||||
last_reset_utc_str = dt_util.as_utc(last_reset).isoformat() if last_reset else None
|
last_reset_utc = dt_util.as_utc(last_reset) if last_reset else None
|
||||||
period1 = zero.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
|
period1 = zero.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
|
||||||
period2 = zero.replace(minute=0, second=0, microsecond=0) + timedelta(hours=2)
|
period2 = zero.replace(minute=0, second=0, microsecond=0) + timedelta(hours=2)
|
||||||
|
|
||||||
|
@ -497,24 +530,22 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period1),
|
||||||
"start": period1.isoformat(),
|
"end": process_timestamp(period1 + timedelta(hours=1)),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(0.0),
|
"state": approx(0.0),
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period2),
|
||||||
"start": period2.isoformat(),
|
"end": process_timestamp(period2 + timedelta(hours=1)),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(1.0),
|
"state": approx(1.0),
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
|
@ -546,17 +577,22 @@ async def test_import_statistics(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
last_stats = get_last_statistics(hass, 1, statistic_id, True)
|
last_stats = get_last_statistics(
|
||||||
|
hass,
|
||||||
|
1,
|
||||||
|
statistic_id,
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert last_stats == {
|
assert last_stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period2),
|
||||||
"start": period2.isoformat(),
|
"end": process_timestamp(period2 + timedelta(hours=1)),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(1.0),
|
"state": approx(1.0),
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
|
@ -576,9 +612,8 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period1),
|
||||||
"start": period1.isoformat(),
|
"end": process_timestamp(period1 + timedelta(hours=1)),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -587,13 +622,12 @@ async def test_import_statistics(
|
||||||
"sum": approx(6.0),
|
"sum": approx(6.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period2),
|
||||||
"start": period2.isoformat(),
|
"end": process_timestamp(period2 + timedelta(hours=1)),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(1.0),
|
"state": approx(1.0),
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
|
@ -643,24 +677,22 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period1),
|
||||||
"start": period1.isoformat(),
|
"end": process_timestamp(period1 + timedelta(hours=1)),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(1.0),
|
"max": approx(1.0),
|
||||||
"mean": approx(2.0),
|
"mean": approx(2.0),
|
||||||
"min": approx(3.0),
|
"min": approx(3.0),
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(4.0),
|
"state": approx(4.0),
|
||||||
"sum": approx(5.0),
|
"sum": approx(5.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period2),
|
||||||
"start": period2.isoformat(),
|
"end": process_timestamp(period2 + timedelta(hours=1)),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(1.0),
|
"state": approx(1.0),
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
|
@ -686,24 +718,22 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period1),
|
||||||
"start": period1.isoformat(),
|
"end": process_timestamp(period1 + timedelta(hours=1)),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(1.0),
|
"max": approx(1.0),
|
||||||
"mean": approx(2.0),
|
"mean": approx(2.0),
|
||||||
"min": approx(3.0),
|
"min": approx(3.0),
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(4.0),
|
"state": approx(4.0),
|
||||||
"sum": approx(5.0),
|
"sum": approx(5.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": process_timestamp(period2),
|
||||||
"start": period2.isoformat(),
|
"end": process_timestamp(period2 + timedelta(hours=1)),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": last_reset_utc_str,
|
"last_reset": last_reset_utc,
|
||||||
"state": approx(1.0),
|
"state": approx(1.0),
|
||||||
"sum": approx(1000 * 1000 + 3.0),
|
"sum": approx(1000 * 1000 + 3.0),
|
||||||
},
|
},
|
||||||
|
@ -947,9 +977,8 @@ def test_weekly_statistics(hass_recorder, caplog, timezone):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"test:total_energy_import": [
|
"test:total_energy_import": [
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": week1_start,
|
||||||
"start": week1_start.isoformat(),
|
"end": week1_end,
|
||||||
"end": week1_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -958,9 +987,8 @@ def test_weekly_statistics(hass_recorder, caplog, timezone):
|
||||||
"sum": 3.0,
|
"sum": 3.0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": week2_start,
|
||||||
"start": week2_start.isoformat(),
|
"end": week2_end,
|
||||||
"end": week2_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -980,9 +1008,8 @@ def test_weekly_statistics(hass_recorder, caplog, timezone):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"test:total_energy_import": [
|
"test:total_energy_import": [
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": week1_start,
|
||||||
"start": week1_start.isoformat(),
|
"end": week1_end,
|
||||||
"end": week1_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -991,9 +1018,8 @@ def test_weekly_statistics(hass_recorder, caplog, timezone):
|
||||||
"sum": 3.0,
|
"sum": 3.0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": week2_start,
|
||||||
"start": week2_start.isoformat(),
|
"end": week2_end,
|
||||||
"end": week2_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1085,9 +1111,8 @@ def test_monthly_statistics(hass_recorder, caplog, timezone):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"test:total_energy_import": [
|
"test:total_energy_import": [
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": sep_start,
|
||||||
"start": sep_start.isoformat(),
|
"end": sep_end,
|
||||||
"end": sep_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1096,9 +1121,8 @@ def test_monthly_statistics(hass_recorder, caplog, timezone):
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": oct_start,
|
||||||
"start": oct_start.isoformat(),
|
"end": oct_end,
|
||||||
"end": oct_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1122,9 +1146,8 @@ def test_monthly_statistics(hass_recorder, caplog, timezone):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"test:total_energy_import": [
|
"test:total_energy_import": [
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": sep_start,
|
||||||
"start": sep_start.isoformat(),
|
"end": sep_end,
|
||||||
"end": sep_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1133,9 +1156,8 @@ def test_monthly_statistics(hass_recorder, caplog, timezone):
|
||||||
"sum": approx(3.0),
|
"sum": approx(3.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "test:total_energy_import",
|
"start": oct_start,
|
||||||
"start": oct_start.isoformat(),
|
"end": oct_end,
|
||||||
"end": oct_end.isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
|
|
@ -17,7 +17,6 @@ from homeassistant.components.recorder.statistics import (
|
||||||
get_last_statistics,
|
get_last_statistics,
|
||||||
get_metadata,
|
get_metadata,
|
||||||
list_statistic_ids,
|
list_statistic_ids,
|
||||||
statistics_during_period,
|
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import recorder as recorder_helper
|
from homeassistant.helpers import recorder as recorder_helper
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
@ -29,6 +28,7 @@ from .common import (
|
||||||
async_wait_recording_done,
|
async_wait_recording_done,
|
||||||
create_engine_test,
|
create_engine_test,
|
||||||
do_adhoc_statistics,
|
do_adhoc_statistics,
|
||||||
|
statistics_during_period,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import async_fire_time_changed
|
||||||
|
@ -167,9 +167,8 @@ async def test_statistics_during_period(recorder_mock, hass, hass_ws_client):
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(10),
|
"mean": approx(10),
|
||||||
"min": approx(10),
|
"min": approx(10),
|
||||||
"max": approx(10),
|
"max": approx(10),
|
||||||
|
@ -180,6 +179,28 @@ async def test_statistics_during_period(recorder_mock, hass, hass_ws_client):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await client.send_json(
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"type": "recorder/statistics_during_period",
|
||||||
|
"start_time": now.isoformat(),
|
||||||
|
"statistic_ids": ["sensor.test"],
|
||||||
|
"period": "5minute",
|
||||||
|
"types": ["mean"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"] == {
|
||||||
|
"sensor.test": [
|
||||||
|
{
|
||||||
|
"start": int(now.timestamp() * 1000),
|
||||||
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
|
"mean": approx(10),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@freeze_time(datetime.datetime(2022, 10, 21, 7, 25, tzinfo=datetime.timezone.utc))
|
@freeze_time(datetime.datetime(2022, 10, 21, 7, 25, tzinfo=datetime.timezone.utc))
|
||||||
@pytest.mark.parametrize("offset", (0, 1, 2))
|
@pytest.mark.parametrize("offset", (0, 1, 2))
|
||||||
|
@ -895,9 +916,8 @@ async def test_statistics_during_period_unit_conversion(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(value),
|
"mean": approx(value),
|
||||||
"min": approx(value),
|
"min": approx(value),
|
||||||
"max": approx(value),
|
"max": approx(value),
|
||||||
|
@ -924,9 +944,8 @@ async def test_statistics_during_period_unit_conversion(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(converted_value),
|
"mean": approx(converted_value),
|
||||||
"min": approx(converted_value),
|
"min": approx(converted_value),
|
||||||
"max": approx(converted_value),
|
"max": approx(converted_value),
|
||||||
|
@ -989,9 +1008,8 @@ async def test_sum_statistics_during_period_unit_conversion(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"max": None,
|
"max": None,
|
||||||
|
@ -1018,9 +1036,8 @@ async def test_sum_statistics_during_period_unit_conversion(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"max": None,
|
"max": None,
|
||||||
|
@ -1150,9 +1167,8 @@ async def test_statistics_during_period_in_the_past(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(stats_start.timestamp() * 1000),
|
||||||
"start": stats_start.isoformat(),
|
"end": int((stats_start + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (stats_start + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(10),
|
"mean": approx(10),
|
||||||
"min": approx(10),
|
"min": approx(10),
|
||||||
"max": approx(10),
|
"max": approx(10),
|
||||||
|
@ -1178,9 +1194,8 @@ async def test_statistics_during_period_in_the_past(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test",
|
"start": int(start_of_day.timestamp() * 1000),
|
||||||
"start": start_of_day.isoformat(),
|
"end": int((start_of_day + timedelta(days=1)).timestamp() * 1000),
|
||||||
"end": (start_of_day + timedelta(days=1)).isoformat(),
|
|
||||||
"mean": approx(10),
|
"mean": approx(10),
|
||||||
"min": approx(10),
|
"min": approx(10),
|
||||||
"max": approx(10),
|
"max": approx(10),
|
||||||
|
@ -1468,9 +1483,8 @@ async def test_clear_statistics(recorder_mock, hass, hass_ws_client):
|
||||||
expected_response = {
|
expected_response = {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(value),
|
"mean": approx(value),
|
||||||
"min": approx(value),
|
"min": approx(value),
|
||||||
"max": approx(value),
|
"max": approx(value),
|
||||||
|
@ -1481,9 +1495,8 @@ async def test_clear_statistics(recorder_mock, hass, hass_ws_client):
|
||||||
],
|
],
|
||||||
"sensor.test2": [
|
"sensor.test2": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(value * 2),
|
"mean": approx(value * 2),
|
||||||
"min": approx(value * 2),
|
"min": approx(value * 2),
|
||||||
"max": approx(value * 2),
|
"max": approx(value * 2),
|
||||||
|
@ -1494,9 +1507,8 @@ async def test_clear_statistics(recorder_mock, hass, hass_ws_client):
|
||||||
],
|
],
|
||||||
"sensor.test3": [
|
"sensor.test3": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test3",
|
"start": int(now.timestamp() * 1000),
|
||||||
"start": now.isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
|
||||||
"mean": approx(value * 3),
|
"mean": approx(value * 3),
|
||||||
"min": approx(value * 3),
|
"min": approx(value * 3),
|
||||||
"max": approx(value * 3),
|
"max": approx(value * 3),
|
||||||
|
@ -1638,14 +1650,13 @@ async def test_update_statistics_metadata(
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"max": 10.0,
|
"max": 10.0,
|
||||||
"mean": 10.0,
|
"mean": 10.0,
|
||||||
"min": 10.0,
|
"min": 10.0,
|
||||||
"start": now.isoformat(),
|
"start": int(now.timestamp() * 1000),
|
||||||
"state": None,
|
"state": None,
|
||||||
"statistic_id": "sensor.test",
|
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1700,14 +1711,13 @@ async def test_change_statistics_unit(recorder_mock, hass, hass_ws_client):
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"max": 10.0,
|
"max": 10.0,
|
||||||
"mean": 10.0,
|
"mean": 10.0,
|
||||||
"min": 10.0,
|
"min": 10.0,
|
||||||
"start": now.isoformat(),
|
"start": int(now.timestamp() * 1000),
|
||||||
"state": None,
|
"state": None,
|
||||||
"statistic_id": "sensor.test",
|
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1756,14 +1766,13 @@ async def test_change_statistics_unit(recorder_mock, hass, hass_ws_client):
|
||||||
assert response["result"] == {
|
assert response["result"] == {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"max": 10000.0,
|
"max": 10000.0,
|
||||||
"mean": 10000.0,
|
"mean": 10000.0,
|
||||||
"min": 10000.0,
|
"min": 10000.0,
|
||||||
"start": now.isoformat(),
|
"start": int(now.timestamp() * 1000),
|
||||||
"state": None,
|
"state": None,
|
||||||
"statistic_id": "sensor.test",
|
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1796,14 +1805,13 @@ async def test_change_statistics_unit_errors(
|
||||||
expected_statistics = {
|
expected_statistics = {
|
||||||
"sensor.test": [
|
"sensor.test": [
|
||||||
{
|
{
|
||||||
"end": (now + timedelta(minutes=5)).isoformat(),
|
"end": int((now + timedelta(minutes=5)).timestamp() * 1000),
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"max": 10.0,
|
"max": 10.0,
|
||||||
"mean": 10.0,
|
"mean": 10.0,
|
||||||
"min": 10.0,
|
"min": 10.0,
|
||||||
"start": now.isoformat(),
|
"start": int(now.timestamp() * 1000),
|
||||||
"state": None,
|
"state": None,
|
||||||
"statistic_id": "sensor.test",
|
|
||||||
"sum": None,
|
"sum": None,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -2292,9 +2300,8 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": (period1 + timedelta(hours=1)),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2303,9 +2310,8 @@ async def test_import_statistics(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2341,13 +2347,18 @@ async def test_import_statistics(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
last_stats = get_last_statistics(hass, 1, statistic_id, True)
|
last_stats = get_last_statistics(
|
||||||
|
hass,
|
||||||
|
1,
|
||||||
|
statistic_id,
|
||||||
|
True,
|
||||||
|
{"last_reset", "max", "mean", "min", "state", "sum"},
|
||||||
|
)
|
||||||
assert last_stats == {
|
assert last_stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2383,9 +2394,8 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2394,9 +2404,8 @@ async def test_import_statistics(
|
||||||
"sum": approx(6.0),
|
"sum": approx(6.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2435,9 +2444,8 @@ async def test_import_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(1.0),
|
"max": approx(1.0),
|
||||||
"mean": approx(2.0),
|
"mean": approx(2.0),
|
||||||
"min": approx(3.0),
|
"min": approx(3.0),
|
||||||
|
@ -2446,9 +2454,8 @@ async def test_import_statistics(
|
||||||
"sum": approx(5.0),
|
"sum": approx(5.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2519,9 +2526,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2530,9 +2536,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2588,9 +2593,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(None),
|
"max": approx(None),
|
||||||
"mean": approx(None),
|
"mean": approx(None),
|
||||||
"min": approx(None),
|
"min": approx(None),
|
||||||
|
@ -2599,9 +2603,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2631,9 +2634,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(None),
|
"max": approx(None),
|
||||||
"mean": approx(None),
|
"mean": approx(None),
|
||||||
"min": approx(None),
|
"min": approx(None),
|
||||||
|
@ -2642,9 +2644,8 @@ async def test_adjust_sum_statistics_energy(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2715,9 +2716,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2726,9 +2726,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2784,9 +2783,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(None),
|
"max": approx(None),
|
||||||
"mean": approx(None),
|
"mean": approx(None),
|
||||||
"min": approx(None),
|
"min": approx(None),
|
||||||
|
@ -2795,9 +2793,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2827,9 +2824,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": approx(None),
|
"max": approx(None),
|
||||||
"mean": approx(None),
|
"mean": approx(None),
|
||||||
"min": approx(None),
|
"min": approx(None),
|
||||||
|
@ -2838,9 +2834,8 @@ async def test_adjust_sum_statistics_gas(
|
||||||
"sum": approx(2.0),
|
"sum": approx(2.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2926,9 +2921,8 @@ async def test_adjust_sum_statistics_errors(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
statistic_id: [
|
statistic_id: [
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period1,
|
||||||
"start": period1.isoformat(),
|
"end": period1 + timedelta(hours=1),
|
||||||
"end": (period1 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -2937,9 +2931,8 @@ async def test_adjust_sum_statistics_errors(
|
||||||
"sum": approx(2.0 * factor),
|
"sum": approx(2.0 * factor),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": statistic_id,
|
"start": period2,
|
||||||
"start": period2.isoformat(),
|
"end": period2 + timedelta(hours=1),
|
||||||
"end": (period2 + timedelta(hours=1)).isoformat(),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
|
|
@ -14,13 +14,12 @@ from homeassistant.components.recorder.db_schema import StatisticsMeta
|
||||||
from homeassistant.components.recorder.models import (
|
from homeassistant.components.recorder.models import (
|
||||||
StatisticData,
|
StatisticData,
|
||||||
StatisticMetaData,
|
StatisticMetaData,
|
||||||
process_timestamp_to_utc_isoformat,
|
process_timestamp,
|
||||||
)
|
)
|
||||||
from homeassistant.components.recorder.statistics import (
|
from homeassistant.components.recorder.statistics import (
|
||||||
async_import_statistics,
|
async_import_statistics,
|
||||||
get_metadata,
|
get_metadata,
|
||||||
list_statistic_ids,
|
list_statistic_ids,
|
||||||
statistics_during_period,
|
|
||||||
)
|
)
|
||||||
from homeassistant.components.recorder.util import get_instance, session_scope
|
from homeassistant.components.recorder.util import get_instance, session_scope
|
||||||
from homeassistant.const import STATE_UNAVAILABLE
|
from homeassistant.const import STATE_UNAVAILABLE
|
||||||
|
@ -32,6 +31,7 @@ from tests.components.recorder.common import (
|
||||||
async_recorder_block_till_done,
|
async_recorder_block_till_done,
|
||||||
async_wait_recording_done,
|
async_wait_recording_done,
|
||||||
do_adhoc_statistics,
|
do_adhoc_statistics,
|
||||||
|
statistics_during_period,
|
||||||
wait_recording_done,
|
wait_recording_done,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -153,9 +153,8 @@ def test_compile_hourly_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -227,9 +226,8 @@ def test_compile_hourly_statistics_purged_state_changes(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -332,9 +330,8 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(13.050847),
|
"mean": approx(13.050847),
|
||||||
"min": approx(-10.0),
|
"min": approx(-10.0),
|
||||||
"max": approx(30.0),
|
"max": approx(30.0),
|
||||||
|
@ -345,9 +342,8 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
|
||||||
],
|
],
|
||||||
"sensor.test2": [
|
"sensor.test2": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": 13.05084745762712,
|
"mean": 13.05084745762712,
|
||||||
"min": -10.0,
|
"min": -10.0,
|
||||||
"max": 30.0,
|
"max": 30.0,
|
||||||
|
@ -358,9 +354,8 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
|
||||||
],
|
],
|
||||||
"sensor.test3": [
|
"sensor.test3": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test3",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": 13.05084745762712,
|
"mean": 13.05084745762712,
|
||||||
"min": -10.0,
|
"min": -10.0,
|
||||||
"max": 30.0,
|
"max": 30.0,
|
||||||
|
@ -371,9 +366,8 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
|
||||||
],
|
],
|
||||||
"sensor.test6": [
|
"sensor.test6": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test6",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(13.050847),
|
"mean": approx(13.050847),
|
||||||
"min": approx(-10.0),
|
"min": approx(-10.0),
|
||||||
"max": approx(30.0),
|
"max": approx(30.0),
|
||||||
|
@ -384,9 +378,8 @@ def test_compile_hourly_statistics_wrong_unit(hass_recorder, caplog, attributes)
|
||||||
],
|
],
|
||||||
"sensor.test7": [
|
"sensor.test7": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test7",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(13.050847),
|
"mean": approx(13.050847),
|
||||||
"min": approx(-10.0),
|
"min": approx(-10.0),
|
||||||
"max": approx(30.0),
|
"max": approx(30.0),
|
||||||
|
@ -492,35 +485,32 @@ async def test_compile_hourly_sum_statistics_amount(
|
||||||
expected_stats = {
|
expected_stats = {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(period0),
|
"last_reset": process_timestamp(period0),
|
||||||
"state": approx(factor * seq[2]),
|
"state": approx(factor * seq[2]),
|
||||||
"sum": approx(factor * 10.0),
|
"sum": approx(factor * 10.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(factor * seq[5]),
|
"state": approx(factor * seq[5]),
|
||||||
"sum": approx(factor * 40.0),
|
"sum": approx(factor * 40.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(factor * seq[8]),
|
"state": approx(factor * seq[8]),
|
||||||
"sum": approx(factor * 70.0),
|
"sum": approx(factor * 70.0),
|
||||||
},
|
},
|
||||||
|
@ -684,26 +674,22 @@ def test_compile_hourly_sum_statistics_amount_reset_every_state_change(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(dt_util.as_local(one)),
|
"last_reset": process_timestamp(dt_util.as_local(one)),
|
||||||
"state": approx(factor * seq[7]),
|
"state": approx(factor * seq[7]),
|
||||||
"sum": approx(factor * (sum(seq) - seq[0])),
|
"sum": approx(factor * (sum(seq) - seq[0])),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=10)),
|
||||||
zero + timedelta(minutes=5)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=10)),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(dt_util.as_local(two)),
|
"last_reset": process_timestamp(dt_util.as_local(two)),
|
||||||
"state": approx(factor * seq[7]),
|
"state": approx(factor * seq[7]),
|
||||||
"sum": approx(factor * (2 * sum(seq) - seq[0])),
|
"sum": approx(factor * (2 * sum(seq) - seq[0])),
|
||||||
},
|
},
|
||||||
|
@ -784,13 +770,12 @@ def test_compile_hourly_sum_statistics_amount_invalid_last_reset(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(dt_util.as_local(one)),
|
"last_reset": process_timestamp(dt_util.as_local(one)),
|
||||||
"state": approx(factor * seq[7]),
|
"state": approx(factor * seq[7]),
|
||||||
"sum": approx(factor * (sum(seq) - seq[0] - seq[3])),
|
"sum": approx(factor * (sum(seq) - seq[0] - seq[3])),
|
||||||
},
|
},
|
||||||
|
@ -868,13 +853,12 @@ def test_compile_hourly_sum_statistics_nan_inf_state(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(one),
|
"last_reset": process_timestamp(one),
|
||||||
"state": approx(factor * seq[7]),
|
"state": approx(factor * seq[7]),
|
||||||
"sum": approx(factor * (seq[2] + seq[3] + seq[4] + seq[6] + seq[7])),
|
"sum": approx(factor * (seq[2] + seq[3] + seq[4] + seq[6] + seq[7])),
|
||||||
},
|
},
|
||||||
|
@ -992,9 +976,8 @@ def test_compile_hourly_sum_statistics_negative_state(
|
||||||
stats = statistics_during_period(hass, zero, period="5minute")
|
stats = statistics_during_period(hass, zero, period="5minute")
|
||||||
assert stats[entity_id] == [
|
assert stats[entity_id] == [
|
||||||
{
|
{
|
||||||
"statistic_id": entity_id,
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1081,9 +1064,8 @@ def test_compile_hourly_sum_statistics_total_no_reset(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1092,9 +1074,8 @@ def test_compile_hourly_sum_statistics_total_no_reset(
|
||||||
"sum": approx(factor * 10.0),
|
"sum": approx(factor * 10.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1103,9 +1084,8 @@ def test_compile_hourly_sum_statistics_total_no_reset(
|
||||||
"sum": approx(factor * 30.0),
|
"sum": approx(factor * 30.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1183,9 +1163,8 @@ def test_compile_hourly_sum_statistics_total_increasing(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1194,9 +1173,8 @@ def test_compile_hourly_sum_statistics_total_increasing(
|
||||||
"sum": approx(factor * 10.0),
|
"sum": approx(factor * 10.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1205,9 +1183,8 @@ def test_compile_hourly_sum_statistics_total_increasing(
|
||||||
"sum": approx(factor * 50.0),
|
"sum": approx(factor * 50.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1297,9 +1274,8 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1308,9 +1284,8 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1319,9 +1294,8 @@ def test_compile_hourly_sum_statistics_total_increasing_small_dip(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"last_reset": None,
|
"last_reset": None,
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
|
@ -1390,35 +1364,32 @@ def test_compile_hourly_energy_statistics_unsupported(hass_recorder, caplog):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(period0),
|
"last_reset": process_timestamp(period0),
|
||||||
"state": approx(20.0),
|
"state": approx(20.0),
|
||||||
"sum": approx(10.0),
|
"sum": approx(10.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(40.0),
|
"state": approx(40.0),
|
||||||
"sum": approx(40.0),
|
"sum": approx(40.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(70.0),
|
"state": approx(70.0),
|
||||||
"sum": approx(70.0),
|
"sum": approx(70.0),
|
||||||
},
|
},
|
||||||
|
@ -1500,105 +1471,96 @@ def test_compile_hourly_energy_statistics_multiple(hass_recorder, caplog):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(period0),
|
"last_reset": process_timestamp(period0),
|
||||||
"state": approx(20.0),
|
"state": approx(20.0),
|
||||||
"sum": approx(10.0),
|
"sum": approx(10.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(40.0),
|
"state": approx(40.0),
|
||||||
"sum": approx(40.0),
|
"sum": approx(40.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(70.0),
|
"state": approx(70.0),
|
||||||
"sum": approx(70.0),
|
"sum": approx(70.0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"sensor.test2": [
|
"sensor.test2": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(period0),
|
"last_reset": process_timestamp(period0),
|
||||||
"state": approx(130.0),
|
"state": approx(130.0),
|
||||||
"sum": approx(20.0),
|
"sum": approx(20.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(45.0),
|
"state": approx(45.0),
|
||||||
"sum": approx(-65.0),
|
"sum": approx(-65.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(75.0),
|
"state": approx(75.0),
|
||||||
"sum": approx(-35.0),
|
"sum": approx(-35.0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"sensor.test3": [
|
"sensor.test3": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test3",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(period0),
|
"last_reset": process_timestamp(period0),
|
||||||
"state": approx(5.0),
|
"state": approx(5.0),
|
||||||
"sum": approx(5.0),
|
"sum": approx(5.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test3",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(50.0),
|
"state": approx(50.0),
|
||||||
"sum": approx(60.0),
|
"sum": approx(60.0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test3",
|
"start": process_timestamp(period2),
|
||||||
"start": process_timestamp_to_utc_isoformat(period2),
|
"end": process_timestamp(period2_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period2_end),
|
|
||||||
"max": None,
|
"max": None,
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"last_reset": process_timestamp_to_utc_isoformat(four),
|
"last_reset": process_timestamp(four),
|
||||||
"state": approx(90.0),
|
"state": approx(90.0),
|
||||||
"sum": approx(100.0),
|
"sum": approx(100.0),
|
||||||
},
|
},
|
||||||
|
@ -1654,9 +1616,8 @@ def test_compile_hourly_statistics_unchanged(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(four),
|
||||||
"start": process_timestamp_to_utc_isoformat(four),
|
"end": process_timestamp(four + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(four + timedelta(minutes=5)),
|
|
||||||
"mean": approx(value),
|
"mean": approx(value),
|
||||||
"min": approx(value),
|
"min": approx(value),
|
||||||
"max": approx(value),
|
"max": approx(value),
|
||||||
|
@ -1687,9 +1648,8 @@ def test_compile_hourly_statistics_partially_unavailable(hass_recorder, caplog):
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(21.1864406779661),
|
"mean": approx(21.1864406779661),
|
||||||
"min": approx(10.0),
|
"min": approx(10.0),
|
||||||
"max": approx(25.0),
|
"max": approx(25.0),
|
||||||
|
@ -1757,9 +1717,8 @@ def test_compile_hourly_statistics_unavailable(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test2": [
|
"sensor.test2": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test2",
|
"start": process_timestamp(four),
|
||||||
"start": process_timestamp_to_utc_isoformat(four),
|
"end": process_timestamp(four + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(four + timedelta(minutes=5)),
|
|
||||||
"mean": approx(value),
|
"mean": approx(value),
|
||||||
"min": approx(value),
|
"min": approx(value),
|
||||||
"max": approx(value),
|
"max": approx(value),
|
||||||
|
@ -1974,9 +1933,8 @@ def test_compile_hourly_statistics_changing_units_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2009,9 +1967,8 @@ def test_compile_hourly_statistics_changing_units_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2149,9 +2106,8 @@ def test_compile_hourly_statistics_changing_units_3(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2184,9 +2140,8 @@ def test_compile_hourly_statistics_changing_units_3(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2263,9 +2218,8 @@ def test_compile_hourly_statistics_equivalent_units_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2294,9 +2248,8 @@ def test_compile_hourly_statistics_equivalent_units_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2305,11 +2258,8 @@ def test_compile_hourly_statistics_equivalent_units_1(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=10)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=15)),
|
||||||
zero + timedelta(minutes=10)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=15)),
|
|
||||||
"mean": approx(mean2),
|
"mean": approx(mean2),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2381,13 +2331,8 @@ def test_compile_hourly_statistics_equivalent_units_2(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(seconds=30 * 5)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(seconds=30 * 15)),
|
||||||
zero + timedelta(seconds=30 * 5)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(
|
|
||||||
zero + timedelta(seconds=30 * 15)
|
|
||||||
),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2451,9 +2396,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean1),
|
"mean": approx(mean1),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2496,9 +2440,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean1),
|
"mean": approx(mean1),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2507,11 +2450,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=10)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=15)),
|
||||||
zero + timedelta(minutes=10)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=15)),
|
|
||||||
"mean": approx(mean2),
|
"mean": approx(mean2),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2554,9 +2494,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean1),
|
"mean": approx(mean1),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2565,11 +2504,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=10)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=15)),
|
||||||
zero + timedelta(minutes=10)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=15)),
|
|
||||||
"mean": approx(mean2),
|
"mean": approx(mean2),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2578,11 +2514,8 @@ def test_compile_hourly_statistics_changing_device_class_1(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=20)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=25)),
|
||||||
zero + timedelta(minutes=20)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=25)),
|
|
||||||
"mean": approx(mean2),
|
"mean": approx(mean2),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2647,9 +2580,8 @@ def test_compile_hourly_statistics_changing_device_class_2(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2692,9 +2624,8 @@ def test_compile_hourly_statistics_changing_device_class_2(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero),
|
||||||
"start": process_timestamp_to_utc_isoformat(zero),
|
"end": process_timestamp(zero + timedelta(minutes=5)),
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=5)),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2703,11 +2634,8 @@ def test_compile_hourly_statistics_changing_device_class_2(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(zero + timedelta(minutes=10)),
|
||||||
"start": process_timestamp_to_utc_isoformat(
|
"end": process_timestamp(zero + timedelta(minutes=15)),
|
||||||
zero + timedelta(minutes=10)
|
|
||||||
),
|
|
||||||
"end": process_timestamp_to_utc_isoformat(zero + timedelta(minutes=15)),
|
|
||||||
"mean": approx(mean2),
|
"mean": approx(mean2),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2823,9 +2751,8 @@ def test_compile_hourly_statistics_changing_statistics(
|
||||||
assert stats == {
|
assert stats == {
|
||||||
"sensor.test1": [
|
"sensor.test1": [
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period0),
|
||||||
"start": process_timestamp_to_utc_isoformat(period0),
|
"end": process_timestamp(period0_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period0_end),
|
|
||||||
"mean": approx(mean),
|
"mean": approx(mean),
|
||||||
"min": approx(min),
|
"min": approx(min),
|
||||||
"max": approx(max),
|
"max": approx(max),
|
||||||
|
@ -2834,9 +2761,8 @@ def test_compile_hourly_statistics_changing_statistics(
|
||||||
"sum": None,
|
"sum": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"statistic_id": "sensor.test1",
|
"start": process_timestamp(period1),
|
||||||
"start": process_timestamp_to_utc_isoformat(period1),
|
"end": process_timestamp(period1_end),
|
||||||
"end": process_timestamp_to_utc_isoformat(period1_end),
|
|
||||||
"mean": None,
|
"mean": None,
|
||||||
"min": None,
|
"min": None,
|
||||||
"max": None,
|
"max": None,
|
||||||
|
@ -3071,9 +2997,8 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog):
|
||||||
)
|
)
|
||||||
expected_stats[entity_id].append(
|
expected_stats[entity_id].append(
|
||||||
{
|
{
|
||||||
"statistic_id": entity_id,
|
"start": process_timestamp(start),
|
||||||
"start": process_timestamp_to_utc_isoformat(start),
|
"end": process_timestamp(end),
|
||||||
"end": process_timestamp_to_utc_isoformat(end),
|
|
||||||
"mean": approx(expected_average),
|
"mean": approx(expected_average),
|
||||||
"min": approx(expected_minimum),
|
"min": approx(expected_minimum),
|
||||||
"max": approx(expected_maximum),
|
"max": approx(expected_maximum),
|
||||||
|
@ -3129,9 +3054,8 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog):
|
||||||
)
|
)
|
||||||
expected_stats[entity_id].append(
|
expected_stats[entity_id].append(
|
||||||
{
|
{
|
||||||
"statistic_id": entity_id,
|
"start": process_timestamp(start),
|
||||||
"start": process_timestamp_to_utc_isoformat(start),
|
"end": process_timestamp(end),
|
||||||
"end": process_timestamp_to_utc_isoformat(end),
|
|
||||||
"mean": approx(expected_average),
|
"mean": approx(expected_average),
|
||||||
"min": approx(expected_minimum),
|
"min": approx(expected_minimum),
|
||||||
"max": approx(expected_maximum),
|
"max": approx(expected_maximum),
|
||||||
|
@ -3187,9 +3111,8 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog):
|
||||||
)
|
)
|
||||||
expected_stats[entity_id].append(
|
expected_stats[entity_id].append(
|
||||||
{
|
{
|
||||||
"statistic_id": entity_id,
|
"start": process_timestamp(start),
|
||||||
"start": process_timestamp_to_utc_isoformat(start),
|
"end": process_timestamp(end),
|
||||||
"end": process_timestamp_to_utc_isoformat(end),
|
|
||||||
"mean": approx(expected_average),
|
"mean": approx(expected_average),
|
||||||
"min": approx(expected_minimum),
|
"min": approx(expected_minimum),
|
||||||
"max": approx(expected_maximum),
|
"max": approx(expected_maximum),
|
||||||
|
@ -3245,9 +3168,8 @@ def test_compile_statistics_hourly_daily_monthly_summary(hass_recorder, caplog):
|
||||||
)
|
)
|
||||||
expected_stats[entity_id].append(
|
expected_stats[entity_id].append(
|
||||||
{
|
{
|
||||||
"statistic_id": entity_id,
|
"start": process_timestamp(start),
|
||||||
"start": process_timestamp_to_utc_isoformat(start),
|
"end": process_timestamp(end),
|
||||||
"end": process_timestamp_to_utc_isoformat(end),
|
|
||||||
"mean": approx(expected_average),
|
"mean": approx(expected_average),
|
||||||
"min": approx(expected_minimum),
|
"min": approx(expected_minimum),
|
||||||
"max": approx(expected_maximum),
|
"max": approx(expected_maximum),
|
||||||
|
|
|
@ -35,7 +35,8 @@ async def test_async_setup_entry(recorder_mock, hass):
|
||||||
None,
|
None,
|
||||||
[statistic_id],
|
[statistic_id],
|
||||||
"hour",
|
"hour",
|
||||||
True,
|
None,
|
||||||
|
{"start", "state", "mean", "min", "max", "last_reset", "sum"},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert len(stats) == 1
|
assert len(stats) == 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue