LoRaWAN dragino Pressure sensor payload for datacake PS-LB

I ordered one of these:

It’s a 5m depth water sensor.

PS-LB Dragino

Depth Formula

There’s a formula in the payload decoder to convert the mA to water depth:

(((decode.IDC_input_mA-4.0)(bytes[3]100/16)).toFixed(3));

Byte[3] of my dragino was returning 65, which is what it would be for a 5m sensor.

But mine must have a 4m sensor on it, because hte levels are out by 80%

I changed the 65 to 52 and it’s more accurate now.

The formula for the 5m sensor is:

depth = 65 x 100 /16 x (mA -4)

A 20ma reading would lead to 6.5m ( I guess the 5m sensor doesn’t go above 15.4mA)

Here’s the formulas I calculated for various probes to convert from mA to the depth

depth(mm) = 130 x probe length x (mA – 4)/16

5m probe depth = 5 x 130 x (mA-4)/16

Which is 650/16 x (mA-4)

4m probe = 520/16 x (mA-4)

2m probe = 260/16 x (mA-4)

1m probe = 130/16 x (mA-4)

Payload Decoder

If you have a dragino PS-LB and you want it to work in Things network you need to put this formula into the payload code.

The default payload code tries to work out the probe type (3m, 5m, etc) and use a multiplier but i found in TNN it was not reading the multiplier properly.

Mine was reading the multiplier as 65 but that’s the multiplier for the 5m version!

I multiplied the reading manually, so I needed to change this line :

decode.Water_deep_cm= parseFloat(((decode.IDC_input_mA-4.0)*(bytes[3]*100/16)).toFixed(3));

to

decode.Water_deep_cm= parseFloat(((decode.IDC_input_mA-4.0)*(65*100/16)).toFixed(3));

Here’s the new code:

PS-LB pressure sensor with 5m sensor, TNN Payload Decoder

function datalog(i,bytes){
  var aa= parseFloat((bytes[2+i]<<8 | bytes[2+i+1])/1000).toFixed(3); 
  var string='['+ aa +']'+',';  
  return string;
}

function Decoder(bytes, port) {
  if(port==5)
  {
  	var freq_band;
  	var sub_band;
    var sensor;
    
    if(bytes[0]==0x16)
      sensor= "PS-LB";
      
	  var firm_ver= (bytes[1]&0x0f)+'.'+(bytes[2]>>4&0x0f)+'.'+(bytes[2]&0x0f);
	  
    if(bytes[3]==0x01)
        freq_band="EU868";
  	else if(bytes[3]==0x02)
        freq_band="US915";
  	else if(bytes[3]==0x03)
        freq_band="IN865";
  	else if(bytes[3]==0x04)
        freq_band="AU915";
  	else if(bytes[3]==0x05)
        freq_band="KZ865";
  	else if(bytes[3]==0x06)
        freq_band="RU864";
  	else if(bytes[3]==0x07)
        freq_band="AS923";
  	else if(bytes[3]==0x08)
        freq_band="AS923_1";
  	else if(bytes[3]==0x09)
        freq_band="AS923_2";
  	else if(bytes[3]==0x0A)
        freq_band="AS923_3";
  	else if(bytes[3]==0x0F)
        freq_band="AS923_4";
  	else if(bytes[3]==0x0B)
        freq_band="CN470";
  	else if(bytes[3]==0x0C)
        freq_band="EU433";
  	else if(bytes[3]==0x0D)
        freq_band="KR920";
  	else if(bytes[3]==0x0E)
        freq_band="MA869";
  	
    if(bytes[4]==0xff)
      sub_band="NULL";
	  else
      sub_band=bytes[4];

    var bat= (bytes[5]<<8 | bytes[6])/1000;
    
  	return {
  	  SENSOR_MODEL:sensor,
      FIRMWARE_VERSION:firm_ver,
      FREQUENCY_BAND:freq_band,
      SUB_BAND:sub_band,
      BAT:bat,
  	};
  }
  else if(port==7)
  {
    var Bat= (bytes[0]<<8 | bytes[1])/1000;
    for(var i=0;i<bytes.length-2;i=i+2)
    {
      var data= datalog(i,bytes);
      if(i=='0')
        data_sum=data;
      else
        data_sum+=data;
    }
    return{
    Bat_V:Bat,
    DATALOG:data_sum
    };    
  }
  else
  {
    var decode={};
    decode.Bat_V= (bytes[0]<<8 | bytes[1])/1000;
    decode.Probe_mod= bytes[2];   
    decode.IDC_input_mA= (bytes[4]<<8 | bytes[5])/1000;  
    decode.VDC_intput_V= (bytes[6]<<8 | bytes[7])/1000; 
    decode.IN1_pin_level= (bytes[8] & 0x08)? "High":"Low";   
    decode.IN2_pin_level= (bytes[8] & 0x04)? "High":"Low";   
    decode.Exti_pin_level= (bytes[8] & 0x02)? "High":"Low";  
    decode.Exti_status= (bytes[8] & 0x01)? "True":"False";
    

        decode.Water_deep_cm= parseFloat(((decode.IDC_input_mA-4.0)*(65*100/16)).toFixed(3));

    
    if(bytes.length!=1)
    {
      return decode;
    }
  }
}

