The system is divided into three independent layers. The Raspberry Pi agent collects and anonymizes raw BLE data; the cloud backend stores, aggregates, and re-broadcasts it; and the web dashboard renders live statistics and exports. Each layer communicates over a single, well-defined interface, so any component can be swapped or scaled without touching the others.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AngelAmoSanchez/TFG-RaspberryPi-BLE/llms.txt
Use this file to discover all available pages before exploring further.
Layer 1 — Raspberry Pi agent
The agent (raspberry-pi/src/main.py) runs as an asyncio loop on the Pi. On every scan cycle it:
- Calls
BLEScanner.scan_devices()via the Bleak library to collect raw BLE advertisements. - Passes each
Detection(MAC address + RSSI + timestamp) throughDetectionProcessor. - Anonymizes the MAC address with SHA-256 (
hashlib.sha256), producing a 64-character hex digest stored asdevice_hash. - Classifies the device into a proximity zone based on RSSI.
- Serializes the resulting
Deviceobjects and sends them to the cloud backend via MQTT or HTTP. - Waits for
SCAN_INTERVALseconds (default: 30 s) and repeats.
MQTT_BUFFER_SIZE (default: 100) messages when the backend is unreachable, and flushes them automatically on reconnection.
Zone classification
Zone boundaries are defined inraspberry-pi/src/scanner/detection.py and are configurable via environment variables.
| Zone | RSSI range | Estimated distance |
|---|---|---|
NEAR | ≥ −60 dBm | 0 – 2 m |
MEDIUM | ≥ −75 dBm and < −60 dBm | 2 – 5 m |
FAR | < −75 dBm | > 5 m |
MAC anonymization
Layer 2 — cloud backend
The backend (backend-cloud/src/api/main.py) is a FastAPI application backed by PostgreSQL. On startup it:
- Runs
init_db()to create or migrate the schema via asyncpg. - Optionally starts an MQTT subscriber (
start_mqtt_subscriber()) whenMQTT_ENABLED=true. - Exposes REST routes under
/api/v1/for detections, statistics, devices, export, and settings. - Runs a WebSocket endpoint at
/wsthrough a connection manager (ws_manager) that broadcasts new detection batches to all connected clients in real time.
GET /health reports the number of active WebSocket connections alongside a timestamp.
Layer 3 — web dashboard
The React frontend connects tows://backend/ws on load and re-renders zone charts whenever the WebSocket delivers a new detection batch. Key capabilities:
- Real-time zone counts — Recharts bar and line charts update without page refresh.
- Hourly and daily trends — aggregated from the
/api/v1/statisticsendpoint. - CSV export — filtered by date range, zone, or device hash via the
/api/v1/exportendpoint.
Data flow
Communication modes
The Pi agent supports two transport modes selected by theCOMMUNICATION_MODE environment variable.
- MQTT mode
- HTTP mode
MQTT is the recommended mode for production. The agent connects to a broker (for example, EMQX Cloud) and publishes detection batches to a configurable topic. The cloud backend subscribes to the same topic.Agent-side flow:
MQTTClientconnects toMQTT_BROKER:MQTT_PORTwith optional TLS (port 8883).- Each scan cycle,
publish_detections()serializes theDevicelist to JSON and publishes toMQTT_TOPIC. - If the publish fails, the message is queued in an in-memory buffer (max
MQTT_BUFFER_SIZEmessages). - On reconnection, buffered messages are flushed in order.
- When
MQTT_ENABLED=true,start_mqtt_subscriber()subscribes toMQTT_TOPICat startup. - Each incoming message is parsed, persisted to PostgreSQL, and broadcast to WebSocket clients.
Component summary
| Component | Runtime | Key dependencies | Transport |
|---|---|---|---|
| Pi agent | Python 3 + asyncio | Bleak, paho-mqtt | MQTT or HTTP |
| Cloud backend | Python 3 + FastAPI | asyncpg, PostgreSQL, aiomqtt | WebSocket push |
| Web dashboard | React | Recharts, WebSocket API | WebSocket + REST |