UNPKG

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
/** 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 **/ 'use strict'; 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