If you want to use this in datacake it needs to be modified to this:

PS-LB pressure sensor with 5m sensor, Datacake Payload Decoder

function decodeUplink(input) {
        return { 
            data: Decode(input.fPort, input.bytes, input.variables)
        };   
}
function datalog(i,bytes){
  var aa= parseFloat((bytes[2+i]<<8 | bytes[2+i+1])/1000).toFixed(3); 
  var string='['+ aa +']'+',';  
  return string;
}

function Decoder(bytes, fPort) {
    
      // Output raw payload coming from webhook of your LNS
  //  console.log(JSON.stringify(rawPayload,0,4));    
    
    
    
  if(fPort==5)
  {
  	var freq_band;
  	var sub_band;
    var sensor;
    
    if(bytes[0]==0x16)
      sensor= "PS-LB";
      
	  var firm_ver= (bytes[1]&0x0f)+'.'+(bytes[2]>>4&0x0f)+'.'+(bytes[2]&0x0f);
	  
    if(bytes[3]==0x01)
        freq_band="EU868";
  	else if(bytes[3]==0x02)
        freq_band="US915";
  	else if(bytes[3]==0x03)
        freq_band="IN865";
  	else if(bytes[3]==0x04)
        freq_band="AU915";
  	else if(bytes[3]==0x05)
        freq_band="KZ865";
  	else if(bytes[3]==0x06)
        freq_band="RU864";
  	else if(bytes[3]==0x07)
        freq_band="AS923";
  	else if(bytes[3]==0x08)
        freq_band="AS923_1";
  	else if(bytes[3]==0x09)
        freq_band="AS923_2";
  	else if(bytes[3]==0x0A)
        freq_band="AS923_3";
  	else if(bytes[3]==0x0F)
        freq_band="AS923_4";
  	else if(bytes[3]==0x0B)
        freq_band="CN470";
  	else if(bytes[3]==0x0C)
        freq_band="EU433";
  	else if(bytes[3]==0x0D)
        freq_band="KR920";
  	else if(bytes[3]==0x0E)
        freq_band="MA869";
  	
    if(bytes[4]==0xff)
      sub_band="NULL";
	  else
      sub_band=bytes[4];

    var bat= (bytes[5]<<8 | bytes[6])/1000;
    
  	return {
  	  SENSOR_MODEL:sensor,
      FIRMWARE_VERSION:firm_ver,
      FREQUENCY_BAND:freq_band,
      SUB_BAND:sub_band,
      BAT:bat,
  	};
  }
  else if(fPort==7)
  {
    var Bat= (bytes[0]<<8 | bytes[1])/1000;
    for(var i=0;i<bytes.length-2;i=i+2)
    {
      var data= datalog(i,bytes);
      if(i=='0')
        data_sum=data;
      else
        data_sum+=data;
    }
    return{
    Bat_V:Bat,
    DATALOG:data_sum
    };    
  }
  else
  {
    var decode={};
    decode.Bat_V= (bytes[0]<<8 | bytes[1])/1000;
    decode.Probe_mod= bytes[2];   
    decode.IDC_intput_mA= (bytes[4]<<8 | bytes[5])/1000;  
    decode.VDC_intput_V= (bytes[6]<<8 | bytes[7])/1000; 
    decode.IN1_pin_level= (bytes[8] & 0x08)? "High":"Low";   
    decode.IN2_pin_level= (bytes[8] & 0x04)? "High":"Low";   
    decode.Exti_pin_level= (bytes[8] & 0x02)? "High":"Low";  
    decode.Exti_status= (bytes[8] & 0x01)? "True":"False";
    
    decode.probe_multiplier = bytes[3];
    decode.Water_deep_cm= parseFloat(((decode.IDC_intput_mA-4.0)*(65*10/16)).toFixed(3));
   
    if(bytes.length!=1)
    {
      // Array where we store the fields that are being sent to Datacake
    var datacakeFields = []
    
    // take each field from decodedElsysFields and convert them to Datacake format
    for (var key in decode) {
        if (decode.hasOwnProperty(key)) {           
            datacakeFields.push({field: key.toUpperCase(), value: decode[key]})
        }
    }      
    
    // forward data to Datacake
    return datacakeFields;
    }
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *