mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-04-24 01:16:47 +02:00
handle timezones with partial hour offsets (#5115)
* handle timezones with partial hour offsets * cleanup
This commit is contained in:
parent
81b3fdb423
commit
3bec28ffef
@ -41,6 +41,7 @@ from frigate.util import (
|
|||||||
ffprobe_stream,
|
ffprobe_stream,
|
||||||
restart_frigate,
|
restart_frigate,
|
||||||
vainfo_hwaccel,
|
vainfo_hwaccel,
|
||||||
|
get_tz_modifiers,
|
||||||
)
|
)
|
||||||
from frigate.storage import StorageMaintainer
|
from frigate.storage import StorageMaintainer
|
||||||
from frigate.version import VERSION
|
from frigate.version import VERSION
|
||||||
@ -91,7 +92,7 @@ def is_healthy():
|
|||||||
@bp.route("/events/summary")
|
@bp.route("/events/summary")
|
||||||
def events_summary():
|
def events_summary():
|
||||||
tz_name = request.args.get("timezone", default="utc", type=str)
|
tz_name = request.args.get("timezone", default="utc", type=str)
|
||||||
tz_offset = f"{int(datetime.now(pytz.timezone(tz_name)).utcoffset().total_seconds()/60/60)} hour"
|
hour_modifier, minute_modifier = get_tz_modifiers(tz_name)
|
||||||
has_clip = request.args.get("has_clip", type=int)
|
has_clip = request.args.get("has_clip", type=int)
|
||||||
has_snapshot = request.args.get("has_snapshot", type=int)
|
has_snapshot = request.args.get("has_snapshot", type=int)
|
||||||
|
|
||||||
@ -111,7 +112,10 @@ def events_summary():
|
|||||||
Event.camera,
|
Event.camera,
|
||||||
Event.label,
|
Event.label,
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d", fn.datetime(Event.start_time, "unixepoch", tz_offset)
|
"%Y-%m-%d",
|
||||||
|
fn.datetime(
|
||||||
|
Event.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
).alias("day"),
|
).alias("day"),
|
||||||
Event.zones,
|
Event.zones,
|
||||||
fn.COUNT(Event.id).alias("count"),
|
fn.COUNT(Event.id).alias("count"),
|
||||||
@ -121,7 +125,10 @@ def events_summary():
|
|||||||
Event.camera,
|
Event.camera,
|
||||||
Event.label,
|
Event.label,
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d", fn.datetime(Event.start_time, "unixepoch", tz_offset)
|
"%Y-%m-%d",
|
||||||
|
fn.datetime(
|
||||||
|
Event.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Event.zones,
|
Event.zones,
|
||||||
)
|
)
|
||||||
@ -912,12 +919,14 @@ def get_recordings_storage_usage():
|
|||||||
@bp.route("/<camera_name>/recordings/summary")
|
@bp.route("/<camera_name>/recordings/summary")
|
||||||
def recordings_summary(camera_name):
|
def recordings_summary(camera_name):
|
||||||
tz_name = request.args.get("timezone", default="utc", type=str)
|
tz_name = request.args.get("timezone", default="utc", type=str)
|
||||||
tz_offset = f"{int(datetime.now(pytz.timezone(tz_name)).utcoffset().total_seconds()/60/60)} hour"
|
hour_modifier, minute_modifier = get_tz_modifiers(tz_name)
|
||||||
recording_groups = (
|
recording_groups = (
|
||||||
Recordings.select(
|
Recordings.select(
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d %H",
|
"%Y-%m-%d %H",
|
||||||
fn.datetime(Recordings.start_time, "unixepoch", tz_offset),
|
fn.datetime(
|
||||||
|
Recordings.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
).alias("hour"),
|
).alias("hour"),
|
||||||
fn.SUM(Recordings.duration).alias("duration"),
|
fn.SUM(Recordings.duration).alias("duration"),
|
||||||
fn.SUM(Recordings.motion).alias("motion"),
|
fn.SUM(Recordings.motion).alias("motion"),
|
||||||
@ -927,13 +936,17 @@ def recordings_summary(camera_name):
|
|||||||
.group_by(
|
.group_by(
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d %H",
|
"%Y-%m-%d %H",
|
||||||
fn.datetime(Recordings.start_time, "unixepoch", tz_offset),
|
fn.datetime(
|
||||||
|
Recordings.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.order_by(
|
.order_by(
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d H",
|
"%Y-%m-%d H",
|
||||||
fn.datetime(Recordings.start_time, "unixepoch", tz_offset),
|
fn.datetime(
|
||||||
|
Recordings.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
).desc()
|
).desc()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -942,7 +955,9 @@ def recordings_summary(camera_name):
|
|||||||
Event.select(
|
Event.select(
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d %H",
|
"%Y-%m-%d %H",
|
||||||
fn.datetime(Event.start_time, "unixepoch", tz_offset),
|
fn.datetime(
|
||||||
|
Event.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
).alias("hour"),
|
).alias("hour"),
|
||||||
fn.COUNT(Event.id).alias("count"),
|
fn.COUNT(Event.id).alias("count"),
|
||||||
)
|
)
|
||||||
@ -950,7 +965,9 @@ def recordings_summary(camera_name):
|
|||||||
.group_by(
|
.group_by(
|
||||||
fn.strftime(
|
fn.strftime(
|
||||||
"%Y-%m-%d %H",
|
"%Y-%m-%d %H",
|
||||||
fn.datetime(Event.start_time, "unixepoch", tz_offset),
|
fn.datetime(
|
||||||
|
Event.start_time, "unixepoch", hour_modifier, minute_modifier
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.objects()
|
.objects()
|
||||||
@ -1147,17 +1164,11 @@ def vod_hour_no_timezone(year_month, day, hour, camera_name):
|
|||||||
# TODO make this nicer when vod module is removed
|
# TODO make this nicer when vod module is removed
|
||||||
@bp.route("/vod/<year_month>/<day>/<hour>/<camera_name>/<tz_name>")
|
@bp.route("/vod/<year_month>/<day>/<hour>/<camera_name>/<tz_name>")
|
||||||
def vod_hour(year_month, day, hour, camera_name, tz_name):
|
def vod_hour(year_month, day, hour, camera_name, tz_name):
|
||||||
tz_offset = int(
|
|
||||||
datetime.now(pytz.timezone(tz_name.replace(",", "/")))
|
|
||||||
.utcoffset()
|
|
||||||
.total_seconds()
|
|
||||||
/ 60
|
|
||||||
/ 60
|
|
||||||
)
|
|
||||||
parts = year_month.split("-")
|
parts = year_month.split("-")
|
||||||
start_date = datetime(
|
start_date = (
|
||||||
int(parts[0]), int(parts[1]), int(day), int(hour), tzinfo=timezone.utc
|
datetime(int(parts[0]), int(parts[1]), int(day), int(hour), tzinfo=timezone.utc)
|
||||||
) - timedelta(hours=tz_offset)
|
- datetime.now(pytz.timezone(tz_name.replace(",", "/"))).utcoffset()
|
||||||
|
)
|
||||||
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
|
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
|
||||||
start_ts = start_date.timestamp()
|
start_ts = start_date.timestamp()
|
||||||
end_ts = end_date.timestamp()
|
end_ts = end_date.timestamp()
|
||||||
|
@ -14,12 +14,13 @@ from abc import ABC, abstractmethod
|
|||||||
from collections import Counter
|
from collections import Counter
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from multiprocessing import shared_memory
|
from multiprocessing import shared_memory
|
||||||
from typing import Any, AnyStr
|
from typing import Any, AnyStr, Tuple
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import os
|
import os
|
||||||
import psutil
|
import psutil
|
||||||
|
import pytz
|
||||||
|
|
||||||
from frigate.const import REGEX_HTTP_CAMERA_USER_PASS, REGEX_RTSP_CAMERA_USER_PASS
|
from frigate.const import REGEX_HTTP_CAMERA_USER_PASS, REGEX_RTSP_CAMERA_USER_PASS
|
||||||
|
|
||||||
@ -1040,3 +1041,14 @@ class SharedMemoryFrameManager(FrameManager):
|
|||||||
self.shm_store[name].close()
|
self.shm_store[name].close()
|
||||||
self.shm_store[name].unlink()
|
self.shm_store[name].unlink()
|
||||||
del self.shm_store[name]
|
del self.shm_store[name]
|
||||||
|
|
||||||
|
|
||||||
|
def get_tz_modifiers(tz_name: str) -> Tuple[str, str]:
|
||||||
|
seconds_offset = (
|
||||||
|
datetime.datetime.now(pytz.timezone(tz_name)).utcoffset().total_seconds()
|
||||||
|
)
|
||||||
|
hours_offset = int(seconds_offset / 60 / 60)
|
||||||
|
minutes_offset = int(seconds_offset / 60 - hours_offset * 60)
|
||||||
|
hour_modifier = f"{hours_offset} hour"
|
||||||
|
minute_modifier = f"{minutes_offset} minute"
|
||||||
|
return hour_modifier, minute_modifier
|
||||||
|
Loading…
Reference in New Issue
Block a user