Um beispielsweise Paketverluste identifizieren zu können, gibt es bei LoRaWAN einen Frame Counter. Der Frame Counter ist ein Zähler, der sich bei jeder Aussendung um 1 erhöht und dessen aktueller Wert sowohl im Endgerät als auch am LoRaWAN-Server gespeichert wird. Dabei werden alle Pakete erfasst, die Gerät an das LoRaWAN-Netzwerk übertragen werden. Dieser Wert wird auch mit der Payload übertragen und kann somit von niotix ausgelesen werden. Wie das funktioniert, wird in folgender Anleitung erklärt.
In jedem Virtuellen Gerät ist automatisch der _raw
-Datenpunkt vorhanden, in dem im JSON-Format alle vom Gerät gesendeten Werte enthalten sind.
In diesem JSON-Objekt befindet sich auch das Objekt frame_counter
.
Wie der Wert einses _raw
-Datenpunkts aussieht, ist hier zu sehen:
{
"ack": null,
"uid": "069218fa-fd24-4a16-b028-9560e642e7f7",
"port": 5,
"topic": "organizations/8046/devices/A81758FFFE03AD50",
"device": {
"id": 31767,
"eui": "A81758FFFE03AD50",
"name": "Luftqualitätssensor",
"address": "286A97AE",
"device_class_id": null,
"organization_id": 8046
},
"parsed": null,
"payload": "0100C802360400870500070DB7",
"location": null,
"mic_pass": true,
"variable": "_raw",
"bandwidth": 125,
"device_id": "A81758FFFE03AD50",
"_device_id": 31767,
"updated_at": "2023-04-19T16:27:10.345594",
"inserted_at": "2023-04-19T16:27:10.345617",
"raw_payload": "40AE976A288090CD05AFF90C098A44270229FFE8444CC71A411D",
"server_data": {
"raw": "QK6XaiiAkM0Fr/kMCYpEJwIp/+hETMcaQR0=",
"chan": 2,
"codr": "4/5",
"datr": "SF11BW125",
"freq": 868.5,
"gwrx": [
{
"lsnr": -15.2,
"rssi": -118,
"time": "2023-04-19T16:27:08.445963Z",
"tmst": 74950700,
"gweui": "0000024B0806061A",
"srv_rcv_time": 1681921628895179
}
],
"modu": "LORA",
"size": 26,
"fopts": "",
"mtype": "unconfirmed_data_up",
"mac_cmds": [],
"mic_pass": true,
"dev_addr_hex": "286a97ae"
},
"device_class": null,
"organization": {},
"frame_counter": 52624,
"parsed_packet": {
"ack": false,
"adr": true,
"dir": "up",
"fcnt": 52624,
"port": 5,
"major": 0,
"mtype": "unconfirmed_data_up",
"pending": false,
"mac_cmds": [],
"mic_pass": true,
"adrackreq": false,
"fopts_len": 0,
"dev_addr_hex": "286a97ae"
},
"organization_id": 8046,
"spreading_factor": 11,
"payload_encrypted": false
}
Design und Implementierung
1. Framecounter anlegen
Für diesen Framecounter legen wir einen neuen Datenpunkt im Virtuellen Gerät, dessen Framecounter wir erfassen wollen, an. Hierzu gehen wir im Virtuellen Gerät auf den Tab “Datenpunkte” und klicken auf den Hinzufügen-Button ().
Metadaten
In den Meta-Daten
- Titel: Framecounter
- Schlüssel: framecounter
- Einheit: -
- Icon: Als Icon bietet sich Beispielsweise “tally” an.
Quelle
Da wir ja auf einen vorhandenen Datenpunkt des aktuellen Virtuellen Geräts zugreifen wollen, wählen wir als Quelle “Virtuelle Geräte” und suchen nach dem aktuellen Gerät.
Am einfachsten geht das über die Device-ID. Diese wird in der URL angezeigt.
_raw
aus.
Den Typ ändern wir zu “number”, denn das ist der Framecounter ja.
Visualisierung
Die Visualisierung können wir bei Standard belassen, was der Zähluhr entspricht.
Javascript-Transformer
Als Quelle haben wir oben den _raw
-Datenpunkt ausgewählt. Daher entspricht der aktuelle Wert des gerade anzugelenden Datenpunktes dem JSON-Objekt dieses _raw
-Datenpunktes.
Daher müssen wir als nächsten Schritt das frame_counter
-Objekt als Wert aus dem gesamten JSON-Objekt extrahieren. Hierzu geben wir folgenden javascript-Code als Transformer ein.
module.exports = (data) => {
return data.frame_counter;
}
data
entspricht dem _raw
-Datenpunkt, da dieser oben ausgewählt wurde. Da das Objekt frame_counter
auf der obersten Hierarchieebene liegt, können wir mit data.frame_counter
auf das frame_counter
-Objekt zugreifen.
Würden wir Beispielsweise auf das Objekt address
zugreifen wollen, müssten wir `data.server_data.address’ eingeben.
Dieser Datenpunkt kann nun gespeichert werden.
2. Differenzwert berechnen anlegen
Um nun einfach zu sehen, ob ein Datenpaket verloren gegangen ist, oder ob ein Datenpaket doppelt gesendet wurde, legen wir nun einen weiteren Datenpunkt an. Dieser Datenpunkt betrachtet die Differenz der letzten beiden empfangenen Framecounter-Werte, die ja wie oben beschrieben, immer den Wert 1 ergeben sollte.
Metadaten
In den Meta-Daten
- Titel: Framecounter-Differenz
- Schlüssel: framecounter-differenz
Quelle
Als Quelle wählen wir nun “Zeitlich aggregiert” und suchen im Dropdown den zuvor angelegten Datenpunkt mit dem Titel Framecounter. Als Operation für die zeitliche aggregation selektrieren wir “Differenz zum letzten Wert”, Den Typ ändern wir dieses Mal zu “boolean”.
Javascript-Transformer
Bevor wir jetzt die Visualisierung anpassen, überspringen wir diesen Punkt und gehen zum Javaspript-Transformer und geben folgenden Javascript-Code ein:
module.exports = (data) => {
if (data != 1) {
return false;
}
return true;
}
Das Script betrachtet den Wert des Datenpunktes und gibt den Wert false
zurück, wenn der Wert NICHT einer 1 entspricht, und gibt true
zurück, wenn der Wert einer 1 entspricht.
Visualisierung
In der Visualisierung wählen wir nun für true
das Icon “check” aus und wählen als Farbe hellgrün.
Für den Wert false
wählen wir das Icon “times” aus und wählen als Farbe rot.
Es wird nun also ein grüner Haken angezeigt, wenn kein Paketverlust vorliegt und ein x, falls ein Paketverlust vorliegt.
Dieser Datenpunkt kann nun gespeichert werden.
Weitere Gedanken & Ideen
Aufbauend auf diesen Datenpunkten ergeben sich folgende Ideen:
- Eine weiterer Datenpunkt des Typs “zeitlich aggregiert”, der die Anzahl an Paketverlusten innerhalb eines Tages ausgibt.
- Eine Regel die mich per E-Mail benachrichtigt, sobald ein Paket verloren gegangen ist.
- Ein angepasster Gesundheitsstatus, der eine Warnung ausgibt, sobald zu viele Paketverluste vorliegen.