mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-01 04:16:50 +03:00
Improve report context management
This commit is contained in:
@@ -310,7 +310,7 @@ class ReviewDescriptionProcessor(PostProcessorApi):
|
|||||||
primary_end = primary_seg["end_time"]
|
primary_end = primary_seg["end_time"]
|
||||||
primary_camera = primary_seg["camera"]
|
primary_camera = primary_seg["camera"]
|
||||||
contextual_items = []
|
contextual_items = []
|
||||||
contextual_by_camera: dict[str, dict[str, Any]] = {}
|
seen_contextual_cameras = set()
|
||||||
|
|
||||||
for seg in segments:
|
for seg in segments:
|
||||||
seg_camera = seg["camera"]
|
seg_camera = seg["camera"]
|
||||||
@@ -326,14 +326,12 @@ class ReviewDescriptionProcessor(PostProcessorApi):
|
|||||||
|
|
||||||
if seg_start < primary_end and primary_start < seg_end:
|
if seg_start < primary_end and primary_start < seg_end:
|
||||||
# Avoid duplicates if same camera has multiple overlapping
|
# Avoid duplicates if same camera has multiple overlapping
|
||||||
# segments, but keep every segment's state changes
|
# segments. One with state changes is kept as its own item
|
||||||
existing_item = contextual_by_camera.get(seg_camera)
|
# so each change stays within its item's time range.
|
||||||
|
if (
|
||||||
if existing_item is not None:
|
seg_camera in seen_contextual_cameras
|
||||||
if seg["state_changes"]:
|
and not seg["state_changes"]
|
||||||
existing_item.setdefault("state_changes", []).extend(
|
):
|
||||||
seg["state_changes"]
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
contextual_item = copy.deepcopy(seg["metadata"])
|
contextual_item = copy.deepcopy(seg["metadata"])
|
||||||
@@ -342,12 +340,10 @@ class ReviewDescriptionProcessor(PostProcessorApi):
|
|||||||
contextual_item["end_time"] = seg_end
|
contextual_item["end_time"] = seg_end
|
||||||
|
|
||||||
if seg["state_changes"]:
|
if seg["state_changes"]:
|
||||||
contextual_item["state_changes"] = list(
|
contextual_item["state_changes"] = seg["state_changes"]
|
||||||
seg["state_changes"]
|
|
||||||
)
|
|
||||||
|
|
||||||
contextual_items.append(contextual_item)
|
contextual_items.append(contextual_item)
|
||||||
contextual_by_camera[seg_camera] = contextual_item
|
seen_contextual_cameras.add(seg_camera)
|
||||||
|
|
||||||
# Add context array to primary item
|
# Add context array to primary item
|
||||||
primary_item["context"] = contextual_items
|
primary_item["context"] = contextual_items
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ class TestSummaryContext(unittest.TestCase):
|
|||||||
|
|
||||||
return client.generate_review_summary.call_args.args[2]
|
return client.generate_review_summary.call_args.args[2]
|
||||||
|
|
||||||
def test_overlapping_context_reviews_keep_all_state_changes(self):
|
def test_context_state_changes_stay_with_their_review(self):
|
||||||
events = self.summarize(
|
events = self.summarize(
|
||||||
[
|
[
|
||||||
self.row("front_door", 10, 60, 1),
|
self.row("front_door", 10, 60, 1),
|
||||||
@@ -230,29 +230,28 @@ class TestSummaryContext(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
[
|
||||||
|
(item["start_time"], item["end_time"], item["state_changes"])
|
||||||
|
for item in events[0]["context"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
(15, 25, ["front gate changed from closed to open"]),
|
||||||
|
(30, 40, ["front gate changed from open to closed"]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_later_context_review_without_changes_is_deduplicated(self):
|
||||||
|
events = self.summarize(
|
||||||
|
[
|
||||||
|
self.row("front_door", 10, 60, 1),
|
||||||
|
self.row("driveway", 15, 25, 0, [gate_change(20.0)]),
|
||||||
|
self.row("driveway", 30, 40, 0),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
self.assertEqual(len(events[0]["context"]), 1)
|
self.assertEqual(len(events[0]["context"]), 1)
|
||||||
self.assertEqual(
|
self.assertEqual(events[0]["context"][0]["start_time"], 15)
|
||||||
events[0]["context"][0]["state_changes"],
|
|
||||||
[
|
|
||||||
"front gate changed from closed to open",
|
|
||||||
"front gate changed from open to closed",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_merging_context_does_not_leak_between_primary_events(self):
|
|
||||||
events = self.summarize(
|
|
||||||
[
|
|
||||||
self.row("front_door", 10, 60, 1),
|
|
||||||
self.row("back_door", 12, 22, 1),
|
|
||||||
self.row("driveway", 15, 25, 0, [gate_change(20.0)]),
|
|
||||||
self.row("driveway", 30, 40, 0, [gate_change(35.0, "open", "closed")]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
events[1]["context"][0]["state_changes"],
|
|
||||||
["front gate changed from closed to open"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user