From 0c96fb9892299f4d6577130472d8bdddefd57262 Mon Sep 17 00:00:00 2001 From: Matthias Range Date: Tue, 29 Jun 2021 11:34:47 +0200 Subject: [PATCH] Node.Monitoring: v1.3.0 - add delay feature - add sort priority feature --- .gitignore | Bin 2024 -> 2054 bytes Monitoring.html | 126 +++++++++++++++++++++++-------- Monitoring.js | 50 +++++++++--- README.md | 19 +++-- Storage.js | 151 +++++++++++++++++++++++++++---------- images/node_properties.PNG | Bin 22092 -> 24239 bytes package.json | 12 +-- 7 files changed, 263 insertions(+), 95 deletions(-) diff --git a/.gitignore b/.gitignore index 269ef1349406939b4da9f48edb9a9635bd9e18d1..ecf45fcda804d39d2dfcac8fb81958bd04091d42 100644 GIT binary patch delta 11 ScmaFC-zKo(1^eVK7C8VOLIi98 delta 7 OcmZn@c)`En1v>x?yaO!& diff --git a/Monitoring.html b/Monitoring.html index 1d079e1..ce80414 100644 --- a/Monitoring.html +++ b/Monitoring.html @@ -44,7 +44,7 @@ }, cycleTime: { value: 3600, - validate: function(v) { + validate: function (v) { var validator = RED.validators.typedInput('cycleTimeType'); if (!validator(v)) return false; if ($("#node-input-cycleTime").typedInput('type') == 'num' && v < 1) return false; @@ -57,7 +57,7 @@ }, maxBufferSize: { value: 100, - validate: function(v) { + validate: function (v) { var validator = RED.validators.typedInput('maxBufferSizeType'); if (!validator(v)) return false; if ($("#node-input-maxBufferSize").typedInput('type') == 'num' && v <= 0) return false; @@ -68,14 +68,27 @@ maxBufferSizeType: { value: "num" }, - /* - maxItemsPerPackage: { - value: 10000, - validate: function(v) { - return v > 0; + delay: { + value: 0, + validate: function (v) { + var validator = RED.validators.typedInput('delayType'); + if (!validator(v)) return false; + if ($("#node-input-delay").typedInput('type') == 'num' && v < 0) return false; + return true; }, required: true - },*/ + }, + delayType: { + value: "num" + }, + priorityMode: { + value: "0", + required: true, + validate: RED.validators.typedInput('priorityModeType') + }, + priorityModeType: { + value: "options" + }, thingsConfigJson: { value: "" } @@ -83,12 +96,12 @@ inputs: 1, outputs: 2, icon: "equipmentcloud.png", - label: function() { + label: function () { return this.name || "Monitoring"; }, inputLabels: "Monitoring v2 Bulk Uploader", outputLabels: ["Response", "Error"], - oneditprepare: function() { + oneditprepare: function () { $("#node-input-customerID").typedInput({ default: 'str', @@ -115,22 +128,59 @@ typeField: $("#node-input-cycleTimeType"), types: ["num", "env", "flow", "global"] }); + if (!$("#node-input-cycleTime").val()) { + $("#node-input-cycleTime").typedInput('value', this._def.defaults.cycleTime.value); + } $("#node-input-maxBufferSize").typedInput({ default: 'num', typeField: $("#node-input-maxBufferSizeType"), types: ["num", "env", "flow", "global"] }); + if (!$("#node-input-maxBufferSize").val()) { + $("#node-input-maxBufferSize").typedInput('value', this._def.defaults.maxBufferSize.value); + } + $("#node-input-delay").typedInput({ + default: 'num', + typeField: $("#node-input-delayType"), + types: ["num", "env", "flow", "global"] + }); + if (!$("#node-input-delay").val()) { + $("#node-input-delay").typedInput('value', this._def.defaults.delay.value); + } + + $("#node-input-priorityMode").typedInput({ + typeField: $("#node-input-priorityModeType"), + types: [{ + value: "num", + options: [{ + value: "0", + label: "First In First Out" + }, + { + value: "1", + label: "Events First" + }, + { + value: "2", + label: "Events Last" + } + ] + }] + }); + if (!$("#node-input-priorityMode").val()) { + $("#node-input-priorityMode").typedInput('value', this._def.defaults.priorityMode.value); + } var configObj = getThingsConfig(); if (configObj != null) { refreshThingSelectionList(configObj); } - $(".credentialInput").change(function() { + $(".credentialInput").change(function () { calcCredentials(); }); - $("#node-input-inputTypeSelection").change(function() { + $("#node-input-inputTypeSelection").change(function () { if (this.value === "file") { $(".customInputField").hide(); $(".fileInputField").show(); @@ -144,8 +194,9 @@ }); // hide credentail field when it depends on environment variables - $("#node-input-clientID,#node-input-clientSecret").on('change', function(type, value) { - if ($("#node-input-clientID").typedInput('type') == 'env' || $("#node-input-clientSecret").typedInput('type') == 'env') { + $("#node-input-clientID,#node-input-clientSecret").on('change', function (type, value) { + if ($("#node-input-clientID").typedInput('type') == 'env' || $( + "#node-input-clientSecret").typedInput('type') == 'env') { $(".clientCredentials").hide(); } else { $(".clientCredentials").show(); @@ -153,12 +204,12 @@ }); //avoid issue when selecting the file with equal name not firing change event - $('#fileSelector').click(function() { + $('#fileSelector').click(function () { //clean input value of file selector (no change event is fired) this.value = null; }); - $("#fileSelector").change(async function() { + $("#fileSelector").change(async function () { readJsonFile(this.files[0], (json) => { $('#node-input-thingsConfigJson').val(JSON.stringify(json)); @@ -178,7 +229,7 @@ //Is fired when a new value is selected - $("#node-input-eqSelection").change(function() { + $("#node-input-eqSelection").change(function () { var configObj = getThingsConfig(); if (configObj) { $('.credentialField').typedInput('type', 'str'); @@ -198,7 +249,7 @@ }); }, - oneditsave: function() { + oneditsave: function () { } }); @@ -246,7 +297,7 @@ function refreshThingSelectionList(configObj) { $("#node-input-eqSelection").empty(); - configObj.things.forEach(function(item, index) { + configObj.things.forEach(function (item, index) { $("#node-input-eqSelection").append(new Option(item.id, item.id)); }); //Write back the last selected value of EQ @@ -310,15 +361,21 @@ +
+ + +
+ +
+ + +
+
- @@ -326,18 +383,25 @@

This node is the easiest way to connect your equipment to the EquipmentCloud® of Kontron AIS GmbH for any Monitoring purposes. The following config parameters can bet set in our Monitoring Node:

- Name
Give the node an individual name (e.g. EquipmentName)

- Authentication
There are 2 different ways for adding the Authentication settings into the node.
The first one is "Custom": You have to login into your EquipmentCloud®, choose "Equipment Configuration" and + Name
Give the node an individual name (e.g. EquipmentName)

+ Authentication
There are 2 different ways for adding the Authentication settings into the node.
The first one is "Custom": You have to login into your EquipmentCloud®, choose "Equipment Configuration" and "Equipment". In the list of available Equipments you will find the REST Service icon behind each equipment. Now choose your equipment and press the REST Service icon for all REST API details. Now you have to copy all values into the relevant input fields.
The second option is "File": You have to login into your EquipmentCloud®, choose "Equipment Configuration" and "Equipment". In the right top corner of the Equipment list, you will find "Download Rest Configuration". A JSON - file will be downloaded. Now you can select the downloaded file at the parameter "Json config". After the upload you have to select the target Equipment from the Dropdown field at parameter "Equipment".

- Cycle Time
This parameters sets the interval for sending values to the EquipmentCloud®. Incoming messages will be stored inside a buffer until the next interval. When the messages are send successfully to the EquipmentCloud® + file will be downloaded. Now you can select the downloaded file at the parameter "Json config". After the upload you have to select the target Equipment from the Dropdown field at parameter "Equipment".

+ Cycle Time
This parameters sets the interval for sending values to the EquipmentCloud®. Incoming messages will be stored inside a buffer until the next interval. When the messages are send successfully to the EquipmentCloud® the buffer will be cleared.

- Max. Buffer Size
You can set a maximum buffer size for storing the messages until the next cycle. If the maximum buffer is reached, older messages will be deleted and new messages will be stored.

When you have configured + Sending Delay
+ The monitoring node automatically sorts all buffered messages in the chronologically correct order before sending them to EquipmentCloud®. This is done using the timestamp attribute in the message. If your process has data or events that are not available until a later point in time, you can also delay the sending of messages. In this case, only messages older than the specified delay time are taken from the buffer during each send cycle.

+ Item Priority
+ This parameter sets the sort order of messages with the same timestamp attribute. This way you can distinguish whether a state change occurred before or after an alarm or a part was produced. The order of events can affects the presentation of data and calculation of KPI values in the EqupmentCloud®. The following options are available for this purpose:

+ Max. Buffer Size
You can set a maximum buffer size for storing the messages until the next cycle. If the maximum buffer is reached, older messages will be deleted and new messages will be stored.

When you have configured your Monitoring node correctly, the node will get a token and will show this as a green point under the node in your flow.

-

Monitoring Data

+

Monitoring Data

The input for the Monitoring node must be a message format based on the REST API of the EquipmentCloud®. The following JSON message is an example for such a message. Please note that you have to be ensure that the correct type for each item (alarm, event, etc.) is selected. @@ -389,7 +453,7 @@

Monitoring Data

}

-

Equipment Configuration

+

Equipment Configuration

You can also dynamically upload the type configuration of the equipment. This allows, e.g., to create an alarm in the EquipmentCloud®, which has not been configured yet. Note that this may affect other equipment of the same type.

@@ -495,7 +559,7 @@ 

Equipment Configuration

}

-

More information

+

More information

If you want to have more information regarding our REST API, please log in to your account and take a look at:
Help Center / Help & Tips / RESTful Service API Explorer / Monitoring API 2.0

diff --git a/Monitoring.js b/Monitoring.js index 708c208..4350adb 100644 --- a/Monitoring.js +++ b/Monitoring.js @@ -53,7 +53,9 @@ module.exports = function (RED) { var defaultSettings = { cycleTime: 3600, maxBufferSize: 100, - maxItemsPerPackage: 10000 + maxItemsPerPackage: 10000, + delay: 0, + priorityMode: Storage.PriorityMode.FIFO }; // if a property is not set in config, take default value Object.keys(defaultSettings).forEach(key => { @@ -71,6 +73,13 @@ module.exports = function (RED) { var clientID = RED.util.evaluateNodeProperty(config.clientID, config.clientIDType, node); var clientSecret = RED.util.evaluateNodeProperty(config.clientSecret, config.clientSecretType, node); var clientCredentials = clientID && clientSecret ? Buffer.from(clientID + ":" + clientSecret).toString("base64") : null; + var maxBufferSize = (RED.util.evaluateNodeProperty(config.maxBufferSize, config.maxBufferSizeType, node) || defaultSettings.maxBufferSize); + maxBufferSize = maxBufferSize > 0 ? maxBufferSize : defaultSettings.maxBufferSize; + var delay = (RED.util.evaluateNodeProperty(config.delay, config.delayType, node) || defaultSettings.delay); + delay = delay >= 0 ? delay : defaultSettings.delay; + var priorityMode = (RED.util.evaluateNodeProperty(config.priorityMode, config.priorityModeType, node) || defaultSettings.priorityMode); + var cycleTime = (RED.util.evaluateNodeProperty(config.cycleTime, config.cycleTimeType, node) || defaultSettings.cycleTime); + cycleTime = cycleTime > 0 ? cycleTime : defaultSettings.cycleTime; if (!(id && customerID && eqID && clientID && clientCredentials)) { handleException(new Error("Not all parameters set!")); @@ -104,7 +113,12 @@ module.exports = function (RED) { var client = new OAuthClient(clientID, clientCredentials, tokenUrl); // set up buffer - var storage = new Storage(id, (RED.util.evaluateNodeProperty(config.maxBufferSize, config.maxBufferSizeType, node) || defaultSettings.maxBufferSize)); + var storage = new Storage( + id, + maxBufferSize, + delay, + priorityMode + ); var storageInitializationInProgress = false; var storageInitialized = false; async function initStorage() { @@ -153,6 +167,7 @@ module.exports = function (RED) { // stop job to send data from buffer to cloud try { clearTimeout(timer); + timer = null; await waitForStorage(); // save close storage await storage.close(); @@ -369,7 +384,7 @@ module.exports = function (RED) { // delete all processed items from storage // Hint: this includes the last processed item although it caused by an error. // This prevents queue processing from being blocked by a single error. - await storage.deleteData(data.firstIndex, data.firstIndex + response.body.result[0].current_item_index); + await storage.deleteData(data.ids.slice(0, response.body.result[0].current_item_index + 1)); // on Precondition fail, do not handle this as an exception // but inform user about the error @@ -416,15 +431,22 @@ module.exports = function (RED) { break; case 404: setNodeStatus(nodeStatus.ERROR); - errorOutput = new Error("Not Found!"); + errorOutput = new Error("Not found!"); break; case 409: setNodeStatus(nodeStatus.ERROR); errorOutput = new Error("Conflict!"); break; + case 500: + setNodeStatus(nodeStatus.ERROR); + errorOutput = new Error("Internal Server Error!"); + break; default: setNodeStatus(nodeStatus.ERROR); - errorOutput = new Error("Unexpected error!"); + // add some info for service logs + errorOutput = new Error("Unexpected error!" + + "\nStatus Code: " + e.response.statusCode + + "\nBody: " + JSON.stringify(e.response.body)); break; } } @@ -517,11 +539,9 @@ module.exports = function (RED) { // set next cycle time // - balance drift - // - note minimum of 1 second for next cycle, so there is no endless transmitting - var nextCycle = Math.max( - (RED.util.evaluateNodeProperty(config.cycleTime, config.cycleTimeType, node) || defaultSettings.cycleTime) * - 1000 - (jobEndDate - jobStartDate), 1000); - timer = setTimeout(async () => transmitData(), nextCycle); + // - minimum of 1 second for next cycle, so there is no endless transmitting + var nextCycle = Math.max(cycleTime * 1000 - (jobEndDate - jobStartDate), 1000); + resetTimerForTransmitData(nextCycle); } // inital timer @@ -538,10 +558,16 @@ module.exports = function (RED) { } catch (e) { handleException(e); // retry authentication with next cycle - timer = setTimeout(() => transmitData(), - (RED.util.evaluateNodeProperty(config.cycleTime, config.cycleTimeType, node) || defaultSettings.cycleTime)); + resetTimerForTransmitData(cycleTime); } }, 1000); + + function resetTimerForTransmitData(timeout) { + // prevent transmitData() resetting the timer again if node was disposed + if (timer) { + timer = setTimeout(() => transmitData(), timeout); + } + } } RED.nodes.registerType("Monitoring", MonitoringNode); }; \ No newline at end of file diff --git a/README.md b/README.md index fb9a537..ed2331e 100644 --- a/README.md +++ b/README.md @@ -19,21 +19,30 @@ After installation you will find the node inside the Node-red palette. ![node_properties](images/node_properties.PNG?raw=true) -**Name** +**Name**: Give the node an individual name (e.g. EquipmentName) -**Authentication** +**Authentication**: There are 2 different ways for adding the Authentication settings into the node. The first one is "Custom": You have to login into your EquipmentCloud®, choose "Equipment Configuration" and "Equipment". In the list of available Equipments you will find the REST Service icon behind each equipment. Now choose your equipment and press the REST Service icon for all REST API details. Now you have to copy all values into the relevant input fields. The second option is "File": You have to login into your EquipmentCloud®, choose "Equipment Configuration" and "Equipment". In the right top corner of the Equipment list, you will find "Download Rest Configuration". A JSON file will be downloaded. Now you can select the downloaded file at the parameter "Json config". After the upload you have to select the target Equipment from the Dropdown field at parameter "Equipment". -**Cycle Time** +**Cycle Time**: This parameters sets the interval for sending values to the EquipmentCloud®. Incoming messages will be stored inside a buffer until the next interval. When the messages are send successfully to the EquipmentCloud® the buffer will be cleared. -**Max. Buffer Size** -You can set a maximum buffer size for storing the messages until the next cycle. If the maximum buffer is reached, older messages will be deleted and new messages will be stored. +**Sending Delay**: +The monitoring node automatically sorts all buffered messages in the chronologically correct order before sending them to EquipmentCloud®. This is done using the *timestamp* attribute in the message. If your process has data or events that are not available until a later point in time, you can also delay the sending of messages. In this case, only messages older than the specified delay time are taken from the buffer during each send cycle. + +**Item Priority**: +This parameter sets the sort order of messages with the same *timestamp* attribute. This way you can distinguish whether a state change occurred before or after an alarm or a part was produced. The order of events can affects the presentation of data and calculation of KPI values in the EqupmentCloud®. The following options are available for this purpose: +- **First In First Out**: The order in which the messages were passed to the node is preserved. +- **Events First**: Events for equipment state change are sent to EquipmentCloud® first. All following alarms and produced parts therefore get the property of the last passed state of the equipment. +- **Events Last**: Events for equipment state change are sent to EquipmentCloud® after the other messages. All alarms and produced parts up to the state change message therefore get the property of the previous equipment state. + +**Max. Buffer Size**: +You can set a maximum buffer size for storing the messages until the next cycle. If the maximum buffer is reached, older messages will be deleted and new messages will be stored. When you have configured your Monitoring node correctly, the node will get a token and will show this as a green point under the node in your flow. diff --git a/Storage.js b/Storage.js index 148cf9e..73b2780 100644 --- a/Storage.js +++ b/Storage.js @@ -31,14 +31,32 @@ module.exports = class Storage { and chaining calls are not working with instance fields in classes */ - constructor(id, maxfileSize) { + // Sort priority for items with equal timestamps + static PriorityMode = { + FIFO: 0, // first in, first out (inserting sortorder) + EventsFirst: 1, // events (state changes) before alarms, units, etc. + EventsLast: 2 // events (state changes) after alarms, units, etc. + }; + + constructor(id, maxfileSize = 100, delay = 0, priorityMode = Storage.PriorityMode.FIFO) { this.id = id; this.db = null; this.filename = id + ".db"; // file watcher settings: this.housekeeperInterval = 10000; - this.maxfileSize = (maxfileSize || 100) * 1024 * 1024; // Size in MB + this.maxfileSize = maxfileSize * 1024 * 1024; // Size in MB this.cleanupFactor = 0.05; + this.delay = delay * 1000 / 86400000; + switch (priorityMode) { + case Storage.PriorityMode.EventsFirst: + this.orderColumn = "is_event DESC, id"; + break; + case Storage.PriorityMode.EventsLast: this.orderColumn = "is_event ASC, id"; + break; + default: + this.orderColumn = "id"; + break; + } } _getDatabase(filename) { @@ -71,13 +89,28 @@ module.exports = class Storage { } async _createTables() { - // drop messages table without specific id column (deprecated) + // upgrade <= v1.1: drop messages table without specific id column (deprecated) var tableDef = await this._getTableDefinition("messages"); if (tableDef && !tableDef.sql.includes("id INTEGER")) { await this.wrapRunPromise("DROP TABLE messages"); } - await this.wrapRunPromise("CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY ASC, data Text)"); + // upgrade <= v1.2: + if (tableDef && !tableDef.sql.includes("timestamp REAL") && !tableDef.sql.includes("is_event INTEGER")) { + // add missing columns + await this.wrapRunPromise("ALTER TABLE messages ADD COLUMN timestamp REAL"); + await this.wrapRunPromise("ALTER TABLE messages ADD COLUMN is_event INTEGER"); + // migrate data + await this.wrapRunPromise("UPDATE messages SET " + + "timestamp = julianday(json_extract(data, '$.timestamp'), 'utc'), " + + "is_event = CASE WHEN json_extract(data, '$.type') = 2 THEN 1 ELSE 0 END;"); + } + // initial: create teables + await this.wrapRunPromise("CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY ASC, timestamp REAL, is_event INTEGER, data Text)"); await this.wrapRunPromise("CREATE TABLE IF NOT EXISTS configMessages (id INTEGER PRIMARY KEY AUTOINCREMENT, category Text, data Text )"); + // initial: create index + await this.wrapRunPromise("CREATE INDEX IF NOT EXISTS idx_messages_events_first ON messages (timestamp, is_event DESC, id)"); + await this.wrapRunPromise("CREATE INDEX IF NOT EXISTS idx_messages_events_last ON messages (timestamp, is_event ASC, id)"); + await this.wrapRunPromise("CREATE INDEX IF NOT EXISTS idx_messages_fifo ON messages (timestamp, id)"); } _getTableDefinition(tablename) { @@ -119,37 +152,50 @@ module.exports = class Storage { var db = this.db; return new Promise((resolve, reject) => { - //"SELECT rowid AS id, data FROM messages, LIMIT 1" var dataArray = []; - var firstIndex = 0; + var idArray = []; + var maxId = 0; + var args = [limit]; + var whereClause = ""; + if (this.delay > 0) { + whereClause = " WHERE timestamp < ?"; + // add filter timestamp value at begin of arguements array + args.unshift(new Date().getTime() / 86400000 + 2440587.5 - this.delay); + } - db.each("SELECT data, id FROM messages LIMIT ?", [limit], (err, row) => { - //Errorhandling - if (err) { - return reject(err); - } - try { - if (firstIndex == 0) { - firstIndex = row.id; + db.each("SELECT data, id FROM messages" + + whereClause + + " ORDER BY timestamp, " + + this.orderColumn + + " LIMIT ?", args, (err, row) => { + //Errorhandling + if (err) { + return reject(err); + } + try { + if (maxId < row.id) { + maxId = row.id; + } + var json = JSON.parse(row.data); + dataArray.push(json); + idArray.push(row.id); + } catch (e) { + return reject(e); } - var json = JSON.parse(row.data); - dataArray.push(json); - } catch (e) { - return reject(e); - } - }, (err) => { - if (err) { - return reject(err); - } + }, (err) => { + if (err) { + return reject(err); + } - const dataWithInformation = { - items: dataArray, - firstIndex: firstIndex, - }; + const dataWithInformation = { + items: dataArray, + ids: idArray, + maxId: maxId + }; - return resolve(dataWithInformation); - }); + return resolve(dataWithInformation); + }); }); } @@ -207,11 +253,12 @@ module.exports = class Storage { this.dataActionCounter++; } - async deleteData(start, end) { - await this.wrapRunPromise("DELETE FROM messages WHERE id BETWEEN $start and $end", { - $start: start, - $end: end - }); + async deleteData(ids) { + var sql = "DELETE FROM messages WHERE id IN ("; + ids.forEach(id => sql += id + ","); + sql = sql.substring(0, sql.length - 1) + ")"; + await this.wrapRunPromise(sql); + // increment data action counter for swap transaction job this.dataActionCounter++; } @@ -240,7 +287,7 @@ module.exports = class Storage { jsons.push(JSON.stringify(chunk[i])); for (var addVal2 of additionalValues) { sql += ",?"; - jsons.push(addVal2.value); + jsons.push(addVal2.value(chunk[i])); } sql += "),(?"; } @@ -285,11 +332,35 @@ module.exports = class Storage { } async storeData(data) { - await this._storeDataInChunks("messages", data); + await this._storeDataInChunks("messages", data, + [ + { + column: "timestamp", + value: function (item) { + // calculate julian date + return (new Date(item.timestamp ?? new Date())).getTime() / 86400000 + 2440587.5; + } + }, + { + column: "is_event", + value: function (item) { + // only item type = 2 is an event + return item.type == 2 ? 1 : 0; + } + } + ]); } async storeConfigData(data, category) { - await this._storeDataInChunks("configMessages", data, [{ column: "category", value: category }]); + await this._storeDataInChunks("configMessages", data, + [ + { + column: "category", + value: function (item) { + return category; + } + } + ]); } _closeDatabase() { @@ -368,10 +439,8 @@ module.exports = class Storage { do { // delete block from storage // calculate block size depending on current item count and cleanup factor - var data = await self.getStorageData(1); - var startIndex = data.firstIndex; - var endIndex = startIndex + Math.ceil(itemCount * self.cleanupFactor); - await self.deleteData(startIndex, endIndex); + var data = await self.getStorageData(Math.ceil(itemCount * self.cleanupFactor)); + await self.deleteData(data.ids); // shrink file size await self._commitTransaction(); await self.wrapRunPromise("VACUUM;"); diff --git a/images/node_properties.PNG b/images/node_properties.PNG index c26d2c452173fc10a9b5a7420a00c21012a2bca5..76a77491d331a7e4eb193f390a2268fe45c0d0b1 100644 GIT binary patch literal 24239 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

m^*^Tbxb-O_tB5 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 diff --git a/package.json b/package.json index 6476ff2..13dc8b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ais_automation/node-red-contrib-eqcloud-monitoring", - "version": "1.2.0", + "version": "1.3.0", "node-red": { "nodes": { "Monitoring": "Monitoring.js" @@ -45,17 +45,17 @@ "DeviceManagement" ], "devDependencies": { - "node-red": "^0.20.6", - "node-red-node-test-helper": "^0.2.2", - "should": "^13.2.3", "eslint": "^5.16.0", "eslint-config-standard": "^12.0.0", "eslint-plugin-import": "^2.17.3", "eslint-plugin-node": "^9.1.0", "eslint-plugin-promise": "^4.1.1", "eslint-plugin-standard": "^4.0.0", - "mocha": "^6.1.4", - "mocha-junit-reporter": "^1.22.0" + "mocha": "^9.0.1", + "mocha-junit-reporter": "^1.22.0", + "node-red": "^1.3.5", + "node-red-node-test-helper": "^0.2.7", + "should": "^13.2.3" }, "scripts": { "test": "mocha --recursive 'test/*_spec.js' --exit"