test_config.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. import json
  2. from unittest import TestCase, main
  3. import voluptuous as vol
  4. from frigate.config import FRIGATE_CONFIG_SCHEMA, FrigateConfig
  5. class TestConfig(TestCase):
  6. def setUp(self):
  7. self.minimal = {
  8. "mqtt": {"host": "mqtt"},
  9. "cameras": {
  10. "back": {
  11. "ffmpeg": {
  12. "inputs": [
  13. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  14. ]
  15. },
  16. "height": 1080,
  17. "width": 1920,
  18. }
  19. },
  20. }
  21. def test_empty(self):
  22. FRIGATE_CONFIG_SCHEMA({})
  23. def test_minimal(self):
  24. FRIGATE_CONFIG_SCHEMA(self.minimal)
  25. def test_config_class(self):
  26. FrigateConfig(config=self.minimal)
  27. def test_inherit_tracked_objects(self):
  28. config = {
  29. "mqtt": {"host": "mqtt"},
  30. "objects": {"track": ["person", "dog"]},
  31. "cameras": {
  32. "back": {
  33. "ffmpeg": {
  34. "inputs": [
  35. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  36. ]
  37. },
  38. "height": 1080,
  39. "width": 1920,
  40. }
  41. },
  42. }
  43. frigate_config = FrigateConfig(config=config)
  44. assert "dog" in frigate_config.cameras["back"].objects.track
  45. def test_override_tracked_objects(self):
  46. config = {
  47. "mqtt": {"host": "mqtt"},
  48. "objects": {"track": ["person", "dog"]},
  49. "cameras": {
  50. "back": {
  51. "ffmpeg": {
  52. "inputs": [
  53. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  54. ]
  55. },
  56. "height": 1080,
  57. "width": 1920,
  58. "objects": {"track": ["cat"]},
  59. }
  60. },
  61. }
  62. frigate_config = FrigateConfig(config=config)
  63. assert "cat" in frigate_config.cameras["back"].objects.track
  64. def test_default_object_filters(self):
  65. config = {
  66. "mqtt": {"host": "mqtt"},
  67. "objects": {"track": ["person", "dog"]},
  68. "cameras": {
  69. "back": {
  70. "ffmpeg": {
  71. "inputs": [
  72. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  73. ]
  74. },
  75. "height": 1080,
  76. "width": 1920,
  77. }
  78. },
  79. }
  80. frigate_config = FrigateConfig(config=config)
  81. assert "dog" in frigate_config.cameras["back"].objects.filters
  82. def test_inherit_object_filters(self):
  83. config = {
  84. "mqtt": {"host": "mqtt"},
  85. "objects": {
  86. "track": ["person", "dog"],
  87. "filters": {"dog": {"threshold": 0.7}},
  88. },
  89. "cameras": {
  90. "back": {
  91. "ffmpeg": {
  92. "inputs": [
  93. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  94. ]
  95. },
  96. "height": 1080,
  97. "width": 1920,
  98. }
  99. },
  100. }
  101. frigate_config = FrigateConfig(config=config)
  102. assert "dog" in frigate_config.cameras["back"].objects.filters
  103. assert frigate_config.cameras["back"].objects.filters["dog"].threshold == 0.7
  104. def test_override_object_filters(self):
  105. config = {
  106. "mqtt": {"host": "mqtt"},
  107. "cameras": {
  108. "back": {
  109. "ffmpeg": {
  110. "inputs": [
  111. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  112. ]
  113. },
  114. "height": 1080,
  115. "width": 1920,
  116. "objects": {
  117. "track": ["person", "dog"],
  118. "filters": {"dog": {"threshold": 0.7}},
  119. },
  120. }
  121. },
  122. }
  123. frigate_config = FrigateConfig(config=config)
  124. assert "dog" in frigate_config.cameras["back"].objects.filters
  125. assert frigate_config.cameras["back"].objects.filters["dog"].threshold == 0.7
  126. def test_global_object_mask(self):
  127. config = {
  128. "mqtt": {"host": "mqtt"},
  129. "objects": {"track": ["person", "dog"]},
  130. "cameras": {
  131. "back": {
  132. "ffmpeg": {
  133. "inputs": [
  134. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  135. ]
  136. },
  137. "height": 1080,
  138. "width": 1920,
  139. "objects": {
  140. "mask": "0,0,1,1,0,1",
  141. "filters": {"dog": {"mask": "1,1,1,1,1,1"}},
  142. },
  143. }
  144. },
  145. }
  146. frigate_config = FrigateConfig(config=config)
  147. assert "dog" in frigate_config.cameras["back"].objects.filters
  148. assert len(frigate_config.cameras["back"].objects.filters["dog"]._raw_mask) == 2
  149. assert (
  150. len(frigate_config.cameras["back"].objects.filters["person"]._raw_mask) == 1
  151. )
  152. def test_ffmpeg_params_global(self):
  153. config = {
  154. "ffmpeg": {"input_args": ["-re"]},
  155. "mqtt": {"host": "mqtt"},
  156. "cameras": {
  157. "back": {
  158. "ffmpeg": {
  159. "inputs": [
  160. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  161. ]
  162. },
  163. "height": 1080,
  164. "width": 1920,
  165. "objects": {
  166. "track": ["person", "dog"],
  167. "filters": {"dog": {"threshold": 0.7}},
  168. },
  169. }
  170. },
  171. }
  172. frigate_config = FrigateConfig(config=config)
  173. assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
  174. def test_ffmpeg_params_camera(self):
  175. config = {
  176. "mqtt": {"host": "mqtt"},
  177. "cameras": {
  178. "back": {
  179. "ffmpeg": {
  180. "inputs": [
  181. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  182. ],
  183. "input_args": ["-re"],
  184. },
  185. "height": 1080,
  186. "width": 1920,
  187. "objects": {
  188. "track": ["person", "dog"],
  189. "filters": {"dog": {"threshold": 0.7}},
  190. },
  191. }
  192. },
  193. }
  194. frigate_config = FrigateConfig(config=config)
  195. assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
  196. def test_ffmpeg_params_input(self):
  197. config = {
  198. "mqtt": {"host": "mqtt"},
  199. "cameras": {
  200. "back": {
  201. "ffmpeg": {
  202. "inputs": [
  203. {
  204. "path": "rtsp://10.0.0.1:554/video",
  205. "roles": ["detect"],
  206. "input_args": ["-re"],
  207. }
  208. ]
  209. },
  210. "height": 1080,
  211. "width": 1920,
  212. "objects": {
  213. "track": ["person", "dog"],
  214. "filters": {"dog": {"threshold": 0.7}},
  215. },
  216. }
  217. },
  218. }
  219. frigate_config = FrigateConfig(config=config)
  220. assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]
  221. def test_inherit_clips_retention(self):
  222. config = {
  223. "mqtt": {"host": "mqtt"},
  224. "clips": {"retain": {"default": 20, "objects": {"person": 30}}},
  225. "cameras": {
  226. "back": {
  227. "ffmpeg": {
  228. "inputs": [
  229. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  230. ]
  231. },
  232. "height": 1080,
  233. "width": 1920,
  234. }
  235. },
  236. }
  237. frigate_config = FrigateConfig(config=config)
  238. assert frigate_config.cameras["back"].clips.retain.objects["person"] == 30
  239. def test_roles_listed_twice_throws_error(self):
  240. config = {
  241. "mqtt": {"host": "mqtt"},
  242. "clips": {"retain": {"default": 20, "objects": {"person": 30}}},
  243. "cameras": {
  244. "back": {
  245. "ffmpeg": {
  246. "inputs": [
  247. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]},
  248. {"path": "rtsp://10.0.0.1:554/video2", "roles": ["detect"]},
  249. ]
  250. },
  251. "height": 1080,
  252. "width": 1920,
  253. }
  254. },
  255. }
  256. self.assertRaises(vol.MultipleInvalid, lambda: FrigateConfig(config=config))
  257. def test_zone_matching_camera_name_throws_error(self):
  258. config = {
  259. "mqtt": {"host": "mqtt"},
  260. "clips": {"retain": {"default": 20, "objects": {"person": 30}}},
  261. "cameras": {
  262. "back": {
  263. "ffmpeg": {
  264. "inputs": [
  265. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  266. ]
  267. },
  268. "height": 1080,
  269. "width": 1920,
  270. "zones": {"back": {"coordinates": "1,1,1,1,1,1"}},
  271. }
  272. },
  273. }
  274. self.assertRaises(vol.MultipleInvalid, lambda: FrigateConfig(config=config))
  275. def test_clips_should_default_to_global_objects(self):
  276. config = {
  277. "mqtt": {"host": "mqtt"},
  278. "clips": {"retain": {"default": 20, "objects": {"person": 30}}},
  279. "objects": {"track": ["person", "dog"]},
  280. "cameras": {
  281. "back": {
  282. "ffmpeg": {
  283. "inputs": [
  284. {"path": "rtsp://10.0.0.1:554/video", "roles": ["detect"]}
  285. ]
  286. },
  287. "height": 1080,
  288. "width": 1920,
  289. "clips": {"enabled": True},
  290. }
  291. },
  292. }
  293. config = FrigateConfig(config=config)
  294. assert config.cameras["back"].clips.objects is None
  295. def test_role_assigned_but_not_enabled(self):
  296. json_config = {
  297. "mqtt": {"host": "mqtt"},
  298. "cameras": {
  299. "back": {
  300. "ffmpeg": {
  301. "inputs": [
  302. {
  303. "path": "rtsp://10.0.0.1:554/video",
  304. "roles": ["detect", "rtmp"],
  305. },
  306. {"path": "rtsp://10.0.0.1:554/record", "roles": ["record"]},
  307. ]
  308. },
  309. "height": 1080,
  310. "width": 1920,
  311. }
  312. },
  313. }
  314. config = FrigateConfig(config=json_config)
  315. ffmpeg_cmds = config.cameras["back"].ffmpeg_cmds
  316. assert len(ffmpeg_cmds) == 1
  317. assert not "clips" in ffmpeg_cmds[0]["roles"]
  318. if __name__ == "__main__":
  319. main(verbosity=2)