From ef7817bf223f25a09bfdf8532e893ada1669e6ed Mon Sep 17 00:00:00 2001 From: rasta5man Date: Wed, 1 Jan 2025 13:12:02 +0100 Subject: [PATCH] Limit, what we send --- flow/cmd_manager.js | 85 ++++++++++++++++++---------------- flow/designer.json | 50 ++++++++++---------- flow/dido_controller.js | 4 ++ flow/helper/DataToTbHandler.js | 47 ++++++++++++++++--- flow/modbus_reader.js | 10 ++-- 5 files changed, 122 insertions(+), 74 deletions(-) diff --git a/flow/cmd_manager.js b/flow/cmd_manager.js index 255f48e..a63185f 100644 --- a/flow/cmd_manager.js +++ b/flow/cmd_manager.js @@ -3,7 +3,6 @@ exports.title = 'CMD Manager'; exports.group = 'Worksys'; exports.color = '#5D9CEC'; exports.version = '0.0.3'; -//blue - send message to relays exports.output = ['red', 'blue', 'yellow', 'blue', 'white']; exports.input = 3; exports.icon = 'cloud-upload'; @@ -141,6 +140,9 @@ exports.install = function(instance) { //helper container for counting resolved group of commands (commands related to set profile) let cmdCounter = {};//key is node, value is counter + + //if sending of profile to node fails, we send notification and push node into set, so we do not send notification twice + const nodeProfileSendFail = new Set(); //END OF VARIABLE SETTINGS //-------------------------------- @@ -1403,7 +1405,7 @@ exports.install = function(instance) { if ((currentTimestamp - reportDuskDawn.dusk_time) < 60 * 1000) { //reportovali sme? if (reportDuskDawn.dusk_time_reported != sunCalcResult.dusk_time) { - sendNotification("CMD Manager: calculated Time of dusk", SETTINGS.rvoTbName, "dusk_has_occured", { value: sunCalcResult["dusk"] }, "", SEND_TO.tb, instance); + //sendNotification("CMD Manager: calculated Time of dusk", SETTINGS.rvoTbName, "dusk_has_occured", { value: sunCalcResult["dusk"] }, "", SEND_TO.tb, instance); reportDuskDawn.dusk_time_reported = sunCalcResult.dusk_time; } } @@ -1420,7 +1422,7 @@ exports.install = function(instance) { if ((currentTimestamp - reportDuskDawn.dawn_time) < 60 * 1000) { //reportovali sme? if (reportDuskDawn.dawn_time_reported != sunCalcResult.dawn_time) { - sendNotification("CMD Manager: calculated Time of dawn", SETTINGS.rvoTbName, "dawn_has_occured", { value: sunCalcResult["dawn"] }, "", SEND_TO.tb, instance); + //sendNotification("CMD Manager: calculated Time of dawn", SETTINGS.rvoTbName, "dawn_has_occured", { value: sunCalcResult["dawn"] }, "", SEND_TO.tb, instance); reportDuskDawn.dawn_time_reported = sunCalcResult.dawn_time; } } @@ -1471,12 +1473,12 @@ exports.install = function(instance) { let type = params.type; let tbname = params.tbname; - let nodeAddress = params.address; + let node = params.address; let line = null; //rpc related - if (nodesData[nodeAddress] !== undefined) line = nodesData[nodeAddress].line; + if (nodesData[node] !== undefined) line = nodesData[node].line; if (params.line !== undefined) line = params.line; let repeatTask = false; @@ -1510,6 +1512,8 @@ exports.install = function(instance) { const value = params.value; let date = new Date(); + let hour = date.getHours(); + date.setDate(date.getDate() + 1);//next day let sunCalcResult; @@ -1532,12 +1536,11 @@ exports.install = function(instance) { } let info = "aplikovany bod profilu"; - let message = ""; - value == 1 ? message = "on" : message = "off"; + let onOrOff = ""; + value == 1 ? onOrOff = "on" : onOrOff = "off"; - turnLine(message, params.line, info); - - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "switching_profile_point_applied_to_line", { line: params.line, value: message }, "", SEND_TO.tb, instance); + turnLine(onOrOff, params.line, info); + interval = setInterval(runTasks, SHORT_INTERVAL); return; } @@ -1590,25 +1593,26 @@ exports.install = function(instance) { } } - let relayStatus = 1; - if (relaysData[line] != undefined) { - relayStatus = relaysData[line].contactor; - } + //TODO -> status offline for rvo if rotary_switch_state is OFF + //let relayStatus = 1; + //if (relaysData[line] != undefined) { + // relayStatus = relaysData[line].contactor; + //} - if (line == 0) relayStatus = 0; - if (type == "cmd-terminal") relayStatus = 1; + //if (line == 0) relayStatus = 0; + //if (type == "cmd-terminal") relayStatus = 1; //check if rotary_switch_state == "Off" - if (relayStatus == 0) { + //if (relayStatus == 0) { //console.log("------------------------------------relayStatus", relayStatus, line); - let values = { "status": "OFFLINE" }; + //let values = { "status": "OFFLINE" }; - sendTelemetry(values, tbname) + //if(tbname) sendTelemetry(values, tbname) - interval = setInterval(runTasks, SHORT_INTERVAL); - return; - } + //interval = setInterval(runTasks, SHORT_INTERVAL); + //return; + //} if (!rsPort.isOpen) { interval = setInterval(runTasks, LONG_INTERVAL); @@ -1667,7 +1671,7 @@ exports.install = function(instance) { } //----------------------- - instance.send(SEND_TO.debug, "address: " + nodeAddress + " register:" + register + "type: " + type); + instance.send(SEND_TO.debug, "address: " + node + " register:" + register + "type: " + type); var startTime, endTime; startTime = new Date(); @@ -1676,7 +1680,7 @@ exports.install = function(instance) { if (!tbname) saveToTb = false; let itIsNodeCommand = listOfCommands.includes(register); //reading data from node (voltage, current, dimming, status) - let resp = com_generic(nodeAddress, params.recipient, params.rw, register, params.name, params.byte1, params.byte2, params.byte3, params.byte4); + let resp = com_generic(node, params.recipient, params.rw, register, params.name, params.byte1, params.byte2, params.byte3, params.byte4); let readBytes = 11; let timeout = 4000; @@ -1717,19 +1721,20 @@ exports.install = function(instance) { //CMD FINISHED if (message == "OK") { - updateNodeStatus(nodeAddress, true); + updateNodeStatus(node, true); //write if (type == "set_node_profile") { - let result = cmdCounterResolve(nodeAddress); + let result = cmdCounterResolve(node); if (result == 0) { - dbNodes.modify({ processed: true }).where("node", nodeAddress).make(function(builder) { + dbNodes.modify({ processed: true }).where("node", node).make(function(builder) { builder.callback(function(err, response) { - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "dimming_profile_was_successfully_received_by_node", { node: nodeAddress }, "", SEND_TO.tb, instance); + sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "dimming_profile_was_successfully_received_by_node", { node: node }, "", SEND_TO.tb, instance); - logger.debug("--> profil úspešne odoslaný na node č. " + nodeAddress); - nodesData[nodeAddress].processed = true; + logger.debug("--> profil úspešne odoslaný na node č. " + node); + nodesData[node].processed = true; + nodeProfileSendFail.delete(node); }); }); } @@ -1746,7 +1751,7 @@ exports.install = function(instance) { } //master node - if (nodeAddress == 0) { + if (node == 0) { sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "master_node_is_responding_again", {}, "", SEND_TO.tb, instance, "rvo_status"); SETTINGS.masterNodeIsResponding = true; if (register == 4) values["edge_fw_version"] = SETTINGS.edge_fw_version; @@ -1779,7 +1784,7 @@ exports.install = function(instance) { if (params.hasOwnProperty("debug")) { if (params.debug) { //logger.debug("writeData err: ", error, result, params); - logger.debug("writeData err: ", tbname, nodeAddress, register, values); + logger.debug("writeData err: ", tbname, node, register, values); } } @@ -1803,11 +1808,9 @@ exports.install = function(instance) { } else { - // if(currentTask.debug) - // { - // //currentTask.timestamp <= currentTimestamp - // logger.debug("currentTask is not processed - task is in the future", currentTask); - // } + if(currentTask.debug) { + // currentTask.timestamp <= currentTimestamp && logger.debug("currentTask is not processed - task is in the future", currentTask); + } interval = setInterval(runTasks, LONG_INTERVAL); return; @@ -1843,7 +1846,11 @@ exports.install = function(instance) { if (type == "set_node_profile") { delete cmdCounter[node]; logger.debug("profil nebol úspešne odoslaný na node č. ", params); - sendNotification("CMD Manager: process cmd", tbName, "configuration_of_dimming_profile_to_node_failed", { node: node }, "", SEND_TO.tb, instance); + + if(!nodeProfileSendFail.has(node)) { + sendNotification("CMD Manager: process cmd", tbName, "configuration_of_dimming_profile_to_node_failed", { node: node }, "", SEND_TO.tb, instance); + nodeProfileSendFail.add(node); + } } if (itIsNodeCommand) { @@ -2870,7 +2877,7 @@ exports.install = function(instance) { //if(byte1 < 10) s = "0" + byte1; var d = new Date(); - d.setHours(h, m, 0); + d.setHours(h, m, 0, 0); timestamp = d.getTime(); } diff --git a/flow/designer.json b/flow/designer.json index 2223c18..e960086 100644 --- a/flow/designer.json +++ b/flow/designer.json @@ -453,8 +453,8 @@ "color": "gray" }, "options": { - "datatype": "object", - "data": "{line: 3, command: \"turnOff\", force: true}" + "data": "{line: 3, command: \"turnOff\", force: true}", + "datatype": "object" }, "color": "#F6BB42", "notes": "" @@ -505,8 +505,8 @@ "color": "gray" }, "options": { - "data": "profile_nodes", - "datatype": "string" + "datatype": "string", + "data": "profile_nodes" }, "color": "#F6BB42", "notes": "" @@ -742,8 +742,8 @@ "color": "gray" }, "options": { - "data": "{line: 1, command: \"turnOn\", force: true}", - "datatype": "object" + "datatype": "object", + "data": "{line: 1, command: \"turnOn\", force: true}" }, "color": "#F6BB42", "notes": "" @@ -872,8 +872,8 @@ "color": "gray" }, "options": { - "datatype": "object", - "data": "{command: \"turnOnAlarm\"}" + "data": "{command: \"turnOnAlarm\"}", + "datatype": "object" }, "color": "#F6BB42", "notes": "" @@ -902,8 +902,8 @@ "color": "gray" }, "options": { - "datatype": "object", - "data": "{command: \"turnOffAlarm\"}" + "data": "{command: \"turnOffAlarm\"}", + "datatype": "object" }, "color": "#F6BB42", "notes": "" @@ -1039,7 +1039,7 @@ "output": [] }, "state": { - "text": "848.02 MB / 985.68 MB", + "text": "870.85 MB / 985.68 MB", "color": "gray" }, "options": { @@ -1069,7 +1069,7 @@ "output": [] }, "state": { - "text": "5.77 GB / 7.26 GB", + "text": "5.78 GB / 7.26 GB", "color": "gray" }, "options": { @@ -1182,9 +1182,9 @@ "color": "gray" }, "options": { - "url": "http://192.168.252.2:8004/sentmessage", + "stringify": "json", "method": "POST", - "stringify": "json" + "url": "http://192.168.252.2:8004/sentmessage" }, "color": "#5D9CEC", "notes": "" @@ -1525,7 +1525,7 @@ "output": [] }, "state": { - "text": "0.5% / 88.03 MB", + "text": "12.8% / 71.62 MB", "color": "gray" }, "options": { @@ -2044,7 +2044,7 @@ "tag_on_include": "[{\"user_id\":\"U072JE5JUQG\", \"includes\":[\"Electrometer\", \"Twilight sensor\"]}]", "message_includes": "[\"is responding again\", \"Lamps have turned\", \"Flow has been restarted\", \"Node db has changed\"]", "types": "[\"emergency\", \"critical\", \"error\", \"alert\"]", - "name": "rvo_senica_1_10.0.0.141" + "name": "rvo_senica_35_10.0.0.129" }, "color": "#30E193", "notes": "" @@ -2073,9 +2073,9 @@ "color": "gray" }, "options": { - "url": "http://192.168.252.2:8004/slack", + "stringify": "json", "method": "POST", - "stringify": "json" + "url": "http://192.168.252.2:8004/slack" }, "color": "#5D9CEC", "notes": "" @@ -2130,8 +2130,8 @@ "color": "gray" }, "options": { - "data": "{ \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\": [ { \"ts\": 1716289039281, \"values\": { \"_event\": { \"type\": \"alert\", \"status\": \"new\", \"source\": { \"func\": \"CMD Manager: process cmd\", \"component\": \"1619515097737\", \"component_name\": \"CMD Manager\", \"edge\": \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\" }, \"message\": \"NOW CONNECTED TO SLACK !\", \"message_data\": \"\" } } } ] }", - "datatype": "object" + "datatype": "object", + "data": "{ \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\": [ { \"ts\": 1716289039281, \"values\": { \"_event\": { \"type\": \"alert\", \"status\": \"new\", \"source\": { \"func\": \"CMD Manager: process cmd\", \"component\": \"1619515097737\", \"component_name\": \"CMD Manager\", \"edge\": \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\" }, \"message\": \"NOW CONNECTED TO SLACK !\", \"message_data\": \"\" } } } ] }" }, "color": "#F6BB42", "notes": "" @@ -2239,11 +2239,11 @@ "color": "green" }, "options": { - "host": "192.168.252.2", - "port": "2764", - "clientid": "", "username": "", - "topic": "" + "clientid": "", + "port": "2764", + "host": "192.168.252.2", + "topic": "u129" }, "color": "#888600", "notes": "" @@ -2869,4 +2869,4 @@ } ], "version": 615 -} +} \ No newline at end of file diff --git a/flow/dido_controller.js b/flow/dido_controller.js index 86fb6a5..e9379ea 100644 --- a/flow/dido_controller.js +++ b/flow/dido_controller.js @@ -565,6 +565,10 @@ exports.install = function(instance) { ws.send(JSON.stringify(cmd)); switchLogic(pin, value) } + + //if rvo is 24/7, it has just one switching profile point at 13:00. we do not want to send notification as it repeats every day. + const d = new Date(); + if(d.getHours() != 13) sendNotification("Dido_controller: ", SETTINGS.rvoTbName, "switching_profile_point_applied_to_line", { line: line, value: onOrOff }, "", SEND_TO.tb, instance); } diff --git a/flow/helper/DataToTbHandler.js b/flow/helper/DataToTbHandler.js index a89b75b..65e4ec3 100644 --- a/flow/helper/DataToTbHandler.js +++ b/flow/helper/DataToTbHandler.js @@ -11,6 +11,34 @@ class DataToTbHandler { this.messageCounter = 0; this.sender = ""; + + // if attribute difference is less than limit value, we do not send to tb. + this.attributeChangeLimit = { + temperature: 0.5, + Phase_1_voltage: 2, + Phase_2_voltage: 2, + Phase_3_voltage: 2, + Phase_1_current: 0.1, + Phase_2_current: 0.1, + Phase_3_current: 0.1, + Phase_1_power: 2, + Phase_2_power: 2, + Phase_3_power: 2, + total_power: 2, + Phase_1_pow_factor: 0.1, + Phase_2_pow_factor: 0.1, + Phase_3_pow_factor: 0.1, + power_factor: 0.1, + lifetime: 0.5, + voltage: 2, + power: 2, + frequency: 3, + energy: 0.1, + current: 2, + inclination_x: 10, + inclination_y: 10, + inclination_z: 10 + }; } dump() { @@ -101,16 +129,20 @@ class DataToTbHandler { continue; } - if(this.previousValues[tbname][key].value === value) + // attributeData ==> voltage: {ts:333333, value:5} + let attributeData = this.previousValues[tbname][key]; + let attributeToChange = false; + if(key in this.attributeChangeLimit) attributeToChange = true; + let limit = this.attributeChangeLimit[key]; + + if(attributeData.value === value || attributeToChange && Math.abs(attributeData.value - value) < limit) { - let diff = timestamp - this.previousValues[tbname][key].ts; - + let diff = timestamp - attributeData.ts; let timestampDiffToRemoveKey = this.getDiffTimestamp(key); if(diff > timestampDiffToRemoveKey) { - this.previousValues[tbname][key].ts = Date.now(); + attributeData.ts = Date.now(); //if(this.debug) console.log(this.sender + ": update ts for key", key, "diff is", diff, "messageCounter", this.messageCounter); - } else { @@ -120,8 +152,8 @@ class DataToTbHandler { } else { - this.previousValues[tbname][key].value = value; - this.previousValues[tbname][key].ts = timestamp; + attributeData.value = value; + attributeData.ts = timestamp; } } @@ -131,3 +163,4 @@ class DataToTbHandler { } module.exports = DataToTbHandler; + diff --git a/flow/modbus_reader.js b/flow/modbus_reader.js index b0908ae..b907148 100644 --- a/flow/modbus_reader.js +++ b/flow/modbus_reader.js @@ -317,20 +317,24 @@ exports.install = function(instance) { } /** - * function sends notification to slack and to tb, if EM total_power value changes more than 500. This should show, that RVO lamps has been switched on or off + * function sends notification to slack and to tb, if EM total_power value changes more than numberOfNodes*15. This should show, that RVO lamps has been switched on or off */ lampSwitchNotification = (values) => { if(!values.hasOwnProperty("total_power")) return; const actualTotalPower = values.total_power; - if(actualTotalPower > 600 && this.onNotificationSent == false) + + const numberOfNodes = Object.keys(FLOW.GLOBALS.nodesData).length; + if(numberOfNodes == 0) numberOfNodes = 20; // to make sure, we send notification if totalPower is more than 300 + + if(actualTotalPower > numberOfNodes * 15 && this.onNotificationSent == false) { sendNotification("modbus_reader: lampSwitchNotification", tbName, "lamps_have_turned_on", {}, "", SEND_TO.tb, instance); this.onNotificationSent = true; this.offNotificationSent = false; } - else if(actualTotalPower <= 600 && this.offNotificationSent == false) + else if(actualTotalPower <= numberOfNodes * 15 && this.offNotificationSent == false) { sendNotification("modbus_reader: lampSwitchNotification", tbName, "lamps_have_turned_off", {}, "", SEND_TO.tb, instance); this.onNotificationSent = false;