Teltonika-Hardware per API nutzen: GPS-Daten für eigene Anwendungen

Teltonika liefert mehr als Koordinaten. Codec 8, TCP-Server, IO-Elemente – so landen GPS- und Telematikdaten in eigener Software, ohne Plattform-Zwischenhand.

Teltonika-Hardware per API nutzen: GPS-Daten für eigene Anwendungen

Teltonika-Hardware per API nutzen: GPS-Daten für eigene Anwendungen

Teltonika-Hardware sitzt in massenhaft Fahrzeugen; viele nutzen eine Standard-Plattform. Brauchen Sie die Daten in eigener Software, führt der Weg über TCP, Codec 8 und Ihren Parser.

Was Teltonika-Geräte liefern

Ein Teltonika-Tracker ist mehr als ein GPS-Empfänger. Je nach Modell sendet er:

  • GPS-Position – Breitengrad, Längengrad, Höhe, Geschwindigkeit, Kurs
  • OBD-Daten – Motordrehzahl, Kraftstoffverbrauch, Fehlercodes (bei Fahrzeugen mit OBD-II)
  • Beschleunigungssensor – Hartes Bremsen, starke Kurvenfahrt, Erschütterungen
  • Digitale Ein-/Ausgänge – Zündung an/aus, Türsensor, externe Schalter
  • CAN-Bus-Daten – Kilometerstand, Tankfüllstand, Achslast (bei LKW)
  • Bluetooth-Sensoren – Temperatur (für Kühlketten), Reifendruck, Beacons

Das alles wird als kompakter Datensatz an einen Server geschickt – Ihren Server, wenn Sie wollen.

Das Codec-8-Protokoll

Teltonika-Geräte kommunizieren über ein eigenes Binärprotokoll: Codec 8 (oder die erweiterte Variante Codec 8 Extended). Das Gerät baut eine TCP-Verbindung zu Ihrem Server auf und sendet Datenpakete in folgendem Aufbau:

┌──────────┬────────┬──────────┬──────────┬──────────┐
│ Preamble │ Length │ Codec ID │ AVL Data │ CRC-16   │
│ 4 bytes  │ 4 bytes│ 1 byte   │ variable │ 4 bytes  │
└──────────┴────────┴──────────┴──────────┴──────────┘

Jedes AVL-Data-Paket enthält einen oder mehrere Datensätze mit Timestamp, GPS-Daten, Priorität und sogenannten IO-Elementen – das sind die Sensorwerte, jeweils identifiziert durch eine numerische ID.

Einen TCP-Server bauen

Der erste Schritt: Ein Server, der TCP-Verbindungen von Teltonika-Geräten annimmt. In Node.js:

const net = require('net')

const server = net.createServer((socket) => {
  socket.on('data', (data) => {
    // Erstes Paket: IMEI des Geräts (15 Bytes ASCII nach 2 Bytes Länge)
    if (data.length < 20) {
      const imeiLength = data.readUInt16BE(0)
      const imei = data.subarray(2, 2 + imeiLength).toString('ascii')
      console.log(`Device connected: ${imei}`)
      // Bestätigung senden: 0x01 = akzeptiert
      socket.write(Buffer.from([0x01]))
      return
    }

    // AVL-Datenpakete parsen
    const records = parseCodec8(data)
    records.forEach(record => {
      console.log(`Position: ${record.lat}, ${record.lng} @ ${record.timestamp}`)
    })

    // Anzahl verarbeiteter Records als Bestätigung zurücksenden
    const ack = Buffer.alloc(4)
    ack.writeUInt32BE(records.length)
    socket.write(ack)
  })
})

server.listen(5027, () => console.log('Teltonika server on port 5027'))

Codec 8 parsen

Das Parsing der Binärdaten ist der aufwändigste Teil. Die IO-Elemente kommen in vier Gruppen (1-Byte, 2-Byte, 4-Byte und 8-Byte-Werte), und jede Gruppe hat eine eigene Struktur:

function parseCodec8(buffer) {
  const records = []
  let offset = 8 // Skip preamble + length
  const codecId = buffer.readUInt8(offset++)
  const recordCount = buffer.readUInt8(offset++)

  for (let i = 0; i < recordCount; i++) {
    const timestamp = Number(buffer.readBigUInt64BE(offset))
    offset += 8
    const priority = buffer.readUInt8(offset++)
    const lng = buffer.readInt32BE(offset) / 10000000
    offset += 4
    const lat = buffer.readInt32BE(offset) / 10000000
    offset += 4
    const altitude = buffer.readUInt16BE(offset)
    offset += 2
    const angle = buffer.readUInt16BE(offset)
    offset += 2
    const satellites = buffer.readUInt8(offset++)
    const speed = buffer.readUInt16BE(offset)
    offset += 2

    // IO-Elemente parsen
    const io = {}
    const eventId = buffer.readUInt8(offset++)
    const ioCount = buffer.readUInt8(offset++)

    for (const byteSize of [1, 2, 4, 8]) {
      const count = buffer.readUInt8(offset++)
      for (let j = 0; j < count; j++) {
        const id = buffer.readUInt8(offset++)
        let value
        if (byteSize === 1) value = buffer.readUInt8(offset)
        else if (byteSize === 2) value = buffer.readUInt16BE(offset)
        else if (byteSize === 4) value = buffer.readUInt32BE(offset)
        else value = Number(buffer.readBigUInt64BE(offset))
        offset += byteSize
        io[id] = value
      }
    }

    records.push({
      timestamp: new Date(timestamp),
      lat, lng, altitude, angle, satellites, speed, io
    })
  }
  return records
}

