2024-09-28 22:21:42 +03:00
from typing import Optional
2026-03-30 08:34:54 -05:00
from pydantic import Field , model_validator
2024-09-28 22:21:42 +03:00
from ..base import FrigateBaseModel
__all__ = [ "DetectConfig" , "StationaryConfig" , "StationaryMaxFramesConfig" ]
class StationaryMaxFramesConfig ( FrigateBaseModel ):
2026-02-27 09:55:36 -06:00
default : Optional [ int ] = Field (
default = None ,
title = "Default max frames" ,
description = "Default maximum frames to track a stationary object before stopping." ,
ge = 1 ,
)
2024-09-28 22:21:42 +03:00
objects : dict [ str , int ] = Field (
2026-02-27 09:55:36 -06:00
default_factory = dict ,
title = "Object max frames" ,
description = "Per-object overrides for maximum frames to track stationary objects." ,
2024-09-28 22:21:42 +03:00
)
class StationaryConfig ( FrigateBaseModel ):
interval : Optional [ int ] = Field (
default = None ,
2026-02-27 09:55:36 -06:00
title = "Stationary interval" ,
description = "How often (in frames) to run a detection check to confirm a stationary object." ,
2024-09-28 22:21:42 +03:00
gt = 0 ,
)
threshold : Optional [ int ] = Field (
default = None ,
2026-02-27 09:55:36 -06:00
title = "Stationary threshold" ,
description = "Number of frames with no position change required to mark an object as stationary." ,
2024-09-28 22:21:42 +03:00
ge = 1 ,
)
max_frames : StationaryMaxFramesConfig = Field (
default_factory = StationaryMaxFramesConfig ,
2026-02-27 09:55:36 -06:00
title = "Max frames" ,
description = "Limits how long stationary objects are tracked before being discarded." ,
2024-09-28 22:21:42 +03:00
)
2025-09-25 09:18:45 -06:00
classifier : bool = Field (
default = True ,
2026-02-27 09:55:36 -06:00
title = "Enable visual classifier" ,
description = "Use a visual classifier to detect truly stationary objects even when bounding boxes jitter." ,
2025-09-25 09:18:45 -06:00
)
2024-09-28 22:21:42 +03:00
class DetectConfig ( FrigateBaseModel ):
2026-02-27 09:55:36 -06:00
enabled : bool = Field (
default = False ,
2026-03-20 08:24:34 -05:00
title = "Enable object detection" ,
description = "Enable or disable object detection for all cameras; can be overridden per-camera." ,
2026-02-27 09:55:36 -06:00
)
2024-09-28 22:21:42 +03:00
height : Optional [ int ] = Field (
2026-02-27 09:55:36 -06:00
default = None ,
title = "Detect height" ,
description = "Height (pixels) of frames used for the detect stream; leave empty to use the native stream resolution." ,
2024-09-28 22:21:42 +03:00
)
width : Optional [ int ] = Field (
2026-02-27 09:55:36 -06:00
default = None ,
title = "Detect width" ,
description = "Width (pixels) of frames used for the detect stream; leave empty to use the native stream resolution." ,
2024-09-28 22:21:42 +03:00
)
fps : int = Field (
2026-02-27 09:55:36 -06:00
default = 5 ,
title = "Detect FPS" ,
description = "Desired frames per second to run detection on; lower values reduce CPU usage (recommended value is 5, only set higher - at most 10 - if tracking extremely fast moving objects)." ,
2024-09-28 22:21:42 +03:00
)
min_initialized : Optional [ int ] = Field (
default = None ,
2026-02-27 09:55:36 -06:00
title = "Minimum initialization frames" ,
description = "Number of consecutive detection hits required before creating a tracked object. Increase to reduce false initializations. Default value is fps divided by 2." ,
2026-03-26 13:47:24 -05:00
ge = 2 ,
2024-09-28 22:21:42 +03:00
)
max_disappeared : Optional [ int ] = Field (
default = None ,
2026-02-27 09:55:36 -06:00
title = "Maximum disappeared frames" ,
description = "Number of frames without a detection before a tracked object is considered gone." ,
2024-09-28 22:21:42 +03:00
)
stationary : StationaryConfig = Field (
default_factory = StationaryConfig ,
2026-02-27 09:55:36 -06:00
title = "Stationary objects config" ,
description = "Settings to detect and manage objects that remain stationary for a period of time." ,
2024-09-28 22:21:42 +03:00
)
annotation_offset : int = Field (
2026-02-27 09:55:36 -06:00
default = 0 ,
title = "Annotation offset" ,
description = "Milliseconds to shift detect annotations to better align timeline bounding boxes with recordings; can be positive or negative." ,
2024-09-28 22:21:42 +03:00
)
2026-03-30 08:34:54 -05:00
@model_validator ( mode = "after" )
def validate_dimensions ( self ) -> "DetectConfig" :
if ( self . width is None ) != ( self . height is None ):
raise ValueError (
"detect -> both width and height must be specified together, or both omitted"
)
return self