Payload Decoding in IoT-Systemen: ChirpStack & Milesight VS373

24. Januar 2026
Timo WevelsiepTimo Wevelsiep

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?

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.

Projekt besprechen →


Quellenverzeichnis

Häufige Fragen

Warum ist Payload Decoding bei IoT-Sensoren notwendig?
IoT-Sensoren senden ihre Daten meist in kompakten, binären Formaten. Payload Decoding übersetzt diese Rohdaten in verständliche Messwerte und Ereignisse, damit Anwendungen, Dashboards und Alarme korrekt damit arbeiten können.
Wo findet das Payload Decoding typischerweise statt?
In der Regel direkt im IoT-Network- oder Application-Server, z. B. in ChirpStack. Dort werden die Daten einmal zentral dekodiert und anschließend an alle nachgelagerten Systeme weitergegeben.
Unterstützt ChirpStack eigenes Payload Decoding?
Ja. ChirpStack erlaubt es, JavaScript-Decoder pro Device Profile zu hinterlegen. Diese werden automatisch auf eingehende Uplink-Daten angewendet.
Liefert Milesight Decoder für seine Sensoren mit?
Ja. Milesight stellt für seine Sensoren, darunter auch den VS373, offizielle Decoder bereit. Diese können als Grundlage genutzt und bei Bedarf an die eigene Plattform angepasst werden.
Warum ist korrektes Decoding wichtig für Plattformen wie Grafana oder ThingsBoard?
Ohne Decoding erhalten diese Plattformen nur Roh-Payloads. Erst dekodierte, strukturierte Daten ermöglichen Visualisierung, Alarmierung, Regeln und Integrationen auf Anwendungsebene.
Unterstützt merkaio bei der Erstellung und Pflege von Payload-Decodern?
Ja. Wir übernehmen die Entwicklung, Anpassung und Wartung von Payload-Decodern, inklusive Tests, Dokumentation und Integration in ChirpStack oder andere Plattformen.
Unterstützt merkaio auch die komplette IoT-Integration?
Ja. Neben Payload Decoding unterstützen wir den Aufbau und Betrieb kompletter IoT-Stacks – von Sensoren und Gateways über ChirpStack bis hin zu Grafana, ThingsBoard oder individuellen Anwendungen.
Für welche Anwendungsfälle ist diese Art von Integration besonders relevant?
Typische Einsatzbereiche sind Elderly Care, Gebäudemonitoring, Industrie, Landwirtschaft, Kühl- und Lagerüberwachung sowie Projekte in Emerging Markets mit verteilten Standorten.

IoT-Projekt umsetzen?

Von der Idee bis zum laufenden Betrieb – wir begleiten Ihr IoT-Vorhaben.

Anforderungsanalyse
Architektur & Technologieauswahl
Implementierung & Integration
Betrieb & Support
Payload Decoding IoT: ChirpStack, LoRaWAN, Milesight VS373 Decoder erklärt | merkaio Blog