IO-Element-IDs entschlüsseln

Die Rohwerte der IO-Elemente sind nur Zahlen. Um sie zu interpretieren, brauchen Sie die Teltonika-Dokumentation. Die wichtigsten IDs:

| IO-ID | Bedeutung | Einheit | |-------|-----------|---------| | 239 | Zündung | 0/1 | | 240 | Bewegungserkennung | 0/1 | | 21 | GSM-Signalstärke | 1–5 | | 66 | Externe Spannung | mV | | 67 | Batteriespannung | mV | | 68 | Batterie-Level | % | | 69 | GNSS-Status | 1–3 | | 181 | PDOP | - | | 182 | HDOP | - | | 16 | Gesamtkilometer | km | | 24 | Geschwindigkeit | km/h |

Die vollständige Liste hängt vom Gerätemodell ab und umfasst bei Modellen mit CAN-Bus-Unterstützung mehrere hundert Parameter.

Von Rohdaten zur Anwendung

Rohe GPS-Punkte sind erst der Anfang. Für eine nützliche Anwendung brauchen Sie:

Fahrterkennung

Wann hat eine Fahrt begonnen? Wann endete sie? Die einfachste Methode: Zündung (IO 239) als Trigger. Robuster: Kombination aus Zündung, Bewegungserkennung (IO 240) und Geschwindigkeit mit einem Timeout für kurze Stopps.

Geofencing

Ist das Fahrzeug innerhalb eines definierten Bereichs? Für einfache rechteckige Zonen reichen Koordinaten-Vergleiche. Für Polygone brauchen Sie einen Point-in-Polygon-Algorithmus – oder PostGIS, wenn Sie die Daten in PostgreSQL speichern.

Echtzeit-Tracking

Für Live-Positionen auf einer Karte braucht es eine WebSocket-Verbindung zwischen Ihrem Server und dem Frontend. Sobald ein neues AVL-Paket eingeht, wird die Position an alle verbundenen Clients gesendet:

// Beim Empfang eines AVL-Pakets
wss.clients.forEach(client => {
  client.send(JSON.stringify({
    imei: device.imei,
    lat: record.lat,
    lng: record.lng,
    speed: record.speed,
    timestamp: record.timestamp
  }))
})

Geräte konfigurieren

Teltonika-Geräte werden über den Teltonika Configurator (Windows) oder per SMS-Befehlen konfiguriert. Die wichtigsten Einstellungen:

  • Server-Adresse: IP und Port Ihres TCP-Servers
  • Sendeintervall: Wie oft sendet das Gerät Daten? (Empfehlung: alle 30s bei Fahrt, alle 5 Min im Stand)
  • IO-Elemente: Welche Sensorwerte sollen mitgesendet werden?
  • Schlafmodus: Wie verhält sich das Gerät im Standby? (Wichtig für Batterielebensdauer)

Für Flotten mit vielen Geräten gibt es das FOTA Web (Firmware Over The Air) – damit konfigurieren und aktualisieren Sie Geräte remote.

Unser Erfahrungsbericht

Wir haben mit Teltonika-Hardware ein GPS-Tracking-System aufgebaut, das über 5 Millionen GPS-Datenpunkte pro Tag verarbeitet. Die Learnings:

  • Datenmenge unterschätzen ist der häufigste Fehler. Ein Gerät, das alle 10 Sekunden sendet, produziert 8.640 Datensätze pro Tag. Bei 1.000 Fahrzeugen sind das 8,6 Millionen Einträge täglich.
  • TimescaleDB oder ClickHouse sind bessere Optionen als reines PostgreSQL, sobald Sie über einige hundert Geräte hinauswachsen.
  • Buffer auf dem Gerät ist Ihr Sicherheitsnetz. Teltonika-Geräte speichern Daten lokal, wenn keine Verbindung besteht, und senden sie nach – manchmal Tausende Records auf einmal.
  • Codec 8 Extended unterstützt 2-Byte IO-IDs und ist für neuere Gerätemodelle Standard. Ihr Parser sollte beide Varianten können.

Fazit

Teltonika: robust, dokumentiert, fair im Preis. Integration heißt Arbeit an TCP und Binärformat – dafür volle Kontrolle, keine Plattformgebühr pro Fahrzeug, keine Abhängigkeit von einem SaaS-Zwischenlayer.


GPS- oder Telematikprojekt? 30 Minuten, kostenlos – welcher Ansatz zu Ihrer Flotte passt.