mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-03 22:04:53 +03:00
Fix motion activity endpoint returning invalid timestamps after pandas 3.0 upgrade
pandas 3.0 changed DatetimeIndex internal storage from datetime64[ns]
(nanoseconds) to datetime64[us] (microseconds). The motion activity
endpoint in review.py converted DatetimeIndex to epoch seconds using:
df.index = df.index.astype(int) // (10**9)
This assumed nanosecond resolution, dividing by 10^9 to get seconds.
With microsecond resolution the division produces values ~1000x too
small (e.g. 1774785 instead of 1774785600), causing every entry to
have a start_time near zero. The frontend timeline could not match
these timestamps to the visible range, so motion indicator bars
disappeared entirely — despite the underlying recording data being
correct.
Replace the resolution-dependent integer division with pandas
Timedelta arithmetic:
df.index = (df.index - _EPOCH) // _ONE_SECOND
This is resolution-independent (produces correct results on
datetime64[s], [ms], [us], and [ns]), ~148x faster than the
per-element .timestamp() alternative, produces native Python int
types that serialize cleanly to JSON, and is backwards-compatible
with older pandas versions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
148e11afc5
commit
317d1acfe1
@ -40,6 +40,11 @@ from frigate.util.time import get_dst_transitions
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Pre-computed constants for resolution-independent datetime-to-epoch conversion
|
||||||
|
# (pandas 3.0+ stores datetime64 as microseconds, not nanoseconds)
|
||||||
|
_EPOCH = pd.Timestamp("1970-01-01")
|
||||||
|
_ONE_SECOND = pd.Timedelta("1s")
|
||||||
|
|
||||||
router = APIRouter(tags=[Tags.review])
|
router = APIRouter(tags=[Tags.review])
|
||||||
|
|
||||||
|
|
||||||
@ -659,7 +664,7 @@ def motion_activity(
|
|||||||
df.iloc[i : i + chunk, 0] = 0.0
|
df.iloc[i : i + chunk, 0] = 0.0
|
||||||
|
|
||||||
# change types for output
|
# change types for output
|
||||||
df.index = df.index.astype(int) // (10**9)
|
df.index = (df.index - _EPOCH) // _ONE_SECOND
|
||||||
normalized = df.reset_index().to_dict("records")
|
normalized = df.reset_index().to_dict("records")
|
||||||
return JSONResponse(content=normalized)
|
return JSONResponse(content=normalized)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user