UNPKG

node-red-contrib-modbus

Version:

The all in one Modbus TCP and Serial contribution long term supported package for Node-RED.

3 lines (2 loc) 13.7 kB
module.exports=function(a){require("source-map-support").install();var c=require("./modbus-basics"),u=require("./core/modbus-client-core"),l=require("./core/modbus-queue-core"),d=require("debug")("contribModbus:config:client"),m=require("underscore");a.nodes.registerType("modbus-client",function(e){a.nodes.createNode(this,e);var t=require("@open-p4nr/modbus-serial"),n=500,i=" Get More About It By Logging",r=(this.clienttype=e.clienttype,this.bufferCommands=void 0===e.parallelUnitIdsAllowed||e.bufferCommands,this.queueLogEnabled=e.queueLogEnabled,this.stateLogEnabled=e.stateLogEnabled,this.failureLogEnabled=e.failureLogEnabled,this.tcpHost=e.tcpHost,this.tcpPort=parseInt(e.tcpPort)||502,this.tcpType=e.tcpType,this.serialPort=e.serialPort,this.serialBaudrate=e.serialBaudrate,this.serialDatabits=e.serialDatabits,this.serialStopbits=e.serialStopbits,this.serialParity=e.serialParity,this.serialType=e.serialType,this.serialConnectionDelay=parseInt(e.serialConnectionDelay)||n,this.serialAsciiResponseStartDelimiter=e.serialAsciiResponseStartDelimiter||"0x3A",this.unit_id=parseInt(e.unit_id),this.commandDelay=parseInt(e.commandDelay)||1,this.clientTimeout=parseInt(e.clientTimeout)||1e3,this.reconnectTimeout=parseInt(e.reconnectTimeout)||2e3,this.reconnectOnTimeout=e.reconnectOnTimeout,this.parallelUnitIdsAllowed=void 0===e.parallelUnitIdsAllowed||e.parallelUnitIdsAllowed,this.showErrors=e.showErrors,this.showWarnings=e.showWarnings,this.showLogs=e.showLogs,this);function o(e){a.settings.verbose&&r.showWarnings&&(r.updateServerinfo(),r.warn("Client -> "+e+" "+r.serverInfo))}function s(e){a.settings.verbose&&r.showLogs&&u.internalDebug("Client -> "+e+" "+r.serverInfo)}r.isFirstInitOfConnection=!0,r.closingModbus=!1,r.client=null,r.bufferCommandList=new Map,r.sendingAllowed=new Map,r.unitSendingAllowed=[],r.messageAllowedStates=u.messageAllowedStates,r.serverInfo="",r.stateMachine=null,r.stateService=null,r.stateMachine=u.createStateMachineService(),r.actualServiceState=r.stateMachine.initialState,r.actualServiceStateBefore=r.actualServiceState,r.stateService=u.startStateService(r.stateMachine),r.reconnectTimeoutId=0,r.serialSendingAllowed=!1,r.internalDebugLog=d,l.queueSerialLockCommand(r),r.setDefaultUnitId=function(){"tcp"===this.clienttype?r.unit_id=0:r.unit_id=1},r.setUnitIdFromPayload=function(e){var t=u.getActualUnitId(r,e);u.checkUnitId(t,r.clienttype)||r.setDefaultUnitId(),r.client.setID(t),e.unitId=t},!Number.isNaN(r.unit_id)&&u.checkUnitId(r.unit_id,r.clienttype)||r.setDefaultUnitId(),r.updateServerinfo=function(){"tcp"===r.clienttype?r.serverInfo=" TCP@"+r.tcpHost+":"+r.tcpPort:r.serverInfo=" Serial@"+r.serialPort+":"+r.serialBaudrate+"bit/s",r.serverInfo+=" default Unit-Id: "+r.unit_id},r.errorProtocolMsg=function(e,t){r.showErrors&&c.logMsgError(r,e,t)},r.queueLog=function(e){r.bufferCommands&&r.queueLogEnabled&&s(e)},r.stateService.subscribe(function(e){var t;if(r.actualServiceStateBefore=r.actualServiceState,r.actualServiceState=e,t=e.value,r.stateLogEnabled&&s(t),e.value&&void 0!==r.actualServiceState.value&&r.actualServiceStateBefore.value!==r.actualServiceState.value){if(e.matches("init")){o("fsm init state after "+r.actualServiceStateBefore.value),r.updateServerinfo(),l.initQueue(r),r.reconnectTimeoutId=0;try{r.isFirstInitOfConnection?(r.isFirstInitOfConnection=!1,o("first fsm init in 500 ms"),setTimeout(r.connectClient,n)):(o("fsm init in "+r.reconnectTimeout+" ms"),setTimeout(r.connectClient,r.reconnectTimeout))}catch(e){r.error(e,{payload:"client connection error "+i})}r.emit("mbinit")}e.matches("connected")&&(o("fsm connected after state "+r.actualServiceStateBefore.value+i),l.queueSerialUnlockCommand(r),r.emit("mbconnected")),e.matches("activated")&&(r.emit("mbactive"),r.bufferCommands)&&!l.checkQueuesAreEmpty(r)&&r.stateService.send("QUEUE"),e.matches("queueing")&&("tcp"===r.clienttype&&r.parallelUnitIdsAllowed?r.stateService.send("SEND"):r.serialSendingAllowed&&(l.queueSerialLockCommand(r),r.stateService.send("SEND"))),e.matches("sending")&&(setTimeout(function(){l.dequeueCommand(r)},r.commandDelay),r.emit("mbqueue")),e.matches("opened")&&(l.queueSerialUnlockCommand(r),r.emit("mbopen")),e.matches("switch")&&(r.emit("mbswitch"),r.stateService.send("CLOSE")),e.matches("closed")&&(r.emit("mbclosed"),r.stateService.send("RECONNECT")),e.matches("stopped")&&(o("stopped state without reconnecting"),r.emit("mbclosed")),e.matches("failed")&&(o("fsm failed state after "+r.actualServiceStateBefore.value+i),r.emit("mberror","Modbus Failure On State "+r.actualServiceStateBefore.value+i),r.stateService.send("BREAK")),e.matches("broken")&&(o("fsm broken state after "+r.actualServiceStateBefore.value+i),r.emit("mbbroken","Modbus Broken On State "+r.actualServiceStateBefore.value+i),r.reconnectOnTimeout?r.stateService.send("RECONNECT"):r.stateService.send("ACTIVATE")),e.matches("reconnecting")&&(o("fsm reconnect state after "+r.actualServiceStateBefore.value+i),l.queueSerialLockCommand(r),r.emit("mbreconnecting"),r.reconnectTimeout<=0&&(r.reconnectTimeout=2e3),setTimeout(function(){r.reconnectTimeoutId=0,r.stateService.send("INIT")},r.reconnectTimeout))}}),r.connectClient=function(){try{if(r.client)try{r.client.close(function(){s("connection closed")}),s("connection close sent")}catch(e){s(e.message)}if(r.client=null,r.client=new t,r.client.on("error",function(e){r.modbusErrorHandling(e),c.setNodeStatusTo("error",r)}),r.clientTimeout||(r.clientTimeout=1e3),r.reconnectTimeout||(r.reconnectTimeout=2e3),"tcp"===r.clienttype){if(!u.checkUnitId(r.unit_id,r.clienttype))return r.error(new Error("wrong unit-id (0..255)"),{payload:r.unit_id}),r.stateService.send("FAILURE"),!1;try{switch(r.tcpType){case"C701":s("C701 port UDP bridge"),r.client.connectC701(r.tcpHost,{port:r.tcpPort,autoOpen:!0}).then(r.setTCPConnectionOptions).then(r.setTCPConnected).catch(function(e){return r.modbusTcpErrorHandling(e),!1});break;case"TELNET":s("Telnet port"),r.client.connectTelnet(r.tcpHost,{port:r.tcpPort,autoOpen:!0}).then(r.setTCPConnectionOptions).catch(function(e){return r.modbusTcpErrorHandling(e),!1});break;case"TCP-RTU-BUFFERED":s("TCP RTU buffered port"),r.client.connectTcpRTUBuffered(r.tcpHost,{port:r.tcpPort,autoOpen:!0}).then(r.setTCPConnectionOptions).catch(function(e){return r.modbusTcpErrorHandling(e),!1});break;default:s("TCP port"),r.client.connectTCP(r.tcpHost,{port:r.tcpPort,autoOpen:!0}).then(r.setTCPConnectionOptions).catch(function(e){return r.modbusTcpErrorHandling(e),!1})}}catch(e){return r.modbusTcpErrorHandling(e),!1}}else{if(!u.checkUnitId(r.unit_id,r.clienttype))return r.error(new Error("wrong unit-id serial (0..247)"),{payload:r.unit_id}),r.stateService.send("FAILURE"),!1;if(r.serialConnectionDelay||(r.serialConnectionDelay=n),!r.serialPort)return r.error(new Error("wrong serial port"),{payload:r.serialPort}),r.stateService.send("FAILURE"),!1;var e={baudRate:parseInt(r.serialBaudrate),dataBits:parseInt(r.serialDatabits),stopBits:parseInt(r.serialStopbits),parity:r.serialParity,autoOpen:!1};try{switch(r.serialType){case"ASCII":s("ASCII port serial"),r.serialAsciiResponseStartDelimiter&&"string"==typeof r.serialAsciiResponseStartDelimiter?e.startOfSlaveFrameChar=parseInt(r.serialAsciiResponseStartDelimiter,16):e.startOfSlaveFrameChar=r.serialAsciiResponseStartDelimiter,s("Using response delimiter: 0x"+e.startOfSlaveFrameChar.toString(16)),r.client.connectAsciiSerial(r.serialPort,e).then(r.setSerialConnectionOptions).catch(function(e){return r.modbusSerialErrorHandling(e),!1});break;case"RTU":s("RTU port serial"),r.client.connectRTU(r.serialPort,e).then(r.setSerialConnectionOptions).catch(function(e){return r.modbusSerialErrorHandling(e),!1});break;default:s("RTU buffered port serial"),r.client.connectRTUBuffered(r.serialPort,e).then(r.setSerialConnectionOptions).catch(function(e){return r.modbusSerialErrorHandling(e),!1})}}catch(e){return r.modbusSerialErrorHandling(e),!1}}}catch(e){return r.modbusErrorHandling(e),!1}return!0},r.setTCPConnectionOptions=function(){r.client.setID(r.unit_id),r.client.setTimeout(r.clientTimeout),r.stateService.send("CONNECT")},r.setTCPConnected=function(){u.modbusSerialDebug("modbus tcp connected on "+r.tcpHost)},r.setSerialConnectionOptions=function(){r.stateService.send("OPENSERIAL"),setTimeout(r.openSerialClient,parseInt(r.serialConnectionDelay))},r.modbusErrorHandling=function(e){l.queueSerialUnlockCommand(r),e.message?u.modbusSerialDebug("modbusErrorHandling:"+e.message):u.modbusSerialDebug("modbusErrorHandling:"+JSON.stringify(e)),e.errno&&u.networkErrors.includes(e.errno)&&r.stateService.send("FAILURE")},r.modbusTcpErrorHandling=function(e){l.queueSerialUnlockCommand(r),r.showErrors&&r.error(e),r.failureLogEnabled&&(e.message?u.modbusSerialDebug("modbusTcpErrorHandling:"+e.message):u.modbusSerialDebug("modbusTcpErrorHandling:"+JSON.stringify(e))),(e.errno&&u.networkErrors.includes(e.errno)||e.code&&u.networkErrors.includes(e.code))&&r.stateService.send("BREAK")},r.modbusSerialErrorHandling=function(e){l.queueSerialUnlockCommand(r),r.showErrors&&r.error(e),r.failureLogEnabled&&(e.message?u.modbusSerialDebug("modbusSerialErrorHandling:"+e.message):u.modbusSerialDebug("modbusSerialErrorHandling:"+JSON.stringify(e))),r.stateService.send("BREAK")},r.openSerialClient=function(){"opened"===r.actualServiceState.value?(s("time to open Unit "+r.unit_id),u.modbusSerialDebug("modbus connection opened"),r.client.setID(r.unit_id),r.client.setTimeout(parseInt(r.clientTimeout)),r.client._port.on("close",r.onModbusClose),r.stateService.send("CONNECT")):(s("wrong state on connect serial "+r.actualServiceState.value),u.modbusSerialDebug("modbus connection not opened state is %s",r.actualServiceState.value),r.stateService.send("BREAK"))},r.onModbusClose=function(){l.queueSerialUnlockCommand(r),o("Modbus closed port"),u.modbusSerialDebug("modbus closed port"),r.stateService.send("CLOSE")},r.on("customModbusMessage",function(e,t,n){u.customModbusMessage(r,e,t,n)}),r.on("readModbus",function(t,e,n){var i=r.actualServiceState;r.isInactive()?n(new Error("Client Not Ready To Read At State "+i.value),t):r.bufferCommands?l.pushToQueueByUnitId(r,u.readModbus,t,e,n).then(function(){r.queueLog(JSON.stringify({info:"queued read msg",message:t.payload,state:i.value,queueLength:r.bufferCommandList.get(t.queueUnitId).length}))}).catch(function(e){n(e,t)}).finally(function(){r.stateService.send("QUEUE")}):u.readModbus(r,t,e,n)}),r.on("writeModbus",function(t,e,n){var i=r.actualServiceState;r.isInactive()?n(new Error("Client Not Ready To Write At State "+i.value),t):r.bufferCommands?l.pushToQueueByUnitId(r,u.writeModbus,t,e,n).then(function(){r.queueLog(JSON.stringify({info:"queued write msg",message:t.payload,state:i.value,queueLength:r.bufferCommandList.get(t.queueUnitId).length}))}).catch(function(e){n(e,t)}).finally(function(){r.stateService.send("QUEUE")}):u.writeModbus(r,t,e,n)}),r.activateSending=function(n){return r.sendingAllowed.set(n.queueUnitId,!0),l.queueSerialUnlockCommand(r),new Promise(function(e,t){try{r.bufferCommands&&(r.queueLog(JSON.stringify({info:"queue response activate sending",queueLength:r.bufferCommandList.length,sendingAllowed:r.sendingAllowed.get(n.queueUnitId),serialSendingAllowed:r.serialSendingAllowed,queueUnitId:n.queueUnitId})),l.checkQueuesAreEmpty(r))&&r.stateService.send("EMPTY"),e()}catch(e){t(e)}})},s("initialized"),r.setMaxListeners(0),r.on("reconnect",function(){r.stateService.send("CLOSE")}),r.on("dynamicReconnect",function(t,e,n){if(c.invalidPayloadIn(t))throw new Error("Message Or Payload Not Valid");try{u.internalDebug("Dynamic Reconnect Parameters "+JSON.stringify(t.payload)),u.setNewNodeSettings(r,t)?e(t):n(new Error("Message Or Payload Not Valid"),t),u.internalDebug("Dynamic Reconnect Starts on actual state "+r.actualServiceState.value),r.stateService.send("SWITCH")}catch(e){n(e,t)}}),r.on("close",function(t){var n=r.name||r.id;r.closingModbus=!0,s("stop fsm on close "+n),r.stateService.send("STOP"),s("close node "+n),r.internalDebugLog("close node "+n),r.client?(r.client.isOpen?r.client.close(function(e){s(e?"Connection closed with error "+n:"Connection closed well "+n),t()}):(s("connection was closed "+n),t()),r.client.removeAllListeners()):(s("Connection closed simple "+n),t()),r.removeAllListeners()}),r.registeredNodeList={},r.registerForModbus=function(e){r.registeredNodeList[e]=e,1===Object.keys(r.registeredNodeList).length&&(r.closingModbus=!1,r.stateService.send("NEW"),r.stateService.send("INIT")),r.emit("mbregister",e)},r.setStoppedState=function(e,t){r.stateService.send("STOP"),r.emit("mbderegister",e),t()},r.closeConnectionWithoutRegisteredNodes=function(e,t){0===Object.keys(r.registeredNodeList).length&&(r.closingModbus=!0,r.client)&&"stopped"!==r.actualServiceState.value&&r.client.isOpen?r.client.close(function(){r.setStoppedState(e,t)}):r.setStoppedState(e,t)},r.deregisterForModbus=function(t,n){try{delete r.registeredNodeList[t],r.closingModbus?(n(),r.emit("mbderegister",t)):r.closeConnectionWithoutRegisteredNodes(t,n)}catch(e){o(e.message+" on de-register node "+t),r.error(e),n()}},r.isInactive=function(){return m.isUndefined(r.actualServiceState)||-1===r.messageAllowedStates.indexOf(r.actualServiceState.value)},r.isActive=function(){return!r.isInactive()},r.isReadyToSend=function(e){return!(!e.actualServiceState.matches("queueing")&&!e.actualServiceState.matches("activated")&&(o("Client not ready to send"),1))}}),a.httpAdmin.get("/modbus/serial/ports",a.auth.needsPermission("serial.read"),function(e,t){require("serialport").SerialPort.list().then(function(e){t.json(e)}).catch(function(e){t.json([e.message]),u.internalDebug(e.message)})})}; //# sourceMappingURL=maps/modbus-client.js.map