node-red-contrib-iiot-opcua
Version:
An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.
431 lines (428 loc) • 14.9 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 debug_1 = __importDefault(require("debug"));
const assertion_1 = require("../types/assertion");
const internalDebugLog = (0, debug_1.default)('opcuaIIoT:response'); // eslint-disable-line no-use-before-define
const detailDebugLog = (0, debug_1.default)('opcuaIIoT:response:details'); // eslint-disable-line no-use-before-define
const EMPTY_LIST = 0;
const NONE = 0;
const analyzeBrowserResults = function (node, payload) {
handlePayloadStatusCode(node, payload.browserResults, payload);
};
const analyzeCrawlerResults = function (node, payload) {
handlePayloadStatusCode(node, payload.value, payload);
};
const analyzeReadResults = (node, payload) => {
handlePayloadStatusCode(node, payload.value, payload);
if (payload.readtype === 'HistoryValue') {
payload.value.map((item) => {
delete item['statusCode'];
});
}
reconsturctNodeIdOnRead(payload);
};
const analyzeListenerResults = function (node, payload) {
switch (payload.injectType) {
case 'subscribe':
case 'event':
handlePayloadStatusCode(node, payload.value, payload);
break;
default:
break;
}
};
const analyzeMethodResults = function (node, payload) {
switch (payload.methodType) {
case 'basic':
case 'complex':
handlePayloadStatusCode(node, payload.value, payload);
break;
default:
break;
}
};
const setNodeStatus = (node, entryStatus, informationText) => {
let fillColor = 'green';
if (entryStatus && Object.keys(entryStatus).length === 3) {
if (entryStatus['other'] > EMPTY_LIST) {
fillColor = 'yellow';
}
if (entryStatus['bad'] > EMPTY_LIST) {
fillColor = 'red';
}
}
node.status({ fill: fillColor, shape: 'dot', text: informationText });
};
const analyzeWriteResults = function (node, msg) {
let entryStatus = handlePayloadArrayOfStatusCodes(msg);
setNodeStatusInfo(node, msg, entryStatus);
};
const isStatusInput = (status) => {
var _a;
if ("statusCode" in status && typeof ((_a = status.statusCode) === null || _a === void 0 ? void 0 : _a.name) === "string") {
return true;
}
if (Array.isArray(status)) {
return status.every((item) => { var _a; return typeof ((_a = item.statusCode) === null || _a === void 0 ? void 0 : _a.name) === "string"; });
}
return false;
};
const handlePayloadStatusCode = (node, statusInputs, payload) => {
if (!isStatusInput(statusInputs)) {
if ((0, assertion_1.isArray)(statusInputs)) {
if (statusInputs.length !== 0)
payload.entryStatus = {
good: statusInputs.length,
bad: 0,
other: 0,
};
else
payload.entryStatus = {
good: 0,
bad: 1,
other: 0,
};
}
else {
if (statusInputs instanceof Error) {
payload.entryStatus = {
bad: 1,
other: 0,
good: 0,
};
}
else {
payload.entryStatus = {
bad: 0,
other: 0,
good: 1,
};
}
}
return;
}
let entryStatus = {
bad: 0,
good: 0,
other: 0
};
if (!statusInputs || statusInputs.length === 0) {
payload.entryStatus = Object.assign(Object.assign({}, entryStatus), { bad: 1 });
return;
}
if ((0, assertion_1.isArray)(statusInputs)) {
entryStatus = handlePayloadArrayOfObjects(statusInputs);
}
else {
entryStatus = handlePayloadObject(statusInputs);
}
setNodeStatusInfo(node, payload, entryStatus);
payload.entryStatus = entryStatus;
};
const setNodeStatusInfo = function (node, payload, entryStatus) {
payload.entryStatus = entryStatus;
payload.entryStatusText = 'Good:' + entryStatus['good'] + ' Bad:' + entryStatus['bad'] + ' Other:' + entryStatus['other'];
setNodeStatus(node, payload.entryStatus, payload.entryStatusText);
};
const handlePayloadArrayOfObjects = function (statusInputs) {
let entryStatus = {
bad: 0,
good: 0,
other: 0
};
statusInputs.forEach((entry) => {
var _a, _b, _c;
switch ((_a = entry.statusCode) === null || _a === void 0 ? void 0 : _a.name) {
case 'Good':
entryStatus['good'] += 1;
break;
case 'Bad':
entryStatus['bad'] += 1;
break;
default:
if (((_c = (_b = entry.statusCode) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.includes('Bad')) || entry.toString().includes('Error')) {
entryStatus['bad'] += 1;
}
else {
entryStatus['good'] += 1;
}
}
});
return entryStatus;
};
const handlePayloadObject = function (statusInput) {
let entryStatus = {
good: 0,
bad: 0,
other: 0,
};
if ((0, assertion_1.isArray)(statusInput)) {
entryStatus = handlePayloadArrayOfObjects(statusInput);
}
if (statusInput && statusInput.statusCode) {
if (statusInput.statusCode.name) {
switch (statusInput.statusCode.name) {
case 'Good':
entryStatus['good'] += 1;
break;
case 'Bad':
entryStatus['bad'] += 1;
break;
default:
if (statusInput.statusCode.name.includes('Good')) {
entryStatus['good'] += 1;
}
else if (statusInput.statusCode.name.includes('Bad')) {
entryStatus['bad'] += 1;
}
else {
entryStatus['other'] += 1;
}
}
}
else {
entryStatus['other'] += 1;
}
}
else {
entryStatus['other'] += 1;
}
return entryStatus;
};
const handlePayloadArrayOfStatusCodes = function (payload) {
var _a;
let entry = null;
let entryStatus = {
good: 0,
bad: 0,
other: 0,
};
if (!payload.statusCodes) {
payload.statusCodes = (_a = payload.value) === null || _a === void 0 ? void 0 : _a.statusCodes;
}
if (payload.statusCodes) {
for (entry of payload.statusCodes) {
if (entry && entry.name) {
switch (entry.name) {
case 'Good':
entryStatus['good'] += 1;
break;
case 'Bad':
entryStatus['bad'] += 1;
break;
default:
if (entry.name.includes('Good')) {
entryStatus['good'] += 1;
}
else if (entry.name.includes('Bad')) {
entryStatus['bad'] += 1;
}
else {
entryStatus['other'] += 1;
}
}
}
else {
entryStatus['other'] += 1;
}
}
}
else {
entryStatus['other'] += 1;
}
return entryStatus;
};
const defaultCompress = function (payload) {
if (payload.value.value) {
payload.value = payload.value.value;
}
trimMessageExtensions(payload);
};
const trimMessageExtensions = function (payload) {
delete payload['nodesToRead'];
delete payload['nodesToReadCount'];
delete payload['addressItemsToRead'];
delete payload['addressItemsToReadCount'];
delete payload['addressItemsToBrowse'];
delete payload['addressItemsToBrowseCount'];
delete payload['addressSpaceItems'];
delete payload['injectType'];
delete payload['entryStatusText'];
if (payload.filter) {
compressFilteredMessage(payload);
}
};
const trimMessagePayloadExtensions = (payload) => {
delete payload['listenerParameters'];
};
const compressBrowseMessageStructure = function (payload) {
var _a;
if ((_a = payload.browserResults) === null || _a === void 0 ? void 0 : _a.length) {
payload.value = payload.browserResults.map((item) => {
var _a, _b, _c, _d;
return {
nodeId: item.nodeId.toString(),
browseName: ((_a = item.browseName) === null || _a === void 0 ? void 0 : _a.namespaceIndex) ? ((_b = item.browseName) === null || _b === void 0 ? void 0 : _b.namespaceIndex) + ':' + ((_c = item.browseName) === null || _c === void 0 ? void 0 : _c.name) : item.browseName,
displayName: (_d = item.displayName) === null || _d === void 0 ? void 0 : _d.text
};
});
trimMessageExtensions(payload);
trimMessagePayloadExtensions(payload);
}
else {
defaultCompress(payload);
}
};
const compressCrawlerMessageStructure = function (payload) {
var _a, _b;
if (payload.hasOwnProperty('crawlerResults') && ((_a = payload.crawlerResults) === null || _a === void 0 ? void 0 : _a.length)) {
payload.value = (_b = payload.crawlerResults) === null || _b === void 0 ? void 0 : _b.map((item) => {
return {
nodeId: item.nodeId.toString(),
browseName: (item.browseName.namespaceIndex) ? item.browseName.namespaceIndex + ':' + item.browseName.name : item.browseName,
displayName: item.displayName.text
};
});
trimMessageExtensions(payload);
trimMessagePayloadExtensions(payload);
}
else {
defaultCompress(payload);
}
};
const reconsturctNodeIdOnRead = function (payload) {
let results = payload.value || payload;
let nodesToRead = payload.nodesToRead;
if (results && results.length) {
payload.value = results.map((item, index) => {
var _a, _b, _c;
if ((_a = item === null || item === void 0 ? void 0 : item.value) === null || _a === void 0 ? void 0 : _a.value) {
let nodeId = null;
if (nodesToRead && index < nodesToRead.length) {
nodeId = nodesToRead[index];
}
else {
if (payload.addressSpaceItems && index < payload.addressSpaceItems.length) {
nodeId = payload.addressSpaceItems[index];
}
}
return {
value: (_b = item.value) === null || _b === void 0 ? void 0 : _b.value,
dataType: (_c = item.value) === null || _c === void 0 ? void 0 : _c.dataType,
nodeId
};
}
else {
return item;
}
});
}
};
const compressVariableValueMessage = function (payload) {
delete payload['nodesToRead'];
delete payload['nodesToReadCount'];
delete payload['addressSpaceItems'];
return payload;
};
const compressFilteredMessage = function (payload) {
delete payload['filter'];
delete payload['filtertype'];
};
const compressReadMessageStructure = function (payload) {
switch (payload.readtype) {
case 'AllAttributes':
delete payload['nodesToRead'];
delete payload['resultsConverted'];
break;
case 'VariableValue':
payload = compressVariableValueMessage(payload);
break;
default:
break;
}
delete payload['readtype'];
delete payload['attributeId'];
delete payload['addressItemsToReadn'];
delete payload['addressItemsToReadCount'];
trimMessageExtensions(payload);
};
const compressWriteMessageStructure = function (payload) {
defaultCompress(payload);
let itemList = [];
payload.value = payload.statusCodes.map((item, index) => {
return {
nodeId: (payload.nodesToWrite) ? payload.nodesToWrite[index] : payload.addressSpaceItems[index],
statusCode: item,
value: (payload.valuesToWrite) ? payload.valuesToWrite[index] : null
};
});
delete payload['valuesToWrite'];
};
const compressListenMessageStructure = function (payload) {
// interpreting payload as any makes reassigning it not cause errors
if (payload.hasOwnProperty('value') && payload.value.hasOwnProperty('value')) {
payload = {
value: payload.value.value,
dataType: payload.value.dataType,
nodeId: (payload.addressSpaceItems[0].nodeId) ? payload.addressSpaceItems[0].nodeId : payload.addressSpaceItems[0]
};
}
trimMessageExtensions(payload);
};
const compressMethodMessageStructure = function (payload) {
defaultCompress(payload);
trimMessageExtensions(payload);
delete payload['inputArguments'];
delete payload['objectId'];
delete payload['methodId'];
delete payload['methodType'];
delete payload['definition'];
};
const compressDefaultMessageStructure = function (payload) {
defaultCompress(payload);
trimMessageExtensions(payload);
};
const coreResponse = {
internalDebugLog,
detailDebugLog,
EMPTY_LIST,
NONE,
analyzeBrowserResults,
analyzeCrawlerResults,
analyzeReadResults,
analyzeListenerResults,
analyzeMethodResults,
setNodeStatus,
analyzeWriteResults,
handlePayloadStatusCode,
setNodeStatusInfo,
handlePayloadArrayOfObjects,
handlePayloadObject,
handlePayloadArrayOfStatusCodes,
defaultCompress,
trimMessageExtensions,
trimMessagePayloadExtensions,
compressBrowseMessageStructure,
compressCrawlerMessageStructure,
reconsturctNodeIdOnRead,
compressVariableValueMessage,
compressFilteredMessage,
compressReadMessageStructure,
compressWriteMessageStructure,
compressListenMessageStructure,
compressMethodMessageStructure,
compressDefaultMessageStructure,
};
exports.default = coreResponse;
//# sourceMappingURL=opcua-iiot-core-response.js.map