Compare nodesDb; thermometer instead evok; no status.table

This commit is contained in:
rasta5man 2024-12-02 17:06:49 +01:00
parent f63ac50497
commit 5270a898a3
13 changed files with 1255 additions and 4969 deletions

3
config
View file

@ -7,7 +7,6 @@ package#flow (Object) : { url: '/' }
table.relays : line:number|tbname:string|contactor:number|profile:string table.relays : line:number|tbname:string|contactor:number|profile:string
table.nodes : node:number|tbname:string|line:number|profile:string|processed:boolean|status:boolean|time_of_last_communication:number table.nodes : node:number|tbname:string|line:number|profile:string|processed:boolean|status:boolean|time_of_last_communication:number
table.settings : rvo_name:string|lang:string|temperature_adress:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|projects_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number table.settings : rvo_name:string|lang:string|temperature_address:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|project_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number|phases:number
table.pins : pin:string|type:string|line:number table.pins : pin:string|type:string|line:number
table.notifications : key:string|weight:string|sk:string|en:string table.notifications : key:string|weight:string|sk:string|en:string
table.status : thermometer:string|em:string|twilight_sensor:string

43
createNode.py Normal file
View file

@ -0,0 +1,43 @@
print("zaciname")
import re, json
search_str = '|'
final = []
counter = 1
with open("/home/unipi/flowserver/databases/nodes.table", 'r') as file:
# with open("/home/rasta5man/dev/oms/flowserver/databases/nodes.table", 'r') as file:
# Read each line in the file
for line in file:
# Print each line
line = line.strip()
print(line)
if counter != 1:
i = [m.start() for m in re.finditer(re.escape(search_str), line)]
node = line[ i[0] + 1 : i[1] ]
tbname = line[ i[1] + 1 : i[2] ]
final.append({node:tbname})
counter += 1
print(json.dumps(final))
f = open("/home/unipi/flowserver/databases/nodes_original/nodes_original.table", "w")
f.write(json.dumps(final))
f.close()
#
# # ``d`` has to be replaced with a different character
# old_character = "'"
#
# # ``t`` will replace ``d`
# new_character = '"'
# resultant_string = 0;
# with open("/home/unipi/flowserver/databases/nodes_original/nodes_original.table", 'r') as file:
# for line in file:
# resultant_string = re.sub("'", '"', line)
#
# resultant_string = re.sub(" ", "", resultant_string)
# print(resultant_string)
#
# f = open("/home/unipi/flowserver/databases/nodes_original/nodes_original.table", "w")
# f.write(str(resultant_string))
# f.close()
#

View file

@ -0,0 +1 @@
[{"3815": "B5EoxeMVp4zwr8nqW0GjjoARjvD1PNamOGbLg63Z"}, {"3799": "roKgWqY95V3mXMRzyAjmmj7bLjexpJPvaGDBw826"}]

View file

@ -34,4 +34,5 @@ key:string|weight:string|sk:string|en:string
+|twilight_sensor_ok|NOTICE|Sensor súmraku znovu odpovedá|Twilight sensor is responding again|............... +|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_on|NOTICE|Lampy sa zapli|Lamps have turned on|...............
+|lamps_have_turned_off|NOTICE|Lampy sa vypli|Lamps have turned off|............... +|lamps_have_turned_off|NOTICE|Lampy sa vypli|Lamps have turned off|...............
+|flow_restart|NOTICE|Restart flowu|Flow has been restarted|............... +|flow_restart|NOTICE|Restart flowu|Flow has been restarted|...............
+|nodes_db_changed|NOTICE|Zmena v node databaze|Node db has changed|...............

View file

