node-red-contrib-plcs
Version:
Mentor Monitor Project Plcs Modbus Controllers
274 lines (228 loc) • 10.6 kB
JavaScript
var numeral = require('numbro');
module.exports = function(RED) {
"use strict";
var log = RED.log;
function convertValue(msg)
{
const buf = Buffer.from(msg.buffer);
const temp = Buffer.allocUnsafe(4);
var value = null;
var offset = 0; //msg.offset;
if (msg.size === 'long32') //DWORD
{
switch(msg.byteorder)
{
case 'ABCD':
value = buf.readInt32BE(offset);
break;
case 'CDAB':
temp.writeInt32LE(buf.readInt32BE(offset));
temp.swap16();
value = temp.readInt32BE();
break;
}
} else if (msg.size === 'long') //DWORD
{
switch(msg.byteorder)
{
case 'ABCD':
value = buf.readUInt32BE(offset);
break;
case 'CDAB':
temp.writeUInt32LE(buf.readUInt32BE(offset));
temp.swap16();
value = temp.readUInt32BE();
break;
}
} else if (msg.size == 'decimal') //WORD
{
switch(msg.byteorder)
{
case 'ABCD':
value = buf.readInt16BE(offset);
break;
case 'CDAB':
temp.writeUInt16LE(buf.readInt16BE(offset));
temp.swap16();
value = temp.readInt16BE();
break;
}
} else if (msg.size == 'integer') //WORD
{
switch(msg.byteorder)
{
case 'ABCD':
value = buf.readUInt16BE(offset);
break;
case 'CDAB':
temp.writeUInt16LE(buf.readUInt16BE(offset));
temp.swap16();
value = temp.readUInt16BE();
break;
}
} else if (msg.size == 'float')
{
value = buf.readFloatBE(offset)
//log.error(value);
} else
{
value = buf.readUInt32BE(offset);
}
// if (msg.topic.operation != "none")
// msg.topic.value *= 1;
switch(msg.opt)
{
case 'x/10':
value = value/10;
break;
case 'x/100':
value = value/100;
break;
case 'x/1000':
value = value/1000;
break;
}
//log.error(msg.format);
if (msg.format && msg.format !== -1)
{
value = numeral(value).format({
thousandSeparated: false,
mantissa: msg.format
});
}
return {[msg.name]: value };
}
function getTypeSize(size)
{
switch(size)
{
case 'long32': //DWORD
case 'long': //DWORD
case 'float':
size = 4;
break;
case 'decimal': //Signed DWORD
case 'integer': //Unsigned WORD
size = 2;
break;
default:
size = 2;
break;
}
return size;
}
function digitalOutput(config) {
RED.nodes.createNode(this,config);
var node = this;
var context = this.context().flow;
var chunks = parseInt(config.chunks, 10) || 0;
var group_name = config.group_name;
var keyed = typeof config.keyed == 'undefined' ? true: config.keyed;
var stringify = typeof config.stringify == 'undefined' ? true : config.stringify;
this.on('input', function(msg) {
const buffer = Buffer.from(msg.payload.buffer);
var msgResult = {payload: {"time": msg.topic.header.time, "code":msg.topic.header.device, "name": msg.topic.header.name, "value":[]}}
if (msg.topic.header.mentor_id > 0)
msgResult.payload.mentor_id = msg.topic.header.mentor_id;
for (var i=0; i<msg.topic.detail.length; i++) {
var msgColumn = {payload:{}, topic:msg.topic.detail[i]};
msgColumn.topic.format = msg.topic.header.format;
msgColumn.topic.buffer = buffer.slice((msg.topic.detail[i].offset)*2, (msg.topic.detail[i].offset)*2 + getTypeSize(msg.topic.detail[i].size));
// log.error(convertValue(msgColumn.topic));
// msgColumn.payload.topic = msgColumn.topic;
// msgColumn.payload.topic.buffer = msgColumn.topic.buffer;
if (msg.topic.header.group)
{
msgResult.payload.value.push(convertValue(msgColumn.topic)); }
else {
var msgInd = {payload: {"time": msg.topic.header.time, "code":msg.topic.header.device, "name": msg.topic.header.name, "value":[]}}
if (msg.topic.header.mentor_id > 0)
msgInd.payload.mentor_id = msg.topic.header.mentor_id;
msgInd.payload.value.push(convertValue(msgColumn.topic));
msgInd.payload = JSON.stringify({"code": msg.topic.header.device, "time": msg.topic.header.time, "head": Object.keys(msgInd.payload.value), "data": Object.values(msgInd.payload.value)});
node.send(msgInd);
}
}
if (msg.topic.header.group)
{
var value = context.get(msg.topic.header.device);
if (value.time != msg.topic.header.time || (value.timeout - 1) != msg.topic.header.try) //(group_name === "" &&
{
return;
}
value.n--;
// Store the data in msg.payload for all operations as they complete
value.data[value.n] = msgResult.payload;
if (value.n == 0) {
value.timeout = 0;
var obj = {};
for (var i = 0; i < value.data.length; i++) {
obj = Object.assign(value.data[value.data.length - i - 1].value, obj);
}
if (group_name === "")
{
if (keyed)
{
var data = Object.keys(obj).map(function(key) {return Object.values(obj[key])[0];});
var head = Object.keys(obj).map(function(key) {return Object.keys(obj[key])[0];});
msgResult.payload = {"code": msg.topic.header.device, "time": msg.topic.header.time, "head": head, "data": data};
} else
{
var data = obj;
msgResult.payload = {"code": msg.topic.header.device, "time": msg.topic.header.time, "data": data};
}
if (msg.topic.header.mentor_id > 0)
msgResult.payload.mentor_id = msg.topic.header.mentor_id;
msgResult.payload = stringify ? JSON.stringify(msgResult.payload) : msgResult.payload ;
node.send(msgResult);
} else {
msgResult.payload = obj;
}
if (chunks > 1 && group_name === msg.topic.header.group_name && group_name !== "")
{
var value_out = context.get(group_name);
if (!value_out || value_out.time != msg.topic.header.time)
{
var value_out = {"chunks":chunks, "time":msg.topic.header.time};
value_out.data = new Array(chunks);
value_out.chunks = chunks;
value_out.chunks--;
context.set(group_name, value_out);
}
else
{
value_out.chunks--;
context.set(group_name, value_out);
}
value_out.data[value_out.chunks] = msgResult.payload;
if (value_out.chunks === 0)
{
context.set(group_name, null);
var obj = [];
var data = [];
var head = [];
for (var i = 0; i < value_out.data.length; i++) {
for (var e = 0; e < value_out.data[value_out.data.length - i - 1].length; e++) {
obj.push(value_out.data[value_out.data.length - i - 1][e]);
data.push(Object.values(value_out.data[value_out.data.length - i - 1][e])[0]);
head.push(Object.keys(value_out.data[value_out.data.length - i - 1][e])[0]);
}
}
msgResult = {};
if (keyed)
msgResult.payload = {"code": group_name, "time": msg.topic.header.time, "head":head, "data":data};
else
msgResult.payload = {"code": group_name, "time": msg.topic.header.time, "data":obj};
if (msg.topic.header.mentor_id > 0)
msgResult.payload.mentor_id = msg.topic.header.mentor_id;
msgResult.payload = stringify ? JSON.stringify(msgResult.payload) : msgResult.payload ;
node.send(msgResult);
}
}
}
context.set(msg.topic.header.device, value);
}
});
}
RED.nodes.registerType("Generic Out",digitalOutput);
};