node-red-contrib-iiot-opcua
Version:
An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.
165 lines (162 loc) • 7.42 kB
JavaScript
/*
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
*/
;
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");
/**
* Server Node-RED node.
*
* @param RED
*/
module.exports = (RED) => {
// SOURCE-MAP-REQUIRED
function OPCUAIIoTServer(config) {
RED.nodes.createNode(this, config);
opcua_iiot_core_server_1.default.internalDebugLog('Open Server Node');
this.asoDemo = config.asoDemo; // ASO (address space objects) Demo
let self = this;
opcua_iiot_core_server_1.default.readConfigOfServerNode(this, config);
opcua_iiot_core_server_1.default.initServerNode(self);
opcua_iiot_core_server_1.default.loadNodeSets(self, __dirname);
// node = coreServer.loadCertificates(node)
const initNewServer = () => {
self = opcua_iiot_core_server_1.default.initRegisterServerMethod(self);
let serverOptions = opcua_iiot_core_server_1.default.buildGeneralServerOptions(self, 'Fix');
try {
opcua_iiot_core_server_1.default.createServer(self, serverOptions, postInitialize, statusHandler, RED.settings.verbose);
}
catch (err) {
this.emit('server_create_error');
handleServerError(err, { payload: '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 statusHandler = (status) => {
this.status(status);
};
const errorHandler = (err, msg) => {
this.error(err, msg);
};
const postInitialize = () => {
opcua_iiot_core_server_1.default.constructAddressSpace(self.iiot.opcuaServer, self.asoDemo)
.then((err) => {
if (err) {
handleServerError(err, { payload: 'Server Address Space Problem' });
}
else {
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) => {
if ((0, opcua_iiot_core_1.isInitializedIIoTNode)(self)) {
self.iiot.opcuaServer = null;
}
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) {
handleServerError(err, { payload: 'Server Address Space Failure' });
});
};
initNewServer();
this.on('input', (msg) => {
if (!self.iiot.opcuaServer || !self.iiot.initialized) {
handleServerError(new Error('Server Not Ready For Inputs'), msg);
return;
}
switch (msg.payload.injectType) {
case 'ASO':
changeAddressSpace(msg);
break;
case 'CMD':
executeOpcuaCommand(msg);
break;
default:
handleServerError(new Error('Unknown Inject Type ' + msg.injectType), msg);
}
this.send(msg);
});
const changeAddressSpace = (msg) => {
// TODO: refactor to work with the new OPC UA type list and option to set add type
if (msg.payload.objecttype && msg.payload.objecttype.indexOf('Variable') > -1) {
opcua_iiot_core_server_1.default.addVariableToAddressSpace(self, msg, msg.payload.objecttype, false, handleServerError);
}
else if (msg.payload.objecttype && msg.payload.objecttype.indexOf('Property') > -1) {
opcua_iiot_core_server_1.default.addVariableToAddressSpace(self, msg, msg.payload.objecttype, true, handleServerError);
}
else {
opcua_iiot_core_server_1.default.addObjectToAddressSpace(self, msg, msg.payload.objecttype, handleServerError);
}
};
const executeOpcuaCommand = (msg) => {
switch (msg.payload.commandType) {
case 'restart':
restartServer();
break;
case 'deleteNode':
opcua_iiot_core_server_1.default.deleteNodeFromAddressSpace(self, msg, handleServerError);
break;
default:
handleServerError(new Error('Unknown OPC UA Command'), msg);
}
};
const sendHandler = (msg) => {
this.send(msg);
};
const emitHandler = (eventName, ...args) => {
this.emit(eventName, ...args);
};
const restartServer = () => {
opcua_iiot_core_server_1.default.internalDebugLog('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.internalDebugLog('OPC UA Server restarted');
}
else {
opcua_iiot_core_server_1.default.internalDebugLog('Can not restart OPC UA Server');
}
};
this.on('close', (done) => {
closeServer(() => {
opcua_iiot_core_server_1.default.internalDebugLog('Close Server Node');
(0, opcua_iiot_core_1.resetIiotNode)(self);
done();
});
});
this.on('shutdown', () => {
this.status({ fill: 'yellow', shape: 'dot', text: 'restarting' });
closeServer(() => {
opcua_iiot_core_server_1.default.internalDebugLog('Server Node Shutdown');
});
self.iiot.opcuaServer = null;
initNewServer();
});
const closeServer = (done) => {
self.removeAllListeners();
opcua_iiot_core_server_1.default.destructAddressSpace(() => {
self.iiot.opcuaServer.removeAllListeners();
self.iiot.opcuaServer.shutdown(self.delayToClose, done);
});
};
}
RED.nodes.registerType('OPCUA-IIoT-Server', OPCUAIIoTServer);
};
//# sourceMappingURL=opcua-iiot-server.js.map