@ -1,5 +1,5 @@
line:number|tbname:string|contactor:number|profile:string line:number|tbname:string|contactor:number|profile:string
+|0|6lQGaY9RDywdVzObj0PadOkPg4NBn3exEK51LWZq|1||........... +|0|6lQGaY9RDywdVzObj0PadOkPg4NBn3exEK51LWZq|1||...........
+|1|JzwxZXOvDj1bVrN4nkWw9Qk8qdyBl3MRKLpGPgaQ|1|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|........... +|1|JzwxZXOvDj1bVrN4nkWw9Qk8qdyBl3MRKLpGPgaQ|9|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|...........
+|2|g9OxBZ5KRwNznlY6pAp6mxkWXvjdEL4eGQobMDy2|1|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|........... +|2|g9OxBZ5KRwNznlY6pAp6mxkWXvjdEL4eGQobMDy2|9|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|...........
+|3|OzNMgZ9n43qPbjXmy7zWMJA2DKdYvW5e6pxGRrVa|1|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|........... +|3|OzNMgZ9n43qPbjXmy7zWMJA2DKdYvW5e6pxGRrVa|9|{"intervals":[{"value":0,"end_time":"20:00","start_time":"13:00"},{"value":1,"end_time":"08:00","start_time":"20:00"},{"value":0,"end_time":"13:00","start_time":"08:00"}],"astro_clock":true,"dawn_lux_sensor":true,"dusk_lux_sensor":true,"dawn_lux_sensor_value":15,"dusk_lux_sensor_value":15,"dawn_astro_clock_offset":0,"dusk_astro_clock_offset":0,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|...........

View file

@ -1,2 +0,0 @@
thermometer:string|em:string|twilight_sensor:string
+|OK|OK|OK|.............

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,6 @@ exports.install = async function(instance) {
const dbNodes = TABLE("nodes"); const dbNodes = TABLE("nodes");
const dbRelays = TABLE("relays"); const dbRelays = TABLE("relays");
const dbSettings = TABLE("settings"); const dbSettings = TABLE("settings");
const dbStatus = TABLE("status");
const dbPins = TABLE("pins"); const dbPins = TABLE("pins");
const dbNotifications = TABLE("notifications"); const dbNotifications = TABLE("notifications");
@ -50,14 +49,12 @@ exports.install = async function(instance) {
const responseSettings = await promisifyBuilder(dbSettings.find()); const responseSettings = await promisifyBuilder(dbSettings.find());
const responseNodes = await promisifyBuilder(dbNodes.find()); const responseNodes = await promisifyBuilder(dbNodes.find());
const responsePins = await promisifyBuilder(dbPins.find()); const responsePins = await promisifyBuilder(dbPins.find());
const responseStatus = await promisifyBuilder(dbStatus.find());
const responseRelays = await promisifyBuilder(dbRelays.find()); const responseRelays = await promisifyBuilder(dbRelays.find());
const response = await promisifyBuilder(dbNotifications.find()); const response = await promisifyBuilder(dbNotifications.find());
dbs.pinsData = makeMapFromDbResult(responsePins, "pin"); dbs.pinsData = makeMapFromDbResult(responsePins, "pin");
dbs.relaysData = makeMapFromDbResult(responseRelays, "line"); dbs.relaysData = makeMapFromDbResult(responseRelays, "line");
dbs.nodesData = makeMapFromDbResult(responseNodes, "node"); dbs.nodesData = makeMapFromDbResult(responseNodes, "node");
dbs.statusData = responseStatus[0];
dbs.notificationsData = makeMapFromDbResult(response, "key"); dbs.notificationsData = makeMapFromDbResult(response, "key");
//+|354|nodesdata.....+|482|nodesdata.... //+|354|nodesdata.....+|482|nodesdata....

View file

@ -140,8 +140,8 @@
"component": "debug", "component": "debug",
"tab": "1612772287426", "tab": "1612772287426",
"name": "to TB", "name": "to TB",
"x": 323.75, "x": 312.75,
"y": 429, "y": 426,
"connections": {}, "connections": {},
"disabledio": { "disabledio": {
"input": [ "input": [
@ -270,9 +270,7 @@
"y": 557.3500061035156, "y": 557.3500061035156,
"connections": {}, "connections": {},
"disabledio": { "disabledio": {
"input": [ "input": [],
0
],
"output": [] "output": []
}, },
"state": { "state": {
@ -291,14 +289,12 @@
"id": "1615809128443", "id": "1615809128443",
"component": "debug", "component": "debug",
"tab": "1611921777196", "tab": "1611921777196",
"name": "Debug", "name": "tempToTb",
"x": 598.8833312988281, "x": 598.8833312988281,
"y": 654.3500061035156, "y": 654.3500061035156,
"connections": {}, "connections": {},
"disabledio": { "disabledio": {
"input": [ "input": [],
0
],
"output": [] "output": []
}, },
"state": { "state": {
@ -1142,7 +1138,7 @@
"output": [] "output": []
}, },
"state": { "state": {
"text": "847.42 MB / 985.68 MB", "text": "846.37 MB / 985.68 MB",
"color": "gray" "color": "gray"
}, },
"options": { "options": {
@ -1172,7 +1168,7 @@
"output": [] "output": []
}, },
"state": { "state": {
"text": "5.79 GB / 7.26 GB", "text": "5.77 GB / 7.26 GB",
"color": "gray" "color": "gray"
}, },
"options": { "options": {
@ -1628,7 +1624,7 @@
"output": [] "output": []
}, },
"state": { "state": {
"text": "1.3% / 74.34 MB", "text": "6.2% / 70.96 MB",
"color": "gray" "color": "gray"
}, },
"options": { "options": {
@ -1960,6 +1956,10 @@
{ {
"index": "0", "index": "0",
"id": "1621340721628" "id": "1621340721628"
},
{
"index": "0",
"id": "1732889185927"
} }
] ]
}, },
@ -2141,9 +2141,9 @@
"options": { "options": {
"slack_channel": "C071KN2Q8SK", "slack_channel": "C071KN2Q8SK",
"tag_on_include": "[{\"user_id\":\"U072JE5JUQG\", \"includes\":[\"Electrometer\", \"Twilight sensor\"]}]", "tag_on_include": "[{\"user_id\":\"U072JE5JUQG\", \"includes\":[\"Electrometer\", \"Twilight sensor\"]}]",
"message_includes": "[\"is responding again\", \"Lamps have turned\", \"Flow has been restarted\"]", "message_includes": "[\"is responding again\", \"Lamps have turned\", \"Flow has been restarted\", \"Node db has changed\"]",
"types": "[\"emergency\", \"critical\", \"error\", \"alert\"]", "types": "[\"emergency\", \"critical\", \"error\", \"alert\"]",
"name": "rvo_senica_1_10.0.0.141" "name": "rvo_senica_46_10.0.0.133"
}, },
"color": "#30E193", "color": "#30E193",
"notes": "" "notes": ""
@ -2342,7 +2342,7 @@
"clientid": "", "clientid": "",
"port": "2764", "port": "2764",
"host": "192.168.252.2", "host": "192.168.252.2",
"topic": "u118" "topic": "u133"
}, },
"color": "#888600", "color": "#888600",
"notes": "" "notes": ""
@ -2780,7 +2780,137 @@
"options": {}, "options": {},
"color": "#F6BB42", "color": "#F6BB42",
"notes": "" "notes": ""
},
{
"id": "1732700042559",
"component": "nodesdb_change_check",
"tab": "1612772287426",
"name": "Nodes DB change check",
"x": 250.88333129882812,
"y": 1813.2333984375,
"connections": {
"0": [
{
"index": "0",
"id": "1732700071298"
},
{
"index": "0",
"id": "1732700642917"
}
]
},
"disabledio": {
"input": [],
"output": []
},
"state": {
"text": "",
"color": "gray"
},
"options": {},
"color": "#888600",
"notes": ""
},
{
"id": "1732700057052",
"component": "virtualwirein",
"tab": "1612772287426",
"name": "db-init",
"x": 71.75,
"y": 1814,
"connections": {
"0": [
{
"index": "0",
"id": "1732700042559"
}
]
},
"disabledio": {
"input": [],
"output": []
},
"state": {
"text": "db-init",
"color": "gray"
},
"options": {
"wirename": "db-init"
},
"color": "#303E4D",
"notes": ""
},
{
"id": "1732700071298",
"component": "debug",
"tab": "1612772287426",
"name": "nodesChange",
"x": 548.8833312988281,
"y": 1875.2333984375,
"connections": {},
"disabledio": {
"input": [],
"output": []
},
"state": {
"text": "Enabled",
"color": "gray"
},
"options": {
"type": "data",
"repository": false,
"enabled": true
},
"color": "#967ADC",
"notes": ""
},
{
"id": "1732700642917",
"component": "virtualwireout",
"tab": "1612772287426",
"name": "tb-push",
"x": 544.8833312988281,
"y": 1769,
"connections": {},
"disabledio": {
"input": [],
"output": []
},
"state": {
"text": "tb-push",
"color": "gray"
},
"options": {
"wirename": "tb-push"
},
"color": "#303E4D",
"notes": ""
},
{
"id": "1732889185927",
"component": "debug",
"tab": "1611921777196",
"name": "tempToDido",
"x": 594.8833312988281,
"y": 745,
"connections": {},
"disabledio": {
"input": [],
"output": []
},
"state": {
"text": "Enabled",
"color": "gray"
},
"options": {
"type": "data",
"repository": false,
"enabled": true
},
"color": "#967ADC",
"notes": ""
} }
], ],
"version": 615 "version": 615
} }

