From 8929cc3a534f793eabf184b3ab67b1b438b09542 Mon Sep 17 00:00:00 2001 From: rasta5man Date: Mon, 9 Sep 2024 12:32:34 +0200 Subject: [PATCH] actual working Senica Rvo code 09/2024 --- databases/modbus_config.js | 3 +- databases/notifications.table | 5 +- flow/cmd_manager.js | 120 ++---- flow/designer.json | 678 +++++++++++++++++++++++----------- flow/dido_controller.js | 174 ++++----- flow/modbus_reader.js | 72 ++-- flow/slack_filter.js | 187 ++++++++++ 7 files changed, 810 insertions(+), 429 deletions(-) create mode 100644 flow/slack_filter.js diff --git a/databases/modbus_config.js b/databases/modbus_config.js index 574de9f..b73116a 100644 --- a/databases/modbus_config.js +++ b/databases/modbus_config.js @@ -1,4 +1,5 @@ const timeoutInterval = 150000; + const deviceConfig = [ { device: "em340", @@ -110,4 +111,4 @@ const deviceConfig = [ } ]; -module.exports = { timeoutInterval, deviceConfig }; +module.exports = { timeoutInterval, deviceConfig }; \ No newline at end of file diff --git a/databases/notifications.table b/databases/notifications.table index b207fe7..a0590d3 100644 --- a/databases/notifications.table +++ b/databases/notifications.table @@ -31,4 +31,7 @@ key:string|weight:string|sk:string|en:string +|voltage_on_phase_restored|NOTICE|Napätie na fáze č. ${phase} bolo obnovené|Voltage on phase no. ${phase} has been restored|............... +|flow_start|NOTICE|FLOW bol spustený|FLOW has been started |............... +|twilight_sensor_nok|ERROR|Sensor súmraku neodpovedá|Twilight sensor is not responding|............... -+|twilight_sensor_ok|NOTICE|Sensor súmraku znovu odpovedá|Twilight sensor is responding again|............... \ No newline at end of file ++|twilight_sensor_ok|NOTICE|Sensor súmraku znovu odpovedá|Twilight sensor is responding again|............... ++|lamps_have_turned_on|NOTICE|Lampy sa zapli|Lamps have turned on|............... ++|lamps_have_turned_off|NOTICE|Lampy sa vypli|Lamps have turned off|............... ++|flow_restart|NOTICE|Restart flowu|Flow has been restarted|............... diff --git a/flow/cmd_manager.js b/flow/cmd_manager.js index 3a03acc..48b4987 100644 --- a/flow/cmd_manager.js +++ b/flow/cmd_manager.js @@ -280,30 +280,20 @@ function processNodeProfile(node) try{ nodeProfile = JSON.parse( profile ); if(Object.keys(nodeProfile).length === 0) throw ("profile is not defined"); - } catch (error) {} - - //test reset profilu - //nodeProfile = undefined; + } catch (error) { + logger.debug("Error parsing node profile", error); + } logger.debug("processNodeProfile", node, line, nodeObj, nodeProfile); - //return; - - //let timestamp = PRIORITY_TYPES.node_cmd; - - //let now = new Date(); - //now.setSeconds(now.getSeconds() + 10); - //let timestamp = now.getTime(); let timestamp = PRIORITY_TYPES.node_cmd; - //nodeProfile = undefined; removeTask({type: "set_node_profile", address: node}); cmdNOKNodeCounter[node] = 0; //co ked sa prave spracovava? //if(cmdNOKNodeCounter[params.address] < 5) saveToTb = false; - if(nodeProfile === undefined) { //vypneme profil nodu, posleme cmd @@ -318,7 +308,7 @@ function processNodeProfile(node) params.byte1 = 0; params.byte2 = 0; params.byte3 = 0; - params.byte4 = 32; + params.byte4 = 96; params.recipient = 1; params.register = 8; params.rw = 1;//write @@ -347,7 +337,7 @@ function processNodeProfile(node) params.byte1 = 0; params.byte2 = 0; params.byte3 = 0; - params.byte4 = 32; + params.byte4 = 96; params.recipient = 1; params.register = 8; params.rw = 1;//write @@ -615,7 +605,7 @@ function processNodeProfile(node) else bits.push(0); //Bit 1 - riadenie úsvitu podľa lux senzoru (1 – zapnuté). Úsvit sa môže posúvať v rámci času v registri 97 podľa intenzity osvetlenia - if(profile.dawn_lux_sensor == true)//usvit + if(nodeProfile.dawn_lux_sensor == true)//usvit { bits.push(1); } @@ -765,7 +755,7 @@ exports.install = function(instance) { if(key == "0") continue; if(line != undefined) { - //ak sa jedna o update profilu linie - pozor di_co_controller posiela command pre loadRelaysData + //ak sa jedna o update profilu linie - pozor dido_controller posiela command pre loadRelaysData if(line != value.line ) continue; } @@ -1254,28 +1244,20 @@ exports.install = function(instance) { { //run broadcast Time of dusk - // addMinutesToTimestamp = 60*5; addMinutesToTimestamp = 60 * 3; //kazde 3 hodiny zisti novy dusk let params = getParams(PRIORITY_TYPES.node_broadcast); - let recipient = 2;//2 broadcast, address = 0 - let address = 0;//0 - if(recipient === 2) - { - address = 0xffffffff;//Broadcast - } - let sunCalcResult = calculateDuskDawn(); let dusk_hours = sunCalcResult["dusk_hours"]; let dusk_minutes = sunCalcResult["dusk_minutes"]; - params.address = address;//broadcast + params.address = 0xffffffff;//broadcast params.byte1 = dusk_hours;//h params.byte2 = dusk_minutes;//m params.byte3 = 0;//s params.byte4 = 0; - params.recipient = recipient; + params.recipient = 2;//2 broadcast, params.register = 6;//Time of dusk - Reg 6 params.rw = 1;//write @@ -1300,23 +1282,16 @@ exports.install = function(instance) { let params = getParams(PRIORITY_TYPES.node_broadcast); - let recipient = 2;//2 broadcast, address = 0 - let address = 0;//0 - if(recipient === 2) - { - address = 0xffffffff;//Broadcast - } - let sunCalcResult = calculateDuskDawn(); let dawn_hours = sunCalcResult["dawn_hours"]; let dawn_minutes = sunCalcResult["dawn_minutes"]; - params.address = address;//broadcast + params.address = 0xffffffff;//broadcast params.byte1 = dawn_hours;//h params.byte2 = dawn_minutes;//m params.byte3 = 0;//s params.byte4 = 0; - params.recipient = recipient; + params.recipient = 2; //2 broadcast params.register = 7;//Time of dawn - Reg 6 params.rw = 1;//write @@ -1332,31 +1307,23 @@ exports.install = function(instance) { tasks.push(params); } - { //run broadcast //Actual time addMinutesToTimestamp = 5; let params = getParams(PRIORITY_TYPES.node_broadcast); - let recipient = 2;//2 broadcast, address = 0 - let address = 0;//0 - if(recipient === 2) - { - address = 0xffffffff;//Broadcast - } - var d = new Date(); let hours = d.getHours(); let minutes = d.getMinutes(); let seconds = d.getSeconds(); - params.address = address;//broadcast + params.address = 0xffffffff;//broadcast params.byte1 = hours;//h params.byte2 = minutes;//m params.byte3 = seconds;//s params.byte4 = 0; - params.recipient = recipient; + params.recipient = 2; //2 broadcast params.register = 87;//Actual time params.rw = 1;//write @@ -1370,37 +1337,8 @@ exports.install = function(instance) { params.info = "run broadcast: Actual time"; tasks.push(params); - } - { - //run broadcast Actual Lux level from cabinet - - //Do tohto registra posiela riadiaca jednotka hodnotu intenzity osvetlenia ktorú meria jej senzor pre potreby riadenia časov súmraku resp. úsvitu podľa intenzity osvetlenia. - //Byty 0 (LSB) a 1 obsahujú 16 bitový integer s luxami. - - let params = getParams(PRIORITY_TYPES.node_broadcast); - - addMinutesToTimestamp = 15; - - let recipient = 2;//2 broadcast, address = 0 - let address = 0;//0 - if(recipient === 2) - { - address = 0xffffffff;//Broadcast - } - - //TODO - //16 bitový integer s luxami - params.byte3 = lux_sensor; - params.byte4 = lux_sensor; - params.timestamp = PRIORITY_TYPES.node_broadcast; - params.addMinutesToTimestamp = addMinutesToTimestamp; - params.info = "run broadcast: Actual Lux level from cabinet"; - params.register = 95;//Actual Lux level from cabinet - params.rw = 1;//write - - } } //process nodes & tasks @@ -1909,7 +1847,7 @@ exports.install = function(instance) { tasks[0].timestamp = currentTimestamp + tasks[0].addMinutesToTimestamp * 60000; } - let info = "aplikovaný bod profilu"; + let info = "aplikovany bod profilu"; let message = ""; if(value == 1) { @@ -2099,8 +2037,9 @@ exports.install = function(instance) { let resp = com_generic(params.address, params.recipient, params.rw, params.register, params.name, params.byte1, params.byte2, params.byte3, params.byte4); let readBytes = 11; + let timeout = 5000; - await writeData(rsPort, resp, readBytes).then(function (data) { + await writeData(rsPort, resp, readBytes, timeout).then(function (data) { endTime = new Date(); var timeDiff = endTime - startTime; @@ -2690,8 +2629,31 @@ exports.install = function(instance) { { lux_sensor = parseInt(flowdata.data.value); - //process profiles - turnOnOffLinesAccordingToLuxSensor(lux_sensor); + // POSSIBLE SOURCE OF PROBLEMS, IF USER SETS LUX TRESHOLD LEVEL GREATER THAN 100 - WE SHOULD BE CHECKING "DUSK/DAWN_LUX_SENSOR_VALUE" IN PROFILE MAYBE ?? + if(lux_sensor < 100) + { + + // we send lux_sensor value to all nodes: + let params = getParams(PRIORITY_TYPES.node_broadcast); + + params.recipient = 2;//2 broadcast, address = 0 + params.address = 0xffffffff;//Broadcast + + let ba = longToByteArray(lux_sensor); + + params.byte3 = ba[1];//msb + params.byte4 = ba[0]; + params.timestamp = PRIORITY_TYPES.node_broadcast; + params.info = "run broadcast: Actual Lux level from cabinet"; + params.register = 95;//Actual Lux level from cabinet + params.rw = 1;//write + + tasks.push(params); + + + //process profiles + turnOnOffLinesAccordingToLuxSensor(lux_sensor); + } } else if(cmd == "state_of_breaker") { diff --git a/flow/designer.json b/flow/designer.json index 7cb3ebb..7d57d69 100644 --- a/flow/designer.json +++ b/flow/designer.json @@ -25,8 +25,8 @@ "component": "debug", "tab": "1611921777196", "name": "ERROR", - "x": 404, - "y": 36, + "x": 401, + "y": 31, "connections": {}, "disabledio": { "input": [], @@ -36,13 +36,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1612776786008", @@ -87,14 +87,14 @@ "text": "Connected", "color": "green" }, - "color": "#888600", - "notes": "", "options": { "username": "", "clientid": "", "port": "1883", "host": "" - } + }, + "color": "#888600", + "notes": "" }, { "id": "1612778461252", @@ -123,11 +123,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1612783322136", @@ -147,13 +147,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615551060773", @@ -173,13 +173,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1615563373927", @@ -199,13 +199,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1615566865233", @@ -223,11 +223,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1615798582262", @@ -247,21 +247,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615802995322", "component": "debug", "tab": "1611921777196", "name": "Debug", - "x": 400.8833312988281, - "y": 484.3500061035156, + "x": 398.8833312988281, + "y": 528.3500061035156, "connections": {}, "disabledio": { "input": [ @@ -270,24 +270,24 @@ "output": [] }, "state": { - "text": "Enabled", + "text": "Disabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, - "enabled": true - } + "enabled": false + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615809128443", "component": "debug", "tab": "1611921777196", "name": "Debug", - "x": 405.8833312988281, - "y": 566.3500061035156, + "x": 401.8833312988281, + "y": 625.3500061035156, "connections": {}, "disabledio": { "input": [ @@ -299,21 +299,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615809595184", "component": "virtualwireout", "tab": "1611921777196", "name": "tb-push", - "x": 401.8833312988281, - "y": 306.25, + "x": 400.8833312988281, + "y": 328.25, "connections": {}, "disabledio": { "input": [], @@ -323,11 +323,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1616165795916", @@ -356,9 +356,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __POST /terminal__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __false__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 10, "cachepolicy": 0, @@ -373,7 +370,10 @@ 10000 ], "emptyresponse": false - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __POST /terminal__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __false__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1616165824813", @@ -391,11 +391,11 @@ "text": "", "color": "gray" }, - "color": "#5D9CEC", - "notes": "", "options": { "datatype": "json" - } + }, + "color": "#5D9CEC", + "notes": "" }, { "id": "1617104731852", @@ -415,13 +415,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1617114651703", @@ -446,19 +446,19 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "data": "{line: 3, command: \"turnOff\", force: true}", "datatype": "object" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1617115013095", "component": "virtualwireout", "tab": "1615551125555", "name": "tb-push", - "x": 747, + "x": 741, "y": 736, "connections": {}, "disabledio": { @@ -469,11 +469,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1617178324650", @@ -491,13 +491,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1617179044099", @@ -522,12 +522,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "datatype": "object", "data": "{table: \"konsberg_production_line_operations_error\", startFrom: 1, delimiter: \";\", uniqueColumn: \"\", path: \"flow/operations_error.csv\", mapImport: {0: \"production_line\",\t1: \"operation\", 2: \"error_type\", 3: \"error_code\", 4: \"error_text\", 5: \"error_text_user_defined\"}}" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1617180390661", @@ -552,11 +552,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1617197763128", @@ -574,9 +574,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#704cff", - "notes": "", - "options": {} + "notes": "" }, { "id": "1617284749681", @@ -601,12 +601,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "datatype": "string", "data": "profile_nodes" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1618235171399", @@ -631,11 +631,11 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "data": "run" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1618300858252", @@ -653,13 +653,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1618300863816", @@ -679,13 +679,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1618393583970", @@ -703,11 +703,11 @@ "text": "from-dido-controller", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "from-dido-controller" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393674428", @@ -732,11 +732,11 @@ "text": "platform-rpc-call", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "platform-rpc-call" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393759854", @@ -765,11 +765,11 @@ "text": "cmd_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "cmd_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393827655", @@ -787,11 +787,11 @@ "text": "cmd_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "cmd_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618558465485", @@ -809,11 +809,11 @@ "text": "platform-rpc-call", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "platform-rpc-call" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618572059773", @@ -838,12 +838,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "datatype": "object", "data": "{line: 1, command: \"turnOn\", force: true}" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1619515097737", @@ -896,9 +896,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5D9CEC", - "notes": "", - "options": {} + "notes": "" }, { "id": "1619605019281", @@ -927,9 +927,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __GET /db__\n- flags: undefined\n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 5, "cachepolicy": 0, @@ -943,7 +940,10 @@ "get", 5000 ] - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __GET /db__\n- flags: undefined\n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1619784672383", @@ -968,12 +968,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "data": "{command: \"turnOnAlarm\"}", "datatype": "object" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1619784812964", @@ -998,20 +998,20 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "data": "{command: \"turnOffAlarm\"}", "datatype": "object" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1621340721628", "component": "virtualwireout", "tab": "1611921777196", "name": "modbus_to_dido", - "x": 403, - "y": 394, + "x": 399, + "y": 433, "connections": {}, "disabledio": { "input": [], @@ -1021,11 +1021,11 @@ "text": "modbus_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "modbus_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1622640022885", @@ -1050,9 +1050,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __POST /db_connector__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 5, "cachepolicy": 0, @@ -1065,7 +1062,10 @@ "post", 5000 ] - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __POST /db_connector__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1622640073521", @@ -1090,11 +1090,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1622641420685", @@ -1112,9 +1112,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5D9CEC", - "notes": "", - "options": {} + "notes": "" }, { "id": "1634303504177", @@ -1136,15 +1136,15 @@ "output": [] }, "state": { - "text": "801.23 MB / 987.80 MB", + "text": "834.19 MB / 985.68 MB", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "enabled": true, "interval": 30000 - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1634303533779", @@ -1166,16 +1166,16 @@ "output": [] }, "state": { - "text": "5.90 GB / 7.26 GB", + "text": "5.84 GB / 7.26 GB", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "enabled": true, "path": "/", "interval": 30000 - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1634303595494", @@ -1204,11 +1204,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303602169", @@ -1226,11 +1226,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303685503", @@ -1248,11 +1248,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303743260", @@ -1278,13 +1278,13 @@ "text": "", "color": "gray" }, - "color": "#5D9CEC", - "notes": "", "options": { "stringify": "json", "method": "POST", "url": "http://192.168.252.2:8004/sentmessage" - } + }, + "color": "#5D9CEC", + "notes": "" }, { "id": "1634463186563", @@ -1304,13 +1304,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634464580289", @@ -1339,13 +1339,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, "code": "let response = {};\nresponse.cpu = value.cpu;\nresponse.uptime = value.uptime;\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465243324", @@ -1365,13 +1365,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634465281992", @@ -1400,13 +1400,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, "code": "value.sender = \"ram\";\n//let total = value.total/1024/1024;\n//let free = value.free/1024/1024;\n//let used = value.used/1024/1024;\nlet response = {};\n//value.memory_total = (total).toFixed(0) + ' MB';\n//value.memory_free = (free).toFixed(0) + ' MB';\n//value.memory_used = (used).toFixed(0) + ' MB';\n\nresponse.memory_total = value.total;\nresponse.memory_free = value.free;\nresponse.memory_used = value.used;\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465338103", @@ -1426,13 +1426,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634465821120", @@ -1461,13 +1461,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, "code": "value.sender = \"hdd\";\n//let total = value.total/1024/1024;\n//let free = value.free/1024/1024;\n//let used = value.used/1024/1024;\nlet response = {};\n//value.hdd_total = (total).toFixed(0) + ' MB';\n//value.hdd_free = (free).toFixed(0) + ' MB';\n//value.used = (used).toFixed(0) + ' MB';\n\nresponse.hdd_total = value.total;\nresponse.hdd_free = value.free;\nresponse.hdd_used = value.used;\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465892500", @@ -1487,13 +1487,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634484067516", @@ -1513,13 +1513,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634488120710", @@ -1548,11 +1548,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1635327431236", @@ -1572,13 +1572,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1635936391935", @@ -1596,11 +1596,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1637069803394", @@ -1622,11 +1622,9 @@ "output": [] }, "state": { - "text": "11.7% / 69.98 MB", + "text": "1.9% / 86.94 MB", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "monitorfiles": true, "monitorconnections": true, @@ -1634,7 +1632,9 @@ "monitorconsumption": true, "enabled": true, "interval": 30000 - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1683664161036", @@ -1654,13 +1654,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1683981346282", @@ -1689,11 +1689,11 @@ "text": "from-dido-controller", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "from-dido-controller" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1684055037116", @@ -1713,13 +1713,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1684060205000", @@ -1739,13 +1739,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1684179110403", @@ -1753,7 +1753,7 @@ "tab": "1611921777196", "name": "MDBToDido", "x": 401, - "y": 125, + "y": 118, "connections": {}, "disabledio": { "input": [], @@ -1763,13 +1763,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1699963668903", @@ -1810,11 +1810,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1699964678894", @@ -1843,11 +1843,11 @@ "text": "modbus_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "modbus_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1699964793925", @@ -1867,13 +1867,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1699965957410", @@ -1897,6 +1897,10 @@ { "index": "0", "id": "1684179110403" + }, + { + "index": "0", + "id": "1717441414646" } ], "2": [ @@ -1918,17 +1922,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#2134B0", - "notes": "", - "options": {} + "notes": "" }, { "id": "1700411878636", "component": "thermometer", "tab": "1611921777196", "name": "Thermometer", - "x": 103.75, - "y": 408, + "x": 107.75, + "y": 449, "connections": { "0": [ { @@ -1961,9 +1965,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5CB36D", - "notes": "", - "options": {} + "notes": "" }, { "id": "1714752862828", @@ -1971,7 +1975,7 @@ "tab": "1611921777196", "name": "MDBToTb", "x": 402, - "y": 215, + "y": 228, "connections": {}, "disabledio": { "input": [], @@ -1981,14 +1985,248 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" + }, + { + "id": "1717441414646", + "component": "code", + "tab": "1611921777196", + "name": "device-status", + "x": 588.0833282470703, + "y": 177, + "connections": { + "0": [ + { + "index": "0", + "id": "1717442627834" + }, + { + "index": "0", + "id": "1717442631338" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "", + "color": "gray" + }, + "options": { + "keepmessage": true, + "code": "if(value.hasOwnProperty(\"status\"))\n{\n\tif(value.status.includes(\"-em\"))\n\t{\n\t\tsend(0, {\"em_status\": \"NOK\"});\n\t}\n\telse if(value.status.includes(\"twilight\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"NOK\"});\n\t}\n}\n\nif(value.hasOwnProperty(\"values\"))\n{\n\tif(value.values.hasOwnProperty(\"twilight_sensor\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"OK\"});\n\t}\n\telse if(value.values.hasOwnProperty(\"Phase_1_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_voltage\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Total_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_current\"))\n\t{\n\t\tsend(0, {\"em_status\": \"OK\"});\n\t}\n}", + "outputs": 1 + }, + "color": "#656D78", + "notes": "" + }, + { + "id": "1717442627834", + "component": "debug", + "tab": "1611921777196", + "name": "modbus service", + "x": 802.0833282470703, + "y": 139, + "connections": {}, + "disabledio": { + "input": [ + 0 + ], + "output": [] + }, + "state": { + "text": "Enabled", + "color": "gray" + }, + "options": { + "type": "data", + "repository": false, + "enabled": true + }, + "color": "#967ADC", + "notes": "" + }, + { + "id": "1717442631338", + "component": "virtualwireout", + "tab": "1611921777196", + "name": "send-to-services", + "x": 801.0833282470703, + "y": 236, + "connections": {}, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "send-to-services", + "color": "gray" + }, + "options": { + "wirename": "send-to-services" + }, + "color": "#303E4D", + "notes": "" + }, + { + "id": "1718016045116", + "component": "virtualwirein", + "tab": "1612772287426", + "name": "tb-push", + "x": 84.75, + "y": 1300, + "connections": { + "0": [ + { + "index": "0", + "id": "1718016052341" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "tb-push", + "color": "gray" + }, + "options": { + "wirename": "tb-push" + }, + "color": "#303E4D", + "notes": "" + }, + { + "id": "1718016052341", + "component": "slack_filter", + "tab": "1612772287426", + "name": "Slack Filter", + "x": 278, + "y": 1297, + "connections": { + "0": [ + { + "index": "0", + "id": "1718016086212" + }, + { + "index": "0", + "id": "1718016073501" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "Running", + "color": "gray" + }, + "options": { + "slack_channel": "C071KN2Q8SK", + "tag_on_include": "[{\"user_id\":\"U072JE5JUQG\", \"includes\":[\"Electrometer\", \"Twilight sensor\"]}]", + "message_includes": "[\"is responding again\", \"Lamps have turned\", \"Flow has been restarted\"]", + "types": "[\"emergency\", \"critical\", \"error\", \"alert\"]", + "name": "RVO16 Senica - 10.0.0.131" + }, + "color": "#30E193", + "notes": "" + }, + { + "id": "1718016073501", + "component": "httprequest", + "tab": "1612772287426", + "name": "http://192.168.252.2:8004/slack", + "x": 471, + "y": 1354, + "connections": { + "0": [ + { + "index": "0", + "id": "1718016086212" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "", + "color": "gray" + }, + "options": { + "stringify": "json", + "method": "POST", + "url": "http://192.168.252.2:8004/slack" + }, + "color": "#5D9CEC", + "notes": "" + }, + { + "id": "1718016086212", + "component": "debug", + "tab": "1612772287426", + "name": "Debug", + "x": 808, + "y": 1302, + "connections": {}, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "Enabled", + "color": "gray" + }, + "options": { + "type": "data", + "repository": false, + "enabled": true + }, + "color": "#967ADC", + "notes": "" + }, + { + "id": "1718016094070", + "component": "trigger", + "tab": "1612772287426", + "name": "Trigger", + "x": 73, + "y": 1388, + "connections": { + "0": [ + { + "index": "0", + "id": "1718016052341" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "", + "color": "gray" + }, + "options": { + "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": "" } ], - "version": 618 + "version": 615 } \ No newline at end of file diff --git a/flow/dido_controller.js b/flow/dido_controller.js index 0952350..b429b14 100644 --- a/flow/dido_controller.js +++ b/flow/dido_controller.js @@ -11,11 +11,11 @@ exports.icon = 'bolt'; exports.options = { edge: "undefined" }; exports.html = `
-
-
-
Edge TB Name
-
-
+
+
+
Edge TB Name
+
+
`; exports.readme = `# Sets RS232 port and all digital pins on device. Then it starts to receive data from sensors. @@ -60,7 +60,7 @@ state_of_contactor - podľa indexu stykača sa reportuje jeho stav, teda //globals //FIRMWARE version -FLOW.OMS_edge_fw_version = "2024-05-10";//rok-mesiac-den +FLOW.OMS_edge_fw_version = "2024-07-08";//rok-mesiac-den FLOW.OMS_edgeName = ""; FLOW.OMS_maintenance_mode = false; @@ -78,7 +78,7 @@ FLOW.OMS_temperature_adress = "";//cmd_manager let alarmStatus = "OFF"; -const instanceSendTo = { +const SEND_TO = { debug: 0, tb: 1, cmd_manager: 2 @@ -152,7 +152,7 @@ exports.install = function(instance) { /* let conversionTable = { "1": {tbname: "", type: "state_of_main_switch", "line": 0}, //state_of_main_switch pin1 - "2": {tbname: "", type: "rotary_switch_state", "line": 0}, //rotary_switch_state - poloha manual = pin2 + "2": {tbname: "", type: "rotary_switch_state", "line": 0}, //rotary_switch_state - poloha manual = pin2 "3": {tbname: "", type: "rotary_switch_state", "line": 0}, //rotary_switch_state - poloha auto = pin3 "4": {tbname: "", type: "power_supply", "line": 0}, "5": {tbname: "", type: "battery", "line": 0}, @@ -192,7 +192,7 @@ exports.install = function(instance) { /* dbRelays.on('change', function(doc, old) { console.log("'DI_DO_Controller - dbRelays.on('change'"); - instance.send(instanceSendTo.cmd_manager, "reload_relays"); + instance.send(SEND_TO.cmd_manager, "reload_relays"); }); */ @@ -264,14 +264,13 @@ exports.install = function(instance) { { errLogger.error("CRITICAL!!! undefined relay", relaysData[line], line); - //sendNotification("set port ", edgeName, ERRWEIGHT.CRITICAL, "local database is corrupted", "", instanceSendTo.tb, instance, null ); - sendNotification("set port ", edgeName, "local_database_is_corrupted", {}, "", instanceSendTo.tb, instance ); + //sendNotification("set port ", edgeName, ERRWEIGHT.CRITICAL, "local database is corrupted", "", SEND_TO.tb, instance, null ); + sendNotification("set port ", edgeName, "local_database_is_corrupted", {}, "", SEND_TO.tb, instance ); } } if(pinsData[key].type == "state_of_contactor") { - let pin = key - 1; if(controller_type === "unipi") pin = key; @@ -298,37 +297,19 @@ exports.install = function(instance) { } ] } - - instance.send(instanceSendTo.tb, dataToTb); + + instance.send(SEND_TO.tb, dataToTb); let time = 3*1000; setTimeout(function(){ - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "buildTasks"}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "buildTasks"}); - sendNotification("rsPort.open()", edgeName, "flow_start", {}, "", instanceSendTo.tb, instance ); + sendNotification("rsPort.open()", edgeName, "flow_start", {}, "", SEND_TO.tb, instance ); monitor.info("-->FLOW bol spustený", edgeName, FLOW.OMS_edge_fw_version); }, time); } - - // TODO: FIND BETTER SOLUTION, THAN REBUILDING TASKS - // we ensure, all tasks will be rebuild twice a week on tuesday or saturday at 11. To set correct switch off and on times - let sendRebuildTasksAt11 = null; - const checkIf11Oclock = () => - { - const d = new Date(); - const h = d.getHours(); - const day = d.getDay(); - - if((day === 2 || day === 6) && h === 11) - { - instance.send(instanceSendTo.cmd_manager, {sender:"dido_controller", cmd:"buildTasks"}); - monitor.info("Task rebuilt at 11 o'clock, tuesday, saturday"); - } - } - sendRebuildTasksAt11 = setInterval(checkIf11Oclock, 3600000); - function handleRsPort() { @@ -339,14 +320,14 @@ exports.install = function(instance) { rsPort.on('error', function(err) { logger.debug("rsPort opened error - failed", err.message); - instance.send(instanceSendTo.debug, err.message); + instance.send(SEND_TO.debug, err.message); errorHandler.sendMessageToService( exports.title + " rsPort opened error - failed: " + err.message); }) rsPort.on('open', async function() { - await runSyncExec("stty -F /dev/ttymxc0 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke").then(function (status) { + await runSyncExec("stty -F /dev/ttymxc0 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke").then(function (status) { //set port rsPort.write(Buffer.from(setRSPortData), function(err) { @@ -361,7 +342,7 @@ exports.install = function(instance) { }) }).catch(function (reason) { - //instance.send(instanceSendTo.debug, exports.title + " runSyncExec - promise rejected:" + reason); + //instance.send(SEND_TO.debug, exports.title + " runSyncExec - promise rejected:" + reason); errLogger.error( exports.title + " runSyncExec - promise rejected:" + reason); errorHandler.sendMessageToService( exports.title + " runSyncExec - promise rejected:" + reason); @@ -490,7 +471,7 @@ exports.install = function(instance) { deviceStatuses["temperature"] = "OK"; previousValues["temperature"] = value; - instance.send(instanceSendTo.tb, dataToTb); + instance.send(SEND_TO.tb, dataToTb); } return; } @@ -508,7 +489,7 @@ exports.install = function(instance) { ws.on('error', (err) => { monitor.info('websocket error, reconnect') - instance.send(instanceSendTo.debug, err.message); + instance.send(SEND_TO.debug, err.message); clearInterval(startRequests); ws = null; setTimeout(handleWebSocket, 1000); @@ -657,14 +638,14 @@ exports.install = function(instance) { //console.log(values); - instance.send(instanceSendTo.tb, dataToTb); + instance.send(SEND_TO.tb, dataToTb); } function turnOnLine(line, pin, force, info) { - instance.send(instanceSendTo.debug, "turn on line " + line ); + instance.send(SEND_TO.debug, "turn on line " + line ); if(force == undefined) force = false; if(line == 0) @@ -698,7 +679,7 @@ exports.install = function(instance) { { if(relaysData[line].contactor == 1) { - instance.send(instanceSendTo.debug, "line is already on " + line ); + instance.send(SEND_TO.debug, "line is already on " + line ); logger.debug("turnOnLine: line is already on: ", line); return; @@ -775,7 +756,7 @@ exports.install = function(instance) { { if(relaysData[line].contactor == 0) { - instance.send(instanceSendTo.debug, "line is already off " + line ); + instance.send(SEND_TO.debug, "line is already off " + line ); logger.debug("turnOffLine: line already off:", line); return; @@ -828,7 +809,7 @@ exports.install = function(instance) { if(!flowdata.data instanceof Object) return; // console.log('***********************', flowdata.data) - instance.send(instanceSendTo.debug, flowdata.data); + instance.send(SEND_TO.debug, flowdata.data); // we handle nok status from modbus_reader component and thermometer if(flowdata.data?.status) @@ -846,33 +827,34 @@ exports.install = function(instance) { { deviceStatuses["temperature"] = "NOK"; } - return; } + else if(flowdata.data?.values) + { + const values = flowdata.data.values; + if(values.hasOwnProperty("twilight_sensor")) + { + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: values["twilight_sensor"]}); + deviceStatuses["twilight_sensor"] = "OK" + } + else if(values.hasOwnProperty("temperature")) + { + deviceStatuses["temperature"] = "OK"; + } + // EM + else if(values.hasOwnProperty("total_power") || values.hasOwnProperty("total_energy") || values.hasOwnProperty("power_factor") || values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_1_current")) + { + deviceStatuses["em"] = "OK"; + } + else + { + return; + } - const values = flowdata.data.values; - if(values.hasOwnProperty("twilight_sensor")) - { - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: values["twilight_sensor"]}); - deviceStatuses["twilight_sensor"] = "OK" + const updateStatus = checkFinalRVOStatus(); + if(updateStatus) values.status = "OK"; + + sendTelemetry(values, FLOW.OMS_rvo_tbname); } - else if(values.hasOwnProperty("temperature")) - { - deviceStatuses["temperature"] = "OK"; - } - // EM - else if(values.hasOwnProperty("total_power") || values.hasOwnProperty("total_energy") || values.hasOwnProperty("power_factor") || values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_1_current")) - { - deviceStatuses["em"] = "OK"; - } - else - { - return; - } - - const updateStatus = checkFinalRVOStatus(); - if(updateStatus) values.status = "OK"; - - sendTelemetry(values, FLOW.OMS_rvo_tbname); }) @@ -902,7 +884,7 @@ exports.install = function(instance) { rsPort.write(Buffer.from(obj), function(err) { switchLogic(obj); - instance.send(instanceSendTo.debug, {"WRITE":obj} ); + instance.send(SEND_TO.debug, {"WRITE":obj} ); }); } }) @@ -1195,14 +1177,14 @@ exports.install = function(instance) { { if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { - sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_off", {}, "", instanceSendTo.tb, instance , "state_of_main_switch"); + sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_off", {}, "", SEND_TO.tb, instance , "state_of_main_switch"); values["status"] = "NOK"; deviceStatuses["state_of_main_switch"] = "Off"; } else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { - sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_on", {}, "", instanceSendTo.tb, instance , "state_of_main_switch"); + sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_on", {}, "", SEND_TO.tb, instance , "state_of_main_switch"); deviceStatuses["state_of_main_switch"] = "On"; } @@ -1247,7 +1229,7 @@ exports.install = function(instance) { //ak je spracovany, a automatic - tak ho zapnem //ak nie je spracovany, iba profil zapisem - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "rotary_switch_state", value: value}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "rotary_switch_state", value: value}); //console.log("rotary_switch_state pin", pin2, pin3, value); } @@ -1256,16 +1238,16 @@ exports.install = function(instance) { { if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.ALERT, "Power supply is not OK", "", instanceSendTo.tb, instance); - sendNotification("switchLogic", edgeName, "power_supply_has_disconnected_input", {}, "", instanceSendTo.tb, instance, "power_supply"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.ALERT, "Power supply is not OK", "", SEND_TO.tb, instance); + sendNotification("switchLogic", edgeName, "power_supply_has_disconnected_input", {}, "", SEND_TO.tb, instance, "power_supply"); values["status"] = "NOK"; deviceStatuses["power_supply"] = "NOK"; } else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Power supply is is OK", "", instanceSendTo.tb, instance); - sendNotification("switchLogic", edgeName, "power_supply_works_correctly", {}, "", instanceSendTo.tb, instance, "power_supply"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Power supply is is OK", "", SEND_TO.tb, instance); + sendNotification("switchLogic", edgeName, "power_supply_works_correctly", {}, "", SEND_TO.tb, instance, "power_supply"); deviceStatuses["power_supply"] = "OK"; } @@ -1275,16 +1257,16 @@ exports.install = function(instance) { { if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Battery is not OK", "", instanceSendTo.tb, instance); - sendNotification("switchLogic", edgeName, "battery_level_is_low", {}, "", instanceSendTo.tb, instance, "battery_level"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Battery is not OK", "", SEND_TO.tb, instance); + sendNotification("switchLogic", edgeName, "battery_level_is_low", {}, "", SEND_TO.tb, instance, "battery_level"); values["status"] = "NOK"; deviceStatuses["battery"] = "NOK"; } else if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Battery is OK", "", instanceSendTo.tb, instance); - sendNotification("switchLogic", edgeName, "battery_level_is_ok", {}, "", instanceSendTo.tb, instance, "battery_level"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Battery is OK", "", SEND_TO.tb, instance); + sendNotification("switchLogic", edgeName, "battery_level_is_ok", {}, "", SEND_TO.tb, instance, "battery_level"); deviceStatuses["battery"] = "OK"; } @@ -1298,19 +1280,19 @@ exports.install = function(instance) { if (newPinValue != previousValues[pinIndex]) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, `RVO door ${value}`, "", instanceSendTo.tb, instance, "rvo_door"); - //TODO ? sendNotification("switchLogic", edgeName, "door_value", {value: value}, "", instanceSendTo.tb, instance, "rvo_door"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, `RVO door ${value}`, "", SEND_TO.tb, instance, "rvo_door"); + //TODO ? sendNotification("switchLogic", edgeName, "door_value", {value: value}, "", SEND_TO.tb, instance, "rvo_door"); } if (value === "open" && FLOW.OMS_maintenance_mode) { - sendNotification("switchLogic", edgeName, "door_has_been_open", {}, "", instanceSendTo.tb, instance, "rvo_door"); + sendNotification("switchLogic", edgeName, "door_has_been_open", {}, "", SEND_TO.tb, instance, "rvo_door"); } if (value === "open" && !FLOW.OMS_maintenance_mode) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.WARNING, "RVO open door out of maintenance mode", "", instanceSendTo.tb, instance); - sendNotification("switchLogic", edgeName, "door_has_been_open_without_permision_alarm_is_on", {}, "", instanceSendTo.tb, instance, "rvo_door"); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.WARNING, "RVO open door out of maintenance mode", "", SEND_TO.tb, instance); + sendNotification("switchLogic", edgeName, "door_has_been_open_without_permision_alarm_is_on", {}, "", SEND_TO.tb, instance, "rvo_door"); values["status"] = "NOK"; //console.log(door_has_been_open_without_permision_alarm_is_on); @@ -1325,7 +1307,7 @@ exports.install = function(instance) { if(alarmStatus == "ON") turnOffAlarm(); //turnOffAlarm(); - sendNotification("switchLogic", edgeName, "door_has_been_closed", {}, "", instanceSendTo.tb, instance, "rvo_door"); + sendNotification("switchLogic", edgeName, "door_has_been_closed", {}, "", SEND_TO.tb, instance, "rvo_door"); } deviceStatuses["door_condition"] = value; @@ -1364,12 +1346,12 @@ exports.install = function(instance) { twilightError = true; values["status"] = "NOK"; let value = twilight_sensor_array.shift(); - //sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Lux sensor error", {"Repeating value": value}, instanceSendTo.tb, instance ); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Lux sensor error", {"Repeating value": value}, SEND_TO.tb, instance ); newPinValue = 0; } else if (set.size !== 1 && twilightError) { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Lux sensor is working again", "", instanceSendTo.tb, instance ); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Lux sensor is working again", "", SEND_TO.tb, instance ); twilightError = false; twilight_sensor_array.shift(); newPinValue = value; @@ -1387,7 +1369,7 @@ exports.install = function(instance) { if(diff >= twilight_sensor_interval * 60 * 1000) { const average = twilight_sensor.reduce((acc, c) => acc + c.value, 0) / twilight_sensor.length; - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: average}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: average}); twilight_sensor = []; @@ -1398,11 +1380,11 @@ exports.install = function(instance) { } else if(type == "state_of_contactor") { - //sendNotification("switchLogic", edgeName, ERRWEIGHT.INFO, `State of contactor ${line} is now ${value}`, "", instanceSendTo.tb, instance ); + //sendNotification("switchLogic", edgeName, ERRWEIGHT.INFO, `State of contactor ${line} is now ${value}`, "", SEND_TO.tb, instance ); if(!(deviceStatuses["state_of_contactor"][line] == value)) { - sendNotification("switchLogic", edgeName, "state_of_contactor_for_line", {line: line, value: value}, "", instanceSendTo.tb, instance ); + sendNotification("switchLogic", edgeName, "state_of_contactor_for_line", {line: line, value: value}, "", SEND_TO.tb, instance ); } else { @@ -1444,7 +1426,7 @@ exports.install = function(instance) { //a budu sa odosielat commandy, tie vsak mozu zlyhat, a preto potrebujeme ich spusti trochu neskor setTimeout(function(){ - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, time: time, value: value, dataChanged: dataChanged}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, time: time, value: value, dataChanged: dataChanged}); }, time); reportLineStatus(line); @@ -1469,7 +1451,7 @@ exports.install = function(instance) { if(valueChanged) { - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line}); //mame iba 3 istice. vyreportujeme a ohandlujeme liniu na tom istom istici ako paralelna linia (napr linia 1, paralelna s nou je linia 4, key je string "4") // ak je 7 linii, na 1 istici je linia 1,4,7 @@ -1483,7 +1465,7 @@ exports.install = function(instance) { { if(!relaysData.hasOwnProperty(lineOnSameBraker[i])) continue; - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: lineOnSameBraker[i]}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: lineOnSameBraker[i]}); deviceStatuses["state_of_breaker"][lineOnSameBraker[i]] = value; reportLineStatus(lineOnSameBraker[i]); @@ -1502,7 +1484,7 @@ exports.install = function(instance) { if(relaysData.hasOwnProperty(lineOnSameBraker)) { - instance.send(instanceSendTo.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line + 3}); + instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line + 3}); deviceStatuses["state_of_breaker"][line + 3] = value; reportLineStatus(line + 3); @@ -1598,7 +1580,7 @@ exports.install = function(instance) { ] } - instance.send(instanceSendTo.tb, dataToTb); + instance.send(SEND_TO.tb, dataToTb); } } diff --git a/flow/modbus_reader.js b/flow/modbus_reader.js index 898816e..f34ec9a 100644 --- a/flow/modbus_reader.js +++ b/flow/modbus_reader.js @@ -14,8 +14,8 @@ exports.readme = ` This device needs to be configured in dido_controller!!! Double check if it is. In dido_controller we calculate final status and all values with status are pushed to tb. `; -const modbus = require('jsmodbus') -const SerialPort = require('serialport') +const modbus = require('jsmodbus'); +const SerialPort = require('serialport'); const { timeoutInterval, deviceConfig } = require("../databases/modbus_config"); const { sendNotification } = require('./helper/notification_reporter'); @@ -30,6 +30,8 @@ const SEND_TO = { //to handle NOK and OK sendNotifications s const numberOfNotResponding = {}; let tbName = null; +let mainSocket; + exports.install = function(instance) { @@ -50,6 +52,10 @@ exports.install = function(instance) { this.lengthOfActualDeviceStream = null; this.device = null; + // lampSwitchNotification helper variables + this.onNotificationSent = false; + this.offNotificationSent = false; + this.startSocket(); } @@ -215,6 +221,7 @@ exports.install = function(instance) { }; this.checkNullVoltage(values); + this.lampSwitchNotification(values); instance.send(SEND_TO.dido_controller, {values: values}); @@ -243,32 +250,6 @@ exports.install = function(instance) { } } - - // sendFinalObjects = (values) => - // { - - // const date = Date.now(); - // // values["status"] = "OK"; - - // const dataToTB = { - // [tbName]: [ - // { - // "ts": date, - // "values": values - // } - // ] - // }; - - // instance.send(SEND_TO.tb, dataToTB); - - // const dataToDiDo = { - // values: values - // } - - // instance.send(SEND_TO.dido_controller, dataToDiDo); - // } - - calculateValue = (response, multiplier) => { let value = 0; @@ -296,7 +277,6 @@ exports.install = function(instance) { return Math.round(value * multiplier * 10) / 10; } - checkNullVoltage = (values) => { if(!(values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_2_voltage") || values.hasOwnProperty("Phase_3_voltage"))) return; @@ -313,19 +293,41 @@ exports.install = function(instance) { if(values[singleValue] == 0) { FLOW.OMS_no_voltage.add(phase); - sendNotification("modbus_citys: checkNullVoltage", tbName, "no_voltage_on_phase", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase ); + sendNotification("modbus_reader: checkNullVoltage", tbName, "no_voltage_on_phase", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase ); // console.log('no voltage') } else { FLOW.OMS_no_voltage.delete(phase); // console.log('voltage detected') - sendNotification("modbus_citys: checkNullVoltage", tbName, "voltage_on_phase_restored", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase); + sendNotification("modbus_reader: checkNullVoltage", tbName, "voltage_on_phase_restored", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase); } } }) } + /** + * 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 + */ + lampSwitchNotification = (values) => { + + if(!values.hasOwnProperty("total_power")) return; + + const actualTotalPower = values.total_power; + if(actualTotalPower > 600 && 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) + { + sendNotification("modbus_reader: lampSwitchNotification", tbName, "lamps_have_turned_off", {}, "", SEND_TO.tb, instance); + this.onNotificationSent = false; + this.offNotificationSent = true; + } + } + } const isObjectEmpty = (objectName) => { @@ -333,8 +335,14 @@ exports.install = function(instance) { } setTimeout(() => { - const newSocket = new SocketWithClients(); + + mainSocket = new SocketWithClients(); tbName = FLOW.OMS_rvo_tbname; + + // this notification is to show, that flow (unipi) has been restarted + sendNotification("modbus_reader", tbName, "flow_restart", {}, "", SEND_TO.slack, instance); + }, 25000); + } diff --git a/flow/slack_filter.js b/flow/slack_filter.js new file mode 100644 index 0000000..a27c9e1 --- /dev/null +++ b/flow/slack_filter.js @@ -0,0 +1,187 @@ +exports.id = 'slack_filter'; +exports.title = 'Slack Filter'; +exports.group = 'Citysys'; +exports.color = '#30E193'; +exports.input = 1; +exports.output = 1; +exports.author = 'Jakub Klena'; +exports.icon = 'plug'; +exports.version = '1.0.8'; +exports.options = { 'name':'', 'types': '["emergency", "critical", "error", "alert"]', 'message_includes':'["is responding again"]', 'tag_on_include':'[{"user_id":"U072JE5JUQG", "includes":["Electrometer", "Twilight sensor"]}]', 'slack_channel':'' }; + +exports.html = `
+
+
+
@(Name of this server)
+
+
+
@(Slack channel to receive the alerts)
+
+
+
@(Watch these types, comma separated names)
+
+
+
@(Watch messages that include any of the following strings)
+
+
+
@(Tag people if message includes something)
+
+
+
`; + +exports.readme = `# Slack Filter`; + +exports.install = function(instance) { + var running = false; + instance["savedSlackMessages"] = []; + var timer = null; + + instance.on('data', function(response) { + if (!running) return; + let value = response.data; + if (typeof value !== 'object') return; + + let can = false + var k = Object.keys(value); + var interested = JSON.parse(instance.options.types); + var msg_incl = JSON.parse(instance.options.message_includes); + var tags = JSON.parse(instance.options.tag_on_include); + + if (k.length <= 0) return; + if (value[k[0]].length <= 0) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0], 'values')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values'], '_event')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values']['_event'], 'type')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values']['_event'], 'source')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values']['_event']['source'], 'func')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values']['_event'], 'message')) return; + if (!Object.prototype.hasOwnProperty.call(value[k[0]][0]['values']['_event'], 'message_data')) return; + + let icon = ':totaljs:'; + let type = value[k[0]][0]['values']['_event']['type']; + let source = value[k[0]][0]['values']['_event']['source']['func']; + let message = value[k[0]][0]['values']['_event']['message']; + let message_data = value[k[0]][0]['values']['_event']['message_data']; + let tag = ''; + + switch(type){ + case 'debug': + icon = ':beetle:'; + break; + case 'info': + icon = ':speech_balloon:'; + break; + case 'notice': + icon = ':speech_balloon:'; + break; + case 'warning': + icon = ':exclamation:'; + break; + case 'alert': + icon = ':warning:'; + break; + case 'error': + icon = ':no_entry:'; + break; + case 'emergency': + icon = ':fire:'; + break; + case 'critical': + icon = ':fire:'; + break; + } + + // Check if this message includes one of the strings we are watching for + for (const msg of msg_incl){ + if (message.includes(msg)){ + if (msg == 'is responding again') icon = ':large_green_circle:'; + can = true; + break; + } + } + // Check if message is one of the types we are watching for + if (interested.includes(type)){ + can = true; + } + + if (!can) return; + + + // Check for each person tags based on what the message includes + for (const person of tags){ + for (const msg of person.includes){ + if (message.includes(msg)){ + tag += '<@'+person.user_id+'> '; + break; // Break out from this person checks as they are already tagged now + } + } + } + // Now that all people are tagged add new line symbol + if (tag != '') tag += '\n'; + + let send_data = tag+instance.options.name+' '+type.toUpperCase()+'\n*Source*: '+source+'\n*Message*: '+message; + if (message_data) { + send_data += '\nData: '+message_data; + } + + let ignore_msg = false + if (message.includes('Configuration of dimming profile to node no')){ + for (let i = 0; i < FLOW["savedSlackMessages"].length; i++){ + if (FLOW["savedSlackMessages"][i].message == message){ + ignore_msg = true; + break; + } + } + if (!ignore_msg){ + FLOW["savedSlackMessages"].push({message, 'dateandtime': Date.now()}); + if (timer === null){ + timer = setTimeout(checkSavedMessages, 60*60000); + } + } + } + + if (!ignore_msg){ + instance.send2({'msg':send_data,'bot_name':instance.options.name+' '+type.toUpperCase(),'bot_icon':icon,'channel':instance.options.slack_channel}); + } + }); + + function checkSavedMessages(){ + var d = Date.now(); + d = d - 86400000; // older then 24hr + var a = []; + //Remove msgs older then 24hr + for (let i = 0; i < FLOW["savedSlackMessages"].length; i++){ + if (FLOW["savedSlackMessages"][i].dateandtime > d){ + a.push(FLOW["savedSlackMessages"][i]); + } + } + FLOW["savedSlackMessages"] = a; + + if (FLOW["savedSlackMessages"].length > 0) { + timer = setTimeout(checkSavedMessages, 60*60000); + } else { + timer = null; + } + } + + instance.reconfigure = function() { + try { + if (!FLOW["savedSlackMessages"]){ + FLOW["savedSlackMessages"] = []; + } + + if (instance.options.name) { + instance.status('Running'); + running = true; + } else { + instance.status('Please enter name', 'red'); + running = false; + } + } catch (e) { + instance.error('Citysys connector: ' + e.message); + } + }; + + instance.on('options', instance.reconfigure); + instance.reconfigure(); +}; \ No newline at end of file