UNPKG

node-red-contrib-iiot-opcua

Version:

An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.

203 lines (200 loc) 8.84 kB
/* The BSD 3-Clause License Copyright 2022 - DATATRONiQ GmbH (https://datatroniq.com) Copyright (c) 2018-2022 Klaus Landsdorf (http://node-red.plus/) Copyright 2015,2016 - Mika Karaila, Valmet Automation Inc. (node-red-contrib-opcua) All rights reserved. node-red-contrib-iiot-opcua */ 'use strict'; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const opcua_iiot_core_server_1 = __importDefault(require("./core/opcua-iiot-core-server")); const opcua_iiot_core_1 = require("./core/opcua-iiot-core"); const vm2_1 = require("vm2"); /** * Server Node-RED node. * * @param RED */ module.exports = (RED) => { // SOURCE-MAP-REQUIRED let scriptObjects = {}; function OPCUAIIoTFlexServer(config) { RED.nodes.createNode(this, config); opcua_iiot_core_server_1.default.flexInternalDebugLog('Open Server Node'); let self = this; opcua_iiot_core_server_1.default.readConfigOfServerNode(self, config); opcua_iiot_core_server_1.default.initServerNode(self); opcua_iiot_core_server_1.default.loadNodeSets(self, __dirname); // node = coreServer.loadCertificates(node) self.context = this.context; const vm = new vm2_1.VM({ allowAsync: false, sandbox: { // allow the node-opcua library to be accessed in user-submitted scripts as 'opcua' opcua: require('node-opcua'), node: self, coreServer: opcua_iiot_core_server_1.default, scriptObjects, RED, sandboxNodeContext: { set: function () { self.context().set.apply(self, arguments); }, get: function () { return self.context().get.apply(self, arguments); }, keys: function () { return self.context().keys.apply(self, arguments); }, get global() { return self.context().global; }, get flow() { return self.context().flow; } }, sandboxFlowContext: { set: function () { self.context().flow.set.apply(self, arguments); }, get: function () { return self.context().flow.get.apply(self, arguments); }, keys: function () { return self.context().flow.keys.apply(self, arguments); } }, sandboxGlobalContext: { set: function () { self.context().global.set.apply(self, arguments); }, get: function () { return self.context().global.get.apply(self, arguments); }, keys: function () { return self.context().global.keys.apply(self, arguments); } }, sandboxEnv: { get: function (envVar) { let flow = self._flow; return flow.getSetting(envVar); } } } }); // Use the vm2 library to make the submitted script executable: // vm.run returns construcAddressSpaceScript as a function const constructAddressSpaceScript = vm.run('constructAddressSpaceScript = ' + config.addressSpaceScript); const statusHandler = (status) => { this.status(status); }; const initNewServer = () => { self = opcua_iiot_core_server_1.default.initRegisterServerMethod(self); let serverOptions = opcua_iiot_core_server_1.default.buildGeneralServerOptions(self, 'Flex'); // serverOptions = coreServer.setDiscoveryOptions(node, serverOptions) try { opcua_iiot_core_server_1.default.createServer(self, serverOptions, postInitialize, statusHandler, RED.settings.verbose); } catch (err) { /* istanbul ignore next */ this.emit('server_create_error'); opcua_iiot_core_server_1.default.flexInternalDebugLog(err.message); handleServerError(err, { payload: 'Flex Server Failure! Please, check the server settings!' }); } }; const handleServerError = (err, msg) => { opcua_iiot_core_server_1.default.internalDebugLog(err); if (self.showErrors) { this.error(err, msg); } }; const postInitialize = () => { self.iiot.eventObjects = {}; // event objects should stay in memory opcua_iiot_core_server_1.default.constructAddressSpaceFromScript(self.iiot.opcuaServer, constructAddressSpaceScript, self.iiot.eventObjects) .then(() => { opcua_iiot_core_server_1.default.start(self.iiot.opcuaServer, self).then(() => { self.oldStatusParameter = (0, opcua_iiot_core_1.setNodeStatusTo)(self, 'active', self.oldStatusParameter, self.showStatusActivities, statusHandler); this.emit('server_running'); }).catch((err) => { /* istanbul ignore next */ this.emit('server_start_error'); self.oldStatusParameter = (0, opcua_iiot_core_1.setNodeStatusTo)(self, 'errors', self.oldStatusParameter, self.showStatusActivities, statusHandler); handleServerError(err, { payload: 'Server Start Failure' }); }); }).catch(function (err) { /* istanbul ignore next */ handleServerError(err, { payload: 'Server Address Space Failure' }); }); }; initNewServer(); this.on('input', function (msg) { if (!self.iiot.opcuaServer || !self.iiot.initialized) { handleServerError(new Error('Server Not Ready For Inputs'), msg); return; } if (msg.payload.injectType === 'CMD') { executeOpcuaCommand(msg); } else { handleServerError(new Error('Unknown Flex Inject Type ' + msg.payload.injectType), msg); } }); const executeOpcuaCommand = (msg) => { if (msg.payload.commandType === 'restart') { restartServer(); this.send(msg); } else { handleServerError(new Error('Unknown Flex OPC UA Command'), msg); } }; const sendHandler = (msg) => { this.send(msg); }; const emitHandler = (eventName, ...args) => { this.emit(eventName, ...args); }; const restartServer = function () { opcua_iiot_core_server_1.default.flexInternalDebugLog('Restart OPC UA Server'); opcua_iiot_core_server_1.default.restartServer(self, statusHandler, emitHandler, sendHandler); if (self.iiot.opcuaServer) { opcua_iiot_core_server_1.default.flexInternalDebugLog('OPC UA Server restarted'); } else { opcua_iiot_core_server_1.default.flexInternalDebugLog('Can not restart OPC UA Server'); } }; this.on('close', function (done) { self.removeAllListeners(); closeServer(() => { opcua_iiot_core_server_1.default.flexInternalDebugLog('Close Server Node'); (0, opcua_iiot_core_1.resetIiotNode)(self); done(); }); }); this.on('shutdown', () => { self.iiot.opcuaServer = null; initNewServer(); }); const closeServer = function (done) { if (opcua_iiot_core_server_1.default.simulatorInterval) { clearInterval(opcua_iiot_core_server_1.default.simulatorInterval); opcua_iiot_core_server_1.default.simulatorInterval = null; } if (self.iiot.opcuaServer) { self.iiot.opcuaServer.removeAllListeners(); self.iiot.opcuaServer.shutdown(self.delayToClose, done); } else { done(); } }; } RED.nodes.registerType('OPCUA-IIoT-Flex-Server', OPCUAIIoTFlexServer); }; //# sourceMappingURL=opcua-iiot-flex-server.js.map