feat(F1): integrate Web Push notifications into event processor
Import send_alert into processor.py, store engine as self._engine after init_db(), extend _execute_action() to accept event_type/severity/source_id and call send_alert for alert_all and push_and_record actions, and pass those params from _handle_event(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2c79e0c044
commit
f33b82cc83
35
tests/unit/test_processor_alerts.py
Normal file
35
tests/unit/test_processor_alerts.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"""Test that event processor calls send_alert for alert actions."""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
from vigilar.config import VigilarConfig
|
||||||
|
from vigilar.events.processor import EventProcessor
|
||||||
|
|
||||||
|
|
||||||
|
def test_execute_action_calls_send_alert():
|
||||||
|
cfg = VigilarConfig()
|
||||||
|
processor = EventProcessor(cfg)
|
||||||
|
processor._engine = MagicMock()
|
||||||
|
mock_bus = MagicMock()
|
||||||
|
|
||||||
|
with patch("vigilar.events.processor.send_alert") as mock_send:
|
||||||
|
processor._execute_action(
|
||||||
|
action="alert_all", event_id=42, bus=mock_bus,
|
||||||
|
payload={"species": "bear"},
|
||||||
|
event_type="WILDLIFE_PREDATOR", severity="CRITICAL", source_id="front",
|
||||||
|
)
|
||||||
|
mock_send.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
def test_execute_action_push_and_record():
|
||||||
|
cfg = VigilarConfig()
|
||||||
|
processor = EventProcessor(cfg)
|
||||||
|
processor._engine = MagicMock()
|
||||||
|
mock_bus = MagicMock()
|
||||||
|
|
||||||
|
with patch("vigilar.events.processor.send_alert") as mock_send:
|
||||||
|
processor._execute_action(
|
||||||
|
action="push_and_record", event_id=10, bus=mock_bus,
|
||||||
|
payload={}, event_type="PERSON_DETECTED", severity="WARNING", source_id="cam1",
|
||||||
|
)
|
||||||
|
mock_send.assert_called_once()
|
||||||
@ -13,6 +13,7 @@ from vigilar.constants import EventType, Severity, Topics
|
|||||||
from vigilar.events.rules import RuleEngine
|
from vigilar.events.rules import RuleEngine
|
||||||
from vigilar.events.state import ArmStateFSM
|
from vigilar.events.state import ArmStateFSM
|
||||||
from vigilar.storage.db import get_db_path, init_db
|
from vigilar.storage.db import get_db_path, init_db
|
||||||
|
from vigilar.alerts.sender import send_alert
|
||||||
from vigilar.storage.queries import insert_event
|
from vigilar.storage.queries import insert_event
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -46,6 +47,7 @@ class EventProcessor:
|
|||||||
# Init DB
|
# Init DB
|
||||||
db_path = get_db_path(self._config.system.data_dir)
|
db_path = get_db_path(self._config.system.data_dir)
|
||||||
engine = init_db(db_path)
|
engine = init_db(db_path)
|
||||||
|
self._engine = engine
|
||||||
|
|
||||||
# Init components
|
# Init components
|
||||||
fsm = ArmStateFSM(engine, self._config)
|
fsm = ArmStateFSM(engine, self._config)
|
||||||
@ -134,7 +136,10 @@ class EventProcessor:
|
|||||||
|
|
||||||
# Execute actions
|
# Execute actions
|
||||||
for action in actions:
|
for action in actions:
|
||||||
self._execute_action(action, event_id, bus, payload)
|
self._execute_action(
|
||||||
|
action, event_id, bus, payload,
|
||||||
|
event_type=event_type, severity=severity, source_id=source_id,
|
||||||
|
)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Error processing event on %s", topic)
|
log.exception("Error processing event on %s", topic)
|
||||||
@ -217,18 +222,35 @@ class EventProcessor:
|
|||||||
event_id: int,
|
event_id: int,
|
||||||
bus: MessageBus,
|
bus: MessageBus,
|
||||||
payload: dict[str, Any],
|
payload: dict[str, Any],
|
||||||
|
event_type: str = "",
|
||||||
|
severity: str = "",
|
||||||
|
source_id: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Execute a rule action."""
|
"""Execute a rule action."""
|
||||||
log.info("Executing action: %s (event_id=%d)", action, event_id)
|
log.info("Executing action: %s (event_id=%d)", action, event_id)
|
||||||
|
|
||||||
if action == "alert_all":
|
if action in ("alert_all", "push_and_record"):
|
||||||
|
try:
|
||||||
|
send_alert(
|
||||||
|
engine=self._engine,
|
||||||
|
event_type=event_type,
|
||||||
|
severity=severity,
|
||||||
|
source_id=source_id,
|
||||||
|
payload=payload,
|
||||||
|
config=self._config,
|
||||||
|
event_id=event_id,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
log.exception("Failed to send alert for event %d", event_id)
|
||||||
|
|
||||||
bus.publish(Topics.SYSTEM_ALERT, {
|
bus.publish(Topics.SYSTEM_ALERT, {
|
||||||
"ts": int(time.time() * 1000),
|
"ts": int(time.time() * 1000),
|
||||||
"event_id": event_id,
|
"event_id": event_id,
|
||||||
"type": "alert",
|
"type": "alert",
|
||||||
"payload": payload,
|
"payload": payload,
|
||||||
})
|
})
|
||||||
elif action == "record_all_cameras":
|
|
||||||
|
if action in ("push_and_record", "record_all_cameras"):
|
||||||
# Publish a command for each configured camera to start recording
|
# Publish a command for each configured camera to start recording
|
||||||
for cam in self._config.cameras:
|
for cam in self._config.cameras:
|
||||||
bus.publish(f"vigilar/camera/{cam.id}/command/record", {
|
bus.publish(f"vigilar/camera/{cam.id}/command/record", {
|
||||||
@ -236,5 +258,3 @@ class EventProcessor:
|
|||||||
"event_id": event_id,
|
"event_id": event_id,
|
||||||
"action": "start_recording",
|
"action": "start_recording",
|
||||||
})
|
})
|
||||||
else:
|
|
||||||
log.warning("Unknown action: %s", action)
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user