Add presence daemon user documentation and architecture guide

This commit is contained in:
Cobra
2026-04-10 14:55:13 -04:00
parent fd014b2a38
commit 09b81deb45
+202
View File
@@ -0,0 +1,202 @@
# Presence Daemon — Person Presence Intelligence
Passive multi-signal WiFi/ARP/DHCP/BLE person presence tracking daemon for BigBrother drop implant.
## Quick Start
```bash
cd /home/n0mad1k/tools/bigbrother/presence
sudo bash install.sh
```
This creates `/opt/sensor/sensor.py`, initializes the database, and starts the systemd service.
## Configuration
Environment variables:
- `PRESENCE_MONITOR_IFACE` — WiFi monitor mode interface (default: wlan1)
- `PRESENCE_DATA_IFACE` — Connected network interface for ARP/DHCP (default: wlan0)
- `PRESENCE_DB_PATH` — SQLite database location (default: /opt/presence/presence.db)
- `PRESENCE_MATRIX_WEBHOOK` — Matrix webhook URL for alerts (default: empty, no alerts)
Example systemd override:
```bash
sudo systemctl edit sensor
# Add to [Service] section:
# Environment=PRESENCE_MONITOR_IFACE=wlan2
# Environment=PRESENCE_MATRIX_WEBHOOK=https://matrix.example.com/hook/...
```
## Architecture
### Sensor Threads (4 concurrent)
1. **Probe Sniffer** — WiFi probe request capture on monitor interface
- Passive 802.11 frame parsing (type 0, subtype 4)
- Extracts source MAC → +0.60 certainty bump
- Runs on PRESENCE_MONITOR_IFACE
2. **ARP Listener** — netlink RTM_NEWNEIGH/RTM_DELNEIGH events
- Kernel neighbor discovery events
- Filters infrastructure IPs
- Extracts MAC → +0.50 certainty bump
3. **DHCP Sniffer** — AF_PACKET raw socket on data interface
- Captures DHCP DISCOVER/REQUEST packets
- Extracts client MAC (chaddr field)
- Extracts hostname (option 12)
- MAC → +0.80 certainty bump
4. **BLE Scanner** — Passive BLE device discovery
- Uses `bleak` library if available
- Gracefully disables if ImportError
- Device address → +0.40 certainty bump
### Core Logic
**Signal Fusion** (per person):
- Collect all device certainties
- Apply exponential decay: `certainty × e^(-0.08 × age_minutes)`
- Aggregate: `max + 0.08 × second_max`
- Check state machine
**Presence Anchor** (critical):
- Once PRESENT (certainty ≥ 0.40), hold PRESENT for 45 minutes from last signal
- Prevents false ABSENT from temporary signal loss (iOS suppression, WiFi roam, power save)
- After 45 minutes without signal ≥ 0.40 → ABSENT
**State Machine**:
```
UNKNOWN → PRESENT → ABSENT → PRESENT
↓ agg_cert ↓
└─────────≥ 0.40 45 min no signal
```
**Alerting**:
- UNKNOWN → PRESENT: "ARRIVED" alert
- PRESENT → ABSENT: "DEPARTED" alert
- Via Matrix webhook if configured
### Database Schema
**persons** — Named people
- id (PK)
- name — Person name
- notes — Optional metadata
**devices** — MAC-to-person mapping
- mac (PK)
- person_id (FK)
- label — Device name (iPhone, Laptop, etc.)
- added_at — Timestamp
**signals** — Raw signal observations
- id (PK)
- mac — Device MAC
- signal_type — "probe", "arp", "dhcp", or "ble"
- certainty — Aggregated certainty after this signal
- ts — Observation timestamp
**occupancy_log** — State transitions
- id (PK)
- person_id (FK)
- old_status — Previous state
- new_status — New state
- ts — Transition timestamp
## HTTP Status Endpoint
GET http://127.0.0.1:9191/
Returns JSON:
```json
{
"persons": [
{
"id": 1,
"name": "Alice",
"status": "PRESENT",
"last_change": 1712761234.5
}
]
}
```
## Limitations (Phase 1)
- **No auto-enrollment**: Device-to-person mapping must be set up manually in database
- **No mDNS parsing**: Hostnames are not extracted or used for identity
- **BLE optional**: Requires `bleak` library; gracefully disabled if missing
- **Monitor mode required**: Probe sniffer needs separate WiFi adapter in monitor mode
- **Root access needed**: Raw sockets require CAP_NET_ADMIN or root
- **Single location**: No multi-room support
## Files
- `presence_daemon.py` — Main daemon (1000+ lines)
- `presence_schema.sql` — SQLite schema
- `install.sh` — Deployment script
- `AUDIT_impl.md` — Implementation notes and audit checklist
- `README.md` — This file
## Logging
Logs to `/var/log/sensor.log` and stdout. Log level: INFO (debug messages only on errors).
Example log output:
```
2026-04-10 14:54:32,123 [INFO] Database initialized at /opt/sensor/sensor.db
2026-04-10 14:54:32,124 [INFO] Loaded 2 persons from database
2026-04-10 14:54:32,125 [INFO] Probe sniffer started on wlan1
2026-04-10 14:54:32,126 [INFO] ARP listener started
2026-04-10 14:54:32,127 [INFO] DHCP sniffer started on wlan0
2026-04-10 14:54:32,128 [INFO] BLE scanner started
2026-04-10 14:54:32,129 [INFO] Status server started on http://127.0.0.1:9191
2026-04-10 14:54:32,130 [INFO] Sensor daemon started
```
## Testing
1. Verify systemd service is running:
```bash
sudo systemctl status sensor
```
2. Check database initialization:
```bash
sqlite3 /opt/sensor/sensor.db ".tables"
```
3. Query persons:
```bash
sqlite3 /opt/sensor/sensor.db "SELECT * FROM persons;"
```
4. Query recent signals:
```bash
sqlite3 /opt/sensor/sensor.db "SELECT * FROM signals ORDER BY ts DESC LIMIT 10;"
```
5. Check status endpoint:
```bash
curl http://127.0.0.1:9191/
```
6. Check logs:
```bash
tail -f /var/log/sensor.log
```
## Phase 2 Roadmap
- Auto-enrollment from mDNS hostnames
- BLE MAC signature recognition (Apple Watch, AirPods)
- Device quorum (multi-device presence confirmation)
- Tentative device linking via co-occurrence windows
## Phase 3 Roadmap
- Pattern of life analytics
- Arrival/departure time learning
- Occupancy forecasting
- Multi-location aggregation