- Python 42.2%
- JavaScript 22.1%
- C++ 15.4%
- CSS 10.2%
- HTML 7%
- Other 3.1%
| .claude | ||
| docs/images | ||
| firmware | ||
| gateway | ||
| scripts | ||
| .gitignore | ||
| DD.md | ||
| README.md | ||
ESP-Tracker
WiFi- und BLE-Tracking-System auf Basis von ESP32-S3 Mikrocontrollern. Nodes scannen Geraete im Promiscuous Mode und senden die Daten per USB-Serial an ein Raspberry Pi Gateway mit Live-Dashboard.
Features
- Echtzeit-Scanning von WiFi- und BLE-Geraeten (Probe Requests, BLE Advertisements)
- Live-Dashboard mit WebSocket-Updates, Geraetetabelle, Filtern und Verweildauer-Tracking
- Geraete-Kategorisierung (Phone, Laptop, Tablet, IoT, Wearable, Router) mit OUI-basierter Hersteller-Erkennung
- Analytics mit Besucher-Statistiken, Kategorien-Chart, Trend-Vergleichen und Auslastungs-Heatmap
- Kalender-Timeline pro Geraet: horizontale 24h-Ansicht mit 15-Minuten-Raster (Tag/Woche)
- PAX-Counter-Modus mit Deep-Sleep fuer batteriebetriebene Zaehlung
- Random-MAC-Erkennung zur Unterscheidung von echten und zufaelligen MAC-Adressen
- Zonen-Erkennung (Nah/Mittel/Fern) basierend auf RSSI-Werten
Architektur
┌──────────────────────┐
│ ESP32-S3 Node │
│ WiFi Promiscuous │
│ BLE Scanner (NimBLE) │
│ JSON Serial Output │
└──────────┬───────────┘
│ USB-CDC 115200 Baud
v
┌──────────────────────┐
│ Raspberry Pi │
│ FastAPI + WebSocket │
│ SQLite (WAL) │
│ OUI-Lookup │
└──────────┬───────────┘
│ HTTP/WS
v
┌──────────────────────┐
│ Browser │
│ Live-Dashboard │
└──────────────────────┘
Screenshots
Geraetetabelle mit Echtzeit-Updates
Live-Ansicht aller erkannten Geraete mit MAC-Adresse, Hersteller, Typ, Kategorie, Zone, RSSI und Verweildauer. Oben die Dwell-Summary (Passanten / Besucher / Aufenthalt).
Analytics und PAX-Counter
Besucher-Statistiken, Geraetekategorien-Doughnut, Trend-Vergleiche, Auslastungs-Heatmap und PAX-Counter-Verlauf.
Geraete-Detail mit Besuchshistorie
RSSI-Verlauf, Besuchsliste mit Zeitstempel, Dauer, Sichtungen und durchschnittlichem RSSI.
Kalender-Timeline
Horizontale 24h-Timeline mit 15-Minuten-Rasterlinien. Jeder Tag eine Zeile, Balkenbreite proportional zur Verweildauer (Minimum 15min), Dauer als Text im Balken.
Voraussetzungen
- Hardware: ESP32-S3-DevKitC-1, Raspberry Pi (3B+/4/5)
- Firmware: PlatformIO (Arduino Framework)
- Gateway: Python 3.11+
Setup
Firmware flashen
# Continuous-Modus (Standard)
cd firmware/node
pio run -e esp32s3 -t upload
# PAX-Counter-Modus
pio run -e esp32s3-pax -t upload
Gateway einrichten
cd gateway
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# OUI-Datenbank herunterladen (Hersteller-Erkennung)
python ../scripts/download_oui.py
# Starten
uvicorn gateway.main:app --host 0.0.0.0 --port 8001
Das Dashboard ist dann unter http://<raspi-ip>:8001 erreichbar.
Konfiguration
Umgebungsvariablen:
| Variable | Default | Beschreibung |
|---|---|---|
SERIAL_PORT |
/dev/esp-gateway |
Serial-Port des ESP32 |
SERIAL_BAUD |
115200 |
Baudrate |
Firmware-Modi
| Modus | PlatformIO-Env | Beschreibung |
|---|---|---|
| Continuous | esp32s3 |
Dauerhaftes Scanning, sendet device_seen/device_gone Events |
| PAX-Counter | esp32s3-pax |
Periodisches Scanning mit Deep-Sleep, sendet aggregierte Zaehlung |
Projektstruktur
esp-tracker/
├── firmware/
│ ├── node/ # ESP32-S3 Firmware (PlatformIO)
│ │ ├── src/
│ │ │ ├── main.cpp # Dual-Mode: Continuous + PAX
│ │ │ ├── config.h # Konfiguration (Sleep-Intervall, etc.)
│ │ │ ├── wifi_scanner.*
│ │ │ ├── ble_scanner.*
│ │ │ └── device_tracker.*
│ │ └── platformio.ini
│ └── shared/
│ └── protocol.h # JSON-Protokoll (constexpr Keys)
├── gateway/
│ ├── gateway/
│ │ ├── main.py # FastAPI App, Serial-Reader, WebSocket
│ │ ├── database.py # SQLite, Visit-Aggregation, Analytics
│ │ ├── oui_lookup.py # IEEE OUI Hersteller-Lookup
│ │ ├── api/
│ │ │ ├── routes.py # REST-Endpoints
│ │ │ └── websocket.py # WebSocket-Manager
│ │ ├── static/ # CSS, JS, Chart.js (lokal, kein CDN)
│ │ ├── templates/ # Jinja2 HTML-Templates
│ │ └── data/
│ │ └── oui.csv # IEEE OUI-Datenbank (~38k Eintraege)
│ └── requirements.txt
├── scripts/
│ ├── simulate_serial.py # Serial-Simulator (--mode pax|continuous)
│ ├── download_oui.py # OUI-Datenbank herunterladen
│ └── flash_node.sh # Flash-Helper
├── docs/images/ # Screenshots
└── DD.md # Design Document
Tech-Stack
| Komponente | Technologie |
|---|---|
| Mikrocontroller | ESP32-S3-DevKitC-1 (Arduino/PlatformIO) |
| BLE-Stack | NimBLE-Arduino 1.4.0 |
| Serialisierung | ArduinoJson 7.0.0 |
| Gateway | Python, FastAPI, Uvicorn |
| Datenbank | SQLite (WAL-Modus, aiosqlite) |
| Serial | pyserial-asyncio mit Auto-Reconnect |
| Frontend | Vanilla JS, Chart.js, WebSocket |
| Templating | Jinja2 |
Simulator
Zum Testen ohne Hardware:
# Terminal 1: Virtuellen Serial-Port erstellen
socat -d -d pty,raw,echo=0,link=/tmp/esp-virtual pty,raw,echo=0,link=/tmp/esp-reader
# Terminal 2: Simulator starten
python scripts/simulate_serial.py --mode continuous # oder --mode pax
# Terminal 3: Gateway mit virtuellem Port starten
SERIAL_PORT=/tmp/esp-reader uvicorn gateway.main:app --host 0.0.0.0 --port 8001
Lizenz
Privates Projekt.