Skip to content

Instantly share code, notes, and snippets.

@CurlyWurly-1
Last active September 19, 2020 01:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save CurlyWurly-1/845bb5b8cf788939dd261f472c289f77 to your computer and use it in GitHub Desktop.
Save CurlyWurly-1/845bb5b8cf788939dd261f472c289f77 to your computer and use it in GitHub Desktop.
TheThingsNetwork TTN decrypt payload

updated 20/12/12 to suit the release of the "production" environment"

OK, this is for people who want to decode the garbled payload data seen in their "TheThingsNetwork" lorawan messages e.g.

  • Text "Hello World!" is seen as "SGVsbG8sIHdvcmxkIQ=="
  • Value "272" (transferred as 2 bytes MSB/LSB) is seen as "ARA="

Be aware that the data appears garbled because it has been encoded using "Base64" and packaged as follows. {"payload":{"payload_raw":"ARA="}}

There are 2 ways to decode the data in the payload:

    1. Use the attached flow to decode the message within Node-red (via a MQTT message)

The flow tries to help you identify how the data is packaged. Just highlight which debug output is correctly showing the data you are expecting and you can then trace back to the function code that works.

    1. Decode within the "TheThingsNetwork" backend software

If your payload is ALPHAMERIC (text), go to where you set up your "application" and add the following code in the "Decoder" section of "Payload functions" The data seen in node-red will miraculously be OK (but check if it fits the above packaging)

var result = ""; for (var i = 0; i < bytes.length; i++) { result += String.fromCharCode(parseInt(bytes[i])); } return { payload: result, };

N.B. If you add the above in the TTN backend, you will see that subsequent MQTT messages will contain an additional Tag called "payload_fields" which shows the decoded data e.g. {"payload_fields": { "payload": "Hello!" } },

N.B. If your payload is BYTES (VALUES-THE PREFERED METHOD BY WHICH TO TRANSFER DATA), look at the example node and check out the function code for ideas on how to adapt your code acordingly for binary and float values

e.g. if 4 bytes are being sent, is this for:

  • 4 distinct values (-128 to 127 or 0 to 255)
  • 1 very large value (-2147483648 to +2147483648 or 0 to 4294967295) - Also - for float values
  • 2 distinct values (-32767 to +32767 or 0 to 65535)
