prisme-flow
Version:
prisme platform flow engine
143 lines (118 loc) • 3.73 kB
JavaScript
/**
* Created by prisme.io on 09/06/2017.
*/
/**
* Modbus Server node.
* @module NodeRedModbusServer
*
* @param RED
*/
module.exports = function (RED) {
'use strict'
let stampit = require('stampit')
let modbus = require('node-modbus')
let mbBasics = require('./modbus-basics')
let internalDebugLog = require('debug')('node_red_contrib_modbus')
function ModbusServer (config) {
RED.nodes.createNode(this, config)
this.name = config.name
this.logEnabled = config.logEnabled
this.serverPort = parseInt(config.serverPort)
this.responseDelay = parseInt(config.responseDelay)
this.delayUnit = config.delayUnit
this.coilsBufferSize = parseInt(config.coilsBufferSize)
this.holdingBufferSize = parseInt(config.holdingBufferSize)
this.inputBufferSize = parseInt(config.inputBufferSize)
let node = this
node.server = null
setNodeStatusTo('initialized')
function verboseWarn (logMessage) {
if (RED.settings.verbose) {
node.warn((node.name) ? node.name + ': ' + logMessage : 'Modbus response: ' + logMessage)
}
}
function verboseLog (logMessage) {
if (RED.settings.verbose) {
internalDebugLog(logMessage)
}
}
function setNodeStatusTo (statusValue) {
if (mbBasics.statusLog) {
verboseLog('server status: ' + statusValue)
}
let fillValue = 'red'
let shapeValue = 'dot'
switch (statusValue) {
case 'initialized':
fillValue = 'green'
shapeValue = 'ring'
break
case 'active':
fillValue = 'green'
shapeValue = 'dot'
break
default:
if (!statusValue || statusValue === 'waiting') {
fillValue = 'blue'
statusValue = 'waiting ...'
}
break
}
node.status({fill: fillValue, shape: shapeValue, text: statusValue})
}
let modbusLogLevel = 'warn'
if (RED.settings.verbose) {
modbusLogLevel = 'debug'
}
let ModbusServer = stampit().refs({
'logLabel': 'ModbusServer',
'logLevel': modbusLogLevel,
'logEnabled': node.logEnabled,
'port': node.serverPort,
'responseDelay': mbBasics.calc_rateByUnit(node.responseDelay, node.delayUnit),
'coils': Buffer.alloc(node.coilsBufferSize, 0),
'holding': Buffer.alloc(node.holdingBufferSize, 0),
'input': Buffer.alloc(node.inputBufferSize, 0)
})
.compose(modbus.server.tcp.complete)
.init(function () {
let init = function () {
this.coils.fill(0)
this.holding.fill(0)
this.input.fill(0)
}.bind(this)
init()
})
verboseLog('starting modbus server')
try {
node.server = ModbusServer()
} catch (err) {
verboseWarn(err)
setNodeStatusTo('error')
}
if (node.server != null) {
verboseLog('modbus server started')
setNodeStatusTo('active')
} else {
verboseWarn("modbus server isn't ready")
setNodeStatusTo('error')
}
node.on('input', function (msg) {
verboseLog('Input:' + msg)
node.send(buildMessage(msg, node.server.getHolding(), node.server.getCoils(), node.server.getInput()))
})
function buildMessage (msg, modbusHolding, modbusCoils, modbusInput) {
return [
{type: 'holding', message: msg, payload: modbusHolding},
{type: 'coils', message: msg, payload: modbusCoils},
{type: 'input', message: msg, payload: modbusInput}
]
}
node.on('close', function () {
setNodeStatusTo('closed')
node.server.close()
node.server = null
})
}
RED.nodes.registerType('modbus-server', ModbusServer)
}