Der Aufbau eines BLE Tag-Asset-Tracking-Systems handelt nicht von der Auswahl des richtigen Tags. Es geht um die Infrastruktur, die Daten von Hunderten oder Tausenden von Tags in einer Anlage empfingt, filtert, transportiert und speichert. Der Tag ist ein einfacher Sender; die Intelligenz liegt im Gateway-Netzwerk, im Edge-Prozessor und im Cloud-Backend. Dieser Artikel analysiert die vollstaendige Systemarchitektur vom Funkempfang bis zum Dashboard, mit Hardware-Auswahltabellen, Filteralgorithmen, Datenpipeline-Schemata und Deployment-Kostenmodellen aus Produktionseinsaetzen in Krankhaeusern, Lagern und Fabriken.
1. Systemarchitektur-Ueberblick
Ein Produktions-BLE-Asset-Tracking-System hat vier Schichten mit unterschiedlichen Latenz-, Durchsatz- und Zuverlaessigkeitsanforderungen:
| Schicht |
Komponenten |
Latenz |
Datenvolumen |
Ausfallimpact |
| T1: Tag-Schicht |
BLE Tags (100-1000) |
N/A (nur Broadcast) |
~30 Bytes/Tag/Event |
Einzelnes Asset verschwindet |
| T2: Gateway-Schicht |
BLE Scanner (5-50) |
100-500 ms Zyklus |
~50 KB/s Spitze/GW |
Zone verschwindet (10-50 Tags) |
| T3: Edge-Schicht |
Lokaler Server/Appliance |
1-5 s Verarbeitung |
~200 KB/s aggregiert |
Tracking verzögert, nicht verloren |
| T4: Cloud-Schicht |
Backend, DB, Dashboard |
1-10 s End-to-End |
~500 KB/s dauerhaft |
Historische Datenluecke |
Der haeufigste Architekturfehler ist, das Gateway als einfachen Relay zu behandeln, der rohe BLE-Pakete an die Cloud weiterleitet. Bei 500 Tags mit 1-Sekunden-Intervall und 10 Gateways sind das 5.000 Pakete pro Sekunde am Cloud-Ingest-Endpunkt, jedes mit duplizierten RSSI-Werten aus ueberlappenden Abdeckungszonen. Edge-Filterung ist keine Optimierung; sie ist eine Anforderung.
2. Gateway-Hardware-Auswahl
| Plattform |
BLE-Chip |
CPU |
RAM |
Leistung |
BOM-Kosten |
Fuer |
| ESP32-basiert |
ESP32 (Dual-Mode) |
240 MHz Xtensa x2 |
520 KB SRAM |
2,5W (WiFi+BLE) |
$3-5 |
Kleine Sites, WiFi |
| Raspberry Pi + USB |
nRF52840 Dongle |
1,4 GHz ARM A72 x4 |
1-4 GB |
5-7W |
$45-60 |
F&E, Prototypen |
| Zweckgebundenes Gateway |
nRF52832/52840 + ESP32 |
ESP32 240MHz + nRF52 |
520KB + 256KB |
2-3W |
$15-25 |
Produktionsdeployments |
| Industrie-Gateway (Linux) |
CC2640R2 + WiFi/LTE |
ARM Cortex-A7 1GHz |
512 MB |
5-15W |
$200-400 |
Raue Umgebungen, Cellular |
2.1 ESP32 als Gateway: Moeglichkeiten und Grenzen
Der ESP32 ist die haeufigste Gateway-Plattform fuer kostenempfindliche Deployments, da er WiFi und BLE integriert hat. Allerdings teilt sich der BLE-Controller das 2,4-GHz-Funkmodul zwischen WiFi und BLE und kann BLE nicht scannen, waehrend er WiFi sendet:
| WiFi-Aktivitaet |
BLE-Scan-Luecke |
Verlust (1s) |
Verlust (500ms) |
| Leerlauf |
0 ms |
0% |
0% |
| MQTT Publish (alle 5s) |
~15 ms/Luecke |
0,3% |
0,6% |
| WiFi-Streaming (kontinuierlich) |
~50 ms/Luecke |
1,0% |
2,0% |
| OTA-Update |
~200 ms/Luecke |
5-8% |
10-15% |
2.2 Zweckgebundene Gateway-Architektur
Produktions-Gateways koppeln typischerweise einen nRF52 (dedizierter BLE-Scanner) mit einem ESP32 (WiFi/CPU). Der nRF52 fuehrt kontinuierliches Active Scanning aus und leitet Pakete per UART/SPI an den ESP32 weiter, der Filterung, Buffering und Cloud-Kommunikation uebernimmt. Dieses Dual-Chip-Design eliminiert Funkkonflikte.
# nRF52-Seite: kontinuierlicher BLE-Scanner
def ble_scan_callback(adv_report):
packet = {
"mac": adv_report.peer_addr,
"rssi": adv_report.rssi,
"data": adv_report.data,
"ts": get_timestamp_us(),
}
uart_send(json.dumps(packet))
# ESP32-Seite: empfangen, filtern, stapel-hochladen
rx_buffer = []
def uart_rx_callback(data):
pkt = json.loads(data)
if should_forward(pkt):
rx_buffer.append(pkt)
if len(rx_buffer) >= BATCH_SIZE or time_since_upload > INTERVAL:
upload_batch(rx_buffer)
rx_buffer.clear()
2.3 Gateway-Platzierung und Abdeckung
| Genauigkeitsstufe |
GW/100m2 |
Abstand |
Kosten/m2 |
Anwendungsfall |
| Präsenz (Raum) |
0,5-1,0 |
10-15 m |
$0,15-0,30 |
Anwesenheit pro Zone |
| Grobposition (3-5 m) |
2-4 |
5-8 m |
$0,60-1,20 |
Lagergang-Tracking |
| Feinposition (1-2 m) |
6-10 |
3-5 m |
$1,80-3,00 |
Instrumenten-Tracking |
| Submeter (0,5 m) |
15-25 |
2-3 m |
$4,50-7,50 |
Hochwert-Audit |
3. BLE-Scan-Strategie
3.1 Active vs. Passive Scan
| Parameter |
Passive Scan |
Active Scan |
| SCAN_REQ senden |
Nein |
Ja |
| SCAN_RSP empfangen |
Nein |
Ja (bis 31 Bytes extra) |
| Verbrauch |
Niedriger (nur Rx) |
Hoeher (Tx + Rx) |
| Verfuegbare Daten |
31 Bytes |
62 Bytes |
3.2 Scan-Fenster und -Intervall
| Intervall |
Fenster |
Duty Cycle |
Capture (1s) |
Capture (500ms) |
| Kontinuierlich |
Kontinuierlich |
100% |
~99,5% |
~99,0% |
| 1000 ms |
1000 ms |
100% |
~99,5% |
~99,0% |
| 1000 ms |
500 ms |
50% |
~50-65% |
~50-65% |
| 5000 ms |
1000 ms |
20% |
~20-30% |
~20-30% |
3.3 Duplikat-Filterung auf Radio-Ebene
| Modus |
Duplikate |
Pakete/s (500 Tags, 1s, 10GW) |
GW-CPU |
| Keine Filterung |
Alle |
~15.000 |
Hoch |
| Controller-Dedup |
1/Tag/Zyklus |
~500 |
Niedrig |
| App-Dedup |
1/Tag/Fenster |
~500 |
Niedrig-Mittel |
4. Edge-Filterung
4.1 Multi-Gateway-Deduplizierung
DEDUP_WINDOW_MS = 2000
def deduplicate(raw_reports):
by_tag = group_by_mac(raw_reports)
result = []
for mac, reports in by_tag.items():
if len(reports) == 1:
result.append(reports[0])
continue
best = max(reports, key=lambda r: score_report(r))
result.append(best)
return result
def score_report(r):
rssi_score = (r.rssi + 100) / 70
age_s = (now() - r.ts) / 1000
fresh_score = max(0, 1 - age_s / 5)
gw_reliability = gateway_stats[r.gw_id].uptime_pct
return rssi_score * 0.6 + fresh_score * 0.2 + gw_reliability * 0.2
4.2 RSSI-Glaettung und Ausreisser-Unterdrueckung
| Filter |
Fenster |
Latenz |
Varianzreduktion |
Komplexitaet |
| Roh (kein Filter) |
1 |
0 s |
0% |
Keine |
| Gleitender Mittelwert |
5 |
2-5 s |
~55% |
Niedrig |
| Exponentielle Glaettung |
Unendlich |
1-3 s |
~50% |
Niedrig |
| Median |
3-7 |
1-3 s |
~65% |
Mittel |
| Kalman |
Adaptiv |
0,5-2 s |
~70% |
Hoch |
4.3 Ereignisbasierte Weiterleitung
| Strategie |
Pak/Tag/Std |
Cloud-BW (500 Tags) |
Anwendungsfall |
| Jeder Scan (1s) |
3.600 |
~14 MB/h |
RTLS sub-Sekunde |
| Alle 5s (Batch) |
720 |
~2,8 MB/h |
Standard-Tracking |
| Nur Zonenwechsel |
~5-20 |
~40 KB/h |
Raum-Praesenz |
| Schwellwert + Heartbeat |
~2-10 |
~20 KB/h |
Temperaturalarme |
5. Datenpipeline-Design
5.1 Transportprotokoll-Vergleich
| Protokoll |
Overhead |
Zuverlaessigkeit |
Latenz |
GW-Leistung |
Fuer |
| HTTP POST (JSON) |
~400 Bytes |
TCP garantiert |
100-500 ms |
Hoch |
Kleine Deployments |
| MQTT (QoS 1) |
~20 Bytes |
TCP + ACK |
50-200 ms |
Niedrig |
Produktionsdeployments |
| UDP (custom) |
~8 Bytes |
Keine |
10-50 ms |
Minimal |
Echtzeit-RTLS, LAN |
| LoRaWAN |
~13 Bytes |
Bestaetigt |
1-10 s |
N/A |
Remote-Sites ohne WiFi |
5.2 MQTT-Topic-Struktur
# MQTT-Topic-Hierarchie
# Format: site/zone/gateway/tag/event
site-001/zone-A/gw-01/+/scan
site-001/zone-A/+/tag-005/scan
site-001/+/+/tag-005/zone_change
site-001/+/+/+/battery_low
site-001/+/+/+/temperature_alert
# Payload (JSON, ~80 Bytes)
{
"mac": "AA:BB:CC:DD:EE:01",
"rssi": -67,
"gw": "gw-01",
"ts": 1722422400000,
"bat": 85,
"temp": 23.5,
"seq": 4823
}
5.3 Datenschema und Speicherung
| Store |
Technologie |
Daten |
Retention |
Query |
| Time-series (hot) |
InfluxDB / TimescaleDB |
Roh-Events |
7-30 Tage |
Bereich nach Tag + Zeit |
| Time-series (cold) |
S3 / Parquet |
Aggregierte Events |
1-5 Jahre |
Batch-Analytics |
| Relational |
PostgreSQL / MySQL |
Metadaten, Zonen |
Permanent |
CRUD, Joins |
| Cache |
Redis |
Letzte Position |
TTL 5 min |
Sub-ms Lookup |
5.4 Speichersizing
# 500 Tags, 5s Intervall
tags = 500
events_per_hour = 500 * (3600 / 5) # = 360.000
events_per_day = 360.000 * 24 # = 8.640.000
bytes_per_day = 8.640.000 * 80 # = 691 MB/Tag
bytes_per_year = 691 * 365 # = ~252 GB (roh)
compressed_per_year = 252 / 5 # = ~50 GB (Parquet 5:1)
total_storage_year = 50 * 1.4 # = ~70 GB (mit DB-Overhead)
6. Positionsschaetzung am Edge
| Algorithmus |
GW Min |
Genauigkeit |
Edge-CPU |
Kalibrierung |
Fuer |
| Proximity (staerkster RSSI) |
1 |
Raum (5-10m) |
Minimal |
Keine |
Einfache Praesenz |
| Gewichteter Zentroid |
3+ |
3-5 m |
Niedrig |
GW-Positionen |
Offene Bereiche |
| Trilateration |
3+ |
2-4 m |
Mittel |
Path-Loss pro Zone |
Lager, Gaenge |
| Fingerprinting (kNN) |
4+ |
1-3 m |
Mittel-Hoch |
RF-Survey |
Komplexe Innenraeume |
| BLE AoA |
1 (Array-Antenne) |
0,5-1 m |
Hoch |
Phasenkalibrierung |
Hochwert-Tracking |
6.1 Gewichteter Zentroid-Algorithmus
def estimate_position(reports, gateway_positions):
total_weight = 0
weighted_x = 0
weighted_y = 0
for r in reports:
gw_id = r["gw_id"]
if gw_id not in gateway_positions:
continue
weight = 10 ** (r["rssi"] / 10)
gx, gy = gateway_positions[gw_id]
weighted_x += weight * gx
weighted_y += weight * gy
total_weight += weight
if total_weight == 0:
return None
return (weighted_x / total_weight, weighted_y / total_weight)
7. Systemzuverlaessigkeit und Failover
7.1 Gateway-Health-Monitoring
| Metrik |
Normal |
Alert |
Intervall |
| Pakete/Min |
50-500 |
< 10 oder > 2000 |
60 s |
| CPU-Temp |
40-65 C |
> 75 C |
300 s |
| WiFi RSSI |
-30 bis -65 dBm |
< -75 dBm |
60 s |
| Uptime |
> 99,5% |
< 99% |
Taeglich |
| Letzter Heartbeat |
< 30 s |
> 120 s |
30 s |
7.2 Buffer bei Edge-Cloud-Verbindungsverlust
| Max Ausfall |
Buffer (500 Tags, 5s) |
Medium |
| 15 min |
~4,3 MB |
RAM |
| 1 Stunde |
~17 MB |
RAM/SD |
| 4 Stunden |
~69 MB |
SD/eMMC |
| 24 Stunden |
~415 MB |
SSD/eMMC |
8. Deployment-Kostenmodell
Vollstaendiges System fuer 10.000 m2 mit 500 Assets:
| Komponente |
Menge |
Einzelpreis |
Summe |
% |
| BLE Tags (CR2032, 3 Jahre) |
500 |
$8 |
$4.000 |
18% |
| Zweckgebundene Gateways |
20 |
$120 |
$2.400 |
11% |
| Edge-Server |
1 |
$800 |
$800 |
4% |
| Netz + Verkabelung |
1 |
$1.500 |
$1.500 |
7% |
| Cloud (Jahr 1) |
1 |
$3.600 |
$3.600 |
16% |
| Software-Lizenzen (Jahr 1) |
1 |
$5.000 |
$5.000 |
23% |
| Installation + Inbetriebnahme |
1 |
$3.000 |
$3.000 |
14% |
| Ersatzteile (10%) |
– |
– |
$640 |
3% |
| RF-Survey + Kalibrierung |
1 |
$1.200 |
$1.200 |
5% |
| Jahr 1 Gesamt |
$22.140 |
100% |
Kosten pro Asset: $22.140 / 500 = $44,28 (Jahr 1), $8.640 / 500 = $17,28/Jahr (wiederkehrend). Guenstiger als RFID ($60-120/Asset) und Wi-Fi RTLS ($80-150/Asset).
9. Produktions-Benchmarks
| Metrik |
Krankenhaus (200 Tags, 8GW) |
Lager (500 Tags, 20GW) |
Fabrik (1000 Tags, 15GW) |
| Scan-Capture-Rate |
98,2% |
96,5% |
94,1% |
| Genauigkeit (Median) |
3,2 m |
4,8 m |
5,5 m |
| E2E-Latenz (p95) |
2,8 s |
4,1 s |
5,3 s |
| GW-Uptime |
99,7% |
99,2% |
98,8% |
| Cloud-Daten/Monat |
4,2 GB |
18,7 GB |
24,3 GB |
| Falsche Zonenwechsel |
0,8% |
2,1% |
3,5% |
| Tag-Batterielebensdauer |
31 Monate |
28 Monate |
26 Monate |
10. Skalierungsaspekte
| Skala |
Tags |
GW |
Edge |
Cloud |
Herausforderung |
| Klein |
1-100 |
1-5 |
Einzel-GW |
Einzel-VPS |
Kosteneffizienz |
| Mittel |
100-1.000 |
5-30 |
Edge-Server |
VPS+Redis+TSDB |
Abdeckungsluecken |
| Gross |
1.000-5.000 |
30-100 |
Multi-Edge |
LB-Cluster |
Edge-Koordination |
| Enterprise |
5.000-50.000 |
100-500 |
Regionale Cluster |
K8s+verteilte TSDB |
Multi-Site-Aggregation |
11. Haeufige Architekturfehler
| Fehler |
Symptom |
Ursache |
Loesung |
| Cloud macht alles |
Hohe Latenz, hohe Kosten |
Keine Edge-Filterung |
Dedup + Glaettung am Edge |
| 1 GW pro Zone |
Abdeckungsluecken |
GW minimiert |
30-50% Ueberlappung |
| HTTP fuer alles |
CPU-Spitzen, Verlust |
TCP-Handshake |
MQTT persistent |
| Kein Offline-Buffer |
Datenluecken |
Fire-and-forget |
SQLite-Buffer + Replay |
| Roh-RSSI fuer Position |
5-10m Spruenge |
Keine Glaettung |
Exponentiell alpha=0,3 |
| Kein Dwell-Timer |
Falsche Zonenwechsel |
Abdeckungs-Flackern |
30s min Dwell |
| GW ueberprovisioniert |
Redundante Daten |
Mehr = besser |
30-50% Ueberlappung |
| Kein Tag-Management |
Geister-Tags |
Tote Tags nicht entfernt |
Auto-Archiv 24h still |
13. Zusammenfassung
Ein Produktions-BLE-Asset-Tracking-System hat Erfolg oder Misserfolg durch seine Infrastruktur, nicht durch seine Tags. Der BLE Tag ist die guenstigste und einfachste Komponente im Stack. Das Gateway-Netzwerk, die Edge-Filter-Pipeline, der Datentransport und das Cloud-Backend bestimmen, ob das System 3-Meter-Genauigkeit bei 2-Sekunden-Latenz oder 10-Meter-Genauigkeit bei 30-Sekunden-Latenz liefert. Die Architekturprinzipien sind klar: frueh und aggressiv am Edge filtern, MQTT fuer Transport verwenden, fuer Offline-Betrieb puffern und Positionsschaetzung pro Zone kalibrieren.