WZ-IT Logo
AnleitungIoT

Milesight-Sensor in ChirpStack: Payload-Decoder einrichten

Timo WevelsiepTimo WevelsiepAktualisiert: 30.06.2026

Hinweis zum Inhalt: Versionen, Befehle und Preise können sich ändern. Bitte prüfen Sie kritische Schritte vor dem produktiven Einsatz eigenständig. Dieser Leitfaden ersetzt keine individuelle Beratung.

Damit ChirpStack aus den rohen LoRaWAN-Bytes eines Milesight-Sensors lesbare Werte wie Temperatur und Feuchte macht, hinterlegen Sie einen Payload-Decoder: Holen Sie die offizielle JavaScript-Decoder-Datei aus dem GitHub-Repo Milesight-IoT/SensorDecoders, öffnen Sie in ChirpStack das passende Device-Profile, setzen Sie unter dem Reiter Codec den Payload-Codec auf "JavaScript functions" und fügen Sie den Decoder ein. Beim nächsten Uplink erscheinen die dekodierten Felder im Gerät. Diese Anleitung zeigt das Schritt für Schritt am Beispiel der EM300-TH (Temperatur und Feuchte) - vollständig self-hosted auf Ihrer eigenen ChirpStack-Instanz, ohne Cloud-Lock-in und ohne Per-Device-Lizenzen.

Diese Anleitung setzt voraus, dass Ihr Gateway und ChirpStack bereits laufen. Falls nicht, richten Sie zuerst ChirpStack und das LoRaWAN-Gateway ein. Bezugsversion ist ChirpStack v4 (aktuell 4.18, Mai 2026).

Warum LoRaWAN-Payloads dekodiert werden müssen

LoRaWAN ist ein Funkprotokoll mit knappem Zeitbudget (Duty Cycle) und sehr kleinen Paketen. Damit ein batteriebetriebener Sensor jahrelang läuft und in das schmale Funkbudget passt, sendet er keine Klartext-JSON-Daten, sondern eine möglichst kurze Bytefolge. Eine typische EM300-TH-Nutzlast sieht so aus:

01 75 5A 03 67 EA 00 04 68 8F

ChirpStack entschlüsselt mit dem AppKey zwar die LoRaWAN-Sicherheitsschicht, kennt aber das herstellerspezifische Format dieser Anwendungsdaten nicht. Ohne Decoder bleibt im Uplink-Event das Feld object leer und Sie sehen nur den Base64- oder Hex-Rohwert. Der Payload-Codec ist die Übersetzungsregel: Er liest die Bytes nach dem Milesight-Kanalschema (Kanal-ID, Kanal-Typ, Daten) und gibt strukturierte Felder zurück. Mehr zu den Schichten erklärt unser Grundlagenartikel Was ist LoRaWAN.

Der entscheidende Vorteil im self-hosted Betrieb: Sie hinterlegen den Decoder einmal auf Ihrer eigenen ChirpStack-Instanz und behalten die volle Kontrolle über die Logik. Anders als bei proprietären Cloud-Plattformen (AWS IoT, Azure IoT, Cumulocity) gibt es keine Per-Device-Gebühr für das Dekodieren und keinen Lock-in - der Codec ist frei einsehbarer Open-Source-Code, den Sie versionieren, anpassen und in der EU betreiben.

Schritt 1: Den offiziellen Milesight-Decoder holen

Milesight pflegt alle Codecs zentral im offiziellen GitHub-Repository Milesight-IoT/SensorDecoders (Lizenz GPL-3.0). Das Repo ist nach Produktserie geordnet:

Serie Beispielgeräte Typische Werte
em-series EM300-TH, EM300-MCS, EM500-CO2 Temperatur, Feuchte, CO2, Füllstand
am-series AM103, AM307, AM319 Luftqualität (CO2, PM2.5, TVOC, Lux)
vs-series VS121, VS133, VS373 Personen- und Belegungszählung
ws-series WS101, WS301, WS523 Taster, Leckage, Smart Plug

Für die EM300-TH liegt die Decoder-Datei unter em-series/em300-th/em300-th-decoder.js. Jeder Geräteordner enthält zusätzlich einen Encoder (für Downlinks) und eine *-codec.json im LoRaWAN-Device-Repository-Format. Kopieren Sie den Inhalt von em300-th-decoder.js in die Zwischenablage. Wichtig: Nehmen Sie immer die Datei zu Ihrem genauen Modell - die Kanalbelegung unterscheidet sich zwischen den Serien.

