[SOLVED] Integrating an array of data from TTStack into Ubidots

I’m new to both The Things Stack and Ubidots. My question is the following: inside The Things Stack application, through the payload formatter, I got a vector with 64 bytes that I would like to plot with Ubidots. My problem is that I need to introduce a time interval between each value of the vector of 100 milliseconds, in order to be able to plot well the signal that represents the vector that arrives to The Things Stack. In this application I see many tutorials in which only one data arrives, it is plotted, and after some time the next one arrives. I would like to know if it would be possible that, instead of a single piece of data arriving, a vector of points arrives and that this vector is plotted correctly in Ubidots, or if there is another application for my question. Thank you very much in advance!

Hi @davidpatrizi,

This one is a bit more tricky but definitely doable. First of all, I suggest learning how to send multiple logged/timestamped values to Ubidots (see the " Send historical data to a Device (data logger)" example.

I guess you have already decoded the 64 bytes long data frame into a decimal vector of values (because Ubidots only receives numerical values, not bytes). If that’s true, you next need at least an initial timestamp, from which you can add 100 ms to each value and build an Ubidots compatible payload like the below:

{
  "temperature": [
    {"value": 10,"timestamp": 1634336087000},
    {"value": 11,"timestamp": 1634336087100},
    {"value": 12,"timestamp": 1634336087200},
    ···, // Other values in between
    {"value": 11,"timestamp": 1634336087300}
  ]
}

With respect to the timestamp, you can either send it directly from the device (in case it has a RTC), or get one at the time of execution of the Payload formatter like this:

var date = new Date()
date.getTime()

This how I sort of imagine the Payload decoder, assuming values is a vector of decimal values that you already decoded from bytes:

var values = [12, 23, 45, 65]; // Your vector of values
var ubiListOfValues = [];
var ubiPayload = {}
var initDate = new Date();
var initTs = initDate.getTime();
values.forEach((currentValue) => {
    ubiListOfValues.push({"value": currentValue, "timestamp": initTs})
    initTs += 100; // Add 100 ms to the initial timestamp.
}); 
ubiPayload.variableLabel = ubiListOfValues; // You need to replace "variableLabel" with your actual variable label. Note that variable label can only contain alphanumeric characters, hyphens ("-") and underscores ("_").

Notes:

  1. All of the above should take place in your Payload formatter at TTS.
  2. Read the comments in the code snippet.
  3. I recommend integrating your TTS data through the Ubidots TTS Plugin. Doing so will make the integration easier, and you will only need to adjust the Payload formatter and no more.

Have a good one!

–D

1 Like

Wow, thank you so much, it’s been a great help, it’s just what I needed to move forward. I’m using the Ubidots Plugin, as I had seen your video and thought it would be a good idea, but I’m a bit lost on how I can modify the “Decoding Function” of Ubidots to get a good graph of my data. Here is an example of how I have the data represented in The Things Stack. Thanks in advance!

image

Hi @davidpatrizi

Seems David’s help did allow you to decoded you logged data into an array of values that is compatible with our API.
Now, please use the following decoder in your Ubidots TTS plugin.

function format_payload(args){
  var ubidots_payload = {};
  // Log received data for debugging purposes:
  console.log(JSON.stringify(args));
  // Get Fcnt and Port variables:
  ubidots_payload['f_cnt'] = args['uplink_message']['f_cnt'];
  ubidots_payload['f_port'] = args['uplink_message']['f_port'];
  
  // Get uplink's timestamp
  ubidots_payload['timestamp'] = new Date(args['uplink_message']['received_at']).getTime(); 
  
  // If you're already decoding in TTS using payload formatters, 
  // then uncomment the following line to use "uplink_message.decoded_payload".
  // PROTIP: Make sure the incoming decoded payload is an Ubidots-compatible JSON (See https://ubidots.com/docs/hw/#sending-data)
  var decoded_payload = args['uplink_message']['decoded_payload'];
 
  Object.assign(ubidots_payload, decoded_payload);
  return ubidots_payload
}

module.exports = { format_payload };

For your reference, the important portion is reading the uplink_message.decoded_payload key, which contains the Ubidots compatible JSON.

Does it make sense?

1 Like

Thank you very much! You have helped me a lot, Java programming is not one of my virtues, thank you very much for making my project possible!

2 Likes

If anyone have any other suggestions, please let me know! thanks all!