From d0acf7703c866cc3b640f7b4c59e86347ba26459 Mon Sep 17 00:00:00 2001 From: "Aaron D. Lee" Date: Fri, 3 Apr 2026 13:20:46 -0400 Subject: [PATCH] Handle pet and wildlife events in event processor --- tests/unit/test_events.py | 54 +++++++++++++++++++++++++++++++++++++ vigilar/events/processor.py | 15 +++++++++++ 2 files changed, 69 insertions(+) diff --git a/tests/unit/test_events.py b/tests/unit/test_events.py index aadabee..689ea30 100644 --- a/tests/unit/test_events.py +++ b/tests/unit/test_events.py @@ -327,3 +327,57 @@ class TestEventHistory: assert len(rows_offset) == 2 # Should be different events assert rows[0]["id"] != rows_offset[0]["id"] + + +# --------------------------------------------------------------------------- +# Pet / Wildlife Event Classification +# --------------------------------------------------------------------------- + +class TestPetEventClassification: + def test_pet_detected_event(self): + from vigilar.events.processor import EventProcessor + from vigilar.constants import EventType, Severity + processor = EventProcessor.__new__(EventProcessor) + etype, sev, source = processor._classify_event( + "vigilar/camera/kitchen/pet/detected", + {"pet_name": "Angel", "confidence": 0.92}, + ) + assert etype == EventType.PET_DETECTED + assert sev == Severity.INFO + assert source == "kitchen" + + def test_wildlife_predator_event(self): + from vigilar.events.processor import EventProcessor + from vigilar.constants import EventType, Severity + processor = EventProcessor.__new__(EventProcessor) + etype, sev, source = processor._classify_event( + "vigilar/camera/front/wildlife/detected", + {"species": "bear", "threat_level": "PREDATOR"}, + ) + assert etype == EventType.WILDLIFE_PREDATOR + assert sev == Severity.CRITICAL + assert source == "front" + + def test_wildlife_nuisance_event(self): + from vigilar.events.processor import EventProcessor + from vigilar.constants import EventType, Severity + processor = EventProcessor.__new__(EventProcessor) + etype, sev, source = processor._classify_event( + "vigilar/camera/back/wildlife/detected", + {"species": "raccoon", "threat_level": "NUISANCE"}, + ) + assert etype == EventType.WILDLIFE_NUISANCE + assert sev == Severity.WARNING + assert source == "back" + + def test_wildlife_passive_event(self): + from vigilar.events.processor import EventProcessor + from vigilar.constants import EventType, Severity + processor = EventProcessor.__new__(EventProcessor) + etype, sev, source = processor._classify_event( + "vigilar/camera/front/wildlife/detected", + {"species": "deer", "threat_level": "PASSIVE"}, + ) + assert etype == EventType.WILDLIFE_PASSIVE + assert sev == Severity.INFO + assert source == "front" diff --git a/vigilar/events/processor.py b/vigilar/events/processor.py index 0983aa7..91b33ec 100644 --- a/vigilar/events/processor.py +++ b/vigilar/events/processor.py @@ -127,6 +127,21 @@ class EventProcessor: if suffix in _TOPIC_EVENT_MAP: etype, sev = _TOPIC_EVENT_MAP[suffix] return etype, sev, camera_id + + # Pet detection + if suffix == "pet/detected": + return EventType.PET_DETECTED, Severity.INFO, camera_id + + # Wildlife detection — severity depends on threat_level in payload + if suffix == "wildlife/detected": + threat = payload.get("threat_level", "PASSIVE") + if threat == "PREDATOR": + return EventType.WILDLIFE_PREDATOR, Severity.CRITICAL, camera_id + elif threat == "NUISANCE": + return EventType.WILDLIFE_NUISANCE, Severity.WARNING, camera_id + else: + return EventType.WILDLIFE_PASSIVE, Severity.INFO, camera_id + # Ignore heartbeats etc. return None, None, None