UNPKG

prisme-flow

Version:

prisme platform flow engine

349 lines (302 loc) 8.94 kB
/** * Created by prisme.io on 09/06/2017. */ module.exports = function (RED) { 'use strict' var modbus = require('modbus-serial') var bluebird = require('bluebird') var util = require('util') var events = require('events') var settings = RED.settings var ports = {} function config (n) { RED.nodes.createNode(this, n) this.port = n.port this.baud = parseInt(n.baud) this.data = parseInt(n.data) this.parity = n.parity this.stop = parseInt(n.stop) this.requests = [] // events.EventEmitter.call(this); if (ports[this.port]) { // error } else { ports[this.port] = this } var node = this this.connected = false this.client = new modbus() this.client.setTimeout(1000) try { this.client.connectRTUBuffered(node.port, { baudRate: node.baud, dataBits: node.data, parity: node.parity, stopBits: node.stop }, function () { node.emit('connected') node.connected = true }) } catch (err) { console.log('foo - ' + err) } node.processing = false function processList () { node.processing = true if (node.requests.length != 0) { var obj = node.requests.pop() var promise switch (obj.type) { case 'readCoils': node.client.setID(obj.id) promise = node.client.readCoils(obj.offset, obj.length) break case 'readDiscreteInputs': node.client.setID(obj.id) promise = node.client.readDiscreteInputs(obj.offset, obj.length) break case 'readInputRegisters': node.client.setID(obj.id) promise = node.client.readInputRegisters(obj.offset, obj.length) break case 'readHoldingRegisters': node.client.setID(obj.id) promise = node.client.readHoldingRegisters(obj.offset, obj.length) break case 'writeCoils': node.client.setID(obj.id) promise = node.client.writeCoils(obj.offset, obj.data) break case 'writeInputRegisters': // console.log("writing regs: ", obj); node.client.setID(obj.id) promise = node.client.writeRegisters(obj.offset, obj.data) break } if (promise) { promise .catch(function (err) { node.log('Error: ' + err) }) .then(function (data) { if (typeof data !== 'undefined') { if (obj.callback) { obj.callback(data) } else { node.log('no callback') } } }).then(function () { processList() }) } else { processList() } } else { node.processing = false } } this.readCoils = function (id, offset, length, callback) { var obj = { id: id, type: 'readCoils', offset: offset, length: length, callback: callback } node.requests.push(obj) if (!node.processing) { processList() } } this.readDiscreteInputs = function (id, offset, length, callback) { var obj = { id: id, type: 'readDiscreteInputs', offset: offset, length: length, callback: callback } node.requests.push(obj) if (!node.processing) { processList() } } this.readInputRegisters = function (id, offset, length, callback) { var obj = { id: id, type: 'readInputRegisters', offset: offset, length: length, callback: callback } node.requests.push(obj) if (!node.processing) { processList() } } this.readHoldingRegisters = function (id, offset, length, callback) { var obj = { id: id, type: 'readHoldingRegisters', offset: offset, length: length, callback: callback } node.requests.push(obj) if (!node.processing) { processList() } } this.writeCoils = function (id, offset, data) { var obj = { id: id, type: 'writeCoils', data: data, offset: offset } node.requests.push(obj) if (!node.processing) { processList() } // node.client.setID(id); // node.client.writeCoils(offset, data); } this.writeDiscreteInputs = function (id, offset, data) { this.writeCoils(id, offset, data) } this.writeInputRegisters = function (id, offset, data) { var obj = { id: id, type: 'writeInputRegisters', data: data, offset: offset } node.requests.push(obj) if (!node.processing) { processList() } // node.client.setID(id); // node.client.writeRegisters(offset,data); } this.writeHoldingRegisters = function (id, offset, data) { this.writeInputRegisters(id, offset, data) } this.on('close', function (done) { if (ports[node.port]) { delete ports[node.port] node.client.close(done) } }) }; // util.inherits(config, events.EventEmitter); RED.nodes.registerType('modbusSerialConfig', config) function read (n) { RED.nodes.createNode(this, n) this.port = n.port this.connection = RED.nodes.getNode(this.port) // this.device = n.device; this.slaves = n.slaves this.start = n.start this.count = n.count this.dtype = n.dtype this.period = n.period this.topic = n.topic var node = this if (node.connection.connected) { node.status({fill: 'green', shape: 'dot', text: 'connected'}) node.interval = setInterval(poll, (1000 * node.period)) poll() } else { node.connection.on('connected', function () { node.status({fill: 'green', shape: 'dot', text: 'connected'}) node.interval = setInterval(poll, (1000 * node.period)) poll() }) } function poll () { var slaves = [] if (node.slaves.indexOf(',')) { slaves = node.slaves.split(',') } else { slaves.push(node.slaves) } function callback (data) { var topic = node.topic if (topic.lastIndexOf('/') != topic.length) { topic += '/' } var msg = { topic: topic + slave, payload: data.buffer } node.send(msg) } for (var i = 0; i < slaves.length; i++) { var slave = slaves[i] if (node.dtype === 'discrete') { node.connection.readDiscreteInputs(slave, node.start, node.count, callback) } else if (node.dtype === 'coil') { node.connection.readCoils(slave, node.start, node.count, callback) } else if (node.dtype === 'input') { node.connection.readInputRegisters(slave, node.start, node.count, callback) } else if (node.dtype === 'holding') { node.connection.readHoldingRegisters(slave, node.start, node.count, callback) } } } node.on('close', function () { clearInterval(node.interval) }) } RED.nodes.registerType('modbusSerial in', read) function write (n) { RED.nodes.createNode(this, n) this.port = n.port this.device = n.slave this.start = n.start this.dtype = n.dtype this.connection = RED.nodes.getNode(this.port) var node = this if (node.connection.connected) { node.status({fill: 'green', shape: 'dot', text: 'connected'}) } else { node.connection.on('connected', function () { node.status({fill: 'green', shape: 'dot', text: 'connected'}) }) } node.on('input', function (msg) { var slave = node.device if (!slave && msg.topic) { if (msg.topic.IndexOf('/') != -1) { var part = msg.topic.substring(msg.topic.lastIndexOf('/'), msg.topic.length) try { slave = parseInt(part) } catch (err) { // not int } } else { try { slave = parseInt(msg.topic) } catch (err) { // not int } } } console.log(node.dtype) // if (util.isBuffer(msg.payload)){ if (node.dtype === 'discrete') { node.connection.writeDiscreteInputs(slave, node.start, msg.payload) } else if (node.dtype === 'coil') { node.connection.writeCoils(slave, node.start, msg.payload) } else if (node.dtype === 'input') { node.connection.writeInputRegisters(slave, node.start, msg.payload) } else if (node.dtype === 'holding') { node.connection.writeHoldingRegisters(slave, node.start, msg.payload) } // } }) }; RED.nodes.registerType('modbusSerial out', write) }