[SOLVED] TheThingsNetwork GPS

I’m trying to implement an GPS from TTN and “Map” is not catching the Lat-Long value.
I’m using this decoder from TTN:

function Decoder(b, port) {
var lat = (b[0] | b[1]<<8 | b[2]<<16 | (b[2] & 0x80 ? 0xFF<<24 : 0)) / 10000 ;
var lng = (b[3] | b[4]<<8 | b[5]<<16 | (b[5] & 0x80 ? 0xFF<<24 : 0)) / 10000;

return {

location: {
lat: lat,
lng: lng
}
}
}

And decoded value is:

{
“location”: {
“lat”: 63.3968,
“lng”: 10.4017
}
}

But it’s shown in two different devices and not caught as a GPS coordinate.

Greetings, your device coordinates must be sent inside a variable’s context as specified at our REST API. Please reference an example below (numerical value is mandatory):

"location" : {
  "value": 1,
  "context": { "lat": 63.3968, "lng": 10.4017 }
}

All the best

I’m connecting the Tabs GPS Tracker to Ubidots and I’m facing issues with the GPS map.

The payload format I used:

function bits(value, lsb, msb) {
  var len = msb - lsb + 1;
  var mask = (1<<len) - 1;
  return value>>lsb & mask;
}

function Decoder(bytes, port) {
  var status = bits(bytes[0], 0, 7);
  var voltage = (25 + bits(bytes[1], 0, 3)) / 10;
  var bat_percentage = 100 * ((bits(bytes[1], 4, 7)) / 15);
  var temp = bits(bytes[2], 0, 7) - 32;
  var lat = ((((bytes[6] << 24) | bytes[5] << 16) | bytes[4] << 8) | bytes[3])/1000000;
  var lon = ((((bytes[10] << 24) | bytes[9] << 16) | bytes[8] << 8) | bytes[7])/1000000;
  var position = {"lat": lat, "lng": lon};

  var json={
    voltage:voltage,
    bat_percentage:bat_percentage,
    temp:temp,
    position:position,
    lat: lat,
    lon: lon
  }
  
    return json;
  }

This gives the following output in the console:

The output in Ubidots:

Somehow, the Latitude and Longitude are not recognized.

Any ideas?

Hey @laurens :wave:t2:,

I’m so happy to see you around the community, welcome. :smiley:

The payload being sent does not manage the correct format. If you refer to the Ubidots API documentation, you will notice that the payload must contain the following format:

{"position": {"value" : 1, "context":{"lat":-6.2, "lng":75.4}}}

In your case, the payload should be:

  var json={
    voltage:voltage,
    bat_percentage:bat_percentage,
    temp:temp,
    position:{"value":1, "context": position},
    lat: lat,
    lon: lon
  }

Please try again, and let me know if everything is working as it should.

Cheers,
Maria H.

1 Like

Thanks Maria, that works like a charm.

1 Like

You’re always welcome :smiley:

@laurens @jotathebest @mariahernandez am having a similar kinda error. I only want GPS data on ubidots. I don’t see any info in my ubidots dashboard. Can you please

the payload format I used


function Decoder(b, port) {


var lon  = (b[0] | b[1]<<8 | b[2]<<16 | (b[2] & 0x80 ? 0xFF<<24 : 0)) / 10000;

var lat = (b[3] | b[4]<<8 | b[5]<<16 | (b[5] & 0x80 ? 0xFF<<24 : 0)) / 10000;
var position = {"lat": lat, "lng": lon};

var json={
    
    position:{"value":1, "context": position},
    lat: lat,
    lon: lon
  }

Good day @chowden !

Thank you for sharing your question with the community.

After reviewing your payload formatted from TheThingsStack, the output JSON seems correct and in accordance with Ubidots’ HTTP data ingestion API. This points the issue to the Plugin integration you’re probably using.
As described in the Plugin user code (see below), if you’re decoding your bytes data frame with TTS’ payload formatters then you need to comment/uncomment some lines in the Plugin code:

// 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'];

With this in mind, please replace your current Plugin user code with the one below:

function format_payload(args){
  var ubidots_payload = {};
  // Log received data for debugging purposes:
  // console.log(JSON.stringify(args));
  // Get RSSI and SNR variables using gateways data:
  var gateways = args['uplink_message']['rx_metadata'];
  for (const i in gateways) {  
    // Get gateway EUI and name
    var gw = gateways[i];
    var gw_eui = gw['gateway_ids']['eui'];
    var gw_id = gw['gateway_ids']['gateway_id'];
    // Build RSSI and SNR variables
    ubidots_payload['rssi-' + gw_id] = {
      "value": gw['rssi'],
      "context": {
        "channel_index": gw['channel_index'],
        "channel_rssi": gw['channel_rssi'],
        "gw_eui": gw_eui,
        "gw_id": gw_id,
        "uplink_token": gw['uplink_token']
      }
    }
    ubidots_payload['snr-' + gw_id] = gw['snr'];

  }
  
  // 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'];
 
  // By default, this plugin uses "uplink_message.frm_payload" and sends it to the decoding function "decodeUplink".
  // For more vendor-specific decoders, check out https://github.com/TheThingsNetwork/lorawan-devices/tree/master/vendor
  // let bytes =  Buffer.from(args['uplink_message']['frm_payload'], 'base64');
  // var 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);
      decoded.lat = ((((bytes[6] << 24) | bytes[5] << 16) | bytes[4] << 8) | bytes[3])/1000000;
      decoded.lon = ((((bytes[10] << 24) | bytes[9] << 16) | bytes[8] << 8) | bytes[7])/1000000;
      decoded.position = {"lat": lat, "lng": lon};
  } 
  return {"data": decoded};
}

module.exports = { format_payload };

I hope that after making this change, the data starts to reflect in your Ubidots account.

All the best,
Ángela