diff --git a/tests/unit/test_profiles.py b/tests/unit/test_profiles.py index 1bf5362..0d2af03 100644 --- a/tests/unit/test_profiles.py +++ b/tests/unit/test_profiles.py @@ -75,3 +75,56 @@ class TestActionForEvent: action, recipients = get_action_for_event(profile, "person", "front_door") assert action == "quiet_log" assert recipients == "none" + + +class TestPetAlertRouting: + def test_known_pet_exterior_gets_push(self): + rules = [ + AlertProfileRule(detection_type="known_pet", camera_location="EXTERIOR", + action="push_and_record", recipients="all"), + AlertProfileRule(detection_type="known_pet", camera_location="INTERIOR", + action="quiet_log", recipients="none"), + ] + profile = _make_profile("Away", ["EMPTY"], rules=rules) + action, recipients = get_action_for_event(profile, "known_pet", "front_entrance", + camera_location="EXTERIOR") + assert action == "push_and_record" + + def test_known_pet_interior_gets_quiet_log(self): + rules = [ + AlertProfileRule(detection_type="known_pet", camera_location="EXTERIOR", + action="push_and_record", recipients="all"), + AlertProfileRule(detection_type="known_pet", camera_location="INTERIOR", + action="quiet_log", recipients="none"), + ] + profile = _make_profile("Home", ["ALL_HOME"], rules=rules) + action, recipients = get_action_for_event(profile, "known_pet", "kitchen", + camera_location="INTERIOR") + assert action == "quiet_log" + + def test_wildlife_predator_gets_urgent(self): + rules = [ + AlertProfileRule(detection_type="wildlife_predator", + action="push_and_record", recipients="all"), + ] + profile = _make_profile("Always", ["EMPTY", "ALL_HOME"], rules=rules) + action, _ = get_action_for_event(profile, "wildlife_predator", "front", + camera_location="EXTERIOR") + assert action == "push_and_record" + + def test_camera_location_any_matches_all(self): + rules = [ + AlertProfileRule(detection_type="wildlife_predator", camera_location="any", + action="push_and_record", recipients="all"), + ] + profile = _make_profile("Always", ["EMPTY"], rules=rules) + action, _ = get_action_for_event(profile, "wildlife_predator", "kitchen", + camera_location="INTERIOR") + assert action == "push_and_record" + + def test_backward_compatible_without_camera_location(self): + """Existing calls without camera_location still work.""" + rules = [AlertProfileRule(detection_type="person", action="push_and_record", recipients="all")] + profile = _make_profile("Away", ["EMPTY"], rules=rules) + action, _ = get_action_for_event(profile, "person", "front_door") + assert action == "push_and_record" diff --git a/vigilar/alerts/profiles.py b/vigilar/alerts/profiles.py index e1e1460..8307f2d 100644 --- a/vigilar/alerts/profiles.py +++ b/vigilar/alerts/profiles.py @@ -46,11 +46,19 @@ def get_action_for_event( profile: AlertProfileConfig, detection_type: str, camera_id: str, + camera_location: str | None = None, ) -> tuple[str, str]: for rule in profile.rules: if rule.detection_type != detection_type: continue - if rule.camera_location not in ("any", camera_id): - continue - return rule.action, rule.recipients + # Check camera_location match + if rule.camera_location == "any": + return rule.action, rule.recipients + if rule.camera_location == camera_id: + return rule.action, rule.recipients + if camera_location and rule.camera_location == camera_location: + return rule.action, rule.recipients + if not camera_location and rule.camera_location == "any": + return rule.action, rule.recipients + continue return "quiet_log", "none"