Skip to content

Commit 256817d

Browse files
authored
Make events summary endpoint DST-aware (#20786)
1 parent 84409ea commit 256817d

File tree

1 file changed

+82
-24
lines changed

1 file changed

+82
-24
lines changed

frigate/api/event.py

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import base64
44
import datetime
5+
import json
56
import logging
67
import os
78
import random
@@ -58,7 +59,7 @@
5859
from frigate.models import Event, ReviewSegment, Timeline, Trigger
5960
from frigate.track.object_processing import TrackedObject
6061
from frigate.util.path import get_event_thumbnail_bytes
61-
from frigate.util.time import get_tz_modifiers
62+
from frigate.util.time import get_dst_transitions, get_tz_modifiers
6263

6364
logger = logging.getLogger(__name__)
6465

@@ -813,7 +814,6 @@ def events_summary(
813814
allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter),
814815
):
815816
tz_name = params.timezone
816-
hour_modifier, minute_modifier, seconds_offset = get_tz_modifiers(tz_name)
817817
has_clip = params.has_clip
818818
has_snapshot = params.has_snapshot
819819

@@ -828,33 +828,91 @@ def events_summary(
828828
if len(clauses) == 0:
829829
clauses.append((True))
830830

831-
groups = (
831+
time_range_query = (
832832
Event.select(
833-
Event.camera,
834-
Event.label,
835-
Event.sub_label,
836-
Event.data,
837-
fn.strftime(
838-
"%Y-%m-%d",
839-
fn.datetime(
840-
Event.start_time, "unixepoch", hour_modifier, minute_modifier
841-
),
842-
).alias("day"),
843-
Event.zones,
844-
fn.COUNT(Event.id).alias("count"),
833+
fn.MIN(Event.start_time).alias("min_time"),
834+
fn.MAX(Event.start_time).alias("max_time"),
845835
)
846836
.where(reduce(operator.and_, clauses) & (Event.camera << allowed_cameras))
847-
.group_by(
848-
Event.camera,
849-
Event.label,
850-
Event.sub_label,
851-
Event.data,
852-
(Event.start_time + seconds_offset).cast("int") / (3600 * 24),
853-
Event.zones,
854-
)
837+
.dicts()
838+
.get()
855839
)
856840

857-
return JSONResponse(content=[e for e in groups.dicts()])
841+
min_time = time_range_query.get("min_time")
842+
max_time = time_range_query.get("max_time")
843+
844+
if min_time is None or max_time is None:
845+
return JSONResponse(content=[])
846+
847+
dst_periods = get_dst_transitions(tz_name, min_time, max_time)
848+
849+
grouped: dict[tuple, dict] = {}
850+
851+
for period_start, period_end, period_offset in dst_periods:
852+
hours_offset = int(period_offset / 60 / 60)
853+
minutes_offset = int(period_offset / 60 - hours_offset * 60)
854+
period_hour_modifier = f"{hours_offset} hour"
855+
period_minute_modifier = f"{minutes_offset} minute"
856+
857+
period_groups = (
858+
Event.select(
859+
Event.camera,
860+
Event.label,
861+
Event.sub_label,
862+
Event.data,
863+
fn.strftime(
864+
"%Y-%m-%d",
865+
fn.datetime(
866+
Event.start_time,
867+
"unixepoch",
868+
period_hour_modifier,
869+
period_minute_modifier,
870+
),
871+
).alias("day"),
872+
Event.zones,
873+
fn.COUNT(Event.id).alias("count"),
874+
)
875+
.where(
876+
reduce(operator.and_, clauses)
877+
& (Event.camera << allowed_cameras)
878+
& (Event.start_time >= period_start)
879+
& (Event.start_time <= period_end)
880+
)
881+
.group_by(
882+
Event.camera,
883+
Event.label,
884+
Event.sub_label,
885+
Event.data,
886+
(Event.start_time + period_offset).cast("int") / (3600 * 24),
887+
Event.zones,
888+
)
889+
.namedtuples()
890+
)
891+
892+
for g in period_groups:
893+
key = (
894+
g.camera,
895+
g.label,
896+
g.sub_label,
897+
json.dumps(g.data, sort_keys=True) if g.data is not None else None,
898+
g.day,
899+
json.dumps(g.zones, sort_keys=True) if g.zones is not None else None,
900+
)
901+
902+
if key in grouped:
903+
grouped[key]["count"] += int(g.count or 0)
904+
else:
905+
grouped[key] = {
906+
"camera": g.camera,
907+
"label": g.label,
908+
"sub_label": g.sub_label,
909+
"data": g.data,
910+
"day": g.day,
911+
"zones": g.zones,
912+
"count": int(g.count or 0),
913+
}
914+
915+
return JSONResponse(content=list(grouped.values()))
858916

859917

860918
@router.get(

0 commit comments

Comments
 (0)