Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include data for entire periods in response to recorder/statistics_during_period #92848

Merged
merged 2 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 39 additions & 4 deletions homeassistant/components/recorder/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,14 @@ def _reduce_statistics_per_week(
)


def _find_month_end_time(timestamp: datetime) -> datetime:
"""Return the end of the month (midnight at the first day of the next month)."""
# We add 4 days to the end to make sure we are in the next month
return (timestamp.replace(day=28) + timedelta(days=4)).replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)


def reduce_month_ts_factory() -> (
tuple[
Callable[[float, float], bool],
Expand All @@ -1007,10 +1015,7 @@ def _month_start_end_ts(time: float) -> tuple[float, float]:
start_local = _local_from_timestamp(time).replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)
# We add 4 days to the end to make sure we are in the next month
end_local = (start_local.replace(day=28) + timedelta(days=4)).replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)
end_local = _find_month_end_time(start_local)
return (
start_local.astimezone(dt_util.UTC).timestamp(),
end_local.astimezone(dt_util.UTC).timestamp(),
Expand Down Expand Up @@ -1629,6 +1634,36 @@ def _statistics_during_period_with_session(
if statistic_ids is not None:
metadata_ids = _extract_metadata_and_discard_impossible_columns(metadata, types)

# Align start_time and end_time with the period
if period == "day":
start_time = dt_util.as_local(start_time).replace(
hour=0, minute=0, second=0, microsecond=0
)
start_time = start_time.replace()
if end_time is not None:
end_local = dt_util.as_local(end_time)
end_time = end_local.replace(
hour=0, minute=0, second=0, microsecond=0
) + timedelta(days=1)
elif period == "week":
start_local = dt_util.as_local(start_time)
start_time = start_local.replace(
hour=0, minute=0, second=0, microsecond=0
) - timedelta(days=start_local.weekday())
if end_time is not None:
end_local = dt_util.as_local(end_time)
end_time = (
end_local.replace(hour=0, minute=0, second=0, microsecond=0)
- timedelta(days=end_local.weekday())
+ timedelta(days=7)
)
elif period == "month":
start_time = dt_util.as_local(start_time).replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)
if end_time is not None:
end_time = _find_month_end_time(dt_util.as_local(end_time))

table: type[Statistics | StatisticsShortTerm] = (
Statistics if period != "5minute" else StatisticsShortTerm
)
Expand Down