Hi,
I am facing problem in decoding the payload received on application server:
I can see the data coming in uplink but my decode function does not work. I am using the NKE Wateco sensor and here is there decode function:
This is my data coming on application server:
EQoEAgAAKQl7
Following is js code:
function UintToInt(Uint, Size) {
if (Size === 2) {
if ((Uint & 0x8000) > 0) {
Uint = Uint - 0x10000;
}
}
if (Size === 3) {
if ((Uint & 0x800000) > 0) {
Uint = Uint - 0x1000000;
}
}
if (Size === 4) {
if ((Uint & 0x80000000) > 0) {
Uint = Uint - 0x100000000;
}
}
return Uint;
}
function decimalToHex(d, padding) {
var hex = Number(d).toString(16).toUpperCase();
padding = typeof (padding) === “undefined” || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return "0x" + hex;
}
function Bytes2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
if (exponent == -127) {
if (significand == 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);
return sign * significand * Math.pow(2, exponent);
}
function parseHexString(str) {
var result = [];
while (str.length >= 2) {
result.push(parseInt(str.substring(0, 2), 16));
str = str.substring(2, str.length);
}
return result;
}
function Decode(bytes, port) {
// Decode an uplink message from a buffer
// (array) of bytes to an object of fields.
var decoded = {};
decoded.lora = {};
decoded.lora.port = port;
// Get raw payload
var bytes_len_ = bytes.length;
var temp_hex_str = ""
decoded.lora.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;
}
decoded.lora.payload += temp_hex_str;
var date = new Date();
decoded.lora.date = date.toISOString();
}
if (port === 125)
{
//batch
batch = !(bytes[0] & 0x01);
//trame standard
if (batch === false){
decoded.zclheader = {};
decoded.zclheader.report = "standard";
attributID = -1;
cmdID = -1;
clusterdID = -1;
//endpoint
decoded.zclheader.endpoint = ((bytes[0]&0xE0)>>5) | ((bytes[0]&0x06)<<2);
//command ID
cmdID = bytes[1]; decoded.zclheader.cmdID = decimalToHex(cmdID,2);
//Cluster ID
clusterdID = bytes[2]*256 + bytes[3]; decoded.zclheader.clusterdID = decimalToHex(clusterdID,4);
// decode report and read atrtribut response
if((cmdID === 0x0a)|(cmdID === 0x8a)|(cmdID === 0x01)){
decoded.data = {};
//Attribut ID
attributID = bytes[4]*256 + bytes[5];decoded.zclheader.attributID = decimalToHex(attributID,4);
if (cmdID === 0x8a) decoded.zclheader.alarm = 1;
//data index start
if ((cmdID === 0x0a) | (cmdID === 0x8a)) index = 7;
if (cmdID === 0x01) {index = 8; decoded.zclheader.status = bytes[6];}
//temperature
if ( (clusterdID === 0x0402 ) & (attributID === 0x0000)) decoded.data.temperature = (UintToInt(bytes[index]*256+bytes[index+1],2))/100;
//humidity
if ( (clusterdID === 0x0405 ) & (attributID === 0x0000)) decoded.data.humidity = (bytes[index]*256+bytes[index+1])/100;
//binary input counter
if ( (clusterdID === 0x000f ) & (attributID === 0x0402)) decoded.data.counter = (bytes[index]*256*256*256+bytes[index+1]*256*256+bytes[index+2]*256+bytes[index+3]);
// binary input present value
if ( (clusterdID === 0x000f ) & (attributID === 0x0055)) decoded.data.pin_state = !(!bytes[index]);
//multistate output
if ( (clusterdID === 0x0013 ) & (attributID === 0x0055)) decoded.data.value = bytes[index];
// on/off present value
if ( (clusterdID === 0x0006 ) & (attributID === 0x0000)) {state = bytes[index]; if(state === 1) decoded.data.state = "ON"; else decoded.data.state = "OFF" ; }
// multibinary input present value
if ( (clusterdID === 0x8005 ) & (attributID === 0x0000))
{
decoded.data.pin_state_1 = ((bytes[index+1]&0x01) === 0x01);
decoded.data.pin_state_2 = ((bytes[index+1]&0x02) === 0x02);
decoded.data.pin_state_3 = ((bytes[index+1]&0x04) === 0x04);
decoded.data.pin_state_4 = ((bytes[index+1]&0x08) === 0x08);
decoded.data.pin_state_5 = ((bytes[index+1]&0x10) === 0x10);
decoded.data.pin_state_6 = ((bytes[index+1]&0x20) === 0x20);
decoded.data.pin_state_7 = ((bytes[index+1]&0x40) === 0x40);
decoded.data.pin_state_8 = ((bytes[index+1]&0x80) === 0x80);
decoded.data.pin_state_9 = ((bytes[index]&0x01) === 0x01);
decoded.data.pin_state_10 = ((bytes[index]&0x02) === 0x02);
}
//analog input
if ( (clusterdID === 0x000c ) & (attributID === 0x0055)) decoded.data.analog = Bytes2Float32(bytes[index]*256*256*256+bytes[index+1]*256*256+bytes[index+2]*256+bytes[index+3]);
//modbus
if ( (clusterdID === 0x8007 ) & (attributID === 0x0001))
{
decoded.data.modbus_payload = "";
decoded.data.modbus_size = bytes[index];
for( var j = 0; j < decoded.data.modbus_size -1; j++ )
{
temp_hex_str = bytes[index+j+1].toString( 16 ).toUpperCase( );
if( temp_hex_str.length == 1 )
{
temp_hex_str = "0" + temp_hex_str;
}
decoded.data.modbus_payload += temp_hex_str;
}
}
//multimodbus
if ( (clusterdID === 0x8009 ) & (attributID === 0x0000))
{
decoded.data.multimodbus_payloads = "";
decoded.data.multimodbus_size = bytes[index];
decoded.data.multimodbus_frame_series_sent = bytes[index+1];
decoded.data.multimodbus_frame_number_in_serie = (bytes[index+2] & 0xE0) >> 5;
decoded.data.multimodbus_last_frame_of_serie = (bytes[index+2] & 0x1C ) >> 2;
decoded.data.multimodbus_EP9 = ((bytes[index+2]&0x01) === 0x01);
decoded.data.multimodbus_EP8 = ((bytes[index+2]&0x02) === 0x02);
decoded.data.multimodbus_EP7 = ((bytes[index+3]&0x80) === 0x80);
decoded.data.multimodbus_EP6 = ((bytes[index+3]&0x40) === 0x40);
decoded.data.multimodbus_EP5 = ((bytes[index+3]&0x20) === 0x20);
decoded.data.multimodbus_EP4 = ((bytes[index+3]&0x10) === 0x10);
decoded.data.multimodbus_EP3 = ((bytes[index+3]&0x08) === 0x08);
decoded.data.multimodbus_EP2 = ((bytes[index+3]&0x04) === 0x04);
decoded.data.multimodbus_EP1 = ((bytes[index+3]&0x02) === 0x02);
decoded.data.multimodbus_EP0 = ((bytes[index+3]&0x01) === 0x01);
for( var j = 0; j < decoded.data.multimodbus_size - 3; j++ )
{
temp_hex_str = bytes[index+j+4].toString( 16 ).toUpperCase( );
if( temp_hex_str.length == 1 )
{
temp_hex_str = "0" + temp_hex_str;
}
decoded.data.multimodbus_payloads += temp_hex_str;
}
}
//simple metering
if ( (clusterdID === 0x0052 ) & (attributID === 0x0000)) {
decoded.data.active_energy_Wh = UintToInt(bytes[index+1]*256*256+bytes[index+2]*256+bytes[index+3],3);
decoded.data.reactive_energy_Varh = UintToInt(bytes[index+4]*256*256+bytes[index+5]*256+bytes[index+6],3);
decoded.data.nb_samples = (bytes[index+7]*256+bytes[index+8]);
decoded.data.active_power_W = UintToInt(bytes[index+9]*256+bytes[index+10],2);
decoded.data.reactive_power_VAR = UintToInt(bytes[index+11]*256+bytes[index+12],2);
}
// configuration node power desc
if ( (clusterdID === 0x0050 ) & (attributID === 0x0006)) {
index2 = index + 3;
if ((bytes[index+2] &0x01) === 0x01) {decoded.data.main_or_external_voltage = (bytes[index2]*256+bytes[index2+1])/1000;index2=index2+2;}
if ((bytes[index+2] &0x02) === 0x02) {decoded.data.rechargeable_battery_voltage = (bytes[index2]*256+bytes[index2+1])/1000;index2=index2+2;}
if ((bytes[index+2] &0x04) === 0x04) {decoded.data.disposable_battery_voltage = (bytes[index2]*256+bytes[index2+1])/1000;index2=index2+2;}
if ((bytes[index+2] &0x08) === 0x08) {decoded.data.solar_harvesting_voltage = (bytes[index2]*256+bytes[index2+1])/1000;index2=index2+2;}
if ((bytes[index+2] &0x10) === 0x10) {decoded.data.tic_harvesting_voltage = (bytes[index2]*256+bytes[index2+1])/1000;index2=index2+2;}
}
//energy and power metering
if ( (clusterdID === 0x800a) & (attributID === 0x0000)) {
index2 = index;
decoded.data.sum_positive_active_energy_Wh = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.sum_negative_active_energy_Wh = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.sum_positive_reactive_energy_Wh = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.sum_negative_reactive_energy_Wh = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.positive_active_power_W = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.negative_active_power_W = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.positive_reactive_power_W = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
index2 = index2 + 4;
decoded.data.negative_reactive_power_W = UintToInt(bytes[index2+1]*256*256*256+bytes[index2+2]*256*256+bytes[index2+3]*256+bytes[index2+4],4);
}
//energy and power metering
if ( (clusterdID === 0x800b) & (attributID === 0x0000)) {
index2 = index;
decoded.data.Vrms = UintToInt(bytes[index2+1]*256+bytes[index2+2],2)/10;
index2 = index2 + 2;
decoded.data.Irms = UintToInt(bytes[index2+1]*256+bytes[index2+2],2)/10;
index2 = index2 + 2;
decoded.data.phase_angle = UintToInt(bytes[index2+1]*256+bytes[index2+2],2);
}
}
//decode configuration response
if(cmdID === 0x07){
//AttributID
attributID = bytes[6]*256 + bytes[7];decoded.zclheader.attributID = decimalToHex(attributID,4);
//status
decoded.zclheader.status = bytes[4];
//batch
decoded.zclheader.batch = bytes[5];
}
//decode read configuration response
if(cmdID === 0x09){
//AttributID
attributID = bytes[6]*256 + bytes[7];decoded.zclheader.attributID = decimalToHex(attributID,4);
//status
decoded.zclheader.status = bytes[4];
//batch
decoded.zclheader.batch = bytes[5];
//AttributType
decoded.zclheader.attribut_type = bytes[8];
//min
decoded.zclheader.min = {}
if ((bytes[9] & 0x80) === 0x80) {decoded.zclheader.min.value = (bytes[9]-0x80)*256+bytes[10];decoded.zclheader.min.unity = "minutes";} else {decoded.zclheader.min.value = bytes[9]*256+bytes[10];decoded.zclheader.min.unity = "seconds";}
//max
decoded.zclheader.max = {}
if ((bytes[9] & 0x80) === 0x80) {decoded.zclheader.max.value = (bytes[9]-0x80)*256+bytes[10];decoded.zclheader.max.unity = "minutes";} else {decoded.zclheader.max.value = bytes[9]*256+bytes[10];decoded.zclheader.max.unity = "seconds";}
decoded.lora.payload = "";
}
}
else
{
decoded.batch = {};
decoded.batch.report = "batch";
}
}
return decoded;
}
function base64ToHex(str) {
alert (str);
for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, “”)), hex = []; i < bin.length; ++i) {
let tmp = bin.charCodeAt(i).toString(16);
if (tmp.length === 1) tmp = “0” + tmp;
hex[hex.length] = tmp;
}
return hex.join("");
}
Thanks
Asif
- List item