Hello @RockiesIOT
I know you’ve already created your The Things Stack plugin to integrate your data coming from the new TTS v3 community version. That’s great by the way.
Now, I’ve inspected the logs of your plugin, that you can found here and then going to respective section
This plugin not only sends the variables in the “decoded_payload” key but also adds others from the metadata sent by TTS. However this conflicts with the STEM accounts limitations, particularly the 10 variables per Device hard stop.
With this in mind, you’ll see that our API response says “You have exceeded the maximum number of variables that can be created
” for some of the variables.
I recommend the following:
- Change your decoder within The Things Stack to match the below format. Pay attention to the comments I’m leaving in the JSON
Doing this will reduce you number of variables to 9 and guarantee the correct format.
{
“ALARM_status”: "FALSE", // Ubidots doesn't accept string values. Change "FALSE" to 0 and "TRUE" to 1
“BatV”: 4.036,
“FW”: 162,
“HDOP”: null, // Same here. Null isn't valid. If null don't send this variable
“LON”: “ON”, // Change "ON" to 1 and "OFF" to 0
“MD”: “Disable”, // This one needs changing as well
“Pitch”: 0,
“Roll”: 0,
“position”: {
“value”: {altitude}, // Instead of sending the Altitude as a separate variable, send it as a the value for the "position" variable
“context”: {
“lat”: 51.176432,
“lng”: -115.563465
}
}
- Update the decoder code (found above the Logs) to the following:
I’ve removed all of the extra metadata added to the payload. With this, only the variables coming in decoded_payload
will be sent to Ubidots.
function format_payload(args) {
console.log(`args from TTS: ${JSON.stringify(args)}`);
var ubidots_payload = {};
// Get uplink's timestamp
ubidots_payload['timestamp'] = new Date(args['uplink_message']['received_at']).getTime();
// See if there's a decoded payload already
var decoded_payload = {};
if("decoded_payload" in args['uplink_message']){
// If "uplink_message.decoded_payload" is found, then it will be used, and "uplink_message.frm_payload" will be ignored
decoded_payload = args['uplink_message']['decoded_payload'];
console.log(`Decoded payload found! --> ${JSON.stringify(decoded_payload)}`);
}
else{
// If no decoded_payload was found, then decode "uplink_message.frm_payload" here:
let bytes = new Buffer(args['uplink_message']['frm_payload'], 'base64');
decoded_payload = decodeUplink(bytes)['data'];
}
// Merge decoded payload into Ubidots payload
Object.assign(ubidots_payload, decoded_payload);
return ubidots_payload
}
function decodeUplink(bytes) {
// Decoder for the RAK1906 WisBlock Environmental Sensor (https://store.rakwireless.com/products/rak1906-bme680-environment-sensor)
var decoded = {};
if (bytes[0] == 1) {
// If received data is of Environment Monitoring type
decoded.temperature = (bytes[1] << 8 | (bytes[2])) / 100;
decoded.humidity = (bytes[3] << 8 | (bytes[4])) / 100;
decoded.pressure = (bytes[8] | (bytes[7] << 8) | (bytes[6] << 16) | (bytes[5] << 24)) / 100;
decoded.gas = bytes[12] | (bytes[11] << 8) | (bytes[10] << 16) | (bytes[9] << 24);
}
return {"data": decoded};
}
module.exports = { format_payload };
- Delete the variables “altitude”, “F port”, “Frame counter”, “latitude” and “longitude” to make room for the others.
UPDATE: By the way, I already modified the TTS decoder to reflect the changes proposed in point 1 except for the condition for the “HDOP” variable.
function Decoder(bytes, port) {
// Decode an uplink message from a buffer
// (array) of bytes to an object of fields.
var latitude;//gps latitude,units: °
latitude = (bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]) / 1000000; // gps latitude,units: °
var longitude;
longitude = (bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7]) / 1000000; // gps longitude,units: °
var alarm = (bytes[8] & 0x40) ? 1 : 0; // Alarm status
var batV = (((bytes[8] & 0x3f) << 8) | bytes[9]) / 1000; // Battery,units:V
if (bytes[10] & 0xC0 == 0x40) {
var motion_mode = "Move";
}
else if (bytes[10] & 0xC0 == 0x80) {
motion_mode = "Collide";
}
else if (bytes[10] & 0xC0 == 0xC0) {
motion_mode = "User";
}
else {
motion_mode = "Disable";
} //mode of motion
var led_updown = (bytes[10] & 0x20) ? 1 : 0; // LED status for position,uplink and downlink
var Firmware = 160 + (bytes[10] & 0x1f); // Firmware version; 5 bits
var roll = (bytes[11] << 8 | bytes[12]) / 100; // roll,units: °
var pitch = (bytes[13] << 8 | bytes[14]) / 100; // pitch,units: °
var hdop = 0;
if (bytes[15] > 0) {
hdop = bytes[15] / 100; // hdop,units: °
}
else {
hdop = bytes[15];
}
var altitude = (bytes[16] << 8 | bytes[17]) / 100; // Altitude,units: °
return {
position: { "value": altitude, "context": { "lat": latitude, "lng": longitude } },
Roll: roll,
Pitch: pitch,
BatV: batV,
ALARM_status: alarm,
MD: { "value": 1, "context": { "md": motion_mode } },
LON: led_updown,
FW: Firmware,
HDOP: hdop,
};
}
Best,
–David