Adeunis Field Tester payload decoder

Hi!

Is there anyone who has a working decoder for the Adeunis Field Tester?

I would also be interested in this.

Wouldn’t it be a good ide to have a library for nodes/devices where people can contribute their codecs?

3 Likes

Here is codec I’m using, it is just slightly modified ttn decoder. Hope it helps.

// Adeunis field tester decoder

function Decode( fPort, bytes ) 

{

// Functions

function parseCoordinate( raw_value, coordinate )

{

// This function parses a coordinate payload part into 

// dmm and ddd 

var raw_itude = raw_value;

var temp	= "";


// Degree section

var itude_string = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


itude_string += ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


coordinate.degrees += itude_string;

itude_string += "°";


// Minute section

temp   = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


temp	+= ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;

itude_string += temp;

itude_string += ".";

coordinate.minutes += temp;


// Decimal section

temp   = ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


temp	+= ( (raw_itude >> 28) & 0xF ).toString( );

raw_itude <<= 4;


itude_string += temp;

coordinate.minutes += ".";

coordinate.minutes += temp;



return itude_string;

}

function parseLatitude( raw_latitude, coordinate )

{

var latitude = parseCoordinate( raw_latitude, coordinate );

latitude   	+= ((raw_latitude & 0xF0) >> 4).toString( );

coordinate.minutes	+= ((raw_latitude & 0xF0) >> 4).toString( );


return latitude;

}

function parseLongitude( raw_longitude, coordinate )

{

var longitude = ( ((raw_longitude >> 28) & 0xF )  ).toString( );

coordinate.degrees	= longitude;

longitude	+= parseCoordinate( raw_longitude << 4, coordinate );


return longitude;

}

function addField( field_no, payload ) 

{

switch( field_no )

{

// Presence of temperature information

case 0: 

payload.temperature = bytes[bytes_pos_] & 0x7F;

// Temperature is negative

if( (bytes[bytes_pos_] & 0x80) > 0 )

{

payload.temperature	-= 128;

}

bytes_pos_++;

break;

// Transmission triggered by the accelerometer

case 1: 

payload.trigger = "accelerometer";

break;

// Transmission triggered by pressing pushbutton 1

case 2: 

payload.trigger = "pushbutton";

break;

// Presence of GPS information

case 3: 

// GPS Latitude

// An object is needed to handle and parse coordinates into ddd notation

var coordinate	= {};

coordinate.degrees = "";

coordinate.minutes	= "";


var raw_value	= 0;

raw_value	|= bytes[bytes_pos_++] << 24;

raw_value	|= bytes[bytes_pos_++] << 16;

raw_value	|= bytes[bytes_pos_++] << 8;

raw_value	|= bytes[bytes_pos_++];


payload.lati_hemisphere	= (raw_value & 1) == 1 ? "South" : "North";

payload.latitude_dmm	= payload.lati_hemisphere.charAt( 0 ) + " ";

payload.latitude_dmm	+= parseLatitude( raw_value, coordinate );

payload.latitude	= ( parseFloat( coordinate.degrees ) + parseFloat( coordinate.minutes ) / 60 ) * ( (raw_value & 1) == 1 ? -1.0 : 1.0);


// GPS Longitude

coordinate.degrees = "";

coordinate.minutes	= "";

raw_value	= 0;

raw_value	|= bytes[bytes_pos_++] << 24;

raw_value	|= bytes[bytes_pos_++] << 16;

raw_value	|= bytes[bytes_pos_++] << 8;

raw_value	|= bytes[bytes_pos_++];


payload.long_hemisphere	= (raw_value & 1) == 1 ? "West" : "East";

payload.longitude_dmm	= payload.long_hemisphere.charAt( 0 ) + " ";

payload.longitude_dmm	+= parseLongitude( raw_value, coordinate );

payload.longitude	= ( parseFloat( coordinate.degrees ) + parseFloat( coordinate.minutes ) / 60 ) * ( (raw_value & 1) == 1 ? -1.0 : 1.0);


// GPS Quality

raw_value	= bytes[bytes_pos_++];


switch( (raw_value & 0xF0) >> 4 )

{

case 1: 

payload.gps_quality = "Good";

break;

case 2: 

payload.gps_quality = "Average";

break;

case 3: 

payload.gps_quality = "Poor";

break;

default:

payload.gps_quality = (raw_value >> 4) & 0xF;

break;

}

payload.hdop	= (raw_value >> 4) & 0xF;


// Number of satellites

payload.sats	= raw_value & 0xF;


break;

// Presence of Uplink frame counter

case 4: 

payload.ul_counter	= bytes[bytes_pos_++];

break;

// Presence of Downlink frame counter

case 5: 

payload.dl_counter	= bytes[bytes_pos_++];

break;

// Presence of battery level information

case 6: 

payload.battery_level	= bytes[bytes_pos_++] << 8;

payload.battery_level	|= bytes[bytes_pos_++];

break;

// Presence of RSSI and SNR information

case 7: 

// RSSI

payload.rssi_dl	= bytes[bytes_pos_++];

payload.rssi_dl	*= -1;


// SNR

payload.snr_dl	= bytes[bytes_pos_] & 0x7F;

if( (bytes[bytes_pos_] & 0x80) > 0 )

{

payload.snr_dl	-= 128;

}

bytes_pos_++;

break;

default:

// Do nothing

break;

}

}


// Declaration & initialization

var status_ = bytes[0];

var bytes_len_	= bytes.length;

var bytes_pos_	= 1;

var i = 0;

var payload	= {};


// Get raw payload

var temp_hex_str = ""

payload.payload  = "";

for( var j = 0; j < bytes_len_; j++ )

{

  temp_hex_str   = bytes[j].toString( 16 ).toUpperCase( );

  if( temp_hex_str.length == 1 )

  {

    temp_hex_str = "0" + temp_hex_str;

  }

payload.payload += temp_hex_str;

}


// Get payload values

do 

{

// Check status, whether a field is set

if( (status_ & 0x80) > 0 )

{

addField( i, payload );

}

i++;

}

while( ((status_ <<= 1) & 0xFF) > 0 );


    return payload;

}

