From 63504df84d8064bf315416ce0dfc69fb1708e2ce Mon Sep 17 00:00:00 2001 From: rasta5man Date: Thu, 9 Jan 2025 14:55:53 +0100 Subject: [PATCH] Do not send 'switching profile applied to line' notification; Handle nok,ok,offline node status --- flow/cmd_manager.js | 56 ++-- flow/dido_controller.js | 584 +++++++++++++++++----------------------- 2 files changed, 277 insertions(+), 363 deletions(-) diff --git a/flow/cmd_manager.js b/flow/cmd_manager.js index a9376a5..6e0bd42 100644 --- a/flow/cmd_manager.js +++ b/flow/cmd_manager.js @@ -140,7 +140,7 @@ 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(); @@ -1538,7 +1538,7 @@ exports.install = function(instance) { value == 1 ? onOrOff = "on" : onOrOff = "off"; turnLine(onOrOff, params.line, info); - + interval = setInterval(runTasks, SHORT_INTERVAL); return; } @@ -1590,27 +1590,35 @@ exports.install = function(instance) { return; } } + + let contactorStatus = 1; + if(relaysData[line] != undefined) contactorStatus = relaysData[line].contactor; + + if (line == 0 || contactorStatus == 0) { + interval = setInterval(runTasks, LONG_INTERVAL); + return; + } - //TODO -> status offline for rvo if rotary_switch_state is OFF - //let relayStatus = 1; - //if (relaysData[line] != undefined) { - // relayStatus = relaysData[line].contactor; - //} + // TODO: -> status offline for rvo if rotary_switch_state is OFF, this is source of errors + // + // 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) { + // console.log("------------------------------------relayStatus", relayStatus, line); + // let values = { "status": "OFFLINE" }; - //check if rotary_switch_state == "Off" - //if (relayStatus == 0) { - //console.log("------------------------------------relayStatus", relayStatus, line); - //let values = { "status": "OFFLINE" }; + // if(tbname) 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); @@ -1806,7 +1814,7 @@ exports.install = function(instance) { } else { - if(currentTask.debug) { + if (currentTask.debug) { // currentTask.timestamp <= currentTimestamp && logger.debug("currentTask is not processed - task is in the future", currentTask); } @@ -1844,11 +1852,11 @@ exports.install = function(instance) { if (type == "set_node_profile") { delete cmdCounter[node]; logger.debug("profil nebol úspešne odoslaný na node č. ", params); - - 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 (!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) { diff --git a/flow/dido_controller.js b/flow/dido_controller.js index e9379ea..3a24f87 100644 --- a/flow/dido_controller.js +++ b/flow/dido_controller.js @@ -92,15 +92,15 @@ const SEND_TO = { exports.install = function(instance) { - process.on('uncaughtException', function (err) { + process.on('uncaughtException', function(err) { //TODO send to service - + errLogger.error('uncaughtException:', err.message) errLogger.error(err.stack); errorHandler.sendMessageToService(err.message + "\n" + err.stack, 0, "js_error"); - + //process.exit(1); }) @@ -133,7 +133,7 @@ exports.install = function(instance) { "16": {tbname: "", type: "twilight_sensor", "line": 0}, // twilight_sensor = pin16 }; */ - + //status for calculating Statecodes let deviceStatus = { //key is device name: temperature,.... "state_of_main_switch": "Off", //Hlavný istič @@ -163,16 +163,14 @@ exports.install = function(instance) { tbHandler.setSender(exports.title); controller_type = SETTINGS.controller_type //"lm" or "unipi" //logicMachine - if(controller_type == "") controller_type = "lm"; + if (controller_type == "") controller_type = "lm"; console.log(exports.title, "controller type: ", controller_type); - if(controller_type === "lm") - { + if (controller_type === "lm") { handleRsPort(); } - else if(controller_type === "unipi") - { + else if (controller_type === "unipi") { handleWebSocket(); } else { @@ -181,35 +179,29 @@ exports.install = function(instance) { } - function initialSetting() - { + function initialSetting() { //force turn off relays let keys = Object.keys(pinsData); - for(let i = 0; i < keys.length; i++) - { + for (let i = 0; i < keys.length; i++) { let key = keys[i]; - let line = pinsData[key].line; + let line = pinsData[key].line; - if(line != undefined) - { - if(relaysData[line] != undefined) - { + if (line != undefined) { + if (relaysData[line] != undefined) { pinsData[key].tbname = relaysData[line].tbname; //relaysData[line].contactor = 0; } - else - { + else { errLogger.error("CRITICAL!!! undefined relay", relaysData[line], line); - sendNotification("set port ", rvoTbName, "local_database_is_corrupted", {}, "", SEND_TO.tb, instance ); + sendNotification("set port ", rvoTbName, "local_database_is_corrupted", {}, "", SEND_TO.tb, instance); } } - if(pinsData[key].type == "state_of_contactor") - { + if (pinsData[key].type == "state_of_contactor") { let pin = key - 1; - if(controller_type === "unipi") pin = key; - + if (controller_type === "unipi") pin = key; + //this will modify database let forceTurnOff = true; turnLine("off", line, pin, forceTurnOff, "turn off on startup"); @@ -223,9 +215,9 @@ exports.install = function(instance) { sendTelemetry(values, rvoTbName); - let time = 5*1000; - setTimeout(function(){ - instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "buildTasks"}); + let time = 5 * 1000; + setTimeout(function() { + instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "buildTasks" }); sendNotification("rsPort.open()", rvoTbName, "flow_start", {}, "", SEND_TO.tb, instance); monitor.info("-->FLOW bol spustený", rvoTbName, SETTINGS.edge_fw_version); @@ -233,27 +225,26 @@ exports.install = function(instance) { } - function handleRsPort() - { + function handleRsPort() { //TODO build according to pins!!! //! rsPort to open are the same for lm and unipi and electromer ("/dev/ttymxc0") - const setRSPortData = [0xAA,6,6,6,6,6,6,0,6,6,6,1,1,1,1,0,0,10,10,10,10,10,10,0,10,10,10,0,0,0,0,0,0,5,0,0,0,15,15,15,15,15,15,0,15,15,15,0,0,0,0,0,0,30,0,0,0]; + const setRSPortData = [0xAA, 6, 6, 6, 6, 6, 6, 0, 6, 6, 6, 1, 1, 1, 1, 0, 0, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0]; rsPort = new SerialPort("/dev/ttymxc0", { autoOpen: false }); rsPort.on('error', function(err) { logger.debug("rsPort opened error - failed", err.message); instance.send(SEND_TO.debug, err.message); - errorHandler.sendMessageToService( exports.title + " rsPort opened error - failed: " + 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) { - if(!err) { + if (!err) { monitor.info(exports.title + "--->Digital in_out has been set (runSyncExec was sucessfull)"); turnAlarm("off"); @@ -265,48 +256,48 @@ exports.install = function(instance) { errLogger.error(exports.title + " runSyncExec - promise rejected:" + reason); errorHandler.sendMessageToService(exports.title + " runSyncExec - promise rejected:" + reason); }); - + }); - + rsPort.on('data', function(data) { - + rsPortReceivedData = [...rsPortReceivedData, ...data]; - + if (rsPortReceivedData[0] != 85) { rsPortReceivedData = []; return; } - + let l = rsPortReceivedData.length; - - if (l < 4 ) return; - - if (l > 4 ) { - + + if (l < 4) return; + + if (l > 4) { + // if array length is greater than 4, we take first 4 byte and do the logic, second 4 bytes, do the logic and so on let i, j, temparray, chunk = 4; - for ( i = 0, j = l; i < j; i += chunk ) { - temparray = rsPortReceivedData.slice(i, i + chunk); - - if ( temparray.length < 4 ){ - rsPortReceivedData = [...temparray]; - return; - } - - switchLogic(temparray); + for (i = 0, j = l; i < j; i += chunk) { + temparray = rsPortReceivedData.slice(i, i + chunk); + + if (temparray.length < 4) { + rsPortReceivedData = [...temparray]; + return; + } + + switchLogic(temparray); } - + rsPortReceivedData = []; return; } - + switchLogic(rsPortReceivedData); - + rsPortReceivedData = []; - + }); - + rsPort.on("close", () => { rsPort.close(); }) @@ -324,62 +315,62 @@ exports.install = function(instance) { ws = new WebSocket('ws:/0.0.0.0:1234/ws'); ws.onopen = function open() { - + instance.send(0, exports.title + " running"); turnAlarm("off"); // useTurnOffCounter = true; // turnOffCounter = relaysData.length - 1; initialSetting(); - ws.send(JSON.stringify({"cmd":"all"})); + ws.send(JSON.stringify({ "cmd": "all" })); // we request dev info about neuron device from evok to keep websocket connection alive // for some reason this request returns no data, but connection keeps alive // https://evok.api-docs.io/1.0/mpqzDwPwirsoq7i5A/websocket startRequests = setInterval(() => { // console.log(" *** data from evok requested"); - ws.send(JSON.stringify({"cmd":"filter", "dev": ["neuron"]})); + ws.send(JSON.stringify({ "cmd": "filter", "dev": ["neuron"] })); }, 150000) }; - -// SAMPLE DATA FROM WEBSOCKET -// { -// glob_dev_id: 1, -// modes: [ 'Simple' ], -// value: 0, -// circuit: '1_07', -// pending: false, -// relay_type: 'physical', -// dev: 'relay', -// mode: 'Simple' -// }, -// { -// counter_modes: [ 'Enabled', 'Disabled' ], -// glob_dev_id: 1, -// modes: [ 'Simple', 'DirectSwitch' ], -// value: 0, -// circuit: '1_08', -// debounce: 50, -// counter: 0, -// counter_mode: 'Enabled', -// dev: 'input', -// mode: 'Simple' -// }, + + // SAMPLE DATA FROM WEBSOCKET + // { + // glob_dev_id: 1, + // modes: [ 'Simple' ], + // value: 0, + // circuit: '1_07', + // pending: false, + // relay_type: 'physical', + // dev: 'relay', + // mode: 'Simple' + // }, + // { + // counter_modes: [ 'Enabled', 'Disabled' ], + // glob_dev_id: 1, + // modes: [ 'Simple', 'DirectSwitch' ], + // value: 0, + // circuit: '1_08', + // debounce: 50, + // counter: 0, + // counter_mode: 'Enabled', + // dev: 'input', + // mode: 'Simple' + // }, ws.onmessage = async function(data) { data = JSON.parse(data.data); // data comes in array except of "temperature" ==> it comes as an object // we do not handle temperature from evok any more => we return, if temperature comes: - if(isObject(data)) return; + if (isObject(data)) return; data.map(item => { let value = item['value']; let pin = item["dev"] + item["circuit"]; // for example "relay1_03" or "input1_01" - if(pin == undefined) return; + if (pin == undefined) return; switchLogic(pin, value); }) } @@ -394,7 +385,7 @@ exports.install = function(instance) { }) - ws.onclose = function(){ + ws.onclose = function() { // connection closed, discard old websocket and create a new one in 5s // stopRequests(); monitor.info('websocket onclose, reconnect') @@ -406,23 +397,20 @@ exports.install = function(instance) { } instance.on("close", () => { - if(rsPort) rsPort.close(); - if(ws) ws.close(); + if (rsPort) rsPort.close(); + if (ws) ws.close(); }) - function getPin(line) - { + function getPin(line) { //conversionTable let keys = Object.keys(pinsData); - for(let i = 0; i < keys.length; i++) - { + for (let i = 0; i < keys.length; i++) { let key = keys[i]; - if(pinsData[key].type == "state_of_contactor" && pinsData[key].line == line) - { - if(rsPort) return key - 1; - if(ws) return key; + if (pinsData[key].type == "state_of_contactor" && pinsData[key].line == line) { + if (rsPort) return key - 1; + if (ws) return key; } } @@ -432,18 +420,16 @@ exports.install = function(instance) { } - function turnAlarm(onOrOff) - { + function turnAlarm(onOrOff) { let value = 0; - if(onOrOff == "on") value = 1; + if (onOrOff == "on") value = 1; - if(value == 1 && SETTINGS.maintenance_mode) return; + if (value == 1 && SETTINGS.maintenance_mode) return; alarmStatus = "OFF"; - if(value == 1) alarmStatus = "ON"; + if (value == 1) alarmStatus = "ON"; - if(rsPort) - { + if (rsPort) { let arr = [0x55]; arr.push(13); arr.push(0); @@ -453,29 +439,25 @@ exports.install = function(instance) { logger.debug(`sirena - ${onOrOff}`); }); } - else if(ws) - { - let cmd = {"cmd": "set", "dev": "relay", "circuit": "1_01", "value": value}; + else if (ws) { + let cmd = { "cmd": "set", "dev": "relay", "circuit": "1_01", "value": value }; ws.send(JSON.stringify(cmd)); logger.debug(`sirena - ${onOrOff}`); } } - function reportLineStatus(line) - { + function reportLineStatus(line) { //Tá hodnota by mala fungovať tak že LSB bit číslo je stav ističa (1 - On, 0 - Off) a druhý bit je stav stýkača (1 - true, 0 - false). let tbname = relaysData[line].tbname; let bits = []; - if(deviceStatus["state_of_breaker"][line] == "On") - { + if (deviceStatus["state_of_breaker"][line] == "On") { bits.push(0); } else bits.push(1); - if(deviceStatus["state_of_contactor"][line] == "On") - { + if (deviceStatus["state_of_contactor"][line] == "On") { bits.push(0); } else bits.push(1); @@ -485,90 +467,80 @@ exports.install = function(instance) { let byte = bitwise.byte.write(bits.reverse()); //console.log("line", line, bits, byte); - sendTelemetry({statecode: byte}, tbname); + sendTelemetry({ statecode: byte }, tbname); } // turn line on or off - function turnLine(onOrOff, line, pin, force, info) - { + function turnLine(onOrOff, line, pin, force, info) { //onOrOff => "on" or "off" let value = 0; - if(onOrOff == "on") value = 1; - - if(force == undefined) force = false; + if (onOrOff == "on") value = 1; - if(line == 0) - { - if(value == 1 && alarmStatus == "ON") turnAlarm("off"); - SETTINGS.maintenance_mode = value? true: false; + if (force == undefined) force = false; + + if (line == 0) { + if (value == 1 && alarmStatus == "ON") turnAlarm("off"); + SETTINGS.maintenance_mode = value ? true : false; let values = {}; values["statecode"] = calculateStateCode(); - values["power_mode"] = value ? "maintenance": "Automatic"; + values["power_mode"] = value ? "maintenance" : "Automatic"; sendTelemetry(values, rvoTbName); - + monitor.info(`turnLine ${onOrOff} - (line, SETTINGS.maintenance_mode)`, line, SETTINGS.maintenance_mode, info); return; } - if(pin === undefined) pin = getPin(line); + if (pin === undefined) pin = getPin(line); - if(pin === undefined) - { + if (pin === undefined) { errLogger.error("pin is undefined!", line); return; } - - if(!force) - { - if(relaysData[line].contactor == value) - { - instance.send(SEND_TO.debug, `line is already ${onOrOff} ` + line ); + + if (!force) { + if (relaysData[line].contactor == value) { + instance.send(SEND_TO.debug, `line is already ${onOrOff} ` + line); logger.debug(`turnLine: line is already ${onOrOff} `, line); return; } } // if(!rsPort.isOpen && !ws) - if(!rsPort && !ws) - { + if (!rsPort && !ws) { errLogger.error("dido controller - port or websocket is not opened"); return; } - - if(rsPort) - { + + if (rsPort) { let arr = [0x55]; arr.push(pin); arr.push(0); arr.push(value); - + rsPort.write(Buffer.from(arr), function(err) { - if(err === undefined) - { + if (err === undefined) { monitor.info(`turnLine ${onOrOff} zapisal do rsPort-u`, line, pin, arr, info); switchLogic(arr); } - else - { + else { monitor.info(`turnLine ${onOrOff} WRITE error`, err); - } + } }); } - else if(ws) - { + else if (ws) { //pin = "relay1_03" or "input1_01" ... we must make just "1_01" with slice method monitor.info(`turnLine ${onOrOff} - (line, pin, force)`, line, pin, force, info); - let cmd = {"cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": value}; + let cmd = { "cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": value }; 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); + //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); } @@ -581,45 +553,37 @@ exports.install = function(instance) { //data from modbus_reader or temperature sensor or twilight sensor or other modbus device instance.on("0", flowdata => { - if(!isObject(flowdata.data)) return; + if (!isObject(flowdata.data)) return; // console.log('***********************', flowdata.data) instance.send(SEND_TO.debug, flowdata.data); // we handle nok status from modbus_reader component and thermometer - if("status" in flowdata.data) - { + if ("status" in flowdata.data) { const status = flowdata.data.status; - if(status == "NOK-twilight_sensor") - { + if (status == "NOK-twilight_sensor") { deviceStatus["twilight_sensor"] = "NOK"; } - else if(status == "NOK-em340" || status == "NOK-em111") - { + else if (status == "NOK-em340" || status == "NOK-em111") { deviceStatus["em"] = "NOK"; } - else if(status == "NOK-thermometer") - { + else if (status == "NOK-thermometer") { deviceStatus["temperature"] = "NOK"; } } - else if("values" in flowdata.data) - { + else if ("values" in flowdata.data) { 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"]}); + if (values.hasOwnProperty("twilight_sensor")) { + instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "lux_sensor", value: values["twilight_sensor"] }); deviceStatus["twilight_sensor"] = "OK" } - else if(values.hasOwnProperty("temperature")) - { + else if (values.hasOwnProperty("temperature")) { deviceStatus["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")) - { + else if (values.hasOwnProperty("total_power") || values.hasOwnProperty("total_energy") || values.hasOwnProperty("power_factor") || values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_1_current")) { deviceStatus["em"] = "OK"; - SETTINGS.no_voltage.size > 0 ? deviceStatus["no_voltage"] = "NOK": deviceStatus["no_voltage"] = "OK"; + SETTINGS.no_voltage.size > 0 ? deviceStatus["no_voltage"] = "NOK" : deviceStatus["no_voltage"] = "OK"; } sendTelemetry(values, rvoTbName); @@ -634,161 +598,137 @@ exports.install = function(instance) { console.log(flowdata.data); - if(!flowdata.data instanceof Object) return; + if (!flowdata.data instanceof Object) return; let obj = flowdata.data; let line = obj.line; let force = obj.force; let info = obj.info; - if(obj.command == "on") turnLine("on", line, undefined, force, info); - else if(obj.command == "off") turnLine("off", line, undefined, force, info); - else if(obj.command == "turnOnAlarm") turnAlarm("on"); - else if(obj.command == "turnOffAlarm") turnAlarm("off"); + if (obj.command == "on") turnLine("on", line, undefined, force, info); + else if (obj.command == "off") turnLine("off", line, undefined, force, info); + else if (obj.command == "turnOnAlarm") turnAlarm("on"); + else if (obj.command == "turnOffAlarm") turnAlarm("off"); //! ake data prichadzaju z cmd_manager.js ??? //TODO transform to websocket - if (Array.isArray(obj)){ + if (Array.isArray(obj)) { rsPort.write(Buffer.from(obj), function(err) { switchLogic(obj); - instance.send(SEND_TO.debug, {"WRITE":obj} ); + instance.send(SEND_TO.debug, { "WRITE": obj }); }); - } + } }) - function calculateStateCode() - { + function calculateStateCode() { let bits = []; //Hlavný istič - state_of_main_switch => v rvo senica je to druhy door pre silovu cast (EM) - if(deviceStatus["state_of_main_switch"] == "closed") - { + if (deviceStatus["state_of_main_switch"] == "closed") { bits.push(0); } - else - { + else { bits.push(1); } //Prevádzkový mód - Manual, Off, Automatic, maintenance_mode = true/false // DAVA 2 BITY - if(!SETTINGS.maintenance_mode) - { - if(deviceStatus["rotary_switch_state"] == "Manual") - { + if (!SETTINGS.maintenance_mode) { + if (deviceStatus["rotary_switch_state"] == "Manual") { bits.push(0); bits.push(1); } - if(deviceStatus["rotary_switch_state"] == "Automatic") - { + if (deviceStatus["rotary_switch_state"] == "Automatic") { bits.push(0); bits.push(0); } - if(deviceStatus["rotary_switch_state"] == "Off") - { + if (deviceStatus["rotary_switch_state"] == "Off") { bits.push(1); bits.push(0); } } - else{ + else { bits.push(1); bits.push(1); } //Dverový kontakt - if(deviceStatus["door_condition"] == "closed") - { + if (deviceStatus["door_condition"] == "closed") { bits.push(0); } - else - { + else { bits.push(1); } //EM - if(deviceStatus["em"] == "NOK") - { + if (deviceStatus["em"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } //Teplomer - if(deviceStatus["temperature"] == "NOK") - { + if (deviceStatus["temperature"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } //Batéria - if(deviceStatus["battery"] == "NOK") - { + if (deviceStatus["battery"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } //Zdroj - if(deviceStatus["power_supply"] == "NOK") - { + if (deviceStatus["power_supply"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } //MN - if(deviceStatus["master_node"] == "NOK") - { + if (deviceStatus["master_node"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } //výpadok napätia na fáze - if(deviceStatus["no_voltage"] == "NOK") - { + if (deviceStatus["no_voltage"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } - if(deviceStatus["twilight_sensor"] == "NOK") - { + if (deviceStatus["twilight_sensor"] == "NOK") { bits.push(1); } - else - { + else { bits.push(0); } - + // doplnime do 16 bitov (2 byty) - for(let i = bits.length; i < 16; i++) - { + for (let i = bits.length; i < 16; i++) { bits.push(0); } - + // console.log("calculateStateCode - deviceStatus", deviceStatus); // console.log("calculateStateCode", bits); - let byte0 = bitwise.byte.write(bits.slice(0,8).reverse()); + let byte0 = bitwise.byte.write(bits.slice(0, 8).reverse()); let byte1 = bitwise.byte.write(bits.slice(8).reverse()); let byte = bytesToInt([byte1, byte0]); @@ -801,7 +741,7 @@ exports.install = function(instance) { async function sendRvoStatus() { - if(SETTINGS === undefined) return; + if (SETTINGS === undefined) return; const table = { "OK": 1, @@ -836,13 +776,12 @@ exports.install = function(instance) { let status = "OK"; for (const [key, value] of Object.entries(deviceStatus)) { - if(["em", "twilight_sensor", "temperature"].includes(key) && value == "NOK") status = "NOK"; + if (["em", "twilight_sensor", "temperature"].includes(key) && value == "NOK") status = "NOK"; } - if(status == "OK") - { + if (status == "OK") { let pinIndexes = [1, 4, 6]; - if(controller_type == 'unipi') pinIndexes = ['input1_01', 'input1_04', 'input1_05']; + if (controller_type == 'unipi') pinIndexes = ['input1_01', 'input1_04', 'input1_05']; for (const pinIndex of pinIndexes) { if (previousValues[pinIndex] === 0) { @@ -855,10 +794,10 @@ exports.install = function(instance) { // battery status. If value is 1 - battery is NOK if (previousValues[5] === 1) status = "NOK"; - if(!SETTINGS.masterNodeIsResponding) status = "NOK"; - if(SETTINGS.no_voltage.size > 0) status = "NOK"; + if (!SETTINGS.masterNodeIsResponding) status = "NOK"; + if (SETTINGS.no_voltage.size > 0) status = "NOK"; - // console.log("rvo status",status) + // console.log("rvo status",status) return status; } @@ -871,23 +810,20 @@ exports.install = function(instance) { let pinIndex, newPinValue, twilight; //data from rsPort - if(args.length == 1) - { + if (args.length == 1) { pinIndex = args[0][1] + 1; if (pinIndex === 17) pinIndex--; newPinValue = args[0][3]; twilight = args[0][2]; } //data from websocket - else - { + else { pinIndex = args[0]; newPinValue = args[1]; } let obj = pinsData[pinIndex]; - if(obj == undefined) - { + if (obj == undefined) { previousValues[pinIndex] = newPinValue; //logger.debug("dido-switchLogic ==> no pinIndex", pinIndex); return; @@ -899,8 +835,8 @@ exports.install = function(instance) { let tbname = obj.tbname; //default value - let value = "On"; - if(newPinValue === 0) value = "Off"; + let value = "On"; + if (newPinValue === 0) value = "Off"; //Hlavný istič //! po novom uz 'state of main switch' nemame. Namiesto neho je 'door_condition', kedze mame dvoje dveri @@ -923,31 +859,26 @@ exports.install = function(instance) { // } //Prevádzkový mód - if(type == "rotary_switch_state") - { + if (type == "rotary_switch_state") { // combination of these two pins required to get result let pin2, pin3; - if(pinIndex == 2 || pinIndex == "input1_02") - { + if (pinIndex == 2 || pinIndex == "input1_02") { pin2 = newPinValue; pin3 = previousValues[3] || previousValues["input1_03"]; - if(pin3 == undefined) - { + if (pin3 == undefined) { previousValues[pinIndex] = newPinValue; return; - } + } } - else if(pinIndex == 3 || pinIndex == "input1_03") - { + else if (pinIndex == 3 || pinIndex == "input1_03") { pin3 = newPinValue; pin2 = previousValues[2] || previousValues["input1_02"]; - if(pin2 == undefined) - { + if (pin2 == undefined) { previousValues[pinIndex] = newPinValue; return; - } + } } //console.log('***********************', pin2, pin3) @@ -961,22 +892,19 @@ exports.install = function(instance) { //ak je spracovany, a automatic - tak ho zapnem //ak nie je spracovany, iba profil zapisem - if(pin2 != undefined && pin3 != undefined) instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "rotary_switch_state", value: value}); + if (pin2 != undefined && pin3 != undefined) instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "rotary_switch_state", value: value }); //console.log("rotary_switch_state pin", pin2, pin3, value); } //Zdroj - pin 4 - else if (type === "power_supply") - { - if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) - { + else if (type === "power_supply") { + if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { sendNotification("switchLogic", rvoTbName, "power_supply_has_disconnected_input", {}, "", SEND_TO.tb, instance, "power_supply"); deviceStatus["power_supply"] = "NOK"; } - else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) - { + else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { sendNotification("switchLogic", rvoTbName, "power_supply_works_correctly", {}, "", SEND_TO.tb, instance, "power_supply"); deviceStatus["power_supply"] = "OK"; @@ -984,16 +912,13 @@ exports.install = function(instance) { } //Batéria - pin 5 - else if (type === "battery") - { - if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) - { + else if (type === "battery") { + if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { sendNotification("switchLogic", rvoTbName, "battery_level_is_low", {}, "", SEND_TO.tb, instance, "battery_level"); deviceStatus["battery"] = "NOK"; } - else if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) - { + else if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { sendNotification("switchLogic", rvoTbName, "battery_level_is_ok", {}, "", SEND_TO.tb, instance, "battery_level"); deviceStatus["battery"] = "OK"; @@ -1003,27 +928,23 @@ exports.install = function(instance) { //Dverový kontakt - pin 6 //! Po novom mame dva dverove kontakty, nie jeden. Druhy je teraz tam, kde bol digital input "state_of_main_switch" //! preto ked pride z evoku signal z input1_05, co bol predytm "main switch" handlujeme ho teraz ako 'door_condition' - else if(type == "door_condition" || type === "state_of_main_switch") - { + else if (type == "door_condition" || type === "state_of_main_switch") { newPinValue === 0 ? value = "open" : value = "closed"; - if (value === "open" && SETTINGS.maintenance_mode) - { + if (value === "open" && SETTINGS.maintenance_mode) { sendNotification("switchLogic", rvoTbName, "door_opened", {}, "", SEND_TO.tb, instance, "rvo_door"); } - if (value === "open" && !SETTINGS.maintenance_mode) - { + if (value === "open" && !SETTINGS.maintenance_mode) { sendNotification("switchLogic", rvoTbName, "door_opened_without_permission", {}, "", SEND_TO.tb, instance, "rvo_door"); // zapneme sirenu // ak sa otvoria dvere len na elektromeri (type === "state_of_main_switch") alarm sa nema spustit. alarm sa spusti len ked sa otvoria hlavne dvere (type === "door_condition") - if(type === "door_condition") turnAlarm("on"); + if (type === "door_condition") turnAlarm("on"); } - if (value === "closed") - { - if(alarmStatus == "ON") turnAlarm("off"); + if (value === "closed") { + if (alarmStatus == "ON") turnAlarm("off"); sendNotification("switchLogic", rvoTbName, "door_closed", {}, "", SEND_TO.tb, instance, "rvo_door"); } @@ -1031,59 +952,53 @@ exports.install = function(instance) { } //lux sensor - else if(type == "twilight_sensor") - { + else if (type == "twilight_sensor") { //! TODO - to show nok status, if lux value is not changing more then 10 times. //Daylight is far more than 1000. So most of the day, when it is sunshine comes just value 1000. But lux sensor is not NOK. //This is not the case in LM. If value from LM is the same 10x, there is 99% possibility, that sensor is NOK. value = newPinValue; - if(controller_type === 'lm') - { - value = parseFloat(newPinValue + (256*twilight)); + if (controller_type === 'lm') { + value = parseFloat(newPinValue + (256 * twilight)); let now = new Date(); //new Date(dusk.getTime() - let obj = {timestamp: now.getTime(), value: value}; + let obj = { timestamp: now.getTime(), value: value }; //test //twilight_sensor_interval = 1; twilight_sensor.push(obj); //twilight_sensor_array.push(value); - + //check if we receive just 1 constant value from lux sensor ==> error - if(twilight_sensor_array.length > 10) { + if (twilight_sensor_array.length > 10) { let set = new Set(twilight_sensor_array); - if(set.size === 1 && !twilightError) - { + if (set.size === 1 && !twilightError) { twilightError = true; let value = twilight_sensor_array.shift(); newPinValue = 0; } - else if (set.size !== 1 && twilightError) - { + else if (set.size !== 1 && twilightError) { //sendNotification("switchLogic", rvoTbName, ERRWEIGHT.NOTICE, "Lux sensor is working again", "", SEND_TO.tb, instance ); twilightError = false; twilight_sensor_array.shift(); newPinValue = value; } - else if (set.size === 1 && twilightError) - { + else if (set.size === 1 && twilightError) { twilight_sensor_array.shift(); newPinValue = 0; } } - let diff = twilight_sensor[ twilight_sensor.length - 1 ].timestamp - twilight_sensor[0].timestamp; - if(diff >= twilight_sensor_interval * 60 * 1000) - { + let diff = twilight_sensor[twilight_sensor.length - 1].timestamp - twilight_sensor[0].timestamp; + if (diff >= twilight_sensor_interval * 60 * 1000) { const average = twilight_sensor.reduce((acc, c) => acc + c.value, 0) / twilight_sensor.length; - instance.send(SEND_TO.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 = []; @@ -1093,27 +1008,25 @@ exports.install = function(instance) { } } - else if(type == "state_of_contactor") - { - if(!(deviceStatus["state_of_contactor"][line] == value)) - { - sendNotification("switchLogic", rvoTbName, "state_of_contactor_for_line", {line: line, value: value}, "", SEND_TO.tb, instance ); + else if (type == "state_of_contactor") { + if (!(deviceStatus["state_of_contactor"][line] == value)) { + sendNotification("switchLogic", rvoTbName, "state_of_contactor_for_line", { line: line, value: value }, "", SEND_TO.tb, instance); } deviceStatus["state_of_contactor"][line] = value; //true, false - if(value === "On") value = true; - else if(value === "Off") value = false; + if (value === "On") value = true; + else if (value === "Off") value = false; //TODO do we need to modify relays table with contactor value, if we do not use it on startup ?? let dataChanged = false; - if(relaysData[line].contactor !== newPinValue) { + if (relaysData[line].contactor !== newPinValue) { dataChanged = true; relaysData[line].contactor = newPinValue; } - instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, value: value, dataChanged: dataChanged}); + instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "reload_relays", line: line, value: value, dataChanged: dataChanged }); reportLineStatus(line); //modify table relays @@ -1145,29 +1058,25 @@ exports.install = function(instance) { // }); } - else if(type === "state_of_breaker") - { + else if (type === "state_of_breaker") { let valueChanged = false; - if(newPinValue != previousValues[pinIndex]) valueChanged = true; + if (newPinValue != previousValues[pinIndex]) valueChanged = true; - if(valueChanged) - { - instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line}); + if (valueChanged) { + 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 - if(line == 1) - { + if (line == 1) { - const lineOnSameBraker = [4,7]; + const lineOnSameBraker = [4, 7]; - for (var i = 0; i < lineOnSameBraker.length; i++) - { - if(!relaysData.hasOwnProperty(lineOnSameBraker[i])) continue; + for (var i = 0; i < lineOnSameBraker.length; i++) { + if (!relaysData.hasOwnProperty(lineOnSameBraker[i])) continue; - instance.send(SEND_TO.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] }); deviceStatus["state_of_breaker"][lineOnSameBraker[i]] = value; reportLineStatus(lineOnSameBraker[i]); @@ -1175,18 +1084,16 @@ exports.install = function(instance) { values[type] = value; const tbname = relaysData[lineOnSameBraker[i]].tbname; sendTelemetry(values, tbname); - + delete values[type]; } } - else - { + else { const lineOnSameBraker = line + 3 + ""; - if(relaysData.hasOwnProperty(lineOnSameBraker)) - { - instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line + 3}); + if (relaysData.hasOwnProperty(lineOnSameBraker)) { + instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "state_of_breaker", value: value, line: line + 3 }); deviceStatus["state_of_breaker"][line + 3] = value; reportLineStatus(line + 3); @@ -1194,14 +1101,14 @@ exports.install = function(instance) { values[type] = value; const tbname = relaysData[lineOnSameBraker].tbname; sendTelemetry(values, tbname); - + delete values[type]; } } } - if(value == "Off") values["status"] = "NOK"; + if (value == "Off") values["status"] = "NOK"; deviceStatus["state_of_breaker"][line] = value; reportLineStatus(line); @@ -1210,19 +1117,18 @@ exports.install = function(instance) { values[type] = value; - if(type == "rotary_switch_state") - { - if(SETTINGS.maintenance_mode) value = "maintenance"; + if (type == "rotary_switch_state") { + if (SETTINGS.maintenance_mode) value = "maintenance"; value = value.toLowerCase(); values["power_mode"] = value; } - if(newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue; - if(Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname); - } + if (newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue; + if (Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname); + } - function sendTelemetry(values, tbname, date=Date.now()) { + function sendTelemetry(values, tbname, date = Date.now()) { let dataToTb = { [tbname]: [ { @@ -1236,7 +1142,7 @@ exports.install = function(instance) { } - function isObject (item) { + function isObject(item) { return (typeof item === "object" && !Array.isArray(item) && item !== null); }