Payload Decoding in IoT-Systemen: ChirpStack & Milesight VS373
In IoT-Systemen senden Sensoren ihre Daten meist in kompakter, binärer Form – als Bytefolge, die für Menschen und viele Anwendungen nicht direkt verständlich ist. Payload-Decodierung bedeutet, diese Rohdaten in aussagekräftige Werte umzuwandeln.
In diesem Artikel erklären wir, warum Decodierung notwendig ist, wie sie technisch funktioniert und zeigen ein umfassendes Praxisbeispiel mit ChirpStack und dem Milesight VS373 Sturzsensor.
Inhaltsverzeichnis
- 1) Was ist Payload-Decodierung und warum ist sie wichtig?
- 2) Wie funktioniert Payload-Decodierung technisch?
- 3) Payload-Decodierung mit ChirpStack
- 4) Der Milesight VS373 – Funktionsweise und Datenformat
- 5) Beispiel-Payloads des VS373 dekodiert
- 6) Warum Decoding für Grafana, ThingsBoard & Co. wichtig ist
- 7) Best Practices für Decoder-Entwicklung
- 8) Fazit
- Ihr IoT-Projekt umsetzen
- Quellenverzeichnis
1) Was ist Payload-Decodierung und warum ist sie wichtig?
Bei LoRaWAN und anderen LPWAN-Technologien zählt jedes Bit. Die Funkbandbreite ist begrenzt, und Hersteller codieren daher Messwerte und Statusinformationen effizient in Bytes, anstatt klarschriftliche JSON- oder Textdaten zu versenden.
Ohne Decodierung würden nachgelagerte Systeme nur kryptische Hex- oder Base64-Strings erhalten, aus denen sich keine direkten Informationen ablesen lassen. Erst die Decodierung übersetzt die rohen Sensordaten in verständliche, nutzbare Informationen – z. B. Temperaturwerte in Grad Celsius oder Alarmmeldungen wie "Bewegung erkannt".
Ein einfaches Beispiel:
Ein Temperatursensor könnte den Wert 23,5 °C als Byte 0xEB senden. Ohne Kontext ist EB (235 dezimal) bedeutungslos. Ein Decoder hingegen weiß, dass er diesen Wert durch 10 teilen muss, um 23,5 °C zu erhalten.
Diese Umwandlung ist essenziell, damit die Daten vom IoT-Gerät für den Nutzer und weitere Plattformen brauchbar werden.
2) Wie funktioniert Payload-Decodierung technisch?
In der Praxis wird die Decodierung häufig über kleine Decoder-Funktionen umgesetzt, typischerweise in JavaScript. Viele IoT-Netzwerkserver oder Cloud-Plattformen (wie The Things Network, ChirpStack, Datacake u. a.) bieten die Möglichkeit, benutzerdefinierten Code auszuführen, sobald ein Gerätedaten-Paket eintrifft.
Diese Funktion liest das Byte-Array und erzeugt ein strukturiertes JSON-Objekt mit benannten Feldern. Das JSON enthält dann z. B. "temperatur": 23.5 anstelle eines rohen Hex-Strings.
Das Channel/Type-Konzept
Viele Hersteller – darunter Milesight – verwenden ein Kanal/Typen-Konzept: Jedes Datenelement im Payload beginnt mit einem Byte für den Kanal und einem Byte für den Datentyp. Daran schließen sich je nach Typ einige Daten-Bytes an.
Beispiel-Decoder in JavaScript
// Beispiel-Decoder-Funktion
function Decoder(bytes, port) {
var decoded = {};
if (port === 1) {
// Temperatur ist als ganze Zahl in Hundertstel °C kodiert:
var rawTemp = (bytes[0] << 8) | bytes[1]; // Zwei Bytes zu 16-bit Int
decoded.temperatur = rawTemp / 100.0; // In Grad Celsius
}
return decoded;
}
In diesem Beispiel würde ein Payload 0x09 0x3B (Hex) vom Decoder wie folgt interpretiert: Die beiden Bytes ergeben zusammen den Wert 0x093B (2363 dezimal). Durch Division durch 100 ergibt sich 23,63 °C. Das Decoder-Ergebnis wäre dann:
{ "temperatur": 23.63 }
Üblicherweise stellt der Gerätehersteller die nötigen Informationen zur Verfügung: welche Bytes welche Messwerte bedeuten, welche Umrechnungsfaktoren gelten, oder welche Bits einzelne Statusflags repräsentieren. Oft existieren sogar fertige Beispiel-Decoder – so unterhält etwa Milesight ein öffentliches Repository mit Payload-Codecs für alle seine Sensoren.
3) Payload-Decodierung mit ChirpStack
ChirpStack ist ein Open-Source LoRaWAN-Netzwerkserver, der Decodierung direkt integriert unterstützt. Für jedes Gerät (bzw. Gerätetyp) kann man im Device Profile eine Codec-Funktion hinterlegen.
Codec-Konfiguration
Über die Web-Oberfläche findet sich dazu ein "Codec"-Tab im Geräteprofil, in dem man entweder vordefinierte Codecs wählen oder eigene JavaScript-Funktionen eingeben kann.
ChirpStack bietet z. B. Cayenne LPP als Standardcodec an – wählt man diesen, werden Payloads nach dem Cayenne-Low-Power-Protokoll automatisch dekodiert. Für proprietäre Formate (wie die meisten Milesight-Geräte) wählt man "Custom JavaScript functions" und fügt dort den Decoder-Code ein.
ChirpStack V3 vs. V4
Beim Einbinden der Milesight-Beispieldecoder ist eine Kleinigkeit zu beachten:
- ChirpStack V3 erwartete standardmäßig eine Funktion mit dem Header
function Decode(fPort, bytes) - ChirpStack V4 wurde mit The Things Network vereinheitlicht – hier wird meist eine Funktion
decodeUplink(input)verwendet, die ein Objekt zurückgibt
Das Prinzip bleibt gleich: man passt ggf. den Funktionsnamen und -kopf an, der Decoder-Inhalt (die Byte-Verarbeitung) kann aus dem Hersteller-Repository übernommen werden.
Überprüfung im Event-Log
Sobald die Decoder-Funktion im Geräteprofil hinterlegt und gespeichert ist, wendet ChirpStack sie automatisch auf jedes empfangene Paket des Geräts an. Im Live Event-Log der ChirpStack-Konsole kann man überprüfen, ob die Dekodierung klappt – die decodierten Daten erscheinen dort unter dem Schlüssel object im JSON.
Wichtig: Der Roh-Payload bleibt trotzdem erhalten und wird zusammen mit den dekodierten Werten gespeichert. Dadurch gehen keine Informationen verloren.
4) Der Milesight VS373 – Funktionsweise und Datenformat
Als praktisches Beispiel betrachten wir den Milesight VS373, einen IoT-Sensor mit komplexen Payloads.
Was ist der VS373?
Der VS373 ist ein Radar-Fall-Erkennungssensor, der mittels 60 GHz Millimeterwellen-Radar Stürze von Personen erkennt. Er wird vor allem in der Altenpflege, in Smart-Home- und Healthcare-Umgebungen eingesetzt, um Stürze oder Notlagen sofort zu detektieren und Alarm zu schlagen.
Dank AI-Auswertung von Punktwolken kann der Sensor mit bis zu 99 % Genauigkeit einen Sturz erkennen – kontaktlos und anonym, da keinerlei Kamera zum Einsatz kommt.
Erkannte Ereignisse und Zustände
Der VS373 kann weit mehr als nur Sturzalarme erzeugen:
| Ereignis | Beschreibung |
|---|---|
| Bewegungs-/Anwesenheitserkennung | Erfasst, ob eine Person anwesend (Occupied) oder abwesend (Vacant) ist. Bis zu 6 Sub-Bereiche definierbar. |
| Sturzerkennung (Fall Alarm) | Registriert schwere Stürze und sendet unmittelbar Alarm. |
| Regungslosigkeit (Motionless Alarm) | Alarm bei ungewöhnlich langer Bewegungslosigkeit (kann auf Bewusstlosigkeit hindeuten). |
| Verweilalarm (Dwell Alarm) | Alarm wenn Person zu lange in einem Bereich verweilt. |
| Aufsteh-Alarm (Out-of-Bed) | Erkennt wenn eine Person das Bett verlässt – wichtig in Pflegeumgebungen. |
| Liegend-Alarm (Lying Alarm) | Erkennt dass eine Person liegt (ggf. auf dem Boden nach Sturz). |
| Atem-/Vitalstatus | Detektiert Atembewegungen, meldet Tachypnoe (zu schnelle Atmung) oder Bradykardie. |
Payload-Struktur des VS373
Der VS373 nutzt das typische Milesight-Format mit Kanal/Typen-Konzept. Beispielsweise nutzt er den Kanal 0x06 zusammen mit Typ 0xFB, um einen Alarmbericht zu senden. Darauf folgen dann 5 Bytes Wertdaten:
| Byte | Bedeutung |
|---|---|
| Bytes 1-2 | Alarm-ID (0–9999, zur Unterscheidung einzelner Alarmereignisse) |
| Byte 3 | Alarm-Typ-Code |
| Byte 4 | Alarm-Status |
| Byte 5 | Sub-Bereich ID (oder 0xFF wenn nicht relevant) |
Alarm-Typ-Codes
| Code | Bedeutung |
|---|---|
0x00 |
Fall (Sturzalarm) |
0x01 |
Motionless (Bewegungslosigkeit) |
0x02 |
Dwell (Verweilalarm) |
0x03 |
Out-of-Bed (aus Bett aufgestanden) |
0x04 |
Occupied (Bereich belegt) |
0x05 |
Vacant (Bereich frei) |
0x06 |
Bradycardia (Atem/Puls langsam) |
0x07 |
Tachypnea (Atmung schnell) |
0x08 |
Lying (liegende Person erkannt) |
Alarm-Status-Codes
| Code | Bedeutung |
|---|---|
0x01 |
Alarm (neu ausgelöst) |
0x02 |
Resolved (behoben) |
0x03 |
Ignore (ignoriert) |
0x04 |
Report Respiratory Status |
5) Beispiel-Payloads des VS373 dekodiert
Nun veranschaulichen wir die Decodierung an zwei konkreten Beispielen:
Beispiel 1: Sturzalarm
Payload (Hex): 06 FB 05 00 00 01 FF
Dekodiert:
| Feld | Wert | Erklärung |
|---|---|---|
| Kanal/Typ | 06 FB |
Alarm-Datensatz |
| Alarm-ID | 05 00 → 5 |
Eindeutige ID dieses Alarms |
| Alarm-Typ | 00 |
Fall/Sturz |
| Status | 01 |
Alarm aktiv |
| Sub-Bereich | FF |
Nicht anwendbar |
Als JSON:
{
"alarm_id": 5,
"alarm_type": "Fall",
"status": "Alarm",
"zone": null
}
In einem Dashboard würde dieser Payload als Meldung "Sturz erkannt (ID 5)" erscheinen.
Beispiel 2: Aufsteh-Alarm (Bett verlassen)
Payload (Hex): 06 FB 02 00 03 01 01
Dekodiert:
| Feld | Wert | Erklärung |
|---|---|---|
| Kanal/Typ | 06 FB |
Alarm-Datensatz |
| Alarm-ID | 02 00 → 2 |
Eindeutige ID dieses Alarms |
| Alarm-Typ | 03 |
Out-of-Bed |
| Status | 01 |
Alarm aktiv |
| Sub-Bereich | 01 |
Zone 1 (z.B. Bett 1) |
Als JSON:
{
"alarm_id": 2,
"alarm_type": "Out-of-Bed",
"status": "Alarm",
"zone": 1
}
Ein Pflege-Dashboard könnte anzeigen: "Alarm: Person hat Bett 1 verlassen".
6) Warum Decoding für Grafana, ThingsBoard & Co. wichtig ist
Nachdem der Payload durch ChirpStack dekodiert wurde, können die Daten an Visualisierungs- und IoT-Plattformen weitergegeben werden – z. B. an Grafana, ThingsBoard, Node-RED, Datacake oder eigene Web-Anwendungen.
ThingsBoard-Integration erfordert Decoding
ChirpStack bietet eine direkte ThingsBoard-Integration an, die jedoch voraussetzt, dass die Payloads bereits dekodiert sind. Die ChirpStack-Dokumentation sagt dazu:
"Before this integration is able to write data to ThingsBoard, the uplink payloads must be decoded. The payload codec can be configured per device profile."
Ohne Decoder würde ThingsBoard nur einen Base64-codierten Payload-String empfangen, mit dem es nichts anfangen kann. Mit Decoder hingegen bekommt es fertige Schlüssel-Wert-Paare (z. B. alarm_type = "Fall", status = "Alarm"), die es direkt als Telemetrie speichert.
Grafana und Zeitreihendatenbanken
Angenommen, ChirpStack schreibt die Sensordaten in eine InfluxDB oder TimescaleDB für Grafana-Visualisierungen. Mit Decoding kann ChirpStack die dekodierten Felder als separate Werte schreiben:
status_code=1, alarm_type="OutOfBed", zone=1
In Grafana lassen sich diese Felder dann gezielt plotten oder für Alerts nutzen:
- Graph der Anzahl an Sturz-Ereignissen über die Zeit
- Live-Alarm-Panel das anzeigt ob gerade ein Alarm aktiv ist
- Benachrichtigungen bei kritischen Events
Ohne Decoding würde in der Datenbank nur ein Feld payload_raw = "06FB0500..." stehen – das müsste man erst mit komplizierten Queries entziffern.
Kurz gesagt: Decodierung bildet die Brücke zwischen den Geräten und den IoT-Anwendungen.
7) Best Practices für Decoder-Entwicklung
Die Erstellung von Payload-Decodern erfordert Sorgfalt. Hier unsere Empfehlungen:
Hersteller-Dokumentation studieren
Grundlage jedes Decoders sind die offiziellen Protokollbeschreibungen. Benutzerhandbücher und Communication Protocol Guides enthalten Tabellen der Payload-Struktur. Diese sollten gründlich verstanden werden, um alle Sonderfälle abzudecken.
Beispiel-Code nutzen und anpassen
Viele Hersteller (Milesight, Dragino, Netvox etc.) liefern Beispiel-Decodierfunktionen. Es ist sinnvoll, nicht bei Null anzufangen, sondern diese Vorlagen zu verwenden und an die eigene Plattform anzupassen.
Einheitliche Struktur für ähnliche Sensoren
Wenn man mehrere Geräte mit ähnlicher Payload-Logik hat, sollte man den Decoder-Code konsistent gestalten. Milesight-Sensoren verwenden z. B. überall das Channel-Type-Format – hier kann man Funktionen zur Byte-Interpretation wiederverwenden.
Umfangreich testen
Vor dem produktiven Einsatz sollte der Decoder mit bekannten Beispieldaten geprüft werden. Hersteller liefern oft Beispielpayloads in der Dokumentation.
Edge Cases beachten
IoT-Payloads haben gerne Sonderfälle:
- Mehrdeutige Flags
- Optionale Felder
- Endianness (Little vs. Big Endian)
- Negative Werte (Signed vs. Unsigned)
Ein guter Decoder berücksichtigt solche Dinge und protokolliert unbekannte Kombinationen.
Kommentar und Dokumentation im Code
Jede Zuordnung (z. B. 0x03 -> Out-of-Bed) und jede Umrechnungsformel sollte dokumentiert sein. So können Teammitglieder den Code später erweitern oder debuggen.
Versionsverwaltung
Behandeln Sie Decoder-Code wie produktiven Softwarecode. Nutzen Sie Git, um Änderungen zu verfolgen – so kann man historische Versionen nachvollziehen, falls ein Update unerwartete Effekte hat.
Decoder frühzeitig einbinden
Es ist am effektivsten, die Decodierung direkt im LoRaWAN-Netzwerkserver vorzunehmen. Das zentrale Decoding spart Zeit und vermeidet Fehlerquellen, weil nicht jedes nachgelagerte System eigene Parsing-Regeln implementieren muss.
8) Fazit
Payload-Decodierung bildet einen unsichtbaren, aber entscheidenden Bestandteil moderner IoT-Lösungen. Sie übersetzt die Sprache der Geräte (Bits und Bytes) in die Sprache der Anwendungen (Zahlen und Bedeutungen).
Anhand von ChirpStack und dem Milesight VS373 Sensor haben wir gesehen, wie wichtig und vielseitig dieser Prozess ist. Vom ersten Moment, in dem ein LoRaWAN-Paket ankommt, bis zur Visualisierung in Grafana oder der Alarmmeldung in ThingsBoard – stets sorgt der Decoder dafür, dass die richtigen Informationen ankommen.
Für IoT-Integratoren bedeutet das: Man muss sowohl die Netzwerkplattform als auch das Gerät selbst gut kennen. Sobald man aber die Struktur verstanden hat, lässt sich mit ein paar Dutzend Zeilen JavaScript aus Rohdaten etwas machen – nämlich transparente IoT-Daten, die echten Mehrwert liefern.
Ihr IoT-Projekt umsetzen
Sie haben eine Idee für vernetzte Sensorik? merkaio begleitet Sie von der Anforderungsanalyse bis zum laufenden Betrieb – Technologieauswahl, Architektur, Implementierung und Operations.
Quellenverzeichnis
- Concepts of LoRaWAN Payload Decoders – Datacake Docs
- ChirpStack V3 Integration – Milesight Support
- Device Profiles – ChirpStack Documentation
- ThingsBoard Integration – ChirpStack Documentation
- Milesight VS373 Radar Fall Detection Sensor – MCCI
- VS373 User Guide – Milesight
- Milesight Sensor Decoders – GitHub
Häufige Fragen
Warum ist Payload Decoding bei IoT-Sensoren notwendig?▼
Wo findet das Payload Decoding typischerweise statt?▼
Unterstützt ChirpStack eigenes Payload Decoding?▼
Liefert Milesight Decoder für seine Sensoren mit?▼
Warum ist korrektes Decoding wichtig für Plattformen wie Grafana oder ThingsBoard?▼
Unterstützt merkaio bei der Erstellung und Pflege von Payload-Decodern?▼
Unterstützt merkaio auch die komplette IoT-Integration?▼
Für welche Anwendungsfälle ist diese Art von Integration besonders relevant?▼
IoT-Projekt umsetzen?
Von der Idee bis zum laufenden Betrieb – wir begleiten Ihr IoT-Vorhaben.