node-red-contrib-iiot-opcua
Version:
An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.
269 lines (266 loc) • 11.5 kB
JavaScript
/*
The BSD 3-Clause License
Copyright 2022 - DATATRONiQ GmbH (https://datatroniq.com)
Copyright (c) 2018-2022 Klaus Landsdorf (http://node-red.plus/)
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_response_1 = __importDefault(require("./core/opcua-iiot-core-response"));
const opcua_iiot_core_1 = require("./core/opcua-iiot-core");
const underscore_1 = __importDefault(require("underscore"));
/**
* Response analyser Node-RED node for OPC UA IIoT nodes.
*
* @param RED
*/
module.exports = (RED) => {
// SOURCE-MAP-REQUIRED
function OPCUAIIoTResponse(config) {
RED.nodes.createNode(this, config);
this.name = config.name;
this.compressStructure = config.compressStructure;
this.showStatusActivities = config.showStatusActivities;
this.showErrors = config.showErrors;
this.activateUnsetFilter = config.activateUnsetFilter;
this.activateFilters = config.activateFilters;
this.negateFilter = config.negateFilter;
this.filters = config.filters;
let self = this;
self.iiot = {};
// prototype functions don't seem to be copied in the above line
// explicitly define node.status here, so it can be used by functions in core-response.ts
self.status = this.status;
this.status({ fill: 'green', shape: 'ring', text: 'active' });
const handleBrowserMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeBrowserResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressBrowseMessageStructure(payload);
}
return payload;
};
const handleCrawlerMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeCrawlerResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressCrawlerMessageStructure(payload);
}
return payload;
};
const handleReadMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeReadResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressReadMessageStructure(payload);
}
return payload;
};
const handleWriteMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeWriteResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressWriteMessageStructure(payload);
}
return payload;
};
const handleListenerMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeListenerResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressListenMessageStructure(payload);
}
return payload;
};
const handleMethodMsg = function (payload) {
opcua_iiot_core_response_1.default.analyzeMethodResults(self, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressMethodMessageStructure(payload);
}
return payload;
};
const handleDefaultMsg = function (payload) {
if (payload) {
opcua_iiot_core_response_1.default.handlePayloadStatusCode(self, payload.value, payload);
if (self.compressStructure) {
opcua_iiot_core_response_1.default.compressDefaultMessageStructure(payload);
}
}
return payload;
};
const handleNodeTypeOfMsg = function (payload) {
switch (payload.nodetype) {
case 'browse':
return handleBrowserMsg(payload);
case 'crawl':
return handleCrawlerMsg(payload);
case 'read':
return handleReadMsg(payload);
case 'write':
return handleWriteMsg(payload);
case 'listen':
return handleListenerMsg(payload);
case 'method':
return handleMethodMsg(payload);
default:
return handleDefaultMsg(payload);
}
};
const extractReadEntriesFromFilter = function (payload) {
let filteredEntries = [];
let filteredValues = [];
if (payload.value.length) {
payload.value.forEach((item, index) => {
if (itemIsNotToFilter(item)) {
filteredEntries.push(item);
filteredValues.push(index);
}
});
}
if (payload.nodesToRead) {
payload.nodesToRead = payload.nodesToRead.filter((item, index) => {
return filteredValues.includes(index);
});
}
return filteredEntries;
};
const extractBrowserEntriesFromFilter = function (payload) {
var _a;
return (_a = payload.browserResults) === null || _a === void 0 ? void 0 : _a.filter((item) => {
return itemIsNotToFilter(item);
});
};
const extractCrawlerEntriesFromFilter = function (payload) {
var _a, _b;
const filter = ((_a = payload.crawlerResults) === null || _a === void 0 ? void 0 : _a.length) === ((_b = payload.addressSpaceItems) === null || _b === void 0 ? void 0 : _b.length)
? payload.value
: payload.crawlerResults;
return filter.filter((item) => {
return itemIsNotToFilter(item);
});
};
const extractPayloadEntriesFromFilter = function (payload) {
return payload.value.filter((item) => {
return itemIsNotToFilter(item);
});
};
const extractMethodEntriesFromFilter = function (payload) {
let filteredEntries = [];
let filteredValues = [];
payload.addressSpaceItems.forEach((item, index) => {
if (itemIsNotToFilter(item)) {
filteredEntries.push(item);
filteredValues.push(index);
}
});
let outputArguments;
if (payload.results) {
outputArguments = payload.results.outputArguments;
}
else {
outputArguments = payload.outputArguments;
}
if (outputArguments) {
outputArguments.forEach((item, index) => {
if (itemIsNotToFilter(item)) {
if (filteredValues.includes(index)) {
filteredEntries[index].dataType = item.dataType;
filteredEntries[index].arrayType = item.arrayType;
filteredEntries[index].value = item.value;
}
}
});
}
return filteredEntries;
};
const extractEntries = function (payload) {
switch (payload.nodetype) {
case 'read':
return extractReadEntriesFromFilter(payload);
case 'browse':
return extractBrowserEntriesFromFilter(payload);
case 'crawl':
return extractCrawlerEntriesFromFilter(payload);
case 'method':
return extractMethodEntriesFromFilter(payload);
default:
return extractPayloadEntriesFromFilter(payload);
}
};
const filterMsg = function (payload) {
if (payload.value.length || (0, opcua_iiot_core_1.isNodeTypeToFilterResponse)(payload)) {
let filteredEntries = extractEntries(payload);
if (filteredEntries === null || filteredEntries === void 0 ? void 0 : filteredEntries.length) {
payload.value = filteredEntries;
payload.payloadType = "filtered";
return payload;
}
}
else {
if (itemIsNotToFilter(payload)) {
payload.payloadType = "unfiltered";
return payload;
}
}
return null;
};
/**
* Ensure msg has the NodeMessageInFlow format
*/
const normalizeMessage = (msg) => {
if (Object.keys(msg).length <= 3) {
return msg;
}
return {
topic: msg.topic,
_msgid: msg._msgid,
payload: Object.assign(Object.assign({}, msg), { value: msg.payload })
};
};
this.on('input', (msg) => {
try {
this.status({ fill: 'green', shape: 'dot', text: 'active' });
const internalMsg = msg;
if (self.activateUnsetFilter) {
if (msg.payload === void 0 ||
underscore_1.default.isNull(msg.payload) ||
underscore_1.default.isEmpty(msg.payload) ||
underscore_1.default.isNull(internalMsg.payload.value)) {
self.error(new Error("Message Structure Is Not As Expected! (expected: msg.payload.value)"));
return;
}
}
msg = normalizeMessage(msg);
const inputPayload = msg.payload;
const handledPayload = Object.assign(Object.assign({}, handleNodeTypeOfMsg(inputPayload)), { compressed: self.compressStructure, payloadType: "handled" });
if (self.activateFilters && self.filters && self.filters.length > 0) {
const filteredPayload = filterMsg(handledPayload);
if (filteredPayload) {
this.send(Object.assign(Object.assign({}, msg), { payload: filteredPayload }));
}
}
else {
this.send(Object.assign(Object.assign({}, msg), { payload: handledPayload }));
}
}
catch (err) {
opcua_iiot_core_response_1.default.internalDebugLog(err);
if (self.showErrors) {
this.error(err, msg);
}
}
});
const itemIsNotToFilter = function (item) {
let result = (0, opcua_iiot_core_1.checkItemForUnsetState)(self, item);
self.filters.forEach((element) => {
result = (0, opcua_iiot_core_1.checkResponseItemIsNotToFilter)(self, item, element, result);
});
return (self.negateFilter) ? !result : result;
};
if (process.env.TEST === "true")
self.functions = {
handleNodeTypeOfMsg,
};
}
RED.nodes.registerType('OPCUA-IIoT-Response', OPCUAIIoTResponse);
};
//# sourceMappingURL=opcua-iiot-response.js.map