Schritt 2: Decoder in ChirpStack als Payload-Codec hinterlegen

In ChirpStack v4 hängt der Codec am Device-Profile, nicht am einzelnen Gerät. So gilt er für alle Sensoren desselben Typs:

  1. Öffnen Sie in der Weboberfläche Device profiles und wählen Sie das Profil Ihres Sensors (oder legen Sie es neu an, siehe Gateway-Anleitung).
  2. Wechseln Sie zum Reiter Codec.
  3. Setzen Sie Payload codec auf JavaScript functions.
  4. Fügen Sie den gesamten Inhalt von em300-th-decoder.js in das Feld Codec functions ein und speichern Sie.

Die Milesight-Datei bringt die von ChirpStack v4 erwartete Einstiegsfunktion bereits mit. Entscheidend ist dieser Wrapper am Dateiende:

// ChirpStack v4
function decodeUplink(input) {
    var decoded = milesightDeviceDecode(input.bytes);
    return { data: decoded };
}

ChirpStack übergibt der Funktion ein Objekt input mit bytes (Byte-Array), fPort und variables. Die eigentliche Logik steckt in milesightDeviceDecode(), das die Kanal-/Typ-Bytes durchläuft. Die JavaScript-Umgebung von ChirpStack basiert auf QuickJS (ES2020); die Node.js-Buffer-Klasse ist verfügbar. Dieselbe Datei enthält außerdem Decode(fPort, bytes) für ChirpStack v3 und Decoder(bytes, port) für The Things Network - für v4 ist allein decodeUplink relevant.

Speichern Sie das Profil und warten Sie auf den nächsten Uplink (EM300 sendet standardmäßig alle 10 Minuten). Prüfen Sie das Ergebnis an zwei Stellen:

  • Web-UI: Öffnen Sie das Gerät, Reiter Events, und sehen Sie sich das up-Event an. Im Feld object stehen jetzt die dekodierten Werte statt nur der Rohbytes.
  • MQTT: Abonnieren Sie das Uplink-Topic und sehen Sie das object live:
mosquitto_sub -h SERVER-IP -t "application/+/device/+/event/up" -v

Für die Beispielnutzlast liefert der Decoder dieses Objekt:

{ "battery": 90, "temperature": 23.4, "humidity": 71.5 }

Wollen Sie testen, ohne auf einen echten Uplink zu warten, gibt es im Reiter Codec keine Eingabe - nutzen Sie stattdessen einen lokalen Node.js-Aufruf der Datei oder das Test-Setup aus dem Repo. Sobald object gefüllt ist, können Sie die Werte über MQTT in eine Zeitreihen-Datenbank und ein Grafana-IoT-Dashboard leiten.

Beispiel: EM300-TH Payload Byte für Byte

Milesight kodiert jeden Messwert als Block aus Kanal-ID + Kanal-Typ + Daten (Daten little-endian). Die EM300-TH belegt drei Kanäle:

Bytes Kanal-ID Kanal-Typ Rohwert Dekodiert
01 75 5A 0x01 Battery 0x75 0x5A = 90 90 %
03 67 EA 00 0x03 Temperatur 0x67 INT16 LE 0x00EA = 234 23,4 °C
04 68 8F 0x04 Feuchte 0x68 0x8F = 143 71,5 %RH

So entsteht aus 01 75 5A 03 67 EA 00 04 68 8F das JSON-Objekt oben. Die Temperatur ist ein vorzeichenbehafteter 16-Bit-Wert geteilt durch 10, die Feuchte ein Byte geteilt durch 2. Andere Modelle nutzen weitere Kanäle - eine AM319 etwa liefert zusätzlich CO2, PM2.5, TVOC und Beleuchtungsstärke. Der jeweilige Decoder aus dem Repo kennt diese Kanäle bereits, Sie müssen nichts selbst rechnen.

Häufige Stolpersteine

  • object bleibt leer: Codec hängt am falschen Device-Profile, oder das Gerät nutzt ein anderes Profil. Prüfen Sie die Zuordnung.
  • Unsinnige Werte: Falsche Decoder-Datei (falsches Modell) oder fehlgeschlagener Join. Bei falschem AppKey bleiben die Anwendungsdaten verschlüsselt.
  • Decoder aktualisiert nicht: Nach dem Einfügen das Profil speichern und auf den nächsten Uplink warten - bereits gespeicherte Events werden nicht rückwirkend neu dekodiert.
  • Falsches Modell aus einer Serie: EM300-TH, EM300-MCS und EM300-DI teilen Kanäle, unterscheiden sich aber - immer die exakte Modell-Datei verwenden.

