The React web dashboard is a single-page application that gives you a live view of all Bluetooth detections captured by your Raspberry Pi nodes. Every panel updates automatically when new detections arrive over WebSocket, and a manual refresh button is always available if you want to pull fresh data on demand.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.
Top bar
The header row appears at the top of every page and contains four interactive controls.Connection status
A
ConnectionStatus indicator shows whether the WebSocket link to the backend is open. A green dot means the socket is connected; a red icon means the dashboard is running in polling-only mode.Device selector
When more than one active Raspberry Pi is registered, a dropdown lets you filter all stats to a single device. If only one Pi is active, the selector is hidden automatically.
Time range picker
A
TimeRangeSelector dropdown lets you switch between preset windows and a fully custom date-time range.Manual refresh
The Actualizar button calls
refresh() from useRealtimeStats to force an immediate API fetch regardless of the current mode.Time range options
- Preset windows
- Custom date-time range
| Label | Value passed to API |
|---|---|
| 1 minuto | minutes=1 |
| 5 minutos | minutes=5 |
| 30 minutos | minutes=30 |
| 1 hora | minutes=60 |
| 12 horas | minutes=720 |
| 1 día | minutes=1440 |
| 7 días | minutes=10080 |
setInterval in Dashboard.jsx.Auto-refresh (every 30 s) is active only in preset mode. Switching to a custom date-time range pauses it so your historical view is not overwritten by live data.
Stats cards
Three summary cards sit below the top bar in a responsive three-column grid.Dispositivos Detectados
Shows
stats.total.unique_devices — the count of distinct Bluetooth MAC hashes seen within the selected window. The subtitle displays the total raw detection count (total_detections).Personas Estimadas
Shows
stats.total.estimated_people, calculated by the backend using a 1.5 devices-per-person ratio (unique_devices / 1.5, rounded).Umbrales RSSI
An inline
ThresholdSettings widget — not a read-only number but a live configuration panel (see Threshold settings below).Zone distribution chart
TheZoneChart component renders a Recharts PieChart that shows the share of estimated people per RSSI zone.
- Unique device count
- Estimated people count (large blue number)
- Average RSSI in dBm (
data.avg_rssi.toFixed(1))
IoT devices list
TheDeviceList component renders a full table of all registered Raspberry Pi nodes. Each row shows:
| Column | Source field |
|---|---|
| Status | device.is_active — green check or red X icon |
| ID / Name | device.name (primary) + device.device_id (secondary) |
| Location | device.location |
| Last seen | device.last_seen formatted with Intl.DateTimeFormat (Europe/Madrid) |
useDevices hook, independently of the stats refresh cycle.
Export filters panel
TheExportFilters component lets you download detection data as a CSV file. It sits in the right column beside the device list.
Filter modes
Preset
Preset
Choose from six preset time windows: last 30 minutes, 1 hour, 6 hours, 24 hours, 7 days, or 30 days. The corresponding query parameter (
last_minutes, last_hours, or last_days) is appended to the export URL automatically.Custom
Custom
Enter an integer and pick a unit (minutes, hours, or days). The component strips non-numeric characters and leading zeros from the input before building the
last_<unit>=<value> parameter.Date range
Date range
Pick a start date and an end date. The component validates that start precedes end before enabling the download button. Parameters sent:
start_date and end_date.Additional filters
Two optional dropdowns narrow the export further:- Zone —
near,medium, orfar(maps to thezonequery parameter) - IoT device — any registered device, including inactive ones (maps to the
device_idparameter)
CSV download
The export callsGET /api/v1/export/detections/csv with the constructed query string. The filename is read from the Content-Disposition response header; it falls back to detections.csv if the header is absent. The downloaded CSV includes: ID, device hash, RSSI, zone, timestamp, device ID, date, and time.
Threshold settings
TheThresholdSettings widget occupies the third stats card slot and lets you tune the RSSI boundaries used to classify detections into Near, Medium, and Far zones.
| Field | Default | Constraint |
|---|---|---|
| NEAR threshold | -60 dBm | Must be greater than MEDIUM |
| MEDIUM threshold | -75 dBm | Must be less than NEAR |
-1 and -127. Changes are saved automatically on blur (onBlur) by calling PUT /api/v1/settings/thresholds. A Reset button restores both values to their defaults by calling POST /api/v1/settings/thresholds/reset.
Real-time WebSocket connection
TheuseRealtimeStats hook manages the WebSocket lifecycle. It connects to VITE_WS_URL (falling back to ws://localhost:8000) and listens for three event types:
| Event | Action |
|---|---|
connection_status | Updates the wsConnected flag shown in the top bar |
stats_update | Replaces stats in state (preset mode only) |
detection_event | Triggers a fresh fetchStats() call (preset mode only) |
ping message every 15 seconds to keep the connection alive, and reconnects automatically with exponential backoff (up to 5 attempts, starting at 1 second) on unexpected disconnection.