node-red-contrib-iiot-opcua
Version:
An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.
137 lines (134 loc) • 6.62 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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const opcua_iiot_core_discovery_1 = __importDefault(require("./core/opcua-iiot-core-discovery"));
const node_opcua_1 = require("node-opcua");
const path_1 = __importDefault(require("path"));
/**
* OPC UA node representation for Node-RED OPC UA IIoT nodes.
*
* @param RED
*/
module.exports = (RED) => {
// SOURCE-MAP-REQUIRED
function OPCUAIIoTDiscovery(config) {
RED.nodes.createNode(this, config);
this.name = config.name;
this.discoveryPort = config.discoveryPort || opcua_iiot_core_discovery_1.default.DEFAULT_OPCUA_DISCOVERY_PORT;
let self = this;
//Create and Start the Discovery Server
const startDiscoveryServer = () => __awaiter(this, void 0, void 0, function* () {
// Access the certificates created by installation
const certificateFolder = process.env.CERTIFICATES || '../certificates';
const serverCertificateManager = new node_opcua_1.OPCUACertificateManager({
automaticallyAcceptUnknownCertificate: true,
rootFolder: certificateFolder,
name: "pki"
});
const certificateFile = path_1.default.join(certificateFolder, "discoveryServer_cert_2048.pem");
const privateKeyFile = serverCertificateManager.privateKey;
yield serverCertificateManager.initialize();
const discoveryServer = new node_opcua_1.OPCUADiscoveryServer({
certificateFile,
privateKeyFile,
serverCertificateManager,
serverInfo: {
applicationUri: (0, node_opcua_1.makeApplicationUrn)(yield (0, node_opcua_1.extractFullyQualifiedDomainName)(), self.name || 'discovery'),
},
port: self.discoveryPort,
});
try {
yield discoveryServer.start();
this.status({ fill: 'green', shape: 'dot', text: 'active' });
opcua_iiot_core_discovery_1.default.internalDebugLog('discovery server started');
}
catch (err) {
this.status({ fill: 'red', shape: 'dot', text: 'error' });
this.error(new Error('Error starting discovery server: ' + err.message));
}
return discoveryServer;
});
this.status({ fill: 'yellow', shape: 'ring', text: 'starting' });
self.discoveryServer = startDiscoveryServer().then((server) => {
this.status({ fill: 'green', shape: 'dot', text: 'active' });
return server;
}).catch((err) => {
this.status({ fill: 'red', shape: 'dot', text: 'error' });
this.error(new Error('Error starting discovery server: ' + err.message));
return undefined;
});
// Convert the numeric Enum value to the string label, for user readability
const applicationTypeToString = (applicationType) => {
return node_opcua_1.ApplicationType[applicationType];
};
// Create the payload objects
const parseServerList = (serverList) => {
const endpoints = serverList.map((server) => {
return {
applicationUri: server.applicationUri,
productUri: server.productUri,
applicationName: server.applicationName,
applicationType: applicationTypeToString(server.applicationType),
gatewayServerUri: server.gatewayServerUri,
discoveryProfileUri: server.discoveryProfileUri,
discoveryUrls: server.discoveryUrls,
};
});
const discoveryUrls = endpoints.flatMap((server) => (server.discoveryUrls || [])).filter((item, index, list) => !!item && list.indexOf(item) === index);
return {
discoveryUrls,
endpoints,
};
};
this.on('input', (msg) => __awaiter(this, void 0, void 0, function* () {
// Ensure that the discovery server has been started
const discoveryServer = yield self.discoveryServer;
if (!discoveryServer) {
const error = new Error('Discovery server undefined');
this.error(error);
this.send(Object.assign(Object.assign({}, msg), { payload: error.toString() }));
return;
}
// @ts-ignore: Ignore required to access discoveryServer.getServers() without arguments, and the argument isn't even used by the function
const { discoveryUrls, endpoints } = parseServerList(discoveryServer.getServers());
const outputMessage = Object.assign(Object.assign({}, msg), { payload: {
discoveryUrls,
endpoints
} });
this.send(outputMessage);
}));
this.on('close', function (done) {
self.removeAllListeners();
if (self.discoveryServer) {
self.discoveryServer.shutdown(function () {
opcua_iiot_core_discovery_1.default.internalDebugLog('shutdown');
done();
});
}
else {
done();
}
});
}
RED.nodes.registerType('OPCUA-IIoT-Discovery', OPCUAIIoTDiscovery);
};
//# sourceMappingURL=opcua-iiot-discovery.js.map