Nächste Schritte

Mit einem hinterlegten Payload-Codec liefert ChirpStack saubere, strukturierte Messwerte - die Grundlage für Dashboards, Alarme und Auswertungen, vollständig souverän auf Ihrer eigenen Infrastruktur. Einrichtung, Decoder-Pflege für gemischte Sensorflotten und den Betrieb übernehmen wir auf Wunsch komplett. Mehr dazu auf unseren Seiten zu Milesight-Sensorintegration und ChirpStack & LoRaWAN Network Server sowie im Überblick zu LoRaWAN-Lösungen und im IoT-Bereich von WZ-IT. Ein unverbindliches Kennenlern-Gespräch buchen Sie direkt online.

Sie möchten IoT nicht selbst betreiben? WZ-IT übernimmt Einrichtung, Betrieb und Wartung – DSGVO-konform aus Deutschland.

Häufig gestellte Fragen

Antworten auf die wichtigsten Fragen

LoRaWAN-Sensoren senden aus Funk- und Batteriegründen möglichst kurze Nutzlasten als rohe Bytes (Hex), zum Beispiel '01 75 5A 03 67 EA 00 04 68 8F'. Ohne Decoder sieht ChirpStack nur diese Bytes. Ein Payload-Codec übersetzt sie nach dem Kanal-Schema des Herstellers in lesbare Felder wie battery, temperature und humidity.

Milesight pflegt das offizielle Repository Milesight-IoT/SensorDecoders auf GitHub (GPL-3.0). Die Decoder sind nach Produktserie geordnet (am-series, em-series, vs-series und weitere). Für die EM300-TH liegt der JavaScript-Decoder unter em-series/em300-th/em300-th-decoder.js.

ChirpStack v4 ruft die Funktion decodeUplink(input) auf. input enthält bytes (Byte-Array), fPort und variables. Die Milesight-Decoder-Datei bringt diese Funktion bereits mit: sie ruft milesightDeviceDecode(input.bytes) auf und gibt { data: decoded } zurück. Daneben enthält die Datei noch Decode() für ChirpStack v3 und Decoder() für The Things Network.

Im Device-Profile unter dem Reiter Codec. Setzen Sie 'Payload codec' auf 'JavaScript functions' und fügen Sie den gesamten Inhalt der Decoder-Datei in das Codec-Feld ein. Der Codec gilt dann für alle Geräte, die dieses Profil nutzen.

Standardmäßig nutzt die EM300-Serie Application-Port (fPort) 85 und meldet die Messwerte alle 10 Minuten, den Batteriestand alle 6 Stunden. Der Milesight-Decoder wertet den fPort nicht streng aus, sondern parst die Kanal-/Typ-Bytes der Nutzlast.

Nichts. Die Decoder im offiziellen GitHub-Repo stehen unter GPL-3.0 zur freien Nutzung. Auch ChirpStack selbst ist Open Source (MIT) ohne Lizenz- oder Per-Device-Gebühren. Kosten entstehen nur für Hardware und Betrieb Ihrer Infrastruktur.

Prüfen Sie drei Punkte: Erstens, ob der Decoder im richtigen Device-Profile hängt und das Gerät dieses Profil nutzt. Zweitens, ob Sie die zum Sensor passende Decoder-Datei (genaue Modellbezeichnung) verwenden. Drittens, ob der Join erfolgreich war - bei falschem AppKey sind die Bytes verschlüsselt und ergeben keinen sinnvollen Wert.

Lassen Sie uns über Ihre Idee sprechen

Ob konkrete IT-Herausforderung oder einfach eine Idee - wir freuen uns auf den Austausch. In einem kurzen Gespräch prüfen wir gemeinsam, ob und wie Ihr Projekt zu WZ-IT passt.

E-Mail
[email protected]

Führende Unternehmen vertrauen WZ-IT

  • Rekorder
  • Keymate
  • Führerscheinmacher
  • SolidProof
  • ARGE
  • Boese VA
  • NextGym
  • Maho Management
  • Golem.de
  • Millenium
  • Paritel
  • Yonju
  • EVADXB
  • Mr. Clipart
  • Aphy
  • Negosh
  • ABCO Water Systems
Timo Wevelsiep & Robin Zins - CEOs of WZ-IT

Timo Wevelsiep & Robin Zins

Geschäftsführer

1/3 - Themenauswahl33%

Worum geht es bei Ihrer Anfrage?

Wählen Sie einen oder mehrere Bereiche, bei denen wir Sie unterstützen dürfen.