How to get the data sent by device?

Viewed 53

I'm completely new to Chirpstack, never used this before and, quite frankly, the documentation is not very newcomer-friendly. I did manage to set up an Arduino-device, I can see it connecting to my Chirpstack-instance and I can see a message posted to topic application/6f121dc1-7e56-4713-a288-a5bd17bd5d81/device/09fd73a08f757e95/event/up on the MQTT-server, but....I have no idea how to get the data sent by the device!

I used the ttn-otaa.ino sketch as suggested by https://www.chirpstack.io/docs/chirpstack/use/devices.html#generic-arduino-lmic-based-devices and it's supposed to just send a "Hello, world!" -- it all seems to work just fine, but I can't find any explanation on why I cannot see the "Hello, world!" under any MQTT-topic. The linked page doesn't explain how one is supposed to set up profiles or devices, so I can only assume that I haven't set everything up correctly.

2 Answers

I figured out how to set up the payload codec option to encode and decode the data. Just for posterity, I'll leave the code here:

/**
 * Decode uplink function
 * 
 * @param {object} input
 * @param {number[]} input.bytes Byte array containing the uplink payload, e.g. [255, 230, 255, 0]
 * @param {number} input.fPort Uplink fPort.
 * @param {Record<string, string>} input.variables Object containing the configured device variables.
 * 
 * @returns {{data: object, errors: string[], warnings: string[]}}
 * An object containing:
 * - data: Object representing the decoded payload.
 * - errors: An array of errors (optional).
 * - warnings: An array of warnings (optional).
 */
function decodeUplink(input) {
	if(input.bytes.length == 0)
		return { data: {}};
	var result = "";
	for (var i = 0; i < input.bytes.length; i++)
		result += (String.fromCharCode(input.bytes[i]));
	result = result.replace(/\0/g, '');
	return { data: JSON.parse(result.trim())};
}

/**
 * Encode downlink function.
 * 
 * @param {object} input
 * @param {object} input.data Object representing the payload that must be encoded.
 * @param {Record<string, string>} input.variables Object containing the configured device variables.
 * 
 * @returns {{bytes: number[], fPort: number, errors: string[], warnings: string[]}}
 * An object containing:
 * - bytes: Byte array containing the downlink payload.
 * - fPort: The downlink LoRaWAN fPort.
 * - errors: An array of errors (optional).
 * - warnings: An array of warnings (optional).
 */

function encodeDownlink(input) {
  var output = JSON.stringify(input.data);
  var array = Array.from(output, (char) => char.charCodeAt(0));
  array.push(0);
  return {
    bytes: array,
  };
}

If you can see the .../event/up message using MQTT, you will see a data key in the JSON payload. Please note that this data key holds the data as a base64 encoded string. You can use this site to decode from various encodings: https://www.asciitohex.com/. In your case it should decode to the test "Hello, world!" if that is what your device is sending as bytes.