UNPKG

node-red-contrib-plcs

Version:

Mentor Monitor Project Plcs Modbus Controllers

217 lines (177 loc) 8.73 kB
var async = require('async'); module.exports = function (RED) { var log = RED.log; const DeviceNode = function (config) { RED.nodes.createNode(this, config); var node = this; this.unitid = parseInt(config.unitid, 10) || 1; this.columns = config.columns; this.name = config.name; this.byteorder = config.byteorder; this.devicetype = config.devicetype; this.send_group = config.send_group; this.group_name = config.group_name; this.individual = config.individual; this.defer = parseInt(config.defer, 10) || 0; this.fc = config.fc; this.initialdefer = parseInt(config.initialdefer, 10) || 0; this.retries = parseInt(config.retries, 10) || 1; this.baseaddress = config.baseaddress; this.offsetbased = config.offsetbased; this.valueformat = parseInt(config.valueformat, 10) || -1; this.on('input', (msg) => { handleMsg(RED, node, msg, config) }); this.mentorConfiguration = RED.nodes.getNode(config.mentorConfiguration); if (!this.mentorConfiguration) this.mentor_id = 0; else this.mentor_id = this.mentorConfiguration.mentor_id; } function getTypeSize(vartype) { var size = 0; switch(vartype) { case 'long32': //DWORD case 'long': //DWORD case 'float': size = 4; break; case 'decimal': //WORD case 'integer': //WORD size = 2; break; default: size = 2; break; } // log.error("type:" + vartype); return size; } async function handleMsg(RED, node, msg, config) { var context = node.context().flow; if (Object.keys(node.columns).length === 0) { node.status({fill:"red",shape:"ring",text:"No Variables"}); return; } if (node.name == '' || node.name == undefined) { node.status({fill:"red",shape:"ring",text:"No Name Device"}); return; } var count = {"n": (node.individual ? node.columns.length : 1), "time": msg.payload, "data": new Array(node.individual ? node.columns.length: 1), timeout:1}; context.set(node.name,count); var time = msg.payload; node.status({fill:"green",shape:"ring",text:"Sending"}); var address = 0; var quantity = 2; var header = { 'mentor_id': node.mentor_id, 'device': node.name, 'group_name': node.group_name, 'time': time, 'devicetype': node.devicetype, 'columns': count.n, 'group': node.send_group, 'format': node.valueformat }; var detail = []; for (var i=0; i<node.columns.length; i++) { var column = node.columns[i]; if (column.name == '' || column.name == undefined ) node.status({fill:"yellow",shape:"ring",text:"No Name Variable"}); else { address = (node.offsetbased ? node.baseaddress*1 : 0) + column.address*1; var field = { 'name': column.name, 'opt': column.opt, 'offset': node.individual ? 0 : (column.address*1 - node.columns[0].address), 'type': column.type, 'size': column.size, 'byteorder': node.byteorder }; if (node.individual) { var newMsg = {}; newMsg.topic = {header:header, detail:[]}; newMsg.topic.detail.push(field); newMsg.payload = { 'fc': parseInt(node.fc,10), 'unitid': node.unitid, 'address': address, 'quantity': quantity //'topic': newMsg.topic }; if (node.defer) { var timerId = setTimeout( function () { node.send(newMsg); clearInterval(timerId); }, node.defer); } else { node.send(newMsg); } } else { detail.push(field); } } } if (!node.individual) { address = (node.offsetbased ? node.baseaddress*1+node.columns[0].address*1 : node.columns[0].address*1); quantity = (node.columns[node.columns.length-1].address*1 - node.columns[0].address*1) * 2 + getTypeSize(node.columns[node.columns.length-1].size); var newMsg = {}; newMsg.topic = { 'header': header, 'detail': detail, }; newMsg.payload = { 'fc': parseInt(node.fc,10), 'unitid': node.unitid*1, 'address': address, 'quantity': quantity //'topic': newMsg.topic }; sendMsg(node, newMsg); } // node.status({fill:"green",shape:"ring",text:"OK"}); } function sendMsg(node, msg) { var context = node.context().flow; async.during( function (callback) { return callback(null, context.get(msg.topic.header.device).timeout <= node.retries + 1 && context.get(msg.topic.header.device).timeout > 0); }, function (callback) { if (context.get(msg.topic.header.device).timeout > 0) { var value = context.get(msg.topic.header.device); msg.topic.header.try = value.timeout; if (value.timeout === 1) { node.status({fill:"green",shape:"ring",text:"Initial Defer " + node.initialdefer + " msecs. "}); setTimeout(callback, node.initialdefer); } else { node.status({fill:"yellow",shape:"ring",text:"Defer " + node.defer + " msecs. Try " + (value.timeout - 1) + " of " + node.retries}); node.send([msg, null]); value.n = value.data.length; setTimeout(callback, node.defer); } value.timeout++; context.set(msg.topic.header.device, value); } }, function (err) { if (context.get(msg.topic.header.device).timeout > 0) { var value = context.get(msg.topic.header.device); value.timeout = 0; context.set(msg.topic.header.device, value); var msgResult = {payload: JSON.stringify({"code":msg.topic.header.device, "time": msg.topic.header.time, "head": ["initialdefer","defer", "retries"], "data":[node.initialdefer, node.defer, node.retries], "text":"Timeout!"})}; node.send([null, msgResult]); node.status({fill:"red",shape:"ring",text:"Timeout!! " + "Retries " + node.retries + " (" + node.defer + " msecs.)"}); } else node.status({}); } ); } RED.nodes.registerType('Generic In', DeviceNode); }