mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-12-23 19:11:14 +01:00
ab50d0b006
* Add isort and ruff linter Both linters are pretty common among modern python code bases. The isort tool provides stable sorting and grouping, as well as pruning of unused imports. Ruff is a modern linter, that is very fast due to being written in rust. It can detect many common issues in a python codebase. Removes the pylint dev requirement, since ruff replaces it. * treewide: fix issues detected by ruff * treewide: fix bare except clauses * .devcontainer: Set up isort * treewide: optimize imports * treewide: apply black * treewide: make regex patterns raw strings This is necessary for escape sequences to be properly recognized.
1542 lines
52 KiB
Python
1542 lines
52 KiB
Python
import json
|
|
import os
|
|
import unittest
|
|
|
|
import numpy as np
|
|
from pydantic import ValidationError
|
|
|
|
from frigate.config import BirdseyeModeEnum, FrigateConfig
|
|
from frigate.const import MODEL_CACHE_DIR
|
|
from frigate.detectors import DetectorTypeEnum
|
|
from frigate.plus import PlusApi
|
|
from frigate.util import deep_merge, load_config_with_no_duplicates
|
|
|
|
|
|
class TestConfig(unittest.TestCase):
|
|
def setUp(self):
|
|
self.minimal = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
self.plus_model_info = {
|
|
"id": "e63b7345cc83a84ed79dedfc99c16616",
|
|
"name": "SSDLite Mobiledet",
|
|
"description": "Fine tuned model",
|
|
"trainDate": "2023-04-28T23:22:01.262Z",
|
|
"type": "ssd",
|
|
"supportedDetectors": ["edgetpu"],
|
|
"width": 320,
|
|
"height": 320,
|
|
"inputShape": "nhwc",
|
|
"pixelFormat": "rgb",
|
|
"labelMap": {
|
|
"0": "amazon",
|
|
"1": "car",
|
|
"2": "cat",
|
|
"3": "deer",
|
|
"4": "dog",
|
|
"5": "face",
|
|
"6": "fedex",
|
|
"7": "license_plate",
|
|
"8": "package",
|
|
"9": "person",
|
|
"10": "ups",
|
|
},
|
|
}
|
|
|
|
if not os.path.exists(MODEL_CACHE_DIR) and not os.path.islink(MODEL_CACHE_DIR):
|
|
os.makedirs(MODEL_CACHE_DIR)
|
|
|
|
def test_config_class(self):
|
|
frigate_config = FrigateConfig(**self.minimal)
|
|
assert self.minimal == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "cpu" in runtime_config.detectors.keys()
|
|
assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu
|
|
assert runtime_config.detectors["cpu"].model.width == 320
|
|
|
|
def test_detector_custom_model_path(self):
|
|
config = {
|
|
"detectors": {
|
|
"cpu": {
|
|
"type": "cpu",
|
|
"model": {"path": "/cpu_model.tflite"},
|
|
},
|
|
"edgetpu": {
|
|
"type": "edgetpu",
|
|
"model": {"path": "/edgetpu_model.tflite", "width": 160},
|
|
},
|
|
"openvino": {
|
|
"type": "openvino",
|
|
},
|
|
},
|
|
# needs to be a file that will exist, doesnt matter what
|
|
"model": {"path": "/etc/hosts", "width": 512},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**(deep_merge(config, self.minimal)))
|
|
runtime_config = frigate_config.runtime_config()
|
|
|
|
assert "cpu" in runtime_config.detectors.keys()
|
|
assert "edgetpu" in runtime_config.detectors.keys()
|
|
assert "openvino" in runtime_config.detectors.keys()
|
|
|
|
assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu
|
|
assert runtime_config.detectors["edgetpu"].type == DetectorTypeEnum.edgetpu
|
|
assert runtime_config.detectors["openvino"].type == DetectorTypeEnum.openvino
|
|
|
|
assert runtime_config.detectors["cpu"].num_threads == 3
|
|
assert runtime_config.detectors["edgetpu"].device is None
|
|
assert runtime_config.detectors["openvino"].device is None
|
|
|
|
assert runtime_config.model.path == "/etc/hosts"
|
|
assert runtime_config.detectors["cpu"].model.path == "/cpu_model.tflite"
|
|
assert runtime_config.detectors["edgetpu"].model.path == "/edgetpu_model.tflite"
|
|
assert runtime_config.detectors["openvino"].model.path == "/etc/hosts"
|
|
|
|
assert runtime_config.model.width == 512
|
|
assert runtime_config.detectors["cpu"].model.width == 512
|
|
assert runtime_config.detectors["edgetpu"].model.width == 160
|
|
assert runtime_config.detectors["openvino"].model.width == 512
|
|
|
|
def test_invalid_mqtt_config(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt", "user": "test"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_inherit_tracked_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "dog" in runtime_config.cameras["back"].objects.track
|
|
|
|
def test_override_birdseye(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"birdseye": {"enabled": False, "mode": "motion"},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert not runtime_config.cameras["back"].birdseye.enabled
|
|
assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion
|
|
|
|
def test_override_birdseye_non_inheritable(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous", "height": 1920},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].birdseye.enabled
|
|
|
|
def test_inherit_birdseye(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"birdseye": {"enabled": True, "mode": "continuous"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].birdseye.enabled
|
|
assert (
|
|
runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous
|
|
)
|
|
|
|
def test_override_tracked_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {"track": ["cat"]},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "cat" in runtime_config.cameras["back"].objects.track
|
|
|
|
def test_default_object_filters(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
|
|
def test_inherit_object_filters(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7
|
|
|
|
def test_override_object_filters(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7
|
|
|
|
def test_global_object_mask(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"mask": "0,0,1,1,0,1",
|
|
"filters": {"dog": {"mask": "1,1,1,1,1,1"}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
back_camera = runtime_config.cameras["back"]
|
|
assert "dog" in back_camera.objects.filters
|
|
assert len(back_camera.objects.filters["dog"].raw_mask) == 2
|
|
assert len(back_camera.objects.filters["person"].raw_mask) == 1
|
|
|
|
def test_default_input_args(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "-rtsp_transport" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_global(self):
|
|
config = {
|
|
"ffmpeg": {"input_args": "-re"},
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_camera(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"ffmpeg": {"input_args": ["test"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
],
|
|
"input_args": ["-re"],
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_ffmpeg_params_input(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"ffmpeg": {"input_args": ["test2"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
"input_args": "-re test",
|
|
}
|
|
],
|
|
"input_args": "test3",
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"threshold": 0.7}},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test2" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
assert "test3" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
|
|
|
|
def test_inherit_clips_retention(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert (
|
|
runtime_config.cameras["back"].record.events.retain.objects["person"] == 30
|
|
)
|
|
|
|
def test_roles_listed_twice_throws_error(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]},
|
|
{"path": "rtsp://10.0.0.1:554/video2", "roles": ["detect"]},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_zone_matching_camera_name_throws_error(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"zones": {"back": {"coordinates": "1,1,1,1,1,1"}},
|
|
}
|
|
},
|
|
}
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_zone_assigns_color_and_contour(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"zones": {"test": {"coordinates": "1,1,1,1,1,1"}},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert isinstance(
|
|
runtime_config.cameras["back"].zones["test"].contour, np.ndarray
|
|
)
|
|
assert runtime_config.cameras["back"].zones["test"].color != (0, 0, 0)
|
|
|
|
def test_clips_should_default_to_global_objects(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {
|
|
"events": {"retain": {"default": 20, "objects": {"person": 30}}}
|
|
},
|
|
"objects": {"track": ["person", "dog"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"record": {"events": {}},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
back_camera = runtime_config.cameras["back"]
|
|
assert back_camera.record.events.objects is None
|
|
assert back_camera.record.events.retain.objects["person"] == 30
|
|
|
|
def test_role_assigned_but_not_enabled(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect", "rtmp"],
|
|
},
|
|
{"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
ffmpeg_cmds = runtime_config.cameras["back"].ffmpeg_cmds
|
|
assert len(ffmpeg_cmds) == 1
|
|
assert "clips" not in ffmpeg_cmds[0]["roles"]
|
|
|
|
def test_max_disappeared_default(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"enabled": True,
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 5 * 5
|
|
|
|
def test_motion_frame_height_wont_go_below_120(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].motion.frame_height == 50
|
|
|
|
def test_motion_contour_area_dynamic(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert round(runtime_config.cameras["back"].motion.contour_area) == 30
|
|
|
|
def test_merge_labelmap(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"model": {"labelmap": {7: "truck"}},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.model.merged_labelmap[7] == "truck"
|
|
|
|
def test_default_labelmap_empty(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.model.merged_labelmap[0] == "person"
|
|
|
|
def test_default_labelmap(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"model": {"width": 320, "height": 320},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.model.merged_labelmap[0] == "person"
|
|
|
|
def test_plus_labelmap(self):
|
|
with open("/config/model_cache/test", "w") as f:
|
|
json.dump(self.plus_model_info, f)
|
|
with open("/config/model_cache/test.json", "w") as f:
|
|
json.dump(self.plus_model_info, f)
|
|
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"model": {"path": "plus://test"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config(PlusApi())
|
|
assert runtime_config.model.merged_labelmap[0] == "amazon"
|
|
|
|
def test_fails_on_invalid_role(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["clips"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
self.assertRaises(ValidationError, lambda: FrigateConfig(**config))
|
|
|
|
def test_fails_on_missing_role(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
"rtmp": {"enabled": True},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
self.assertRaises(ValueError, lambda: frigate_config.runtime_config())
|
|
|
|
def test_works_on_missing_role_multiple_cams(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
},
|
|
"cam2": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
frigate_config.runtime_config()
|
|
|
|
def test_global_detect(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"detect": {"max_disappeared": 1},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 1
|
|
assert runtime_config.cameras["back"].detect.height == 1080
|
|
|
|
def test_default_detect(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"].detect.max_disappeared == 25
|
|
assert runtime_config.cameras["back"].detect.height == 720
|
|
|
|
def test_global_detect_merge(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"detect": {"max_disappeared": 1, "height": 720},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].detect.max_disappeared == 1
|
|
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 is False
|
|
assert runtime_config.cameras["back"].snapshots.height == 150
|
|
assert runtime_config.cameras["back"].snapshots.enabled
|
|
|
|
def test_global_rtmp_disabled(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 not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_default_not_rtmp(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 not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_global_rtmp_merge(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"rtmp": {"enabled": False},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect", "rtmp"],
|
|
},
|
|
]
|
|
},
|
|
"rtmp": {
|
|
"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"].rtmp.enabled
|
|
|
|
def test_global_rtmp_default(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video2",
|
|
"roles": ["record"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert not runtime_config.cameras["back"].rtmp.enabled
|
|
|
|
def test_global_jsmpeg(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"live": {"quality": 4},
|
|
"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"].live.quality == 4
|
|
|
|
def test_default_live(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"].live.quality == 8
|
|
|
|
def test_global_live_merge(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"live": {"quality": 4, "height": 480},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"live": {
|
|
"quality": 7,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].live.quality == 7
|
|
assert runtime_config.cameras["back"].live.height == 480
|
|
|
|
def test_global_timestamp_style(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"timestamp_style": {"position": "bl"},
|
|
"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"].timestamp_style.position == "bl"
|
|
|
|
def test_default_timestamp_style(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"].timestamp_style.position == "tl"
|
|
|
|
def test_global_timestamp_style_merge(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"rtmp": {"enabled": False},
|
|
"timestamp_style": {"position": "br", "thickness": 2},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"timestamp_style": {"position": "bl", "thickness": 4},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert runtime_config.cameras["back"].timestamp_style.position == "bl"
|
|
assert runtime_config.cameras["back"].timestamp_style.thickness == 4
|
|
|
|
def test_allow_retain_to_be_a_decimal(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"retain": {"default": 1.5}},
|
|
"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.retain.default == 1.5
|
|
|
|
def test_fails_on_bad_camera_name(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"snapshots": {"retain": {"default": 1.5}},
|
|
"cameras": {
|
|
"back camer#": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
|
|
self.assertRaises(
|
|
ValidationError, lambda: frigate_config.runtime_config().cameras
|
|
)
|
|
|
|
def test_fails_on_bad_segment_time(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"record": {"enabled": True},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"output_args": {
|
|
"record": "-f segment -segment_time 70 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an"
|
|
},
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
],
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
|
|
self.assertRaises(
|
|
ValueError,
|
|
lambda: frigate_config.runtime_config().ffmpeg.output_args.record,
|
|
)
|
|
|
|
def test_fails_zone_defines_untracked_object(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {"track": ["person"]},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{
|
|
"path": "rtsp://10.0.0.1:554/video",
|
|
"roles": ["detect"],
|
|
},
|
|
]
|
|
},
|
|
"zones": {
|
|
"steps": {
|
|
"coordinates": "0,0,0,0",
|
|
"objects": ["car", "person"],
|
|
},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
|
|
frigate_config = FrigateConfig(**config)
|
|
|
|
self.assertRaises(ValueError, lambda: frigate_config.runtime_config().cameras)
|
|
|
|
def test_fails_duplicate_keys(self):
|
|
raw_config = """
|
|
cameras:
|
|
test:
|
|
ffmpeg:
|
|
inputs:
|
|
- one
|
|
- two
|
|
inputs:
|
|
- three
|
|
- four
|
|
"""
|
|
|
|
self.assertRaises(
|
|
ValueError, lambda: load_config_with_no_duplicates(raw_config)
|
|
)
|
|
|
|
def test_object_filter_ratios_work(self):
|
|
config = {
|
|
"mqtt": {"host": "mqtt"},
|
|
"objects": {
|
|
"track": ["person", "dog"],
|
|
"filters": {"dog": {"min_ratio": 0.2, "max_ratio": 10.1}},
|
|
},
|
|
"cameras": {
|
|
"back": {
|
|
"ffmpeg": {
|
|
"inputs": [
|
|
{"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
|
|
]
|
|
},
|
|
"detect": {
|
|
"height": 1080,
|
|
"width": 1920,
|
|
"fps": 5,
|
|
},
|
|
}
|
|
},
|
|
}
|
|
frigate_config = FrigateConfig(**config)
|
|
assert config == frigate_config.dict(exclude_unset=True)
|
|
|
|
runtime_config = frigate_config.runtime_config()
|
|
assert "dog" in runtime_config.cameras["back"].objects.filters
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].min_ratio == 0.2
|
|
assert runtime_config.cameras["back"].objects.filters["dog"].max_ratio == 10.1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|