2024-09-28 22:21:42 +03:00
from typing import Any , Optional , Union
2025-08-09 01:33:11 +03:00
from pydantic import Field , PrivateAttr , field_serializer , field_validator
2024-09-28 22:21:42 +03:00
from . . base import FrigateBaseModel
2025-08-09 01:33:11 +03:00
__all__ = [ " ObjectConfig " , " GenAIObjectConfig " , " FilterConfig " ]
2024-09-28 22:21:42 +03:00
DEFAULT_TRACKED_OBJECTS = [ " person " ]
class FilterConfig ( FrigateBaseModel ) :
2025-02-10 00:48:23 +03:00
min_area : Union [ int , float ] = Field (
default = 0 ,
2026-01-29 18:31:58 +03:00
title = " Minimum object area " ,
2026-01-29 17:50:15 +03:00
description = " Minimum bounding box area (pixels or percentage) required for this object type. Can be pixels (int) or percentage (float between 0.000001 and 0.99). " ,
2024-09-28 22:21:42 +03:00
)
2025-02-10 00:48:23 +03:00
max_area : Union [ int , float ] = Field (
default = 24000000 ,
2026-01-29 18:31:58 +03:00
title = " Maximum object area " ,
2026-01-29 17:50:15 +03:00
description = " Maximum bounding box area (pixels or percentage) allowed for this object type. Can be pixels (int) or percentage (float between 0.000001 and 0.99). " ,
2024-09-28 22:21:42 +03:00
)
min_ratio : float = Field (
default = 0 ,
2026-01-29 18:31:58 +03:00
title = " Minimum aspect ratio " ,
2026-01-29 17:50:15 +03:00
description = " Minimum width/height ratio required for the bounding box to qualify. " ,
2024-09-28 22:21:42 +03:00
)
max_ratio : float = Field (
default = 24000000 ,
2026-01-29 18:31:58 +03:00
title = " Maximum aspect ratio " ,
2026-01-29 17:50:15 +03:00
description = " Maximum width/height ratio allowed for the bounding box to qualify. " ,
2024-09-28 22:21:42 +03:00
)
threshold : float = Field (
default = 0.7 ,
2026-01-29 18:31:58 +03:00
title = " Avg confidence " ,
2026-01-29 17:50:15 +03:00
description = " Average detection confidence threshold required for the object to be considered a true positive. " ,
2024-09-28 22:21:42 +03:00
)
min_score : float = Field (
2026-01-29 17:50:15 +03:00
default = 0.5 ,
2026-01-29 18:31:58 +03:00
title = " Minimum confidence " ,
2026-01-29 17:50:15 +03:00
description = " Minimum single-frame detection confidence required for the object to be counted. " ,
2024-09-28 22:21:42 +03:00
)
mask : Optional [ Union [ str , list [ str ] ] ] = Field (
default = None ,
2026-01-29 18:31:58 +03:00
title = " Filter mask " ,
2026-01-29 17:50:15 +03:00
description = " Polygon coordinates defining where this filter applies within the frame. " ,
2024-09-28 22:21:42 +03:00
)
raw_mask : Union [ str , list [ str ] ] = " "
@field_serializer ( " mask " , when_used = " json " )
def serialize_mask ( self , value : Any , info ) :
return self . raw_mask
@field_serializer ( " raw_mask " , when_used = " json " )
def serialize_raw_mask ( self , value : Any , info ) :
return None
2025-08-09 01:33:11 +03:00
class GenAIObjectTriggerConfig ( FrigateBaseModel ) :
tracked_object_end : bool = Field (
2026-01-29 17:50:15 +03:00
default = True ,
2026-01-29 18:31:58 +03:00
title = " Send on end " ,
2026-01-29 17:50:15 +03:00
description = " Send a request to GenAI when the tracked object ends. " ,
2025-08-09 01:33:11 +03:00
)
after_significant_updates : Optional [ int ] = Field (
default = None ,
2026-01-29 18:31:58 +03:00
title = " Early GenAI trigger " ,
2026-01-29 17:50:15 +03:00
description = " Send a request to GenAI after a specified number of significant updates for the tracked object. " ,
2025-08-09 01:33:11 +03:00
ge = 1 ,
)
class GenAIObjectConfig ( FrigateBaseModel ) :
2026-01-29 17:50:15 +03:00
enabled : bool = Field (
default = False ,
2026-01-29 18:31:58 +03:00
title = " Enable GenAI " ,
2026-01-29 17:50:15 +03:00
description = " Enable GenAI generation of descriptions for tracked objects by default. " ,
)
2025-08-09 01:33:11 +03:00
use_snapshot : bool = Field (
2026-01-29 17:50:15 +03:00
default = False ,
2026-01-29 18:31:58 +03:00
title = " Use snapshots " ,
2026-01-29 17:50:15 +03:00
description = " Use object snapshots instead of thumbnails for GenAI description generation. " ,
2025-08-09 01:33:11 +03:00
)
prompt : str = Field (
default = " Analyze the sequence of images containing the {label} . Focus on the likely intent or behavior of the {label} based on its actions and movement, rather than describing its appearance or the surroundings. Consider what the {label} is doing, why, and what it might do next. " ,
2026-01-29 18:31:58 +03:00
title = " Caption prompt " ,
2026-01-29 17:50:15 +03:00
description = " Default prompt template used when generating descriptions with GenAI. " ,
2025-08-09 01:33:11 +03:00
)
object_prompts : dict [ str , str ] = Field (
2026-01-29 17:50:15 +03:00
default_factory = dict ,
2026-01-29 18:31:58 +03:00
title = " Object prompts " ,
2026-01-29 17:50:15 +03:00
description = " Per-object prompts to customize GenAI outputs for specific labels. " ,
2025-08-09 01:33:11 +03:00
)
objects : Union [ str , list [ str ] ] = Field (
default_factory = list ,
2026-01-29 18:31:58 +03:00
title = " GenAI objects " ,
2026-01-29 17:50:15 +03:00
description = " List of object labels to send to GenAI by default. " ,
2025-08-09 01:33:11 +03:00
)
required_zones : Union [ str , list [ str ] ] = Field (
default_factory = list ,
2026-01-29 18:31:58 +03:00
title = " Required zones " ,
2026-01-29 17:50:15 +03:00
description = " Zones that must be entered for objects to qualify for GenAI description generation. " ,
2025-08-09 01:33:11 +03:00
)
debug_save_thumbnails : bool = Field (
default = False ,
2026-01-29 18:31:58 +03:00
title = " Save thumbnails " ,
2026-01-29 17:50:15 +03:00
description = " Save thumbnails sent to GenAI for debugging and review. " ,
2025-08-09 01:33:11 +03:00
)
send_triggers : GenAIObjectTriggerConfig = Field (
default_factory = GenAIObjectTriggerConfig ,
2026-01-29 18:31:58 +03:00
title = " GenAI triggers " ,
2026-01-29 17:50:15 +03:00
description = " Defines when frames should be sent to GenAI (on end, after updates, etc.). " ,
2025-08-09 01:33:11 +03:00
)
enabled_in_config : Optional [ bool ] = Field (
2026-01-29 17:50:15 +03:00
default = None ,
2026-01-29 18:31:58 +03:00
title = " Original GenAI state " ,
2026-01-29 17:50:15 +03:00
description = " Indicates whether GenAI was enabled in the original static config. " ,
2025-08-09 01:33:11 +03:00
)
@field_validator ( " required_zones " , mode = " before " )
@classmethod
def validate_required_zones ( cls , v ) :
if isinstance ( v , str ) and " , " not in v :
return [ v ]
return v
2024-09-28 22:21:42 +03:00
class ObjectConfig ( FrigateBaseModel ) :
2026-01-29 17:50:15 +03:00
track : list [ str ] = Field (
default = DEFAULT_TRACKED_OBJECTS ,
title = " Objects to track " ,
description = " List of object labels to track globally; camera configs can override this. " ,
)
2024-09-28 22:21:42 +03:00
filters : dict [ str , FilterConfig ] = Field (
2026-01-29 17:50:15 +03:00
default_factory = dict ,
title = " Object filters " ,
description = " Filters applied to detected objects to reduce false positives (area, ratio, confidence). " ,
)
mask : Union [ str , list [ str ] ] = Field (
default = " " ,
title = " Object mask " ,
description = " Mask polygon used to prevent object detection in specified areas. " ,
2024-09-28 22:21:42 +03:00
)
2025-08-09 01:33:11 +03:00
genai : GenAIObjectConfig = Field (
default_factory = GenAIObjectConfig ,
2026-01-29 18:31:58 +03:00
title = " GenAI object config " ,
2026-01-29 17:50:15 +03:00
description = " GenAI options for describing tracked objects and sending frames for generation. " ,
2025-08-09 01:33:11 +03:00
)
2024-10-26 21:14:21 +03:00
_all_objects : list [ str ] = PrivateAttr ( )
@property
def all_objects ( self ) - > list [ str ] :
return self . _all_objects
def parse_all_objects ( self , cameras ) :
if " _all_objects " in self :
return
# get list of unique enabled labels for tracking
enabled_labels = set ( self . track )
for camera in cameras . values ( ) :
enabled_labels . update ( camera . objects . track )
self . _all_objects = list ( enabled_labels )