[{"id":"6b13d75a.780ac8","type":"mqtt in","z":"371c5602.3adbca","name":"MQTT Node - TheThingsNetwork","topic":"#","qos":"2","broker":"fb2a3684.cf4c38","x":152,"y":92,"wires":[["d4dd1fb1.22cae","9b2e45a1.f97c18"]]},{"id":"ad211251.d3aef8","type":"debug","z":"371c5602.3adbca","name":"msg.payload.payload_raw - DATA (as is)","active":true,"console":"false","complete":"payload","x":342,"y":283,"wires":[]},{"id":"d4dd1fb1.22cae","type":"function","z":"371c5602.3adbca","name":"Decrypt Payload","func":"// msg1 - Unencrypted (vanilla data)\nvar msg1 = { payload: msg.payload.length };\nmsg1.payload = JSON.parse(msg.payload);\nmsg1.payload = msg1.payload.payload_raw;\n\n// msg2 - Decrypt to Text\nvar msg2 = { payload: msg.payload.length };\nmsg2.payload = JSON.parse(msg.payload);\nmsg2.payload = new Buffer(msg2.payload.payload_raw, 'base64').toString('ascii');\n\n// msg3 - Decrypt as Binary value (MSB,LSB)\nvar msg3 = { payload: msg.payload.length };\nmsg3.payload = JSON.parse(msg.payload);\nmsg3.payload = new Buffer(msg3.payload.payload_raw, 'base64').toString('hex');\nmsg3.payload = parseInt(msg3.payload, 16);\n\nreturn [ msg1, msg2, msg3 ];","outputs":"3","noerr":0,"x":419,"y":141,"wires":[["ad211251.d3aef8"],["c1b3a1f7.8dc05"],["ac6c9888.4de598"]]},{"id":"c1b3a1f7.8dc05","type":"debug","z":"371c5602.3adbca","name":"msg.payload.payload_raw - DATA (decrypted to text)","active":true,"console":"false","complete":"payload","x":378,"y":345.5,"wires":[]},{"id":"ac6c9888.4de598","type":"debug","z":"371c5602.3adbca","name":"msg.payload.payload_raw - DATA (decrypted to Bytes HiLo)","active":true,"console":"false","complete":"payload","x":388,"y":410.5,"wires":[]},{"id":"7d86172.c8a55e8","type":"debug","z":"371c5602.3adbca","name":"message (as is)","active":true,"console":"false","complete":"payload","x":557,"y":91.5,"wires":[]},{"id":"7f316b06.9289fc","type":"inject","z":"371c5602.3adbca","name":"Byte Value example","topic":"","payload":"{\"payload_raw\":\"ARA=\"}","payloadType":"str","repeat":"","crontab":"","once":false,"x":127,"y":167,"wires":[["d4dd1fb1.22cae"]]},{"id":"669e85c.889947c","type":"inject","z":"371c5602.3adbca","name":"Text example","topic":"","payload":"{\"payload_raw\":\"SGVsbG8sIHdvcmxkIQ==\"}","payloadType":"str","repeat":"","crontab":"","once":false,"x":109,"y":217,"wires":[["d4dd1fb1.22cae"]]},{"id":"58d8e850.4765b","type":"function","z":"371c5602.3adbca","name":"Example A - Two \"byte pairs\" (4 bytes in total) for Temp and Humidity","func":"var buf = new Buffer(msg.payload.raw, 'base64'); // put in msg.payload the payload raw data stored initially as Base64\nvar node = msg.devEUI;\n\ntemp = buf[2] * 255 + buf[3];\nhum = buf[0] * 255 + buf[1];\n\n// construct a new object to store the data message\nvar data = {\npayload : [\n [{\n numValue: temp/10.0,\n time: new Date(msg.metadata.server_time).getTime()\n },\n {\n tag1:\"temp\",\n sensor:node\n }],\n [{\n numValue: hum/10.0,\n time: new Date(msg.metadata.server_time).getTime()\n },\n {\n tag1:\"hum\",\n sensor:node\n }]\n]};\nreturn data;","outputs":1,"noerr":0,"x":304,"y":479,"wires":[[]]},{"id":"9b2e45a1.f97c18","type":"json","z":"371c5602.3adbca","name":"","x":387.5,"y":92,"wires":[["7d86172.c8a55e8"]]},{"id":"7e9126c1.c6b9a8","type":"comment","z":"371c5602.3adbca","name":"For MQTT \"user\"/\"password\", use \"Application ID\"/\"default key\" ","info":"\n1) Sign in to TTN and go to your application page where \"app_1\" is your \"Application ID\" e.g.\nhttps://console.thethingsnetwork.org/applications/app_1\n\n2) For MQTT User, use \"Application ID\" \n\n3) For MQTT password, scroll to bottom and use \"default key\" (you need to press the \"eye\" to see the long text)","x":253,"y":40,"wires":[]},{"id":"240e8211.679c7e","type":"function","z":"371c5602.3adbca","name":"Example B - Two \"Float value Byte Quads\" (8 bytes in total) for Lat. and Longitude (Float)","func":"var msg2 = { payload: msg.payload.length };\nmsg2.payload = JSON.parse(msg.payload);\nmsg2.payload = new Buffer(msg2.payload.payload, 'base64').toString('hex');\nvar lat = Buffer(msg2.payload, 'hex').readFloatLE(0);\nvar lon = Buffer(msg2.payload, 'hex').readFloatLE(4);\nmsg2.payload= \"[{\\\"lat\\\":\" + lat + \",\\\"lng\\\":\" + lon + \"}]\";//\"{\"lat\":lat,\"lng\":lon};\nreturn msg2;","outputs":1,"noerr":0,"x":351,"y":531,"wires":[[]]},{"id":"fb2a3684.cf4c38","type":"mqtt-broker","z":"371c5602.3adbca","broker":"eu.thethings.network","port":"1883","clientid":"","usetls":false,"verifyservercert":true,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willRetain":null,"willPayload":"","birthTopic":"","birthQos":"0","birthRetain":null,"birthPayload":""}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment