# events ## Purpose Central classifier and persistence layer for everything that happens on the MQTT bus. Subscribes to the whole bus, parses topic paths into `EventType`/`Severity`/`source_id`, writes rows into `events`, evaluates the rule engine against the arm-state FSM, and executes resulting actions (send alert, broadcast system-alert, command all cameras to record). ## Key files - `vigilar/events/processor.py` — `EventProcessor`: subscribes via `bus.subscribe_all`, classifies topics in `_classify_event` (a big if-chain, no routing table), writes via `insert_event`, executes rule actions - `vigilar/events/state.py` — `ArmStateFSM` (HOME/AWAY/NIGHT/DISARMED), publishes `Topics.SYSTEM_ARM_STATE`, persists to `arm_state_log` - `vigilar/events/rules.py` — `RuleEngine` evaluating TOML-configured rules against topic/payload/arm-state - `vigilar/events/history.py` — thin wrapper around `get_events`/`acknowledge_event` ## MQTT topics **Subscribes:** `vigilar/#` (wildcard via `bus.subscribe_all`) **Publishes:** - `vigilar/system/arm_state` (from `ArmStateFSM`) - `vigilar/system/alert` (when a rule fires `alert_all`/`push_and_record`) - `vigilar/camera/{id}/command/record` (per-camera record command for `push_and_record`/`record_all_cameras`) ## Database tables - `events` — canonical event log; every classified message becomes a row - `arm_state_log` — arm-state transitions written by the FSM - `pet_sightings` — inserted when classification produces `PET_DETECTED`, `PET_ESCAPE`, or `UNKNOWN_ANIMAL` - `wildlife_sightings` — inserted for `WILDLIFE_PREDATOR`/`NUISANCE`/`PASSIVE` ## Depends on - Every publisher on the bus (camera, sensors, ups, presence, detection, health, highlights, etc.) - `storage` — uses `vigilar.storage.queries` for all inserts - `alerts` — calls `send_alert` from `vigilar.alerts.sender` when a rule requests it ## Consumed by - `alerts` — triggered indirectly via rule actions - `web` — reads `events` table through `vigilar.storage.queries` for the timeline and SSE stream - `highlights` — consumes the `events` table for reel scoring ## Notes Classification is a hand-written if-chain keyed on the topic path. Camera `heartbeat` and `error` topics are intentionally ignored (return `None`). Person and vehicle YOLO detections ride on `camera/{id}/motion/start` and currently collapse back to a plain `MOTION_START` event — a known artefact of the publishing quirk in the camera worker. Arm-state change messages on `vigilar/system/*` are also deliberately ignored by the classifier to avoid feedback loops.