Thanks!!
Hmm… is there somethong wrong with it? i got this in my mqtt stream on this decoder…

“type”:“CODEC”,“error”:“js vm error: (anonymous): Line 24:12 Unexpected token ILLEGAL (and 66 more errors)”

That would be great!! i think it should be on a special page at loraserver.io and not in the forums…

Perhaps a managed GitHub repository that accepts pull requests…

I have this decoder running on my latest version loraserver under device profile for adeunis field tester. Check that you did not get any extra while copying or that you dont miss any brackets etc. Been using it for couple of months now without issues.
Here is example output under device data using this decoder (position data anonymized):

  • battery_level:4075
  • dl_counter:11
  • gps_quality:“Good”
  • hdop:1
  • lati_hemisphere:“North”
  • latitude:**.62068333333333
  • latitude_dmm:“N **°37.241”
  • long_hemisphere:“East”
  • longitude:**.2815
  • longitude_dmm:“E 0**°16.89”
  • payload:“BF********************07”
  • rssi_dl:-46
  • sats:7
  • snr_dl:7
  • temperature:25
  • trigger:“pushbutton”
  • ul_counter:11

hmm, i tried three times, copy straight from here, copy via programmers notepad, cleaning up blank lines… but no, i get the same error…

Oct 28 15:52:31 lorawan lora-app-server[1607]: time=“2019-10-28T15:52:31+01:00” level=error msg=“decode payload error” application_id=3 codec= dev_eui=0018b200000215b6 error=“js vm error: (anonymous): Line 14:12 Unexpected token ILLEGAL (and 66 more errors)” f_cnt=20 f_port=1

I did some testing and when I compare the decoder copied from here and copied from loraserver in sublime all the quotes etc. seem to be changed so this is probably the cause for the error since the error you get is usually caused by illegal characters.
I have saved the decoder and zip´d it so it stays intact. Try if it works.
Adeunis_decoder

That did it! Thanks!
I suspected something was wrong with the script when it was posted. But the zip file took care of that.

1 Like

Does this decoder insert rssi & db into along with location? as i try to locate this data i only find location in device_frmpayload_data_location as listed below.

time application_name dev_eui device_name f_port geohash latitude longitude


1572360052384613389 Nossebro_Energi 0018b200000215b6 Adeunis 1 u63512d89hqw 58.18645 12.714667

or is it hiding someplace else?

Don’t really understand your question. Couple of posts up I posted the example output from this decoder, that is all the data it decodes and that is available, it includes rssi & sn data from device. If you want rssi from receiving gateway it is available via metadata.

Well, i wanted to do a coverage map in grafana and i got the locations working but i couldnt find the rssi & snr as i wanted to colour the locatations based on rssi & snr but those walues end up in another “table” and i cant get grafana to combine those… i tried som different approaches but the closest i come is that i get all locations first in series and then the rssi & snr values following the locations, not combined… but that is as i understand it a influxdb problem…