Milesight-Sensor in ChirpStack: Payload-Decoder einrichten
Timo Wevelsiep•Aktualisiert: 30.06.2026Hinweis 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:
- Ö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).
- Wechseln Sie zum Reiter Codec.
- Setzen Sie Payload codec auf JavaScript functions.
- Fügen Sie den gesamten Inhalt von
em300-th-decoder.jsin 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.
Schritt 3: Uplink prüfen und Werte sehen
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 Feldobjectstehen jetzt die dekodierten Werte statt nur der Rohbytes. - MQTT: Abonnieren Sie das Uplink-Topic und sehen Sie das
objectlive:
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
objectbleibt 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.
Mehr zu IoT
- Was ist LoRaWAN?
- Was ist MQTT?
- Was ist ThingsBoard?
- Was ist ChirpStack?
- IoT-Architektur in Schichten
- LoRaWAN vs NB-IoT vs WLAN/5G
- ThingsBoard Preise & Editionen
- Was kostet ChirpStack?
- ThingsBoard vs ChirpStack
- IoT-Plattform: self-hosted vs Cloud
- Open-Source-IoT-Plattformen im Vergleich
- ThingsBoard vs AWS IoT Core & Azure IoT Hub
- ThingsBoard mit Docker installieren
- ChirpStack & LoRaWAN-Gateway einrichten
- Grafana IoT-Dashboard mit InfluxDB
- ThingsBoard Rule Engine: Alarme & Benachrichtigungen
- Milesight-Sensor in ChirpStack: Payload-Decoder
- Node-RED MQTT-Dashboard für Sensordaten
- Predictive Maintenance & Retrofit
- Gebäude-IoT / Smart Building mit LoRaWAN







