Skip to content

Commit

Permalink
Implement config migration and restructure config for new review form…
Browse files Browse the repository at this point in the history
…at (blakeblackshear#10961)

* Update reference config to reflect new config

* Migrate 0.13 config to match 0.14 config style

* Overwrite existing config

* Adjust config schema to remove events required zones and include reviews

* Update object config to check correct required zones config

* Refactor reviews to remove motion and only create review segments in expected circumstances

* Cleanup

* Formatting

* Fix update ordering

* Update pydantic

* Remove rtmp references as part of migration

* Catch file not found for alert frame
  • Loading branch information
NickM-27 committed Apr 13, 2024
1 parent 11dc407 commit 3788df5
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 92 deletions.
2 changes: 1 addition & 1 deletion docker/main/requirements-wheels.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pandas == 2.2.*
peewee == 3.17.*
peewee_migrate == 1.12.*
psutil == 5.9.*
pydantic == 2.6.*
pydantic == 2.7.*
git+https://github.com/fbcotter/py3nvml#egg=py3nvml
PyYAML == 6.0.*
pytz == 2024.1
Expand Down
24 changes: 22 additions & 2 deletions docs/docs/configuration/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ objects:
# Checks based on the bottom center of the bounding box of the object
mask: 0,0,1000,0,1000,200,0,200

# Optional: Review configuration
# NOTE: Can be overridden at the camera level
review:
# Optional: alerts configuration
alerts:
# Optional: labels that qualify as an alert (default: shown below)
labels:
- car
- person
# Optional: required zones for an object to be marked as an alert (default: none)
required_zones:
- driveway
# Optional: detections configuration
detections:
# Optional: labels that qualify as a detection (default: all labels that are tracked / listened to)
labels:
- car
- person
# Optional: required zones for an object to be marked as a detection (default: none)
required_zones:
- driveway

# Optional: Motion configuration
# NOTE: Can be overridden at the camera level
motion:
Expand Down Expand Up @@ -345,8 +367,6 @@ record:
# Optional: Objects to save recordings for. (default: all tracked objects)
objects:
- person
# Optional: Restrict recordings to objects that entered any of the listed zones (default: no required zones)
required_zones: []
# Optional: Retention settings for recordings of events
retain:
# Required: Default retention days (default: shown below)
Expand Down
4 changes: 4 additions & 0 deletions frigate/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
from frigate.timeline import TimelineProcessor
from frigate.types import CameraMetricsTypes, PTZMetricsTypes
from frigate.util.builtin import save_default_config
from frigate.util.config import migrate_frigate_config
from frigate.util.object import get_camera_regions_grid
from frigate.version import VERSION
from frigate.video import capture_camera, track_camera
Expand Down Expand Up @@ -126,6 +127,9 @@ def init_config(self) -> None:
config_file = config_file_yaml
save_default_config(config_file)

# check if the config file needs to be migrated
migrate_frigate_config(config_file)

user_config = FrigateConfig.parse_file(config_file)
self.config = user_config.runtime_config(self.plus_api)

Expand Down
49 changes: 42 additions & 7 deletions frigate/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,6 @@ class EventsConfig(FrigateBaseModel):
default=5, title="Seconds to retain before event starts.", le=MAX_PRE_CAPTURE
)
post_capture: int = Field(default=5, title="Seconds to retain after event ends.")
required_zones: List[str] = Field(
default_factory=list,
title="List of required zones to be entered in order to save the event.",
)
objects: Optional[List[str]] = Field(
None,
title="List of objects to be detected in order to save the event.",
Expand Down Expand Up @@ -657,13 +653,45 @@ def generate_contour(self, frame_shape: tuple[int, int]):

class ObjectConfig(FrigateBaseModel):
track: List[str] = Field(default=DEFAULT_TRACKED_OBJECTS, title="Objects to track.")
alert: List[str] = Field(
default=DEFAULT_ALERT_OBJECTS, title="Objects to create alerts for."
)
filters: Dict[str, FilterConfig] = Field(default={}, title="Object filters.")
mask: Union[str, List[str]] = Field(default="", title="Object mask.")


class AlertsConfig(FrigateBaseModel):
"""Configure alerts"""

labels: List[str] = Field(
default=DEFAULT_ALERT_OBJECTS, title="Labels to create alerts for."
)
required_zones: List[str] = Field(
default_factory=list,
title="List of required zones to be entered in order to save the event as an alert.",
)


class DetectionsConfig(FrigateBaseModel):
"""Configure detections"""

labels: Optional[List[str]] = Field(
default=None, title="Labels to create detections for."
)
required_zones: List[str] = Field(
default_factory=list,
title="List of required zones to be entered in order to save the event as a detection.",
)


class ReviewConfig(FrigateBaseModel):
"""Configure reviews"""

alerts: AlertsConfig = Field(
default_factory=AlertsConfig, title="Review alerts config."
)
detections: DetectionsConfig = Field(
default_factory=DetectionsConfig, title="Review detections config."
)


class AudioConfig(FrigateBaseModel):
enabled: bool = Field(default=False, title="Enable audio events.")
max_not_heard: int = Field(
Expand Down Expand Up @@ -942,6 +970,9 @@ class CameraConfig(FrigateBaseModel):
objects: ObjectConfig = Field(
default_factory=ObjectConfig, title="Object configuration."
)
review: ReviewConfig = Field(
default_factory=ReviewConfig, title="Review configuration."
)
audio: AudioConfig = Field(
default_factory=AudioConfig, title="Audio events configuration."
)
Expand Down Expand Up @@ -1263,6 +1294,9 @@ class FrigateConfig(FrigateBaseModel):
objects: ObjectConfig = Field(
default_factory=ObjectConfig, title="Global object configuration."
)
review: ReviewConfig = Field(
default_factory=ReviewConfig, title="Review configuration."
)
audio: AudioConfig = Field(
default_factory=AudioConfig, title="Global Audio events configuration."
)
Expand Down Expand Up @@ -1310,6 +1344,7 @@ def runtime_config(self, plus_api: PlusApi = None) -> FrigateConfig:
"snapshots": ...,
"live": ...,
"objects": ...,
"review": ...,
"motion": ...,
"detect": ...,
"ffmpeg": ...,
Expand Down
8 changes: 6 additions & 2 deletions frigate/object_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ def should_save_snapshot(self, camera, obj: TrackedObject):

return True

def should_retain_recording(self, camera, obj: TrackedObject):
def should_retain_recording(self, camera: str, obj: TrackedObject):
if obj.false_positive:
return False

Expand All @@ -1022,7 +1022,11 @@ def should_retain_recording(self, camera, obj: TrackedObject):
return False

# If there are required zones and there is no overlap
required_zones = record_config.events.required_zones
review_config = self.config.cameras[camera].review
required_zones = (
review_config.alerts.required_zones
+ review_config.detections.required_zones
)
if len(required_zones) > 0 and not set(obj.entered_zones) & set(required_zones):
logger.debug(
f"Not creating clip for {obj.obj_data['id']} because it did not enter required zones"
Expand Down
Loading

0 comments on commit 3788df5

Please sign in to comment.