Funkübertragung mit LoRaWAN
Grundlagen
Das Wort LoRaWAN ist eine Abkürzung für “Long Range Wide Area Network”. Es handelt sich um eine Funk-Technologie, die recht weite Entfernungen überbrücken kann und trotzdem mit wenig Energie auskommt. Im städtischen Umfeld werden einige hundert Meter erreicht, bei freier Sicht können Übertragungen bis zu 10 km erfolgreich sein. Die Übertragung erfolgt verschlüsselt in einem freien Frequenzbereich, in Europa im freien 868MHz-Band.
Die Spezifikation von LoRaWAN definiert über die eigentliche Funkstrecke hinaus aber auch weitere Komponenten, die für eine einfache Nutzbarkeit in vielen Anwendungen sorgen.
LoRaWAN eignet sich gut für die Übertragung von Zählerständen, weil wegen des niedrigen Energieverbrauchs eine Batterie für die gesamte Eichzeit eines Zählers ausreichend ist.
Komponenten
Die LoRaWAN-Spezifikation beschreibt mehrere Komponenten, die im Folgenden genauer beschrieben werden. Da die Technologie offen und einfach ist, sind die Komponenten vergleichsweise preiswert.
LoRaWAN-Gerät
Hierbei handelt es sich um das Gerät, das über das LoRaWAN-Protokoll kommunizieren möchte, in unserem Fall um den Zähler. LoRaWAN-Geräte können nicht nur Nachrichten senden, sondern auch empfangen. Diese Funktion wird jedoch für Zähler nicht benötigt. Alle über Funk übertragenen Nachrichten sind verschlüsselt, sodass sie nicht abgehört werden können. Um Energie zu sparen, sind die Nachrichten so kurz wie möglich und deshalb binär codiert.
LoRaWAN-Gateway
Dieses empfängt die über Funk versandten Nachrichten oder sendet Nachrichten über Funk an das LoRaWAN-Gerät. Die empfangenen Nachrichten werden über ein IP-Netzwerk weiter an einen Application-Server versandt. Die Verschlüsselung bleibt dabei bestehen. Ein LoRaWAN-Gateway kann meist Verbindungen zu mehreren Application-Servern halten und wählt den für eine Funk-Nachricht richtigen automatisch aus.
LoRaWAN Application-Server
Er entschlüsselt die empfangene Nachricht und wandelt die binäre Codierung in ein besser lesbares JSON-Format um. Diese neue Nachricht kann dann auf verschiedene Weisen weiter verarbeitet oder weiter gesendet werden. Für das Weitersenden der JSON-Nachricht wird meist das Standard-Protokoll MQTT verwendet.
Der Mibakus Smartmeter-Server unterstützt zwei Implementierungen für LoraWAN Application-Server:
- Die Implementierung des The-Things-Netzwerks (TTN) in der Version 3. Das The-Things-Network betreibt einen öffentlichen Application-Server. Für smarte Zähler eignet sich jedoch besser die Benutzung eines eigenen Application-Servers, weil die Zählerstände nach der Heizkostenverordnung als schützenswerte persönliche Daten anzusehen sind, für deren Bearbeitung auf öffentlichen Servern besondere Bedingungen eingehalten werden müssen.
- Die Implementierung ChirpStack. Dieses ist eine OpenSource-Entwicklung. Ein ChirpStack-Application-Server ist in einer Docker-Umgebung vergleichsweise einfach aufzusetzen.
Auf dem Markt sind LoRaWAN-Gateways erhältlich, die einen Application-Server gleich mit enthalten, sodass ein Komplettsystem einfach aufzubauen ist.
Überblick

