diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index 9128fead5..74bacde50 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -167,21 +167,6 @@ record: person: 15 ``` -## `snapshots` - -Can be overridden at the camera level. Global snapshot retention settings. - -```yaml -# Optional: Configuration for the jpg snapshots written to the clips directory for each event -snapshots: - retain: - # Required: Default retention days (default: shown below) - default: 10 - # Optional: Per object retention days - objects: - person: 15 -``` - ### `ffmpeg` Can be overridden at the camera level. diff --git a/frigate/config.py b/frigate/config.py index ae280b267..910e78d27 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -371,7 +371,7 @@ class CameraFfmpegConfig(FfmpegConfig): return v -class CameraSnapshotsConfig(BaseModel): +class SnapshotsConfig(BaseModel): enabled: bool = Field(default=False, title="Snapshots enabled.") clean_copy: bool = Field( default=True, title="Create a clean copy of the snapshot image." @@ -457,9 +457,11 @@ class CameraConfig(BaseModel): rtmp: CameraRtmpConfig = Field( default_factory=CameraRtmpConfig, title="RTMP restreaming configuration." ) - live: Optional[CameraLiveConfig] = Field(title="Live playback settings.") - snapshots: CameraSnapshotsConfig = Field( - default_factory=CameraSnapshotsConfig, title="Snapshot configuration." + live: CameraLiveConfig = Field( + default_factory=CameraLiveConfig, title="Live playback settings." + ) + snapshots: SnapshotsConfig = Field( + default_factory=SnapshotsConfig, title="Snapshot configuration." ) mqtt: CameraMqttConfig = Field( default_factory=CameraMqttConfig, title="MQTT configuration." @@ -468,7 +470,9 @@ class CameraConfig(BaseModel): default_factory=ObjectConfig, title="Object configuration." ) motion: Optional[MotionConfig] = Field(title="Motion detection configuration.") - detect: Optional[DetectConfig] = Field(title="Object detection configuration.") + detect: DetectConfig = Field( + default_factory=DetectConfig, title="Object detection configuration." + ) timestamp_style: TimestampStyleConfig = Field( default_factory=TimestampStyleConfig, title="Timestamp style configuration." ) @@ -628,12 +632,6 @@ class LoggerConfig(BaseModel): ) -class SnapshotsConfig(BaseModel): - retain: RetainConfig = Field( - default_factory=RetainConfig, title="Global snapshot retention configuration." - ) - - class FrigateConfig(BaseModel): mqtt: MqttConfig = Field(title="MQTT Configuration.") database: DatabaseConfig = Field( @@ -670,8 +668,8 @@ class FrigateConfig(BaseModel): motion: Optional[MotionConfig] = Field( title="Global motion detection configuration." ) - detect: Optional[DetectConfig] = Field( - title="Global object tracking configuration." + detect: DetectConfig = Field( + default_factory=DetectConfig, title="Global object tracking configuration." ) cameras: Dict[str, CameraConfig] = Field(title="Camera configuration.") @@ -703,10 +701,7 @@ class FrigateConfig(BaseModel): {"name": name, **merged_config} ) - # Default detect configuration - if camera_config.detect is None: - camera_config.detect = DetectConfig() - + # Default max_disappeared configuration max_disappeared = camera_config.detect.fps * 5 if camera_config.detect.max_disappeared is None: camera_config.detect.max_disappeared = max_disappeared @@ -758,10 +753,6 @@ class FrigateConfig(BaseModel): **camera_config.motion.dict(exclude_unset=True), ) - # Default live configuration - if camera_config.live is None: - camera_config.live = CameraLiveConfig() - config.cameras[name] = camera_config return config diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index 9e71e3d27..e0d09d191 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -802,6 +802,88 @@ class TestConfig(unittest.TestCase): assert runtime_config.cameras["back"].detect.height == 1080 assert runtime_config.cameras["back"].detect.width == 1920 + def test_global_snapshots(self): + + config = { + "mqtt": {"host": "mqtt"}, + "snapshots": {"enabled": True}, + "cameras": { + "back": { + "ffmpeg": { + "inputs": [ + { + "path": "rtsp://10.0.0.1:554/video", + "roles": ["detect"], + }, + ] + }, + "snapshots": { + "height": 100, + }, + } + }, + } + frigate_config = FrigateConfig(**config) + assert config == frigate_config.dict(exclude_unset=True) + + runtime_config = frigate_config.runtime_config + assert runtime_config.cameras["back"].snapshots.enabled + assert runtime_config.cameras["back"].snapshots.height == 100 + + def test_default_snapshots(self): + + config = { + "mqtt": {"host": "mqtt"}, + "cameras": { + "back": { + "ffmpeg": { + "inputs": [ + { + "path": "rtsp://10.0.0.1:554/video", + "roles": ["detect"], + }, + ] + } + } + }, + } + frigate_config = FrigateConfig(**config) + assert config == frigate_config.dict(exclude_unset=True) + + runtime_config = frigate_config.runtime_config + assert runtime_config.cameras["back"].snapshots.bounding_box + assert runtime_config.cameras["back"].snapshots.quality == 70 + + def test_global_snapshots_merge(self): + + config = { + "mqtt": {"host": "mqtt"}, + "snapshots": {"bounding_box": False, "height": 300}, + "cameras": { + "back": { + "ffmpeg": { + "inputs": [ + { + "path": "rtsp://10.0.0.1:554/video", + "roles": ["detect"], + }, + ] + }, + "snapshots": { + "height": 150, + "enabled": True, + }, + } + }, + } + frigate_config = FrigateConfig(**config) + assert config == frigate_config.dict(exclude_unset=True) + + runtime_config = frigate_config.runtime_config + assert runtime_config.cameras["back"].snapshots.bounding_box == False + assert runtime_config.cameras["back"].snapshots.height == 150 + assert runtime_config.cameras["back"].snapshots.enabled + if __name__ == "__main__": unittest.main(verbosity=2)