- README.md komplett neu geschrieben: - Fokus auf n8n-tracker.json (MQTT-only) - Entfernt: Telegram-Workflows, Datei-basierte Speicherung - Hinzugefügt: OwnTracks-Setup, Geräte-Mapping, erweiterte Features - Neue Sektionen: Sicherheitshinweise, DSGVO-Compliance - Praktische Code-Beispiele für Customization - CLAUDE.md aktualisiert: - Neue Workflow-Architektur dokumentiert - NocoDB-Schema mit battery/speed Feldern - Web-Interface Details (Filter, Kartenebenen, Marker) - Wichtige Gotchas und Edge Cases hinzugefügt - Dateien bereinigt: - Gelöscht: tracker.json, tracker-db.json, tracker-mqtt.json - Gelöscht: index_owntrack.html, locations-example.csv - Hinzugefügt: n8n-tracker.json (aktueller Workflow) - Hinzugefügt: database-example.csv (aktuelles Schema) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Location Tracker für n8n
Ein MQTT-basiertes Location-Tracking-System mit n8n, NocoDB und interaktiver Web-Visualisierung für OwnTracks-Geräte.
Überblick
Dieses Repository enthält ein MQTT-basiertes Location-Tracking-System mit folgenden Komponenten:
- n8n-tracker.json - n8n-Workflow zur MQTT-Datenerfassung und API-Bereitstellung
- index.html - Interaktive Web-Oberfläche mit Leaflet.js
Das System empfängt Location-Updates von OwnTracks-kompatiblen Geräten über MQTT, speichert diese in einer NocoDB-Datenbank und bietet sowohl eine REST-API als auch eine Web-Visualisierung mit Echtzeit-Updates.
Funktionen
Workflow-Features
- MQTT-Erfassung: Automatischer Empfang von OwnTracks-Standortdaten über MQTT
- Persistente Speicherung: Unbegrenzte Historie in NocoDB-Datenbank
- Telemetrie-Daten: Batteriestatus und Geschwindigkeit werden mitgespeichert
- REST-API: JSON-Endpunkt für externe Anwendungen
- Fehlerbehandlung: Validierung und Fehlertoleranz bei ungültigen MQTT-Nachrichten
Web-Oberflächen-Features
- 📍 Interaktive Karte mit Leaflet.js
- 🗺️ 4 Kartenebenen: Standard (OpenStreetMap), Satellit (Esri), Gelände (OpenTopoMap), Dunkel-Modus (CartoDB)
- 📱 Geräte-Filter: Separate Ansicht pro Gerät
- ⏱️ Zeitfilter: 1h, 3h, 6h, 12h, 24h
- 🔄 Auto-Refresh: Toggle-fähig, 5-Sekunden-Intervall
- 📊 Bewegungshistorie: Farbcodierte Polyline-Darstellung pro Gerät
- 🔋 Telemetrie-Anzeige: Batteriestatus und Geschwindigkeit in Popups
- 🎨 Geräte-spezifische Farben: Unterschiedliche Farben pro Gerät
Voraussetzungen
Basis-Anforderungen
- Eine laufende n8n-Instanz (Version 1.0+)
- NocoDB-Instanz mit API-Zugriff
- MQTT-Broker (z.B. Mosquitto)
- OwnTracks-App oder kompatibles MQTT-Gerät
MQTT-Broker
Wenn noch kein MQTT-Broker vorhanden ist:
# Ubuntu/Debian
sudo apt install mosquitto mosquitto-clients
# Mosquitto starten
sudo systemctl start mosquitto
sudo systemctl enable mosquitto
# Test
mosquitto_sub -h localhost -p 1883 -t 'owntracks/#' -v
Installation
Schritt 1: n8n-Workflow importieren
- Öffne deine n8n-Instanz
- Navigiere zu Workflows → Import from File
- Wähle
n8n-tracker.jsonaus diesem Repository - Workflow wird als "Telegram Location Tracker - NocoDB" importiert (Name kann angepasst werden)
Schritt 2: NocoDB-Datenbank einrichten
NocoDB-Tabelle erstellen
- Erstelle ein neues Project in NocoDB
- Erstelle eine Tabelle mit folgendem Schema:
| Spaltenname | Datentyp | Beschreibung |
|---|---|---|
latitude |
Decimal | Breitengrad |
longitude |
Decimal | Längengrad |
timestamp |
DateTime | Zeitstempel (ISO 8601) |
user_id |
Number | Immer 0 für MQTT |
first_name |
Text | Tracker-ID (z.B. "10") |
last_name |
Text | Source-Typ (z.B. "fused") |
username |
Text | Tracker-ID (wie first_name) |
marker_label |
Text | Anzeigename für Karte |
display_time |
Text | Formatierter Zeitstempel |
chat_id |
Number | Immer 0 für MQTT |
battery |
Number | Batteriestatus (0-100) |
speed |
Decimal | Geschwindigkeit in m/s |
- Notiere Project ID und Table ID aus der NocoDB-URL:
https://nocodb.example.com/nc/PROJECT_ID/TABLE_ID
NocoDB API-Token generieren
- In NocoDB: Account Settings → Tokens → Create Token
- Kopiere den generierten Token
Schritt 3: Credentials in n8n konfigurieren
MQTT-Credentials
- In n8n: Credentials → Create New
- Wähle "MQTT"
- Konfiguriere:
- Protocol: mqtt (oder mqtts für TLS)
- Host: Dein MQTT-Broker (z.B.
localhostoderbroker.example.com) - Port: 1883 (Standard) oder 8883 (TLS)
- Username: MQTT-Benutzername
- Password: MQTT-Passwort
- Speichere als "MQTT account"
NocoDB-Credentials
- In n8n: Credentials → Create New
- Wähle "NocoDB API Token"
- Konfiguriere:
- API Token: Token aus Schritt 2
- Base URL: NocoDB-URL (z.B.
https://nocodb.example.com)
- Speichere als "NocoDB Token account"
Schritt 4: Workflow-IDs anpassen
Öffne den importierten Workflow in n8n und passe an:
In den Nodes "Lade Daten aus NocoDB" und "Speichere in NocoDB":
- Project ID: Deine NocoDB-Projekt-ID (ersetze
pdxl4cx4dbu9nxi) - Table ID: Deine NocoDB-Tabellen-ID (ersetze
m8pqj5ixgnnrzkg)
Credential-Zuordnung prüfen:
- MQTT Trigger → Wähle deine "MQTT account" Credentials
- NocoDB-Nodes → Wähle deine "NocoDB Token account" Credentials
Schritt 5: OwnTracks-App konfigurieren
-
OwnTracks-App installieren (Android/iOS)
-
MQTT-Modus aktivieren:
- Öffne OwnTracks → Preferences
- Mode: MQTT
- Host: Dein MQTT-Broker (z.B.
broker.example.com) - Port: 1883 (oder 8883 für TLS)
- Username: MQTT-Benutzername
- Password: MQTT-Passwort
- Device ID (tid): z.B. "10" oder "11" (wichtig für Geräte-Identifikation!)
- Tracker ID (tid): Gleicher Wert wie Device ID
-
TLS/Verschlüsselung (optional aber empfohlen):
- Port auf 8883 ändern
- TLS aktivieren
-
Tracking-Einstellungen:
- Monitoring: Signifikante Standortänderungen
- Move Mode: 100m (oder nach Bedarf)
Schritt 6: Web-Oberfläche konfigurieren
API-Endpunkt anpassen
Öffne index.html und passe die API-URL an (Zeile 178):
const API_URL = 'https://deine-n8n-instanz.de/webhook/location';
Webhook-URL finden:
- In n8n: Öffne den Workflow
- Klicke auf den Node "Webhook - Location API"
- Die URL steht unter "Webhook URLs" (z.B.
https://n8n.example.com/webhook/location)
Geräte-Namen konfigurieren
Passe die Geräte-Zuordnung in index.html an (Zeilen 142-152):
const DEVICE_NAMES = {
'10': 'Joachim Pixel', // Device ID '10' → Anzeigename
'11': 'Huawei Smartphone' // Device ID '11' → Anzeigename
};
const DEVICE_COLORS = {
'10': '#e74c3c', // Rot
'11': '#3498db', // Blau
'default': '#95a5a6' // Grau für unbekannte Geräte
};
Wichtig: Die Keys ('10', '11') müssen mit der Tracker ID (tid) aus OwnTracks übereinstimmen!
Web-Oberfläche hosten
Option 1: Webserver (empfohlen)
# Apache
sudo cp index.html /var/www/html/tracker/
# nginx
sudo cp index.html /usr/share/nginx/html/tracker/
Option 2: Lokaler Test
- Öffne
index.htmldirekt im Browser - Funktioniert nur, wenn CORS korrekt konfiguriert ist
Option 3: Static Hosting
- GitHub Pages
- Netlify
- Vercel
Schritt 7: Workflow aktivieren und testen
-
Workflow aktivieren:
- In n8n: Öffne den Workflow
- Klicke auf "Active" (Toggle oben rechts)
- Prüfe, dass alle Nodes grün sind (keine roten Fehler)
-
Testen:
- Öffne OwnTracks-App
- Sende einen Location-Update (App sendet automatisch oder manuell triggern)
- Prüfe in n8n die Execution History
- Öffne die Web-Oberfläche → Standort sollte erscheinen
-
API-Test:
curl https://deine-n8n-instanz.de/webhook/locationSollte JSON zurückgeben mit
success: trueund Location-Daten
Verwendung
Standort senden (OwnTracks)
Die OwnTracks-App sendet automatisch Location-Updates basierend auf deinen Einstellungen:
- Automatisch: Bei signifikanten Standortänderungen
- Manuell: In der App auf "Publish" klicken
- Intervall: Konfigurierbar in App-Einstellungen
MQTT-Topic-Format:
owntracks/user/device
Beispiel: owntracks/joachim/pixel
Nachrichtenformat (JSON):
{
"_type": "location",
"lat": 48.1351,
"lon": 11.5820,
"tst": 1700000000,
"tid": "10",
"batt": 85,
"vel": 5,
"acc": 10,
"alt": 520
}
Web-Oberfläche verwenden
Filter-Optionen
🗺️ Kartenebene:
- Standard: OpenStreetMap (gut für Navigation)
- Satellit: Esri World Imagery (Luftbild)
- Gelände: OpenTopoMap (Höhenlinien)
- Dunkel: CartoDB Dark (Nachtmodus)
📱 Gerät-Filter:
- Alle Geräte: Zeigt alle MQTT-Geräte
- Einzelnes Gerät: Wähle aus Dropdown (wird dynamisch befüllt)
⏱️ Zeitfilter:
- 1 Stunde: Nur letzte Stunde (Standard)
- 3/6/12/24 Stunden: Weitere Zeiträume
- Alle älteren Punkte werden ausgeblendet
🔄 Auto-Refresh:
- AN (grün): Aktualisiert alle 5 Sekunden
- AUS (rot): Keine automatische Aktualisierung
Karte verstehen
Marker:
- Größe: Größter Marker = neuester Standort (32x32px), kleinere = Historie (16x16px)
- Farbe: Geräte-spezifisch (siehe
DEVICE_COLORSKonfiguration) - Icon: Kreisförmig mit dekorativem Zeiger (kein tatsächlicher Richtungsindikator)
Polylines:
- Verbinden Standorte chronologisch
- Farbe entspricht Gerät
- Zeigen Bewegungspfad
Popups:
- Klicke auf Marker für Details
- Zeigt: Gerätename, Zeitstempel, Batterie %, Geschwindigkeit (km/h)
REST-API verwenden
Endpunkt:
GET https://deine-n8n-instanz.de/webhook/location
Beispiel-Antwort:
{
"success": true,
"current": {
"latitude": 48.1351,
"longitude": 11.5820,
"timestamp": "2025-11-14T10:30:00.000Z",
"user_id": 0,
"first_name": "10",
"last_name": "fused",
"username": "10",
"marker_label": "10",
"display_time": "14.11.2025, 11:30:00",
"chat_id": 0,
"battery": 85,
"speed": 5.2
},
"history": [
{ /* weitere Location-Objekte */ }
],
"total_points": 42,
"last_updated": "2025-11-14T10:30:00.000Z"
}
Integration in eigene Apps:
// JavaScript Beispiel
fetch('https://n8n.example.com/webhook/location')
.then(response => response.json())
.then(data => {
console.log('Aktueller Standort:', data.current);
console.log('Batterie:', data.current.battery + '%');
});
# Python Beispiel
import requests
response = requests.get('https://n8n.example.com/webhook/location')
data = response.json()
if data['success']:
current = data['current']
print(f"Position: {current['latitude']}, {current['longitude']}")
print(f"Batterie: {current['battery']}%")
Workflow-Architektur
Übersicht
Der n8n-tracker.json Workflow besteht aus zwei unabhängigen Flows:
Flow 1: MQTT Location Capture
┌──────────────┐
│ MQTT Trigger │ (owntracks/#)
└──────┬───────┘
│
v
┌──────────────────────────┐
│ MQTT Location verarbeiten│ (JavaScript)
└──────┬───────────────────┘
│
v
┌──────────────────┐
│ Speichere in │ (NocoDB Create)
│ NocoDB │
└──────────────────┘
Flow 2: Location API
┌──────────────────────┐
│ Webhook - Location │ (GET /webhook/location)
│ API │
└──────┬───────────────┘
│
v
┌──────────────────────┐
│ Lade Daten aus │ (NocoDB Get All)
│ NocoDB │
└──────┬───────────────┘
│
v
┌──────────────────────┐
│ Format API Response │ (JavaScript)
└──────┬───────────────┘
│
v
┌──────────────────────┐
│ JSON Response │ (CORS + JSON)
└──────────────────────┘
Flow 1: MQTT Location Capture (Details)
MQTT Trigger:
- Subscribed auf Topic:
owntracks/# - Empfängt alle OwnTracks-Messages
- Keine Filter auf Trigger-Ebene
MQTT Location verarbeiten (JavaScript):
// Wichtige Schritte:
1. Parse JSON aus message-Feld
2. Validiere lat, lon, tst (erforderlich)
3. Konvertiere Unix-Timestamp → ISO 8601
4. Extrahiere tid (Tracker ID) → username
5. Formatiere displayTime (de-DE, Europe/Berlin)
6. Packe Telemetrie in mqtt_data Objekt
7. Überspringe ungültige Nachrichten mit continue
Speichere in NocoDB:
- Erstellt neuen Datensatz pro Location
- Mappt 12 Felder (inkl. battery, speed)
- Keine Duplikatsprüfung (alle Updates werden gespeichert)
Flow 2: Location API (Details)
Webhook - Location API:
- HTTP GET auf
/location - CORS:
Access-Control-Allow-Origin: * - Keine Authentifizierung (öffentlich!)
Lade Daten aus NocoDB:
- Holt ALLE Datensätze (
returnAll: true) - Keine Sortierung auf DB-Ebene
- Keine Pagination
Format API Response (JavaScript):
// Schritte:
1. Sammle alle Location-Objekte
2. Sortiere nach timestamp (neueste zuerst)
3. Wähle neuste als "current"
4. Baue Response-Struktur
5. Zähle total_points
JSON Response:
- Content-Type: application/json
- CORS-Header gesetzt
- Keine Kompression
Datenspeicherung & Schema
NocoDB-Konfiguration
Aktuelle IDs im Workflow:
- Project ID:
pdxl4cx4dbu9nxi(muss angepasst werden!) - Table ID:
m8pqj5ixgnnrzkg(muss angepasst werden!) - Credential: "NocoDB Token account"
Datenbank-Schema
Vollständiges Schema mit Beispieldaten:
| Feld | Typ | Beispielwert | Beschreibung |
|---|---|---|---|
latitude |
Decimal | 48.1383784 |
Breitengrad (WGS84) |
longitude |
Decimal | 11.4276172 |
Längengrad (WGS84) |
timestamp |
DateTime | 2025-11-14T18:00:37.000Z |
UTC-Zeitstempel (ISO 8601) |
user_id |
Number | 0 |
Immer 0 für MQTT-Geräte |
first_name |
Text | "11" |
Tracker-ID (tid) |
last_name |
Text | "fused" |
Location-Source |
username |
Text | "11" |
Tracker-ID (gleich wie first_name) |
marker_label |
Text | "11" |
Anzeigename für Karte |
display_time |
Text | "14.11.2025, 19:00:37" |
Formatiert (de-DE) |
chat_id |
Number | 0 |
Immer 0 für MQTT-Geräte |
battery |
Number | 73 |
Batteriestatus (0-100%) |
speed |
Decimal | 0 |
Geschwindigkeit in m/s |
OwnTracks-Feld-Mapping
| NocoDB-Feld | OwnTracks-Feld | Transformation |
|---|---|---|
latitude |
lat |
Direkt |
longitude |
lon |
Direkt |
timestamp |
tst |
Unix → ISO 8601 |
user_id |
- | Konstant: 0 |
first_name |
tid |
Tracker-ID |
last_name |
source |
Location-Quelle |
username |
tid |
Tracker-ID |
marker_label |
tid |
Tracker-ID |
display_time |
tst |
Formatiert (de-DE, Berlin) |
chat_id |
- | Konstant: 0 |
battery |
batt |
Direkt |
speed |
vel |
m/s (nicht konvertiert!) |
Nicht gespeicherte OwnTracks-Felder:
acc- Genauigkeit (Meter)alt- Höhe (Meter)cog- Kurs über Grundconn- Verbindungstyp (w/m)_id- Device Identifier
Anpassungen & Customization
Neues Gerät hinzufügen
Schritt 1: OwnTracks-App konfigurieren
- Setze Tracker ID (tid) auf eindeutige ID, z.B. "12"
- Konfiguriere MQTT-Verbindung wie oben beschrieben
Schritt 2: index.html anpassen (Zeilen 142-152)
const DEVICE_NAMES = {
'10': 'Joachim Pixel',
'11': 'Huawei Smartphone',
'12': 'Neues Gerät' // HINZUFÜGEN
};
const DEVICE_COLORS = {
'10': '#e74c3c',
'11': '#3498db',
'12': '#2ecc71', // HINZUFÜGEN (Grün)
'default': '#95a5a6'
};
Farb-Vorschläge:
#e74c3c- Rot#3498db- Blau#2ecc71- Grün#f39c12- Orange#9b59b6- Lila#1abc9c- Türkis
Schritt 3: Testen
- Sende Location von neuem Gerät
- Prüfe Web-Oberfläche → Gerät sollte im Dropdown erscheinen
- Marker sollte in konfigurierter Farbe erscheinen
Zeitzone ändern
In n8n-Workflow, Node "MQTT Location verarbeiten" (Zeile 124):
// Aktuell: Berlin-Zeit
const displayTime = new Date(timestampMs).toLocaleString('de-DE', {
timeZone: 'Europe/Berlin'
});
// Ändern zu New York:
const displayTime = new Date(timestampMs).toLocaleString('en-US', {
timeZone: 'America/New_York'
});
// Ändern zu UTC:
const displayTime = new Date(timestampMs).toISOString();
// Eigenes Format:
const displayTime = new Date(timestampMs).toLocaleString('de-DE', {
timeZone: 'Europe/Berlin',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
Standard-Zeitfilter ändern
In index.html (Zeile 125):
<!-- Aktuell: 1 Stunde (1h) -->
<option value="1h" selected>Letzte Stunde</option>
<!-- Ändern zu 24 Stunden: -->
<option value="1h">Letzte Stunde</option>
<option value="24h" selected>Letzte 24 Stunden</option>
Auto-Refresh-Intervall anpassen
In index.html (Zeile 419):
// Aktuell: 5 Sekunden (5000ms)
refreshInterval = setInterval(loadLocations, 5000);
// Ändern zu 10 Sekunden:
refreshInterval = setInterval(loadLocations, 10000);
// Ändern zu 1 Minute:
refreshInterval = setInterval(loadLocations, 60000);
CORS einschränken (Sicherheit!)
In n8n-Workflow, Node "JSON Response" (Zeile 67):
// Aktuell (unsicher):
{
"name": "Access-Control-Allow-Origin",
"value": "*"
}
// Ändern zu spezifischer Domain:
{
"name": "Access-Control-Allow-Origin",
"value": "https://web.example.com"
}
Weitere NocoDB-Felder speichern
Beispiel: Genauigkeit (accuracy) und Höhe (altitude) hinzufügen
Schritt 1: NocoDB-Spalten erstellen
accuracy(Number)altitude(Number)
Schritt 2: Workflow-Node "MQTT Location verarbeiten" anpassen:
// In mqtt_data Objekt ergänzen:
mqtt_data: {
accuracy: mqttData.acc,
altitude: mqttData.alt,
battery: mqttData.batt,
velocity: mqttData.vel,
course: mqttData.cog,
connection: mqttData.conn,
device_id: mqttData._id
}
Schritt 3: Node "Speichere in NocoDB" anpassen:
Füge in fieldsUi.fieldValues hinzu:
{
"fieldName": "accuracy",
"fieldValue": "={{ $json.mqtt_data.accuracy }}"
},
{
"fieldName": "altitude",
"fieldValue": "={{ $json.mqtt_data.altitude }}"
}
Schritt 4: index.html Popups erweitern (Zeile 320):
// Nach Speed-Anzeige hinzufügen:
if (loc.accuracy !== undefined && loc.accuracy !== null) {
popupContent += `<br>📍 Genauigkeit: ${loc.accuracy}m`;
}
if (loc.altitude !== undefined && loc.altitude !== null) {
popupContent += `<br>⛰️ Höhe: ${loc.altitude}m`;
}
MQTT-Topic einschränken
In n8n-Workflow, Node "MQTT Trigger" (Zeile 104):
// Aktuell: Alle OwnTracks-Topics
topics: "owntracks/#"
// Nur spezifischer Benutzer:
topics: "owntracks/joachim/#"
// Nur spezifisches Gerät:
topics: "owntracks/joachim/pixel"
// Mehrere Topics:
topics: "owntracks/joachim/#,owntracks/lisa/#"
Sicherheitshinweise
Kritisch (sofort beheben!)
1. API ohne Authentifizierung
- ⚠️ Problem: Jeder kann Standortdaten abrufen, wenn er die URL kennt
- ⚠️ Risiko: DSGVO-Verstoß, Privatsphäre-Verletzung
- ✅ Lösung:
- Implementiere API-Key-Authentifizierung in n8n
- Oder nutze Reverse-Proxy mit Basic Auth
- Oder beschränke Zugriff per IP-Whitelist
2. CORS offen für alle Domains
- ⚠️ Problem:
Access-Control-Allow-Origin: * - ⚠️ Risiko: XSS-Angriffe, unautorisierten Zugriff
- ✅ Lösung: Beschränke auf deine Domain (siehe "CORS einschränken")
3. DSGVO-Compliance
- ⚠️ Problem: Personenbezogene Standortdaten ohne Einwilligung/Löschkonzept
- ⚠️ Pflichten: Informationspflicht, Einwilligung, Auskunftsrecht, Löschung
- ✅ Lösung:
- Hole explizite Einwilligung von Nutzern ein
- Implementiere automatische Löschung alter Daten (z.B. >30 Tage)
- Dokumentiere Datenschutzmaßnahmen
- Stelle Löschfunktion bereit
Wichtig (empfohlen)
4. MQTT ohne TLS
- ⚠️ Problem: Unverschlüsselte Übertragung auf Port 1883
- ⚠️ Risiko: Standortdaten können abgefangen werden
- ✅ Lösung:
- Aktiviere TLS in Mosquitto (Port 8883)
- Konfiguriere OwnTracks mit TLS
5. Keine Rate-Limiting
- ⚠️ Problem: API kann unbegrenzt oft abgerufen werden
- ⚠️ Risiko: DoS-Angriff, Server-Überlastung
- ✅ Lösung: Implementiere Rate-Limiting (z.B. via nginx)
6. NocoDB-Token zu weitreichend
- ⚠️ Problem: Token hat möglicherweise Schreibrechte für API-Endpunkt
- ⚠️ Risiko: Datenmanipulation
- ✅ Lösung: Nutze separaten Read-Only-Token für API-Endpunkt (falls möglich)
Best Practices
- HTTPS erzwingen: n8n-Webhooks nur über HTTPS erreichbar machen
- Monitoring: Überwache ungewöhnliche API-Zugriffe
- Backup: Sichere NocoDB-Datenbank regelmäßig
- Updates: Halte n8n, NocoDB, Mosquitto und Dependencies aktuell
- Secrets: Speichere Credentials nur in n8n Credential Store, nicht im Code
- Logging: Aktiviere Audit-Logging für Zugriffe
Fehlerbehebung
MQTT-Daten kommen nicht an
Symptome: OwnTracks sendet, aber nichts in NocoDB gespeichert
Lösungen:
-
MQTT-Broker testen:
mosquitto_sub -h broker.example.com -p 1883 -u user -P pass -t 'owntracks/#' -vSollte Nachrichten anzeigen, wenn OwnTracks sendet.
-
OwnTracks-Konfiguration prüfen:
- Mode: MQTT (nicht HTTP!)
- Topic:
owntracks/USER/DEVICE - Verbindungsstatus in App prüfen
- Test-Nachricht senden (Publish Button)
-
n8n MQTT-Node prüfen:
- Credentials korrekt?
- Topic-Pattern passt? (
owntracks/#) - Workflow ist aktiviert?
-
n8n Execution History prüfen:
- Workflows → n8n-tracker → Executions
- Gibt es Executions?
- Gibt es Fehler (rot markiert)?
-
Debug mit manuellem Test:
# Sende Test-Nachricht per mosquitto_pub mosquitto_pub -h broker.example.com -p 1883 -u user -P pass \ -t 'owntracks/test/device' \ -m '{"_type":"location","lat":48.1351,"lon":11.5820,"tid":"10","tst":1700000000,"batt":85,"vel":5}'
API gibt leere Daten zurück
Symptome: API antwortet mit {"history": []} oder "current": null
Lösungen:
-
NocoDB-Verbindung testen:
- In n8n: Credentials → NocoDB → Test Connection
- Sollte grüner Haken erscheinen
-
NocoDB direkt testen:
curl -H "xc-token: YOUR_TOKEN" \ "https://nocodb.example.com/api/v1/db/data/v1/PROJECT_ID/TABLE_ID"Sollte JSON mit Daten zurückgeben.
-
Project/Table IDs prüfen:
- Öffne NocoDB-Tabelle im Browser
- URL enthält die IDs:
/nc/PROJECT_ID/TABLE_ID - Vergleiche mit IDs in n8n-Workflow
-
Daten in NocoDB vorhanden?
- Öffne Tabelle in NocoDB
- Sind Einträge vorhanden?
- Wenn nicht: Problem liegt bei MQTT-Erfassung (siehe oben)
Web-Oberfläche zeigt keine Karte
Symptome: Weiße Seite, Karte lädt nicht, Marker fehlen
Lösungen:
-
Browser-Console prüfen (F12 → Console):
- CORS-Fehler? → API-CORS-Header prüfen
- 404 auf Leaflet.js? → CDN-Problem (lokale Kopie nutzen)
- API-Fehler? → Siehe "API gibt leere Daten zurück"
- JavaScript-Fehler? → Code-Syntax prüfen
-
API-URL prüfen:
- In index.html Zeile 178:
const API_URL = '...' - URL muss erreichbar sein
- Test im Browser: URL direkt aufrufen → Sollte JSON zurückgeben
- In index.html Zeile 178:
-
Netzwerk-Tab prüfen (F12 → Network):
- Request zu API wird gesendet?
- Status 200 OK?
- Response enthält Daten?
- CORS-Header vorhanden?
-
Leaflet.js CDN erreichbar?
- Prüfe ob
https://unpkg.com/leaflet@1.9.4/dist/leaflet.jsgeladen wird - Falls CDN-Problem: Nutze lokale Kopie
- Prüfe ob
Koordinaten sind falsch/vertauscht
Symptome: Marker erscheinen im Meer, falsche Position
Lösungen:
-
Reihenfolge prüfen:
- Leaflet erwartet:
[latitude, longitude] - NICHT:
[longitude, latitude] - OwnTracks sendet korrekt:
lat,lon
- Leaflet erwartet:
-
Daten in NocoDB prüfen:
- Öffne Tabelle
- Ist
latitudeder Breitengrad (z.B. 48.x)? - Ist
longitudeder Längengrad (z.B. 11.x)? - Für München: ca. 48°N, 11°O
-
JavaScript-Code prüfen:
// RICHTIG: const lat = parseFloat(loc.latitude); const lon = parseFloat(loc.longitude); L.marker([lat, lon]) // FALSCH: L.marker([lon, lat]) // Vertauscht!
Geräte-Filter zeigt nicht alle Geräte
Symptome: Dropdown zeigt "Alle Geräte" aber keine einzelnen Geräte
Lösungen:
-
MQTT-Daten vorhanden?
- API aufrufen und prüfen: Gibt es Einträge mit
user_id: 0? - Wenn nicht: Keine MQTT-Daten in Datenbank
- API aufrufen und prüfen: Gibt es Einträge mit
-
username-Feld befüllt?
- In NocoDB prüfen: Ist
usernamegesetzt? - Sollte gleich wie
first_namesein (tid)
- In NocoDB prüfen: Ist
-
JavaScript-Console prüfen:
// In Browser-Console (F12): console.log(allData.history.filter(loc => loc.user_id == 0));Sollte MQTT-Einträge zeigen.
-
Filter-Code prüfen (index.html Zeile 267):
let filteredData = allData.history.filter(loc => loc.user_id == 0);Muss MQTT-Daten filtern.
Geschwindigkeit wird nicht angezeigt
Symptome: Popup zeigt keine Geschwindigkeit, obwohl OwnTracks sendet
Lösungen:
-
OwnTracks sendet velocity?
- Prüfe MQTT-Nachricht (mosquitto_sub)
- Sollte
velFeld enthalten
-
NocoDB-Feld
speedvorhanden?- Tabellen-Schema prüfen
- Spalte
speed(Decimal) muss existieren
-
Workflow speichert speed?
- Node "Speichere in NocoDB" prüfen
- Mapping:
fieldName: "speed",fieldValue: "={{ $json.mqtt_data.velocity }}"
-
Null-Werte prüfen:
- Nicht alle OwnTracks-Messages enthalten
vel - Code prüft auf
!== null(index.html Zeile 328)
- Nicht alle OwnTracks-Messages enthalten
Batteriestatus zeigt 0% oder fehlt
Symptome: Batterie wird als 0% angezeigt oder fehlt im Popup
Lösungen:
-
OwnTracks sendet battery?
- Android/iOS unterscheiden sich
- Manche Geräte senden kein
battFeld - Prüfe MQTT-Nachricht
-
Berechtigungen in OwnTracks:
- Android: Batterie-Optimierung deaktivieren
- iOS: Standortfreigabe "Immer" setzen
-
NocoDB-Wert prüfen:
- Tabelle öffnen
- Ist
batterybefüllt? - Typ Number (nicht Text!)
Repository-Inhalte
| Datei | Beschreibung |
|---|---|
n8n-tracker.json |
n8n-Workflow für MQTT-Erfassung und API |
index.html |
Web-Oberfläche mit Leaflet.js |
database-example.csv |
Beispiel-Datenexport aus NocoDB |
README.md |
Diese Dokumentation |
CLAUDE.md |
Technische Architektur-Dokumentation |
Lizenz
Dieses Projekt steht unter der MIT-Lizenz zur freien Verfügung.
Support & Contributing
- Issues: Melde Bugs oder Feature-Requests via GitHub Issues
- Pull Requests: Beiträge sind willkommen!
- Fragen: Öffne eine Discussion auf GitHub
Roadmap (Potenzielle Features)
- API-Authentifizierung (API-Key, JWT)
- Automatische Datenlöschung (DSGVO-Compliance)
- Geofencing / Location-Alerts
- Multi-User-Support mit Zugriffsrechten
- Erweiterte Statistiken (Distanz, Durchschnittsgeschwindigkeit)
- Export-Funktion (GPX, KML, CSV)
- Push-Notifications bei Location-Updates
- Offline-Support für Web-UI (PWA)
- Mobile App (React Native / Flutter)