LoRaWAN Community
Weil ein Gateway die Nachricht weiter senden kann, ohne sie entschlüsseln zu müssen, kann er auch öffentlich benutzt werden, ohne dass die Inhalte lesbar sind. Wenn im Empfangsbereich des Gateways z.B. ein LoRaWAN-GPS-Empfänger an einem Container seinen Standort versendet und der GPS-Empfänger im öffentlichen Application-Server des The-Things-Networks registriert ist, wird das Gateway die GPS-Daten an den öffentlichen Server weiterleiten und dort können sie verarbeitet oder wiederum weitergeleitet werden.
Deshalb ist es gute Praxis, den öffentlichen TTN-Server in einem LoRaWAN-Gateway als einen der Application-Server zu konfigurieren
LoRaWAN-Praxis
Beim Kauf eines LoRaWAN-Geräts erhalten Sie drei Werte:
- Die dev-eui. Dieses ist eine eindeutige ID, die das Gerät identifiziert. Sie ist immer auch auf dem Gerät sichtbar angebracht
- Den app-key. Dieses ist ein Schlüssel, der zur Entschlüsselung der ersten verschlüsselten Nachricht benötigt wird
- Die join-eui. Sie dient als Identifikation für den Application-Server, der für das Gerät zuständig ist. Meist ist sie identisch für alle Geräte eines Typs
Um ein LoRaWAN-Gerät zu benutzen, muss dieses erst in einem Application-Server registriert werden. Dabei werden die drei Werte eingetragen. Außerdem muss dem Application-Server bei der Konfiguration eines Gerätes noch ein einfacher in der Sprache Javascript geschriebener Decoder mitgegeben werden, der benötigt wird, um den binären Inhalt der Nachricht in eine Nachricht im JSON-Format zu dekodieren. Erst nach dieser Konfiguration sollte das Gerät eingeschaltet werden.
Nach dem ersten Einschalten wird eine Kopplung zwischen dem Gerät und dem Application-Server durchgeführt, die als Join bezeichnet wird. Dazu sendet das LoRaWAN-Gerät eine Nachricht mit seiner dev-eui und der join-eui. Ein LoRaWAN-Gateway, das diese Nachricht empfangen hat, fragt mit den Informationen daraus die konfigurierten Application-Server an. Wenn sich einer meldet, dem diese Daten bekannt sind, werden in Zukunft alle Nachrichten dieses Geräts an den Application-Server gesendet. Die Antwort des Application-Servers wird an das LoRaWAN-Gerät geschickt. In dem Join wird zwischen Gerät und Application-Server ein zufälliger Schlüssel vereinbart, mit dem die Nachrichten zwischen ihnen in Zukunft verschlüsselt werden.
Je nach Typ des LoRaWAN-Geräts wird so ein Join wiederholt, wenn der Versand einer Nachricht später fehlschlägt. Bei Zählern erfolgt aus Datenschutzgründen eine solche Wiederholung nicht. Um ein neues Join durchzuführen, muss im Zähler mit einem Kommando explizit ein Reset der LoRaWAN-Schnittstelle ausgeführt werden. Dieser Reset wird über versteckte Menü-Kommandos oder spezielle Interfaces ausgelöst. Ein späterer Wechsel auf einen anderen Application-Server ist deshalb aufwendig, die Wahl des Application-Servers sollte also gut bedacht sein.
Nach dem Join sendet der Zähler einmal täglich den aktuellen Zählerstand. Der Empfang der Nachricht wird vom Application-Server bestätigt. Wenn diese Bestätigung nicht eintrifft, wird die Nachricht mehrfach wiederholt. Sollte auch dann keine Bestätigung eintreffen, wird ein Zähler für fehlgeschlagene Versuche erhöht, der im Zählermenü angezeigt werden kann.
Der Application-Server benutzt nach dem Empfang einer Nachricht den konfigurierten Javascript-Decoder, um den binären Inhalt in eine Nachricht im JSON-Format zu dekodieren, die er zusätzlich mit vielen weiteren Informationen anreichert. Die erzeugte JSON-Nachricht wird dann über das Protokoll MQTT weiter gesendet, wenn sich ein MQTT-Empfänger beim Application-Server registriert hat. Auch MQTT kann in einem verschlüsselten Modus betrieben werden, sodass der Datenschutz weiterhin gewährleistet ist.
Beispiel-Nachricht
Unten sieht man ein Beispiel für eine JSON-Nachricht eines Wärmemengenzählers. Sie stammt von einem TTN-Application-Server. Das JSON-Format eines ChirpStack-Servers unterscheidet sich davon, enthält aber dieselben Inhalte. Von den enthaltenen Informationen sind die folgenden Abschnitte wichtig:
device-identhält eine Geräte-Identifikation, die Sie bei der Registrierung des Zählers beliebig wählen könnenapplication_identhält einen Namen der Applikation, die Sie im Application-Server angelegt haben und unter der dieser Zähler registriert istdev_euienthält die dev-eui, die in diesem Fall als Zählernummer aufgefasst werden kanndecoded_payloadenthält die vom Zähler versendete dekodierte Nachricht. Der für das Beispiel verwendete Zähler ist ein Zähler der Firma Zenner. Die genauen Inhalte sind abhängig vom Zähler und dem verwendeten Decoder-Skript.- Das Feld
energyenthält den Zählerstand. Die Zähler der Firma Zenner senden immer den Stand des Zählers um 00:00 Uhr des Tages, auch wenn der Versand erst später erfolgt - In
energyUnitist die verwendete Einheit angegeben - Das Feld
statuseinen aktuellen Status. Bei Fehlern wären hier weitere Informationen zu sehen
- Das Feld
{
"end_device_ids":{
"device_id":"waerme-eg",
"application_ids":{
"application_id":"app-id"
},
"dev_eui":"0123456789123456",
"join_eui":"04B6480000000000",
"dev_addr":"260B251F"
},
"correlation_ids":["gs:uplink:01K1HM87GTGS7VT9TKK6B7B6T4"],
"received_at":"2025-08-01T01:34:25.511446707Z",
"uplink_message":{
"session_key_id":"AYTYROa+iv0kRnI1PmVMsg==",
"f_port":1,
"f_cnt":1042,
"frm_payload":"UeMRAAAAAAAAAAA=",
"decoded_payload":{
"energy":4579,
"energyUnit":"kWh",
"status":""
},
"rx_metadata":[
{
"gateway_ids":{
"gateway_id":"gateway-id",
"eui":"1234567890123456"
},
"time":"2025-08-01T01:34:25.282420Z",
"timestamp":1852176022,
"rssi":-93,
"channel_rssi":-93,
"snr":7.2,
"frequency_offset":"6361",
"location":{
"latitude":52.123456789012345,
"longitude":8.123456789012345,
"altitude":80,
"source":"SOURCE_REGISTRY"
},
"uplink_token":"Ch0KGwoPaHBoLWxvcmEtZ3ctZG9lEgioQEH//yLZTBCW7ZfzBhoMCKGzsMQGEM/FiZEBIPDzrPLz0iA=",
"channel_index":5,
"received_at":"2025-08-01T01:34:25.259344993Z"
}
],
"settings":{
"data_rate":{
"lora":{
"bandwidth":125000,
"spreading_factor":12,
"coding_rate":"4/5"
}
},
"frequency":"867500000",
"timestamp":1852176022,
"time":"2025-08-01T01:34:25.282420Z"
},
"received_at":"2025-08-01T01:34:25.307015074Z",
"confirmed":true,
"consumed_airtime":"1.482752s",
"network_ids":{
"net_id":"000013",
"ns_id":"EC656E0000000181",
"tenant_id":"ttn",
"cluster_id":"eu1",
"cluster_address":"eu1.cloud.thethings.network"
},
"last_battery_percentage":{
"f_cnt":1041,
"value":30.83004,
"received_at":"2025-07-31T01:34:39.515024151Z"
}
}
}
