UNPKG

prisme-flow

Version:

prisme platform flow engine

208 lines (177 loc) 5.33 kB
/** * Created by prisme.io on 09/06/2017. */ /** * Modbus Read node. * @module NodeRedModbusRead * * @param RED */ module.exports = function (RED) { 'use strict' let mbBasics = require('./modbus-basics') let internalDebugLog = require('debug')('node_red_contrib_modbus') function ModbusRead (config) { RED.nodes.createNode(this, config) this.name = config.name this.unitid = config.unitid this.dataType = config.dataType this.adr = config.adr this.quantity = config.quantity this.rate = config.rate this.rateUnit = config.rateUnit this.showStatusActivities = config.showStatusActivities this.showErrors = config.showErrors this.connection = null let node = this let modbusClient = RED.nodes.getNode(config.server) let timerID = null let timeoutOccurred = false setNodeStatusTo('waiting') node.onModbusInit = function () { setNodeStatusTo('initialize') } node.onModbusConnect = function () { if (!timerID) { timerID = setInterval(node.modbusPollingRead, mbBasics.calc_rateByUnit(node.rate, node.rateUnit)) } setNodeStatusTo('connected') } node.onModbusActive = function () { setNodeStatusTo('active') } node.onModbusError = function (failureMsg) { setNodeStatusTo('failure') if (timerID) { clearInterval(timerID) // clear Timer from events } timerID = null if (node.showErrors) { node.warn(failureMsg) } } node.onModbusClose = function () { setNodeStatusTo('closed') if (timerID) { clearInterval(timerID) // clear Timer from events } timerID = null } modbusClient.on('mbinit', node.onModbusInit) modbusClient.on('mbconnected', node.onModbusConnect) modbusClient.on('mbactive', node.onModbusActive) modbusClient.on('mberror', node.onModbusError) modbusClient.on('mbclosed', node.onModbusClose) node.modbusPollingRead = function () { if (!modbusClient.client) { setNodeStatusTo('waiting') return } let msg = { topic: 'polling', from: node.name, payload: { unitid: node.unitid, fc: node.functionCodeModbus(node.dataType), address: node.adr, quantity: node.quantity } } if (node.showStatusActivities) { setNodeStatusTo('polling') verboseLog(JSON.toString(msg)) } modbusClient.emit('readModbus', msg, node.onModbusReadDone, node.onModbusReadError) } node.functionCodeModbus = function (dataType) { switch (dataType) { case 'Coil': return 1 case 'Input': return 2 case 'HoldingRegister': return 3 case 'InputRegister': return 4 default: return dataType } } node.onModbusReadDone = function (resp, msg) { if (node.showStatusActivities) { setNodeStatusTo('reading done') verboseLog('reading done -> ' + JSON.stringify(msg)) } node.send(buildMessage(resp.data, resp, msg)) } node.onModbusReadError = function (err, msg) { setModbusError(err, msg) } node.on('close', function () { if (timerID) { clearInterval(timerID) } timerID = null setNodeStatusTo('closed') }) function verboseLog (logMessage) { if (RED.settings.verbose) { internalDebugLog(logMessage) } } function buildMessage (values, response, msg) { return [{payload: values, responseBuffer: response, input: msg}, {payload: response, values: values, input: msg}] } function setNodeStatusTo (statusValue) { if (statusValue === 'polling' && timeoutOccurred) { return } let statusOptions = mbBasics.set_node_status_properties(statusValue, node.showStatusActivities) if (statusValue.search('active') !== -1 || statusValue === 'polling') { timeoutOccurred = false node.status({ fill: statusOptions.fill, shape: statusOptions.shape, text: statusOptions.status + getTimeInfo() }) } else { node.status({ fill: statusOptions.fill, shape: statusOptions.shape, text: statusOptions.status }) } } function getTimeInfo () { return ' ( ' + node.rate + ' ' + mbBasics.get_timeUnit_name(node.rateUnit) + ' ) ' } function setModbusError (err, msg) { let working = false if (err) { switch (err.message) { case 'Timed out': timeoutOccurred = true setNodeStatusTo('timeout') working = true break case 'FSM Not Ready To Read': setNodeStatusTo('not ready to read') working = true break case 'Port Not Open': setNodeStatusTo('reconnect') modbusClient.emit('reconnect') working = true break default: setNodeStatusTo('error: ' + JSON.stringify(err)) if (node.showErrors) { node.error(err, msg) } } } return working } } RED.nodes.registerType('modbus-read', ModbusRead) }