Framecounter

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:

Beispiel _raw-Datenpunkt
{
  "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.

Wurde das Virtuelle Gerät ausgewählt, wird die Liste an vorhandenen Datenpunkten ausgewählt. Hier wählen wir den ersten Datenpunkt mit Schlüssel _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 falsezurü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.