Decoding Winext GPS tracker data

Hi

I’m trying to do a custom decode on a application with devices.

My decode function is as follows.

function Decode(fPort, bytes) {

function base64toHEX(base64) {    //// Convert To HEX
  var raw = atob(base64);
  var HEX = '';
  for (i = 0; i < raw.length; i++) {
    var _hex = raw.charCodeAt(i).toString(16)
    HEX += (_hex.length == 2 ? _hex : '0' + _hex);
  }
  return HEX.toUpperCase();
}

var Hex = base64toHEX(bytes);
var spHex = Hex.split('');

var antiDismantled = spHex[0]+spHex[1];
var Gsensor = spHex[2]+spHex[3];
var charGing =  spHex[4]+spHex[5];
var volts = "0x"+spHex[6]+spHex[7];
volts = volts/10;

var latTemp = "0x"+spHex[8]+spHex[9]+spHex[10]+spHex[11]+spHex[12]+spHex[13];
var lngTemp = "0x"+spHex[14]+spHex[15]+spHex[16]+spHex[17]+spHex[18]+spHex[19];
var lat = 0;
var lng = 0;

if(latTemp > 0x7FFFFF) {
    lat = - (0x01000000 - latTemp) * 90 / 0x800000;
}else{
    lat = (latTemp) * 90 / 0x7FFFFF;
}
if(lngTemp > 0x7FFFFF) {
    lng = - (0x01000000 - lngTemp) * 180 / 0x800000;
}else{
    lng = (lngTemp) * 180 / 0x7FFFFF;
}
return {AntiDismantled:antiDismantled,Gsensor:Gsensor,charGing:charGing,volts:volts,latitude:lat,longitude:lng};

}

But in the MQTT is only get

application/6/node/70c5a8ffee000020/rx {“applicationID”:“6”,“applicationName”:“Wi360_Tracker”,“deviceName”:“WI360_001”,“devEUI”:“70c5a8ffee000020”,“rxInfo”:[{“mac”:“b827ebfffec0f3de”,“rssi”:-16,“loRaSNR”:7.8,“name”:“RakGW001”,“latitude”:-24.672563155826822,“longitude”:25.938591957092285,“altitude”:0}],“txInfo”:{“frequency”:867700000,“dataRate”:{“modulation”:“LORA”,“bandwidth”:125,“spreadFactor”:9},“adr”:false,“codeRate”:“4/5”},“fCnt”:1047,“fPort”:33,“data”:“AQABKQAAAAAAAA==”,“object”:null}

object stays null

But when it run it in jsfiddle is works.

Is my objects wrongly formatted?

Thanks

What do you see:

  • on the MQTT .../error topic
  • in the live events tab
  • or in the LoRa App Server log?

Hi

On the Error topic there is nothing.

But on the App server log i get the following.

Jul 10 19:00:19 lora-srv lora-app-server[1643]: time="2018-07-10T19:00:19Z" level=error msg="decode payload error" application_id=6 codec=CUSTOM_JS dev_eui=xxxx error="js vm error: ReferenceError: 'atob' is not defined" f_cnt=1304 f_port=33

Jul 10 19:00:19 lora-srv lora-app-server[1643]: time="2018-07-10T19:00:19Z" level=info msg="handler/mqtt: publishing data-up payload" topic="application/6/node/xxxx/rx"

Jul 10 19:00:22 lora-srv lora-app-server[1643]: time="2018-07-10T19:00:22Z" level=error msg="decode payload error" application_id=6 codec=CUSTOM_JS dev_eui=xxxx error="js vm error: ReferenceError: 'atob' is not defined" f_cnt=1304 f_port=33

Jul 10 19:00:22 lora-srv lora-app-server[1643]: time="2018-07-10T19:00:22Z" level=info msg="handler/mqtt: publishing data-up payload" topic="application/6/node/xxxx/rx"

“‘atob’ is not defined”

aaaagggg looks like atob is not supported by the app server.

Hi

is there a function on the app server that can decode from base64 to hex?

it wont allow my function to work. :sob:

function base64toHEX(base64) {    //// Convert To HEX
  var raw = atob(base64);
  var HEX = '';
  for (i = 0; i < raw.length; i++) {
    var _hex = raw.charCodeAt(i).toString(16)
    HEX += (_hex.length == 2 ? _hex : '0' + _hex);
  }
  return HEX.toUpperCase();
}

atob(); is not supported and charCodeAt();

:soccer: :fr:

Why would you want to encode byte64 to hex?

// Decode decodes an array of bytes into an object.
//  - fPort contains the LoRaWAN fPort number
//  - bytes is an array of bytes, e.g. [225, 230, 255, 0]
// The function must return an object, e.g. {"temperature": 22.5}
function Decode(fPort, bytes) {
  return {};
}

