From 58622722c77bd00e002443a263a8286aaa1d4de4 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sun, 5 Apr 2026 09:47:35 -0400 Subject: [PATCH] docs: add presence subsystem reference --- docs/architecture/subsystems/presence.md | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/architecture/subsystems/presence.md diff --git a/docs/architecture/subsystems/presence.md b/docs/architecture/subsystems/presence.md new file mode 100644 index 0000000..bc2f389 --- /dev/null +++ b/docs/architecture/subsystems/presence.md @@ -0,0 +1,36 @@ +# presence + +## Purpose + +Tracks whether household members are home by ICMP-pinging their phones on the LAN at a fixed interval. Derives an overall household state (EMPTY, OCCUPIED, etc.) from per-member presence and publishes both to MQTT so the rule engine and arm-state FSM can react. + +## Key files + +- `vigilar/presence/monitor.py` — `PresenceMonitor`: ping loop, per-member state machine with `departure_delay_m` grace period, publishes per-member and household-level topics +- `vigilar/presence/models.py` — `MemberPresence` dataclass and `derive_household_state` aggregator +- `vigilar/presence/__init__.py` + +## MQTT topics + +**Subscribes:** none +**Publishes:** +- `vigilar/presence/{name}` — per-member status (`HOME` or `AWAY`, plus role) +- `vigilar/presence/status` — aggregated household state and a `{name: HOME|AWAY}` map + +## Database tables + +none — presence state lives only in memory and on the bus. + +## Depends on + +- LAN reachability of configured `[presence.members]` IPs +- `ping` binary on the host + +## Consumed by + +- `events` — rules and the arm-state FSM react to household state changes +- `alerts` — smart alert profile matcher in `vigilar/alerts/profiles.py` branches on `HouseholdState` + +## Notes + +A member is marked HOME the moment a ping succeeds, but only marked AWAY after `departure_delay_m` minutes without a successful ping — this prevents a single dropped reply from flipping the household state. The monitor uses `time.monotonic()` for the grace window, so it is immune to wall-clock jumps. Per-member and household topics are republished every poll, not only on transitions, so late subscribers always get current state.