View file

@ -56,7 +56,6 @@ state_of_contactor - podľa indexu stykača sa reportuje jeho stav, teda
momentálne sa stav zmení len keď vo flow klikneš aby sa zmenil, ale zmena by sa mala ukázať aj na platforme momentálne sa stav zmení len keď vo flow klikneš aby sa zmenil, ale zmena by sa mala ukázať aj na platforme
*/ */
const dbStatus = TABLE("status");
const { errLogger, logger, monitor } = require('./helper/logger'); const { errLogger, logger, monitor } = require('./helper/logger');
const SerialPort = require('serialport'); const SerialPort = require('serialport');
const WebSocket = require('ws'); const WebSocket = require('ws');
@ -90,9 +89,6 @@ const SEND_TO = {
cmd_manager: 2 cmd_manager: 2
} }
const TIME_AFTER_TEMPERATURE_NOK_STATUS = 3600; //seconds
const DIFFERENCE_TO_SEND_TEMPERATURE = 0.31;
exports.install = function(instance) { exports.install = function(instance) {
@ -108,8 +104,7 @@ exports.install = function(instance) {
//process.exit(1); //process.exit(1);
}) })
// temperature value is initialized to -1000. It can be literally anything, we just needs to be able to enter if block in ws.onmessage function, when first temperatere data comes let previousValues = {};
let previousValues = {temperature: {value: -1000, lastTimeTemperatureReceived: Date.now() / 1000}};
let rsPortReceivedData = []; let rsPortReceivedData = [];
//to be able to get proper twilight values, when //to be able to get proper twilight values, when
@ -163,15 +158,12 @@ exports.install = function(instance) {
rvoTbName = SETTINGS.rvoTbName; rvoTbName = SETTINGS.rvoTbName;
pinsData = GLOBALS.pinsData; pinsData = GLOBALS.pinsData;
relaysData = GLOBALS.relaysData; relaysData = GLOBALS.relaysData;
statusData = GLOBALS.statusData;
tbHandler = new DataToTbHandler(SEND_TO.tb) tbHandler = new DataToTbHandler(SEND_TO.tb)
tbHandler.setSender(exports.title); tbHandler.setSender(exports.title);
controller_type = SETTINGS.controller_type //"lm" or "unipi" //logicMachine controller_type = SETTINGS.controller_type //"lm" or "unipi" //logicMachine
if(controller_type == "") controller_type = "lm"; if(controller_type == "") controller_type = "lm";
deviceStatus["temperature"] = statusData.thermometer;
console.log(exports.title, "controller type: ", controller_type); console.log(exports.title, "controller type: ", controller_type);
@ -379,39 +371,19 @@ exports.install = function(instance) {
data = JSON.parse(data.data); data = JSON.parse(data.data);
// data comes in array except of "temperature" ==> it comes as an object // data comes in array except of "temperature" ==> it comes as an object
if(isObject(data)) // we do not handle temperature from evok any more => we return, if temperature comes:
{ if(isObject(data)) return;
let value = data['value'];
const values = {};
previousValues["temperature"]["lastTimeTemperatureReceived"] = data['time'];
// we received data from thermometer, but thermometer status is NOK:
if(deviceStatus["temperature"] === "NOK")
{
await writeThermometerStatusToDb("OK");
sendRvoStatus();
}
// temperature value comes very often. To handle it, we check if it change for more than 0.3 degrees, if yes, we send to TB
if(Math.abs(previousValues["temperature"]["value"] - value) > DIFFERENCE_TO_SEND_TEMPERATURE)
{
previousValues["temperature"]["value"] = value;
values['temperature'] = value;
sendTelemetry(values, rvoTbName);
}
return;
}
data.map(item => { data.map(item => {
let value = item['value']; let value = item['value'];
let pin = item["dev"] + item["circuit"]; // for example "relay1_03" or "input1_01" let pin = item["dev"] + item["circuit"]; // for example "relay1_03" or "input1_01"
if(pin == undefined) return; if(pin == undefined) return;
switchLogic(pin, value); switchLogic(pin, value);
}) })
} }
ws.on('error', (err) => { ws.on('error', (err) => {
monitor.info('websocket error, reconnect') monitor.info('websocket error, reconnect')
@ -464,19 +436,19 @@ exports.install = function(instance) {
{ {
let value = 0; 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"; alarmStatus = "OFF";
if(value == 1) alarmStatus = "ON"; if(value == 1) alarmStatus = "ON";
if(rsPort) if(rsPort)
{ {
let arr = [0x55]; let arr = [0x55];
arr.push(13); arr.push(13);
arr.push(0); arr.push(0);
arr.push(value); arr.push(value);
rsPort.write(Buffer.from(arr), function(err) { rsPort.write(Buffer.from(arr), function(err) {
logger.debug(`sirena - ${onOrOff}`); logger.debug(`sirena - ${onOrOff}`);
}); });
@ -605,7 +577,7 @@ exports.install = function(instance) {
//data from modbus_reader or temperature sensor or twilight sensor or other modbus device //data from modbus_reader or temperature sensor or twilight sensor or other modbus device
instance.on("0", flowdata => { instance.on("0", flowdata => {
if(!flowdata.data instanceof Object) return; if(!isObject(flowdata.data)) return;
// console.log('***********************', flowdata.data) // console.log('***********************', flowdata.data)
instance.send(SEND_TO.debug, flowdata.data); instance.send(SEND_TO.debug, flowdata.data);
@ -622,10 +594,8 @@ exports.install = function(instance) {
{ {
deviceStatus["em"] = "NOK"; deviceStatus["em"] = "NOK";
} }
//"NOK-thermometer" comes just from LM. Unipi handles thermometer from ws evok.
else if(status == "NOK-thermometer") else if(status == "NOK-thermometer")
{ {
previousValues["temperature"]["lastTimeTemperatureReceived"] = null;
deviceStatus["temperature"] = "NOK"; deviceStatus["temperature"] = "NOK";
} }
} }
@ -637,10 +607,8 @@ exports.install = function(instance) {
instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: values["twilight_sensor"]}); instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "lux_sensor", value: values["twilight_sensor"]});
deviceStatus["twilight_sensor"] = "OK" deviceStatus["twilight_sensor"] = "OK"
} }
//"temperature" comes just from LM. Unipi handles thermometer from ws evok.
else if(values.hasOwnProperty("temperature")) else if(values.hasOwnProperty("temperature"))
{ {
previousValues["temperature"]["lastTimeTemperatureReceived"] = Date.now() / 1000; //time in seconds
deviceStatus["temperature"] = "OK"; deviceStatus["temperature"] = "OK";
} }
// EM // EM
@ -669,8 +637,8 @@ exports.install = function(instance) {
let force = obj.force; let force = obj.force;
let info = obj.info; let info = obj.info;
if(obj.command == "turnOn") turnLine("on", line, undefined, force, info); if(obj.command == "on") turnLine("on", line, undefined, force, info);
else if(obj.command == "turnOff") turnLine("off", 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 == "turnOnAlarm") turnAlarm("on");
else if(obj.command == "turnOffAlarm") turnAlarm("off"); else if(obj.command == "turnOffAlarm") turnAlarm("off");
@ -822,15 +790,13 @@ exports.install = function(instance) {
let byte = bytesToInt([byte1, byte0]); let byte = bytesToInt([byte1, byte0]);
//console.log("calculateStateCode -------------------", byte); //console.log("calculateStateCode -------------------", byte);
return byte; return byte;
} }
async function sendRvoStatus() { async function sendRvoStatus() {
// test if dbLoaded is ok to check
//if(!FLOW.dbLoaded) return;
if(SETTINGS === undefined) return; if(SETTINGS === undefined) return;
const table = { const table = {
@ -849,21 +815,11 @@ exports.install = function(instance) {
}; };
for (const phase of SETTINGS.no_voltage) dataToTb[`phase_${phase}_status`] = 0; for (const phase of SETTINGS.no_voltage) dataToTb[`phase_${phase}_status`] = 0;
//thermometer did not send data for more than a hour. Time in seconds
if(deviceStatus["temperature"] === "OK")
{
if(previousValues["temperature"]["lastTimeTemperatureReceived"] + TIME_AFTER_TEMPERATURE_NOK_STATUS < Date.now() / 1000)
{
// to be able to calculate proper RVO status, we need to await writeThermometerStatusToDb function
await writeThermometerStatusToDb("NOK");
dataToTb["thermometer_status"] = 0;
}
}
dataToTb["status"] = checkRvoStatus(); dataToTb["status"] = checkRvoStatus();
dataToTb["statecode"] = calculateStateCode(); dataToTb["statecode"] = calculateStateCode();
//console.log(dataToTb);
sendTelemetry(dataToTb, rvoTbName); sendTelemetry(dataToTb, rvoTbName);
} }
@ -876,8 +832,7 @@ exports.install = function(instance) {
let status = "OK"; let status = "OK";
for (const [key, value] of Object.entries(deviceStatus)) { 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(["em", "twilight_sensor"].includes(key) && value == "NOK") status = "NOK";
} }
if(status == "OK") if(status == "OK")
@ -899,6 +854,7 @@ exports.install = function(instance) {
if(!SETTINGS.masterNodeIsResponding) status = "NOK"; if(!SETTINGS.masterNodeIsResponding) status = "NOK";
if(SETTINGS.no_voltage.size > 0) status = "NOK"; if(SETTINGS.no_voltage.size > 0) status = "NOK";
// console.log("rvo status",status)
return status; return status;
} }
@ -1258,7 +1214,6 @@ exports.install = function(instance) {
} }
if(newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue; if(newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue;
if(rvoTbName == tbname) sendRvoStatus();
if(Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname); if(Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname);
} }
@ -1277,24 +1232,6 @@ exports.install = function(instance) {
} }
function writeThermometerStatusToDb(status) {
return new Promise(function(resolve, reject) {
dbStatus.modify({ thermometer: status }).make(function(builder) {
builder.callback(function(err, response) {
if(!err)
{
deviceStatus["temperature"] = status;
console.log(`Wrote to db status: thermometer ${status}`);
resolve("ok")
}
reject("nok")
});
});
})
}
function isObject (item) { function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null); return (typeof item === "object" && !Array.isArray(item) && item !== null);
} }

View file

@ -0,0 +1,70 @@
exports.id = 'nodesdb_change_check';
exports.title = 'Nodes DB change check';
exports.group = 'Worksys';
exports.color = '#888600';
exports.version = '1.0.2';
exports.icon = 'sign-out';
exports.input = 1;
exports.output = 1;
exports.readme = `Check, if nodes.table db changed compared to original database`;
const fs = require('fs');
const path = require('path');
const { sendNotification } = require('./helper/notification_reporter');
const nodesOriginalFile = path.join(__dirname, '../databases/nodes_original/', 'nodes_original.table');
exports.install = function(instance) {
function compareArrays(array1, array2) {
let message = "";
let areEqual = true;
let zmenene = []
if (array1.length !== array2.length) {
message += "Nezhoda v pocte nodov. "
}
const set1 = new Set(array1.map(obj => JSON.stringify(obj)));
const set2 = new Set(array2.map(obj => JSON.stringify(obj)));
for (const objStr of set1) {
if (!set2.has(objStr)) {
zmenene.push(objStr)
areEqual = false;
} else {
set2.delete(objStr);
}
}
if(!areEqual) {
message += `Aktualne nody: ${zmenene.toString()}. Zmenene proti originalu: ${Array.from(set2).join(' ')}`;
sendNotification("Nodesdb_changecheck", FLOW.GLOBALS.settings.rvoTbName, "nodes_db_changed", "", message, 0, instance);
}
else console.log("Arrays are equal.");
console.log(message)
}
instance.on("data", _ => {
let nodesData = FLOW.GLOBALS.nodesData;
// we check if nodes.table has changed compared to nodes_original.table (we have array of nodes e.g. [{node:255, tbname: "agruhuwhgursuhgo34hgsdiguhrr"}]
const nodes_actual = Object.keys(nodesData).map(node => ({[node]: nodesData[node].tbname}))
let nodes_original = fs.readFileSync(nodesOriginalFile, { encoding: 'utf8', flag: 'r' });
try {
nodes_original = JSON.parse(nodes_original);
} catch(e) {
console.log(e)
}
setTimeout(() => compareArrays(nodes_actual, nodes_original),10000);
})
}

View file

@ -1,122 +1,98 @@
exports.id = 'thermometer'; exports.id = 'thermometer';
exports.title = 'Thermometer'; exports.title = 'Thermometer';
exports.group = 'Worksys'; exports.group = 'Worksys';
exports.color = '#5CB36D'; exports.color = '#5CB36D';
exports.input = 1; exports.input = 1;
exports.version = '1.0.3'; exports.version = '1.0.3';
exports.output = ["red", "white", "blue"]; exports.output = ["red", "white", "blue"];
exports.author = 'Rastislav Kovac'; exports.icon = 'thermometer-three-quarters';
exports.icon = 'thermometer-three-quarters';
exports.readme = `# Getting temperature values for RVO. In case of LM, you need device address. In case of unipi, evok sends values, in case thermometer is installed`;
exports.readme = `# Getting temperature values for RVO. In case of LM, you need device address. In case of unipi, evok sends values, in case thermometer is installed`;
const { errLogger, logger, monitor } = require('./helper/logger');
const { errLogger, logger, monitor } = require('./helper/logger');
const SEND_TO = {
const SEND_TO = { debug: 0,
debug: 0, tb: 1,
tb: 1, dido_controller: 2
dido_controller: 2 }
}
//read temperature - frequency
//read temperature - frequency let timeoutMin = 5;//minutes
let timeoutMin = 5;//minutes let NUMBER_OF_FAILURES_TO_SEND_ERROR = 13;
exports.install = function(instance) {
exports.install = function(instance) {
const { exec } = require('child_process');
const { exec } = require('child_process'); const { sendNotification } = require('./helper/notification_reporter');
const { sendNotification } = require('./helper/notification_reporter');
let startRead;
let startRead; let counter = 0;
let counter = 0; let rvoTbName = "";
let rvoTbName = ""; let temperatureAddress = "";
let temperatureAddress = "";
logger.debug(exports.title, "installed");
logger.debug(exports.title, "installed");
instance.on("close", function(){
instance.on("close", function(){ clearInterval(startRead);
clearInterval(startRead); })
})
const main = function() {
const main = function() {
try {
try {
if(temperatureAddress === "") throw "Thermometer: temperatureAddress is not defined";
if(FLOW.GLOBALS.settings.controller_type === "unipi")
{ exec(`owread -C ${temperatureAddress}/temperature`, (error, stdout, stderr) => {
clearInterval(startRead);
return; if(!error)
} {
parseData(stdout)
if(temperatureAddress === "") throw "gettemperature: temperatureAddress is not defined"; return;
}
exec(`owread -C ${temperatureAddress}/temperature`, (error, stdout, stderr) => {
counter++;
if(!error) if(counter == NUMBER_OF_FAILURES_TO_SEND_ERROR) sendNotification("Thermometer_main", rvoTbName, "thermometer_is_not_responding", {}, {"Error": error}, SEND_TO.tb, instance, "thermometer");
{ monitor.info("Thermometer is not responding", error);
parseData(stdout) instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"});
return; });
}
}
sendNotification("main", rvoTbName, "thermometer_is_not_responding", {}, {"Error": error}, SEND_TO.tb, instance, "thermometer"); catch(err) {
monitor.info("Thermometer is not responding", error); errLogger.error(exports.title, err);
instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"}); clearInterval(startRead);
}); }
}
}
catch(err) { const parseData = function(data) {
errLogger.error(exports.title, err);
clearInterval(startRead); data = parseFloat(data);
} logger.debug("Thermometer", data);
}
if(isNaN(data)) {
const parseData = function(data) { errLogger.error("Thermometer sends invalid data");
return;
data = parseFloat(data); }
logger.debug("gettemperature", data); if(counter > NUMBER_OF_FAILURES_TO_SEND_ERROR) //1 hour
{
if(!isNaN(data)) { instance.send(SEND_TO.debug, "Thermometer - temperature data are comming again");
sendNotification("Thermometer_parseData", rvoTbName, "thermometer_is_responding_again", {}, "", SEND_TO.tb, instance, "thermometer");
if(counter > 290) }
{
instance.send(SEND_TO.debug, "[Get temperature component] - temperature data are comming again from RVO after more than 1 day break"); const values = {
sendNotification("parseData", rvoTbName, "thermometer_is_responding_again", {}, "", SEND_TO.tb, instance, "thermometer"); "temperature": Number(data.toFixed(2)),
} }
logger.debug("gettemperature", data); instance.send(SEND_TO.dido_controller, {values: values});
counter = 0;
const values = { }
"temperature": Number(data.toFixed(2)),
} instance.on("data", _ => {
temperatureAddress = FLOW.GLOBALS.settings.temperature_address;
instance.send(SEND_TO.dido_controller, {values: values}); rvoTbName = FLOW.GLOBALS.settings.rvoTbName;
counter = 0; startRead = setInterval(main, timeoutMin * 1000 * 60);
setTimeout(main, 20000);
} else { })
};
counter++;
monitor.info("gettemperature err", counter, data);
//ked je problem 1 den
let day = 24 * 60 / timeoutMin;
if ( counter > day && counter < day + 2 ) {
//sendNotification("parseData", rvoTbName, ERRWEIGHT.WARNING, "Thermometer receives invalid data", "", SEND_TO.tb, instance, "thermometer");
sendNotification("parseData", rvoTbName, "thermometer_sends_invalid_data", {}, "", SEND_TO.tb, instance, "thermometer");
instance.send(SEND_TO.debug, "[Get temperature component] - no temperature data from RVO for more than 1 day");
instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"});
}
}
}
instance.on("data", _ => {
temperatureAddress = FLOW.GLOBALS.settings.temperature_address;
rvoTbName = FLOW.GLOBALS.settings.rvoTbName;
startRead = setInterval(main, timeoutMin * 1000 * 60);
main();
})
};