// - bytes is an array of bytes, e.g. [225, 230, 255, 0]

Bytes is an array containing the byte values, it is not a string.

Hi

the device results are in hex. My knowledge of bytes a very little, will go to google, lol

http://test.wi360.net/LoRaWAN_Protocol_FPort_and_FRMPayload.pdf

I don’t think it is. The document describes a payload of 10 bytes, the examples are printed in HEX for your convenience. The bytes given to the Decode functions are the actual byte values, not a HEX string.

Hi

I did the following.

Data: AQAAKNzoqRJxtw==

HEX: 00010029000000000000

function Decode(fPort, bytes) {
return {fPort:fPort,bytes1:bytes[0],bytes2:bytes[1],bytes3:bytes[2],bytes4:bytes[3],bytes5:bytes[4],bytes6:bytes[5],bytes7:bytes[6],bytes8:bytes[7],bytes9:bytes[8],bytes10:bytes[9]};
}

“bytes1”:0 ->hex:00
“bytes2”:1 ->hex:01
“bytes3”:0 ->hex:00
“bytes4”:41 ->hex:29
“bytes5”:0 ->hex:00
“bytes6”:0 ->hex:00
“bytes7”:0 ->hex:00
“bytes8”:0 ->hex:00
“bytes9”:0 ->hex:00
“bytes10”:0 ->hex:00

Does it look like i’m on the right track?

Hi

I managed to do a decoding.

"object":{"AntiDismantled":0,"Gsensor":0,"charGing":0,"latitude":-24.672943353652954,"longitude":25.93713592733573,"volts":4.1}

function Decode(fPort, bytes) {
  if(fPort == 33){
    function intFromBytes( x ){
        var val = 0;
        for (var i = 0; i < x.length; ++i) {        
            val += x[i];        
            if (i < x.length-1) {
                val = val << 8;
            }
        }
        return val;
    }
    
    var antiDismantled = bytes[0];
    var Gsensor = bytes[1];
    var charGing =  bytes[2];
    var volts = bytes[3];
    volts = volts/10;
    
    var byteArrayLAT = [bytes[4],bytes[5],bytes[6]];
    var latTemp = intFromBytes(byteArrayLAT);
    
    var byteArrayLNG = [bytes[7],bytes[8],bytes[9]];
    var lngTemp = intFromBytes(byteArrayLNG);
    var lat = 0;
    var lng = 0;

    if(latTemp > 0x7FFFFF) {
        lat = - (0x01000000 - latTemp) * 90 / 0x800000;
    }else{
        lat = (latTemp) * 90 / 0x7FFFFF;
    }
    if(lngTemp > 0x7FFFFF) {
        lng = - (0x01000000 - lngTemp) * 180 / 0x800000;
    }else{
        lng = (lngTemp) * 180 / 0x7FFFFF;
    }
    return {AntiDismantled:antiDismantled,Gsensor:Gsensor,charGing:charGing,volts:volts,latitude:lat,longitude:lng};
  }else{
    return {};
  }
}

Thank you very much for all your help, i see now what you mean by bytes.

Great you’ve solved the issue :slight_smile: I’ve renamed the topic so that it is easier to find for others that want to decode the same payload!

1 Like

sorry to raise an old thread, I am however battling with a codec for the WINEXT AN106 field tester.

I found this for Helium, however I need it for CS and just cannot seem to get it right.

This is what i have:

function Decode(fPort, bytes)  {

var lat = ((bytes[0] << 16) | (bytes[1] << 8) | bytes[2])

if (lat & 0x800000)
    lat |= ~0xffffff;
    
var lon = ((bytes[3] << 16) | (bytes[4] << 8) | bytes[5])

if (lon & 0x800000)
    lon |= ~0xffffff;
    
  return {
    {latitude: lat / (2.**23 - 1) * 90,
    longitude: lon / (2.**23 - 1) * 180,
    altitude: (bytes[6] << 8) | bytes[7],
    accuracy: 0
};
}

Has anyone got this working?

For those looking, this seems to be working:

function Decode(fPort, bytes) {
var lat = ((bytes[0] << 16) | (bytes[1] << 8) | bytes[2])

if (lat & 0x800000)
    lat |= ~0xffffff;
    
var lon = ((bytes[3] << 16) | (bytes[4] << 8) | bytes[5])

if (lon & 0x800000)
    lon |= ~0xffffff;
    
  return {
    latitude: lat / (Math.pow(2, 23) - 1) * 90,
    longitude: lon / (Math.pow(2, 23) - 1) * 180,
    altitude: (bytes[6] << 8) | bytes[7],
    accuracy: 0
  };
}
1 Like