Milesight(WS52x)

I have the following ‘standard’ decoder that works in TTN but trying to get it to work in Tago’s payload parser

Can anybody help me in converting this to work on Tago connector?

Thank you.

/**

* Payload Decoder for The Things Network

*

* Copyright 2021 Milesight IoT

*

* @product WS52x

*/

function Decoder(bytes, port) {

var decoded = {};



for (var i = 0; i < bytes.length; ) {

    var channel\_id = bytes\[i++\];

    var channel\_type = bytes\[i++\];



    // VOLTAGE

    if (channel\_id === 0x03 && channel\_type === 0x74) {

        decoded.voltage = readUInt16LE(bytes.slice(i, i + 2)) / 10;

        i += 2;

    }

// ACTIVE POWER

    else if (channel\_id === 0x04 && channel\_type === 0x80) {

        decoded.power = readUInt32LE(bytes.slice(i, i + 4));

        i += 4;

    }

    // POWER FACTOR

    else if (channel\_id === 0x05 && channel\_type === 0x81) {

        decoded.factor = bytes\[i\];

        i += 1;

    }

    // POWER CONSUMPTION

    else if (channel\_id === 0x06 && channel\_type == 0x83) {

        decoded.power\_sum = readUInt32LE(bytes.slice(i, i + 4));

        i += 4;

    }

    // CURRENT

    else if (channel\_id === 0x07 && channel\_type == 0xc9) {

        decoded.current = readUInt16LE(bytes.slice(i, i + 2));

        i += 2;

    }

    // STATE

    else if (channel\_id === 0x08 && channel\_type == 0x70) {

        decoded.state = bytes\[i\] == 1 || bytes\[i\] == 0x11 ? "open" : "close";

        i += 1;

    }

else if (channel_id === 0xFF && channel_type == 0x3F) {

        decoded.outage = bytes\[i\] == 0xFF ? 1 : 0;

    } else {

        break;

    }

}



return decoded;

}

/* ******************************************

* bytes to number

********************************************/

function readUInt16LE(bytes) {

var value = (bytes\[1\] << 8) + bytes\[0\];

return value & 0xffff;

}

function readUInt32LE(bytes) {

var value = (bytes\[3\] << 24) + (bytes\[2\] << 16) + (bytes\[1\] << 8) + bytes\[0\];

return (value & 0xffffffff) >>> 0;

}

Hi Redland,

You can create the decoder like such:

/**

* Payload Decoder for The Things Network

*

* Copyright 2021 Milesight IoT

*

* @product WS52x

*/

const ignore_vars = ;

function Decoder(bytes) {

var decoded = {};

for (var i = 0; i < bytes.length; ) {

var channel_id = bytes[i++];

var channel_type = bytes[i++];

// VOLTAGE

if (channel_id === 0x03 && channel_type === 0x74) {

decoded.voltage = readUInt16LE(bytes.slice(i, i + 2)) / 10;

i += 2;

}

// ACTIVE POWER

else if (channel_id === 0x04 && channel_type === 0x80) {

decoded.power = readUInt32LE(bytes.slice(i, i + 4));

i += 4;

}

// POWER FACTOR

else if (channel_id === 0x05 && channel_type === 0x81) {

decoded.factor = bytes[i];

i += 1;

}

// POWER CONSUMPTION

else if (channel_id === 0x06 && channel_type == 0x83) {

decoded.power_sum = readUInt32LE(bytes.slice(i, i + 4));

i += 4;

}

// CURRENT

else if (channel_id === 0x07 && channel_type == 0xc9) {

decoded.current = readUInt16LE(bytes.slice(i, i + 2));

i += 2;

}

// STATE

else if (channel_id === 0x08 && channel_type == 0x70) {

decoded.state = bytes[i] == 1 || bytes[i] == 0x11 ? “open” : “close”;

i += 1;

} else if (channel_id === 0xff && channel_type == 0x3f) {

decoded.outage = bytes[i] == 0xff ? 1 : 0;

} else {

break;

}

}

return decoded;

}

/* ******************************************

* bytes to number

********************************************/

function readUInt16LE(bytes) {

var value = (bytes[1] << 8) + bytes[0];

return value & 0xffff;

}

function readUInt32LE(bytes) {

var value = (bytes[3] << 24) + (bytes[2] << 16) + (bytes[1] << 8) + bytes[0];

return (value & 0xffffffff) >>> 0;

}

const payload_raw = payload.find(

(x) =>

x.variable === “payload_raw” ||

x.variable === “payload” ||

x.variable === “data”

);

function toTagoFormat(object_item, serie, prefix = “”) {

const result = ;

for (const key in object_item) {

if (ignore_vars.includes(key)) continue;

if (typeof object_item[key] === “object”) {

result.push({

variable: object_item[key].variable || `${prefix}${key}`,

value: object_item[key].value,

serie: object_item[key].serie || serie,

metadata: object_item[key].metadata,

location: object_item[key].location,

unit: object_item[key].unit,

});

} else {

result.push({

variable: `${prefix}${key}`,

value: object_item[key],

serie,

});

}

}

return result;

}

if (payload_raw) {

try {

// Convert the data from Hex to Javascript Buffer.

const buffer = Buffer.from(payload_raw.value, “hex”);

const serie = new Date().getTime();

let payload_aux = Decoder(buffer);

payload_aux = toTagoFormat(payload_aux, serie);

payload = payload.concat(payload_aux.map((x) => ({ …x, serie })));

} catch (e) {

// Print the error to the Live Inspector.

console.error(e);

// Return the variable parse_error for debugging.

payload = [{ variable: “parse_error”, value: e.message }];

}

}

You can use the following payload to test it out:

let payload = [

{

variable: “payload”,

value: “0374ED0806835604000008700105815207C9A400048001000000”,

},

];

It should output the following:

[

{

variable: 'payload',

value: '0374ED0806835604000008700105815207C9A400048001000000'

},

{ variable: ‘voltage’, value: 228.5, serie: 1694441137726 },

{ variable: ‘power_sum’, value: 1110, serie: 1694441137726 },

{ variable: ‘state’, value: ‘open’, serie: 1694441137726 },

{ variable: ‘factor’, value: 82, serie: 1694441137726 },

{ variable: ‘current’, value: 164, serie: 1694441137726 },

{ variable: ‘power’, value: 1, serie: 1694441137726 }

]

Hope this helps! :slight_smile:

Hello Freddy,

It works perfect.

Thank you very much for your help!