Payload Formatierung

Die Payload Formatierer erlauben es, statt auf der Ebene von einzelnen Bytes Daten zu veschicken, mit strukturierten Daten im JSON Format zu arbeiten. Das funktioniert sowohl für den Uplink als auch für den Downlink. Die Formatierer werden in die TTN Konsole eingeben, es handelt sich um JavaScript Code.

      unstrukturiert (Bytes)              strukturiert (JSON)
      ------------------------------------------------------------
      00 3f                   -->         { adc: 1536, button: 0 }
      01                      -->         { "led": "on" }

Nachdem die Formatierer angelegt wurden (siehe unten) sieht man den Uplink sofort neben den Bytes auch in strukturierter Form. Auch kann man nun beim Downlink auswählen ob man Bytes oder JSON Objekte übertragen möchte.

Payload Formatter

Siehe Verzeichnis payload. Darin sind die Quelltextdateien der Formatter.

Man kann die Formatter entweder an die Anwendung koppeln (sie gelten dann für alle Geräte dieser Anwendung) oder individuell an jedes Gerät. In diesem Beispiel ist er an der Anwendung festgemacht. Der Quelltext ist in JavaScript geschrieben (es gibt auch noch andere Formate).

Der Formatierer schreibt die ersten beiden Bytes der Payload in die Variablen button und adc. Diese werden dann in ein JSON Objekt { adc: ..., button: ... } gefüllt. Der ADC Wert wird wieder um 5 Bit nach links geschoben, so dass der ursprüngliche Wertebereich wieder hergestellt wurde (natürlich fehlen nun 5 Bit Genauigkeit, aber darum geht es hier nicht).

// Uplink formatter (decoder.js)

function decodeUplink(input) {
  var adc = 0;
  var button = 0;
  button = input.bytes[0];
  adc = input.bytes[1];
  return {
    data: {
      adc: adc << 5,
      button: button
      // bytes: input.bytes,
    }
    // warnings: [],
    // errors: []
  };
}

In der Konsole kann man beim Downlink entweder direkt die Bytes angeben (z.B. 01 (zwei Hex-Ziffern) um die LED einzuschalten), oder man kann ein JSON Objekt definieren. Für den gleichen Zweck könnte man z.B. { "led": "on" } nehmen. Die Aufgabe des Downlink Formatieres encodeDownlink() ist es, das JSON Objekt in die Bytes zu verwandeln.

Der Downlink Formatierer muss auch immer eine Umkehrungsfunktion decodeDownlink() haben, die von Bytes in das JSON Objekt umwandelt.

// Downlink formatter (encoder.js)

// Called when a downlink with decoded payload is scheduled to be sent to
// device. The result is an encoded array of bytes.
// input is either { "led": "on" } or { "led": "off" }

var led_state = ["off", "on"];

function encodeDownlink(input) {
    var b = 0;
    if (input.data.led == "on") {
        b = 1
    }
    return {
        bytes: [b],
        fPort: 1,
        warnings: [],
        errors: []
    };
}

// Decodes the binary payload back to decoded payload.
function decodeDownlink(input) {
    return {
        data: {
            // bytes: input.bytes
            led: led_state[input.bytes[0]]
        },
        warnings: [],
        errors: []
    }
}

Test der Formatierer

Die Endgeräte haben in der Konsole einen Reiter Payload formatters. Dort kann man den Uplink- und Downlink-Formatter mit Testdaten füttern und sieht dann ob er richtig funktioniert.

Test der Formatierer

Test der Formatierer

Übertragen der Formatierer mit ttn-lw-cli

Üblicherweise überträgt man die Formatierer per Copy/Paste in die entsprechenden Eingabefelder der TTN Konsole. Eleganter, da automatisierbar, ist die Übertragung per ttn-lw-cli Werkzeug. Die Formatter liegen dabei als JavaScript Dateien encoder.js und decoder.js auf der Platte.

Das Shell Skript ist in formatter/payload-formatter.sh zu finden, das ist der Inhalt:

# Muss vielleicht angepasst werden
appid=heltec-demo-1

ttn-lw-cli applications link set ${appid} \
--api-key $WORKSHOP_API_KEY \
--default-formatters.down-formatter FORMATTER_JAVASCRIPT \
--default-formatters.down-formatter-parameter-local-file "encoder.js" \
--default-formatters.up-formatter FORMATTER_JAVASCRIPT \
--default-formatters.up-formatter-parameter-local-file "decoder.js"

Payload im Base64 Format

Intern werden die Daten immer im Base64 Format übermittelt, sowohl beim Uplink als auch beim Downlink. Man sieht das auch, wenn man die Payload im JSON Format in der TTN Konsole genauer untersucht. Zum Beispiel wäre die Folge der zwei Bytes 01 3A im Base64 Format ATo=.

Das kann man mit dem Programm base64/base64tool.py zum Konvertieren von Base64 in Bytes und umgekehrt nachvollziehen. Ein paar Beispiele:

python base64tool.py -B 01 3A
ATo=

python base64tool.py -b ATo=
0x01  0x3a

python base64tool.py -B 00
AA==

Die Folge der Hex-Bytes hinter der -B Option kann beliebig lang sein.