node-red-contrib-iiot-opcua
Version:
An Industrial IoT OPC UA toolbox contribution package for Node-RED based on node-opcua.
214 lines (211 loc) • 8.73 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 2013, 2016 IBM Corp. (node-red)
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_inject_1 = __importDefault(require("./core/opcua-iiot-core-inject"));
const opcua_iiot_core_1 = require("./core/opcua-iiot-core");
const cron_1 = require("cron");
/**
* Inject Node-RED node for OPC UA IIoT nodes.
*
* @param RED
*/
module.exports = function (RED) {
// SOURCE-MAP-REQUIRED
function OPCUAIIoTInject(config) {
RED.nodes.createNode(this, config);
this.topic = config.topic;
this.payload = config.payload;
this.payloadType = config.payloadType;
this.crontab = config.crontab;
this.once = config.once;
this.startDelay = parseFloat(config.startDelay) || 10;
this.name = config.name;
this.injectType = config.injectType || 'inject';
this.repeat = config.repeat || 0;
this.addressSpaceItems = config.addressSpaceItems || [];
let self = this;
let intervalId = null;
let onceTimeout = null;
let cronjob = null;
const REPEAT_FACTOR = 1000.0;
const ONE_SECOND = 1000;
const INPUT_TIMEOUT_MILLISECONDS = 1000;
const repeaterSetup = () => {
opcua_iiot_core_inject_1.default.internalDebugLog('Repeat Is ' + self.repeat);
opcua_iiot_core_inject_1.default.internalDebugLog('Crontab Is ' + self.crontab);
if (self.repeat !== 0) {
self.repeat = config.repeat * REPEAT_FACTOR;
if (self.repeat === 0) {
self.repeat = ONE_SECOND;
}
opcua_iiot_core_inject_1.default.internalDebugLog('Repeat Interval Start With ' + self.repeat + ' msec.');
// existing interval timer must be deleted
if (intervalId) {
clearInterval(intervalId);
intervalId = null;
}
if (typeof self.repeat !== "number" || isNaN(self.repeat))
return;
intervalId = setInterval(() => {
this.emit('input', newMessage());
}, self.repeat);
}
else if (self.crontab !== '') {
cronjob = new cron_1.CronJob(self.crontab, () => {
this.emit('input', newMessage());
}, null, true);
}
};
const newMessage = function () {
return {
_msgid: RED.util.generateId(),
topic: self.topic,
payload: generateOutputValue(self.payload, {
_msgid: RED.util.generateId(),
payload: {
injectType: self.injectType
}
})
};
};
// existing timers must be deleted
const resetAllTimer = function () {
if (onceTimeout) {
clearTimeout(onceTimeout);
onceTimeout = null;
}
if (intervalId) {
clearInterval(intervalId);
intervalId = null;
}
};
const generateOutputValue = (payloadType, inputMessage) => {
switch (payloadType) {
case 'none':
return '';
case 'str':
return self.payload.toString();
case 'num':
return Number(self.payload);
case 'bool':
return (self.payload === true || self.payload === 'true');
case 'json':
return JSON.parse(self.payload);
case 'date':
return Date.now();
default:
if (self.payloadType === null) {
if (self.payload === '') {
return Date.now();
}
else {
return self.payload;
}
}
else {
return RED.util.evaluateNodeProperty(self.payload, self.payloadType, this, inputMessage);
}
}
};
this.on('input', (msg) => {
var _a;
if (Object.keys(msg).length === 0) {
// security: never use a completely empty message with any key, this is not a valid node-red msg than
return;
}
try {
const topic = self.topic || msg.topic;
const payload = {
payload: msg.payload,
payloadType: self.payloadType,
value: generateOutputValue(self.payloadType, msg),
nodetype: 'inject',
injectType: ((_a = msg.payload) === null || _a === void 0 ? void 0 : _a.injectType) || self.injectType,
addressSpaceItems: [...self.addressSpaceItems],
manualInject: Object.keys(msg).length !== 0
};
const outputMessage = Object.assign(Object.assign({}, msg), { topic,
payload });
this.send(outputMessage);
}
catch (err) {
/* istanbul ignore next */
if (RED.settings.verbose) {
this.error(err, msg);
}
}
});
// existing timer must be deleted
if (onceTimeout) {
clearTimeout(onceTimeout);
onceTimeout = null;
}
let timeout = INPUT_TIMEOUT_MILLISECONDS * self.startDelay;
if (this.once) {
opcua_iiot_core_inject_1.default.detailDebugLog('injecting once at start delay timeout ' + timeout + ' msec.');
onceTimeout = setTimeout(() => {
opcua_iiot_core_inject_1.default.detailDebugLog('injecting once at start');
this.emit('input', newMessage());
repeaterSetup();
}, timeout);
}
else if (self.repeat || self.crontab) {
opcua_iiot_core_inject_1.default.detailDebugLog('start with delay timeout ' + timeout + ' msec.');
onceTimeout = setTimeout(function () {
opcua_iiot_core_inject_1.default.detailDebugLog('had a start delay of ' + timeout + ' msec. to setup inject interval');
repeaterSetup();
}, timeout);
}
else {
repeaterSetup();
}
this.close = (removed) => __awaiter(this, void 0, void 0, function* () {
if (cronjob) {
cronjob.stop();
delete self['cronjob'];
}
yield resetAllTimer(); // all timers have to be reset
self.removeAllListeners();
(0, opcua_iiot_core_1.resetIiotNode)(self);
});
}
RED.nodes.registerType('OPCUA-IIoT-Inject', OPCUAIIoTInject);
RED.httpAdmin.post('/opcuaIIoT/inject/:id', RED.auth.needsPermission('opcuaIIoT.inject.write'), function (req, res) {
const node = RED.nodes.getNode(req.params.id);
if (node) {
try {
node.receive();
res.sendStatus(200);
}
catch (err) {
/* istanbul ignore next */
res.sendStatus(500);
node.error(RED._('opcuaiiotinject.failed', { error: err.toString() }));
}
}
else {
/* istanbul ignore next */
res.sendStatus(404);
}
});
};
//# sourceMappingURL=opcua-iiot-inject.js.map