Send to rado platform; show_dbdata, db loads after start
This commit is contained in:
parent
ed0fe5b15d
commit
f63ac50497
22 changed files with 6380 additions and 2279 deletions
|
|
@ -20,9 +20,9 @@ key:string|weight:string|sk:string|en:string
|
||||||
+|power_supply_works_correctly|NOTICE|Napájací zdroj pracuje správne|Power supply works correctly|...............
|
+|power_supply_works_correctly|NOTICE|Napájací zdroj pracuje správne|Power supply works correctly|...............
|
||||||
+|battery_level_is_low|ERROR|Batéria má nízku úroveň napätia|Battery level is low|...............
|
+|battery_level_is_low|ERROR|Batéria má nízku úroveň napätia|Battery level is low|...............
|
||||||
+|battery_level_is_ok|NOTICE|Batéria má správnu úroveň napätia|Battery level is OK|...............
|
+|battery_level_is_ok|NOTICE|Batéria má správnu úroveň napätia|Battery level is OK|...............
|
||||||
+|door_has_been_open|NOTICE|Dvere boli otvorené|Door has been open|...............
|
+|door_opened|NOTICE|Dvere boli otvorené|Door has been opeed|...............
|
||||||
+|door_has_been_closed|NOTICE|Dvere boli zatvorené|Door has been closed|...............
|
+|door_closed|NOTICE|Dvere boli zatvorené|Door has been closed|...............
|
||||||
+|door_has_been_open_without_permision_alarm_is_on|WARNING|Dvere boli otvorené bez povolania - zapnutá siréna|Door has been open without permision - alarm is on|...............
|
+|door_opened_without_permission|WARNING|Dvere boli otvorené bez povoeania - zapnutá siréna|Door has been oed without permision - alarm is on|...............
|
||||||
+|state_of_contactor_for_line|INFORMATIONAL|Stav stýkača pre líniu č. ${line} je ${value}|State of contactor for line no. ${line} is ${value}|...............
|
+|state_of_contactor_for_line|INFORMATIONAL|Stav stýkača pre líniu č. ${line} je ${value}|State of contactor for line no. ${line} is ${value}|...............
|
||||||
+|local_database_is_corrupted|CRITICAL|||...............
|
+|local_database_is_corrupted|CRITICAL|||...............
|
||||||
+|electrometer_nok|ERROR|Elektromer neodpovedá|Electrometer is not responding|...............
|
+|electrometer_nok|ERROR|Elektromer neodpovedá|Electrometer is not responding|...............
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
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
|
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|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
|
||||||
+|rvo_senica_39_10.0.0.132|en|28.427B45920702|48.70826502|17.28455203|192.168.252.1|rvo_senica_39_10.0.0.132|qzSNuCNrLP4OL1v47YEe|1883|0|68|unipi|ttyUSB0|1|20|5|...........................................
|
+|rvo_senica_42_10.0.0.118|en|28.427B45920702|48.70826502|17.28455203|192.168.252.1|rvo_senica_42_10.0.0.118|QMvF7etEvbYMMr8Q6baP|1883|0|59|unipi|ttyUSB0|1|20|5|6|3|..............
|
||||||
|
|
|
||||||
0
databases/tbdatacloud.nosql
Normal file
0
databases/tbdatacloud.nosql
Normal file
404
flow/cloudmqttconnect.js
Normal file
404
flow/cloudmqttconnect.js
Normal file
|
|
@ -0,0 +1,404 @@
|
||||||
|
exports.id = 'cloudmqttconnect';
|
||||||
|
exports.title = 'Cloud connect mqtt';
|
||||||
|
exports.group = 'MQTT';
|
||||||
|
exports.color = '#888600';
|
||||||
|
exports.version = '1.0.2';
|
||||||
|
exports.icon = 'sign-out';
|
||||||
|
exports.input = 1;
|
||||||
|
exports.output = 2;
|
||||||
|
exports.options = { host: 'tb-stage.worksys.io', port: 1883, clientid: "", username: "" };
|
||||||
|
|
||||||
|
exports.html = `<div class="padding">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="host" data-jc-config="placeholder:test.mosquitto.org;required:false" class="m">Hostname or IP address (if not empty - setting will override db setting)</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="port" data-jc-config="placeholder:1883;required:true" class="m">Port</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="clientid">@(Client id)</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="topic" data-jc-config="required:true" class="m">topic</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const { promisifyBuilder } = require('./helper/db_helper');
|
||||||
|
const fs = require('fs');
|
||||||
|
const mqtt = require('mqtt');
|
||||||
|
|
||||||
|
const SEND_TO = {
|
||||||
|
debug: 0,
|
||||||
|
rpcCall: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONFIG
|
||||||
|
let saveTelemetryOnError = true;//backup_on_failure overrides this value
|
||||||
|
//------------------------
|
||||||
|
|
||||||
|
const noSqlFileSizeLimit = 4194304;//use 5MB - 4194304
|
||||||
|
let insertNoSqlCounter = 0;
|
||||||
|
let insertBackupNoSqlCounter = 0;
|
||||||
|
let processingData = false;
|
||||||
|
|
||||||
|
let backup_on_failure = true;//== saveTelemetryOnError - create backup client send failure
|
||||||
|
let restore_from_backup = 50; //how many rows process at once?
|
||||||
|
let restore_backup_wait = 3;//wait seconds
|
||||||
|
let lastRestoreTime = 0;
|
||||||
|
|
||||||
|
// if there is an error in client connection, flow logs to monitor.txt. Not to log messages every second, we use sendClientError variable
|
||||||
|
let sendClientError = true;
|
||||||
|
|
||||||
|
|
||||||
|
const nosql = NOSQL('tbdatacloud');
|
||||||
|
|
||||||
|
|
||||||
|
exports.install = function(instance) {
|
||||||
|
|
||||||
|
var client;
|
||||||
|
var opts;
|
||||||
|
var clientReady = false;
|
||||||
|
|
||||||
|
let o = null; //options
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
//set opts according to db settings
|
||||||
|
function loadSettings()
|
||||||
|
{
|
||||||
|
|
||||||
|
o = instance.options;
|
||||||
|
opts = {
|
||||||
|
host: o.host,
|
||||||
|
port: o.port,
|
||||||
|
clientId: o.clientid,
|
||||||
|
username: o.username,
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
resubscribe: false
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
console.log("wsmqttpublich -> loadSettings from instance.options", instance.options);
|
||||||
|
|
||||||
|
connectToTbServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectToTbServer()
|
||||||
|
{
|
||||||
|
var url = "mqtt://" + opts.host + ":" + opts.port;
|
||||||
|
console.log("MQTT URL: ", url);
|
||||||
|
|
||||||
|
client = mqtt.connect(url, opts);
|
||||||
|
|
||||||
|
client.on('connect', function() {
|
||||||
|
client.subscribe(`${o.topic}_backward`, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
console.log("MQTT subscribed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
instance.status("Connected", "green");
|
||||||
|
clientReady = true;
|
||||||
|
sendClientError = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('reconnect', function() {
|
||||||
|
client.subscribe(`${o.topic}_backward`, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
console.log("MQTT subscribed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
instance.status("Reconnecting", "yellow");
|
||||||
|
clientReady = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('message', function(topic, message) {
|
||||||
|
// message is type of buffer
|
||||||
|
message = message.toString();
|
||||||
|
if (message[0] === '{') {
|
||||||
|
TRY(function() {
|
||||||
|
|
||||||
|
message = JSON.parse(message);
|
||||||
|
if (message.hasOwnProperty("device") && message.hasOwnProperty("data") && message.data.hasOwnProperty("id")) {
|
||||||
|
client.publish(`${o.topic}_forward`, `{"device": "${message.device}", "id": ${message.data.id}, "data": {"success": true}}`, {qos:1});
|
||||||
|
instance.send(SEND_TO.rpcCall, {"device": message.device, "id": message.data.id, "RPC response": {"success": true}});
|
||||||
|
}
|
||||||
|
|
||||||
|
}, () => instance.debug('MQTT: Error parsing data', message));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.send(SEND_TO.rpcCall, {"topic":o.topic, "content":message });
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('close', function(err) {
|
||||||
|
clientReady = false;
|
||||||
|
|
||||||
|
if (err && err.toString().indexOf('Error')) {
|
||||||
|
instance.status("Err: "+err.code, "red");
|
||||||
|
instance.send(SEND_TO.debug, {"message":"Client CLOSE signal received !", "error":err, "opt":opts });
|
||||||
|
} else {
|
||||||
|
instance.status("Disconnected", "red");
|
||||||
|
instance.send(SEND_TO.debug, {"message":"Client CLOSE signal received !", "error":err, "opt":opts });
|
||||||
|
}
|
||||||
|
|
||||||
|
client.reconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on('error', function(err) {
|
||||||
|
instance.status("Err: "+ err.code, "red");
|
||||||
|
instance.send(SEND_TO.debug, {"message":"Client ERROR signal received !", "error":err, "opt":opts });
|
||||||
|
if(sendClientError) {
|
||||||
|
console.log('MQTT client error', err);
|
||||||
|
sendClientError = false;
|
||||||
|
}
|
||||||
|
clientReady = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
instance.on('0', function(data) {
|
||||||
|
|
||||||
|
if(clientReady)
|
||||||
|
{
|
||||||
|
//do we have some data in backup file?
|
||||||
|
//if any, process data from database
|
||||||
|
if(saveTelemetryOnError)
|
||||||
|
{
|
||||||
|
//read telemetry data and send back to server
|
||||||
|
if(!processingData) processDataFromDatabase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(clientReady)
|
||||||
|
{
|
||||||
|
client.publish(`${o.topic}_forward`, data.data, {qos: 1});
|
||||||
|
//console.log("ondata..",data.data)
|
||||||
|
|
||||||
|
|
||||||
|
// Pokad ten error na 38 chápem tak tento parameter MUSÍ byt string...
|
||||||
|
// Tak to musim dekódovat na strane Cloudu zas
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
//logger.debug("Client unavailable. Data not sent !", JSON.stringify(data.data));
|
||||||
|
instance.send(SEND_TO.debug, {"message":"Client unavailable. Data not sent !", "data": data.data });
|
||||||
|
|
||||||
|
if(saveTelemetryOnError)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
let d = JSON.parse(data.data);
|
||||||
|
//create new file from tbdata.nosql, if file size exceeds given limit, and clear tbdata.nosql
|
||||||
|
makeBackupFromDbFile();
|
||||||
|
|
||||||
|
//write to tb
|
||||||
|
d.id = UID();
|
||||||
|
nosql.insert(d);
|
||||||
|
} catch(e) {
|
||||||
|
console.log("cloudconnect - unable to parse data from wsmqtt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
instance.close = function(done) {
|
||||||
|
if(clientReady){
|
||||||
|
client.end();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function getDbBackupFileCounter(type)
|
||||||
|
{
|
||||||
|
var files = fs.readdirSync(__dirname + "/../databases");
|
||||||
|
|
||||||
|
let counter = 0;
|
||||||
|
for(var i = 0; i < files.length; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(files[i] == "tbdatacloud.nosql") continue;
|
||||||
|
|
||||||
|
if(files[i].endsWith(".nosql"))
|
||||||
|
{
|
||||||
|
|
||||||
|
let pos = files[i].indexOf(".");
|
||||||
|
if(pos > -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
let fileCounter = counter;
|
||||||
|
let firstDigit = files[i].slice(0, pos);
|
||||||
|
|
||||||
|
fileCounter = parseInt(firstDigit);
|
||||||
|
if(isNaN(fileCounter)) fileCounter = 0;
|
||||||
|
//console.log("getDbBackupFileCounter digit:", files[i], firstDigit, fileCounter, isNaN(fileCounter), type);
|
||||||
|
|
||||||
|
if(type == "max")
|
||||||
|
{
|
||||||
|
if(fileCounter > counter)
|
||||||
|
{
|
||||||
|
counter = fileCounter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(type == "min")
|
||||||
|
{
|
||||||
|
if(counter == 0) counter = fileCounter;
|
||||||
|
|
||||||
|
if(fileCounter < counter)
|
||||||
|
{
|
||||||
|
counter = fileCounter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == "max") counter++;
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const makeBackupFromDbFile = async () => {
|
||||||
|
|
||||||
|
if(!saveTelemetryOnError) return;
|
||||||
|
|
||||||
|
//to avoid large file: tbdata.nosql
|
||||||
|
|
||||||
|
//init value is 0!
|
||||||
|
if(insertNoSqlCounter > 0)
|
||||||
|
{
|
||||||
|
--insertNoSqlCounter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
insertNoSqlCounter = 100;
|
||||||
|
|
||||||
|
let source = __dirname + "/../databases/tbdatacloud.nosql";
|
||||||
|
|
||||||
|
var stats = fs.statSync(source);
|
||||||
|
var fileSizeInBytes = stats.size;
|
||||||
|
|
||||||
|
if(fileSizeInBytes > noSqlFileSizeLimit)
|
||||||
|
{
|
||||||
|
|
||||||
|
let counter = 1;
|
||||||
|
counter = getDbBackupFileCounter("max");
|
||||||
|
|
||||||
|
let destination = __dirname + "/../databases/" + counter + "." + "tbdatacloud.nosql";
|
||||||
|
|
||||||
|
//make backup file
|
||||||
|
fs.copyFileSync(source, destination);
|
||||||
|
//fs.renameSync(p, p + "." + counter);
|
||||||
|
|
||||||
|
//clear tbdata.nosql
|
||||||
|
fs.writeFileSync(source, "");
|
||||||
|
fs.truncateSync(source, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const processDataFromDatabase = async () => {
|
||||||
|
|
||||||
|
if(restore_from_backup <= 0) return;
|
||||||
|
|
||||||
|
//calculate diff
|
||||||
|
const now = new Date();
|
||||||
|
let currentTime = now.getTime();
|
||||||
|
let diff = currentTime - lastRestoreTime;
|
||||||
|
|
||||||
|
if( (diff / 1000) < restore_backup_wait)
|
||||||
|
{
|
||||||
|
//console.log("*********restore_backup_wait", diff, restore_backup_wait);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processingData = true;
|
||||||
|
|
||||||
|
//get filename to process
|
||||||
|
let counter = getDbBackupFileCounter("min");
|
||||||
|
|
||||||
|
//we have some backup files
|
||||||
|
let dataBase = 'tbdata';
|
||||||
|
|
||||||
|
var nosql;
|
||||||
|
if(counter == 0) dataBase = 'tbdatacloud';
|
||||||
|
else dataBase = counter + "." + 'tbdatacloud';
|
||||||
|
|
||||||
|
nosql = NOSQL(dataBase);
|
||||||
|
|
||||||
|
//select all data - use limit restore_from_backup
|
||||||
|
let records = await promisifyBuilder(nosql.find().take(restore_from_backup));
|
||||||
|
|
||||||
|
for(let i = 0; i < records.length; i++)
|
||||||
|
{
|
||||||
|
if(clientReady) {
|
||||||
|
|
||||||
|
let item = records[i];
|
||||||
|
let id = item.id;
|
||||||
|
|
||||||
|
if(id !== undefined)
|
||||||
|
{
|
||||||
|
//console.log("------------processDataFromDatabase - remove", id, dataBase, i);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
let o = JSON.parse(JSON.stringify(item));
|
||||||
|
delete o.id;
|
||||||
|
let message = JSON.stringify(o);
|
||||||
|
|
||||||
|
client.publish(`${o.topic}_forward`, message, {qos:1});
|
||||||
|
//console.log("db...", message)
|
||||||
|
//remove from database
|
||||||
|
await promisifyBuilder(nosql.remove().where("id", id));
|
||||||
|
|
||||||
|
} catch(error) {
|
||||||
|
//process error
|
||||||
|
console.log("processDataFromDatabase", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processingData = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(records.length > 0)
|
||||||
|
{
|
||||||
|
//clean backup file
|
||||||
|
if(counter > 0) nosql.clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//no data in db, remove
|
||||||
|
if(records.length == 0)
|
||||||
|
{
|
||||||
|
if(counter > 0) nosql.drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
const d = new Date();
|
||||||
|
lastRestoreTime = d.getTime();
|
||||||
|
|
||||||
|
processingData = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.on('options', main);
|
||||||
|
main();
|
||||||
|
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load diff
3603
flow/cmd_manager131.js
Normal file
3603
flow/cmd_manager131.js
Normal file
File diff suppressed because it is too large
Load diff
108
flow/db_init.js
Normal file
108
flow/db_init.js
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
exports.id = 'db_init';
|
||||||
|
exports.title = 'DB Initialization';
|
||||||
|
exports.group = 'Worksys';
|
||||||
|
exports.color = '#888600';
|
||||||
|
exports.version = '1.0.2';
|
||||||
|
exports.icon = 'sign-out';
|
||||||
|
exports.input = 1;
|
||||||
|
exports.output = ["blue"];
|
||||||
|
|
||||||
|
exports.html = `<div class="padding">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="host" data-jc-config="placeholder:test.mosquitto.org;required:false" class="m">Hostname or IP address (if not empty - setting will override db setting)</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="port" data-jc-config="placeholder:1883;required:true" class="m">Port</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="clientid">@(Client id)</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div data-jc="textbox" data-jc-path="username" class="m">@(Username)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
|
exports.readme = `
|
||||||
|
# DB initialization
|
||||||
|
`;
|
||||||
|
|
||||||
|
const { promisifyBuilder, makeMapFromDbResult } = require('./helper/db_helper.js');
|
||||||
|
const { initNotification } = require('./helper/notification_reporter');
|
||||||
|
|
||||||
|
|
||||||
|
exports.install = async function(instance) {
|
||||||
|
|
||||||
|
const dbNodes = TABLE("nodes");
|
||||||
|
const dbRelays = TABLE("relays");
|
||||||
|
const dbSettings = TABLE("settings");
|
||||||
|
const dbStatus = TABLE("status");
|
||||||
|
const dbPins = TABLE("pins");
|
||||||
|
const dbNotifications = TABLE("notifications");
|
||||||
|
|
||||||
|
FLOW.GLOBALS = {};
|
||||||
|
const dbs = FLOW.GLOBALS;
|
||||||
|
|
||||||
|
const responseSettings = await promisifyBuilder(dbSettings.find());
|
||||||
|
const responseNodes = await promisifyBuilder(dbNodes.find());
|
||||||
|
const responsePins = await promisifyBuilder(dbPins.find());
|
||||||
|
const responseStatus = await promisifyBuilder(dbStatus.find());
|
||||||
|
const responseRelays = await promisifyBuilder(dbRelays.find());
|
||||||
|
const response = await promisifyBuilder(dbNotifications.find());
|
||||||
|
|
||||||
|
dbs.pinsData = makeMapFromDbResult(responsePins, "pin");
|
||||||
|
dbs.relaysData = makeMapFromDbResult(responseRelays, "line");
|
||||||
|
dbs.nodesData = makeMapFromDbResult(responseNodes, "node");
|
||||||
|
dbs.statusData = responseStatus[0];
|
||||||
|
dbs.notificationsData = makeMapFromDbResult(response, "key");
|
||||||
|
|
||||||
|
//+|354|nodesdata.....+|482|nodesdata....
|
||||||
|
//for some reason, if last line in nodes.table is not empty, flow wrote more nodes data in one row,
|
||||||
|
//so we have to add empty line at the bottom of nodes table to avoid this.
|
||||||
|
//now, remove empty lines from nodesData database:
|
||||||
|
if(dbs.nodesData.hasOwnProperty("0")) delete dbs.nodesData["0"];
|
||||||
|
|
||||||
|
dbs.settings = {
|
||||||
|
edge_fw_version : "2024-11-04", //rok-mesiac-den
|
||||||
|
language : responseSettings[0]["lang"],
|
||||||
|
rvo_name : responseSettings[0]["rvo_name"],
|
||||||
|
project_id : responseSettings[0]["project_id"],
|
||||||
|
rvoTbName : dbs.relaysData[0]["tbname"],
|
||||||
|
temperature_address : responseSettings[0]["temperature_address"],
|
||||||
|
controller_type : responseSettings[0]["controller_type"],
|
||||||
|
serial_port : responseSettings[0]["serial_port"],
|
||||||
|
node_status_nok_time : responseSettings[0]["node_status_nok_time"] * 60 * 60 * 1000 ,// hour * minutes *
|
||||||
|
latitude : responseSettings[0]["latitude"],
|
||||||
|
longitude : responseSettings[0]["longitude"],
|
||||||
|
no_voltage : new Set(),//modbus_citysys - elektromer
|
||||||
|
backup_on_failure : responseSettings[0]["backup_on_failure"],
|
||||||
|
restore_from_backup : responseSettings[0]["restore_from_backup"],
|
||||||
|
restore_backup_wait : responseSettings[0]["restore_backup_wait"],
|
||||||
|
mqtt_host : responseSettings[0]["mqtt_host"],
|
||||||
|
mqtt_clientid : responseSettings[0]["mqtt_clientid"],
|
||||||
|
mqtt_username : responseSettings[0]["mqtt_username"],
|
||||||
|
mqtt_port : responseSettings[0]["mqtt_port"],
|
||||||
|
phases: responseSettings[0]["phases"],
|
||||||
|
|
||||||
|
//dynamic values
|
||||||
|
masterNodeIsResponding : true, //cmd_manager
|
||||||
|
maintenance_mode : false,
|
||||||
|
}
|
||||||
|
|
||||||
|
FLOW.dbLoaded = true;
|
||||||
|
initNotification();
|
||||||
|
|
||||||
|
setTimeout(()=> {
|
||||||
|
console.log("DB_INIT - data loaded");
|
||||||
|
instance.send(0, "_")
|
||||||
|
}, 5000)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -3,8 +3,8 @@ exports.title = 'DIDO_Controller';
|
||||||
exports.version = '2.0.0';
|
exports.version = '2.0.0';
|
||||||
exports.group = 'Worksys';
|
exports.group = 'Worksys';
|
||||||
exports.color = '#2134B0';
|
exports.color = '#2134B0';
|
||||||
exports.input = 2;
|
exports.input = 3;
|
||||||
exports.output = ["red", "white", "yellow"];
|
exports.output = ["red", "white", "yellow", "green"];
|
||||||
exports.click = false;
|
exports.click = false;
|
||||||
exports.icon = 'bolt';
|
exports.icon = 'bolt';
|
||||||
exports.options = { edge: "undefined" };
|
exports.options = { edge: "undefined" };
|
||||||
|
|
@ -56,25 +56,31 @@ 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 tá zmena by sa mala ukázať aj na platforme
|
momentálne sa stav zmení len keď vo flow klikneš aby sa zmenil, ale tá zmena by sa mala ukázať aj na platforme
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const dbStatus = TABLE("status");
|
||||||
|
const { errLogger, logger, monitor } = require('./helper/logger');
|
||||||
|
const SerialPort = require('serialport');
|
||||||
|
const WebSocket = require('ws');
|
||||||
|
//const { exec } = require('child_process');
|
||||||
|
const { runSyncExec } = require('./helper/serialport_helper');
|
||||||
|
const { bytesToInt, resizeArray } = require('./helper/utils');
|
||||||
|
const { sendNotification } = require('./helper/notification_reporter');
|
||||||
|
const bitwise = require('bitwise');
|
||||||
|
|
||||||
//globals
|
const DataToTbHandler = require('./helper/DataToTbHandler');
|
||||||
//FIRMWARE version
|
let tbHandler;
|
||||||
//TODO remove FLOW.OMS_edgeName variable, as we have FLOW.OMS_rvo_tbname
|
|
||||||
FLOW.OMS_edge_fw_version = "2024-09-23";//rok-mesiac-den
|
|
||||||
FLOW.OMS_edgeName = "";
|
|
||||||
FLOW.OMS_maintenance_mode = false;
|
|
||||||
|
|
||||||
//dynamic values
|
const ErrorToServiceHandler = require('./helper/ErrorToServiceHandler');
|
||||||
FLOW.OMS_masterNodeIsResponding = true; //cmd_manager
|
const errorHandler = new ErrorToServiceHandler();
|
||||||
//FLOW.OMS_brokerready = false //wsmqttpublish
|
|
||||||
FLOW.OMS_no_voltage = new Set();//modbus_citysys - elektromer
|
|
||||||
|
|
||||||
//see loadSettings() in cmd_manager
|
let ws = null;
|
||||||
FLOW.OMS_language = "en";//cmd_manager
|
let rsPort = null;
|
||||||
FLOW.OMS_rvo_name = "";//cmd_manager
|
|
||||||
FLOW.OMS_rvo_tbname = "";//relaysData
|
let pinsData;
|
||||||
FLOW.OMS_temperature_adress = "";//cmd_manager
|
let relaysData;
|
||||||
//-----------------------------------------------
|
let rvoTbName;
|
||||||
|
let GLOBALS; //FLOW global GLOBALS
|
||||||
|
let SETTINGS; // GLOBALS.settings
|
||||||
|
let controller_type;
|
||||||
|
|
||||||
let alarmStatus = "OFF";
|
let alarmStatus = "OFF";
|
||||||
|
|
||||||
|
|
@ -87,43 +93,6 @@ const SEND_TO = {
|
||||||
const TIME_AFTER_TEMPERATURE_NOK_STATUS = 3600; //seconds
|
const TIME_AFTER_TEMPERATURE_NOK_STATUS = 3600; //seconds
|
||||||
const DIFFERENCE_TO_SEND_TEMPERATURE = 0.31;
|
const DIFFERENCE_TO_SEND_TEMPERATURE = 0.31;
|
||||||
|
|
||||||
var log4js = require("log4js");
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
log4js.configure({
|
|
||||||
appenders: {
|
|
||||||
errLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../", 'err.txt') },
|
|
||||||
monitorLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../", 'monitor.txt') },
|
|
||||||
console: { type: 'console' }
|
|
||||||
},
|
|
||||||
categories: {
|
|
||||||
errLogs: { appenders: ['console', 'errLogs'], level: 'error' },
|
|
||||||
monitorLogs: { appenders: ['console', 'monitorLogs'], level: 'trace' },
|
|
||||||
//another: { appenders: ['console'], level: 'trace' },
|
|
||||||
default: { appenders: ['console'], level: 'trace' }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const errLogger = log4js.getLogger("errLogs");
|
|
||||||
const logger = log4js.getLogger();
|
|
||||||
const monitor = log4js.getLogger("monitorLogs");
|
|
||||||
|
|
||||||
//console.log(path.join(__dirname, 'err.txt', "-----------------------------"));
|
|
||||||
|
|
||||||
/*
|
|
||||||
process.on('uncaughtException', function (err) {
|
|
||||||
|
|
||||||
errLogger.error('uncaughtException:', err.message)
|
|
||||||
errLogger.error(err.stack);
|
|
||||||
|
|
||||||
//process.exit(1);
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
//USAGE
|
|
||||||
//logger.debug("text")
|
|
||||||
//monitor.info('info');
|
|
||||||
//errLogger.error("some error");
|
|
||||||
|
|
||||||
exports.install = function(instance) {
|
exports.install = function(instance) {
|
||||||
|
|
||||||
|
|
@ -149,8 +118,6 @@ exports.install = function(instance) {
|
||||||
const twilight_sensor_array = [];
|
const twilight_sensor_array = [];
|
||||||
let twilightError = false;
|
let twilightError = false;
|
||||||
|
|
||||||
let edgeName = "";
|
|
||||||
|
|
||||||
monitor.info("DIDO_Relay_Controller installed");
|
monitor.info("DIDO_Relay_Controller installed");
|
||||||
|
|
||||||
//key is PIN number , line: 0 = RVO
|
//key is PIN number , line: 0 = RVO
|
||||||
|
|
@ -172,15 +139,6 @@ exports.install = function(instance) {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const dbPins = TABLE("pins");
|
|
||||||
let pinsData = {};//key is pin
|
|
||||||
|
|
||||||
const dbRelays = TABLE("relays");
|
|
||||||
let relaysData = {};//key is line
|
|
||||||
|
|
||||||
const dbStatus = TABLE("status");
|
|
||||||
let statusData = null;
|
|
||||||
|
|
||||||
//status for calculating Statecodes
|
//status for calculating Statecodes
|
||||||
let deviceStatus = { //key is device name: temperature,....
|
let deviceStatus = { //key is device name: temperature,....
|
||||||
"state_of_main_switch": "Off", //Hlavný istič
|
"state_of_main_switch": "Off", //Hlavný istič
|
||||||
|
|
@ -190,53 +148,32 @@ exports.install = function(instance) {
|
||||||
"temperature": "OK", //templomer
|
"temperature": "OK", //templomer
|
||||||
"battery": "OK", //Batéria
|
"battery": "OK", //Batéria
|
||||||
"power_supply": "OK", //Zdroj
|
"power_supply": "OK", //Zdroj
|
||||||
"master_node": "OK", //MN - FLOW.OMS_masterNodeIsResponding
|
"master_node": "OK", //MN - GLOBALS.settings.masterNodeIsResponding
|
||||||
"no_voltage": "OK", //FLOW.OMS_no_voltage - výpadok napätia na fáze
|
"no_voltage": "OK", //GLOBALS.settings.no_voltage - výpadok napätia na fáze
|
||||||
"state_of_breaker": {}, //"Off",//Istič
|
"state_of_breaker": {}, //"Off",//Istič
|
||||||
"state_of_contactor": {}, //"Off",//Stykač
|
"state_of_contactor": {}, //"Off",//Stykač
|
||||||
"twilight_sensor": "OK" //lux sensor
|
"twilight_sensor": "OK" //lux sensor
|
||||||
};
|
};
|
||||||
|
|
||||||
const SerialPort = require('serialport');
|
|
||||||
const WebSocket = require('ws');
|
|
||||||
|
|
||||||
let ws = null;
|
function main() {
|
||||||
let rsPort = null;
|
|
||||||
|
|
||||||
const { runSyncExec } = require('./helper/serialport_helper.js');
|
GLOBALS = FLOW.GLOBALS;
|
||||||
const { bytesToInt, resizeArray } = require('./helper/utils');
|
SETTINGS = FLOW.GLOBALS.settings;
|
||||||
const { promisifyBuilder, makeMapFromDbResult } = require('./helper/db_helper.js');
|
rvoTbName = SETTINGS.rvoTbName;
|
||||||
const { sendNotification } = require('./helper/notification_reporter.js');
|
pinsData = GLOBALS.pinsData;
|
||||||
const bitwise = require('bitwise');
|
relaysData = GLOBALS.relaysData;
|
||||||
|
statusData = GLOBALS.statusData;
|
||||||
|
|
||||||
const DataToTbHandler = require('./helper/DataToTbHandler.js');
|
tbHandler = new DataToTbHandler(SEND_TO.tb)
|
||||||
const tbHandler = new DataToTbHandler(SEND_TO.tb);
|
|
||||||
tbHandler.setSender(exports.title);
|
tbHandler.setSender(exports.title);
|
||||||
|
|
||||||
const ErrorToServiceHandler = require('./helper/ErrorToServiceHandler.js');
|
controller_type = SETTINGS.controller_type //"lm" or "unipi" //logicMachine
|
||||||
const errorHandler = new ErrorToServiceHandler();
|
|
||||||
|
|
||||||
//let useTurnOffCounter = false;
|
|
||||||
//let turnOffCounter = 0;
|
|
||||||
let controller_type = FLOW.OMS_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);
|
|
||||||
|
|
||||||
|
|
||||||
async function loadAllDb()
|
|
||||||
{
|
|
||||||
let responsePins = await promisifyBuilder(dbPins.find());
|
|
||||||
pinsData = makeMapFromDbResult(responsePins, "pin");
|
|
||||||
|
|
||||||
let responseRelays = await promisifyBuilder(dbRelays.find());
|
|
||||||
relaysData = makeMapFromDbResult(responseRelays, "line");
|
|
||||||
|
|
||||||
let responseStatus = await promisifyBuilder(dbStatus.find());
|
|
||||||
statusData = responseStatus[0]; // {thermometer: 'OK', em: 'OK', twilight_sensor: 'OK'}
|
|
||||||
deviceStatus["temperature"] = statusData.thermometer;
|
deviceStatus["temperature"] = statusData.thermometer;
|
||||||
|
|
||||||
FLOW.OMS_rvo_tbname = relaysData[0].tbname;
|
console.log(exports.title, "controller type: ", controller_type);
|
||||||
|
|
||||||
if(controller_type === "lm")
|
if(controller_type === "lm")
|
||||||
{
|
{
|
||||||
|
|
@ -254,7 +191,8 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
function initialSetting()
|
function initialSetting()
|
||||||
{
|
{
|
||||||
//force turn off relays & set tbname
|
//force turn off relays
|
||||||
|
|
||||||
let keys = Object.keys(pinsData);
|
let keys = Object.keys(pinsData);
|
||||||
for(let i = 0; i < keys.length; i++)
|
for(let i = 0; i < keys.length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -266,15 +204,12 @@ exports.install = function(instance) {
|
||||||
if(relaysData[line] != undefined)
|
if(relaysData[line] != undefined)
|
||||||
{
|
{
|
||||||
pinsData[key].tbname = relaysData[line].tbname;
|
pinsData[key].tbname = relaysData[line].tbname;
|
||||||
|
//relaysData[line].contactor = 0;
|
||||||
relaysData[line].contactor = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errLogger.error("CRITICAL!!! undefined relay", relaysData[line], line);
|
errLogger.error("CRITICAL!!! undefined relay", relaysData[line], line);
|
||||||
|
sendNotification("set port ", rvoTbName, "local_database_is_corrupted", {}, "", SEND_TO.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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,36 +220,23 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
//this will modify database
|
//this will modify database
|
||||||
let forceTurnOff = true;
|
let forceTurnOff = true;
|
||||||
turnOffLine(line, pin, forceTurnOff, "turn off on startup");
|
turnLine("off", line, pin, forceTurnOff, "turn off on startup");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//report RVO version relaysData[0].tbname;
|
//report RVO version relaysData[0].tbname;
|
||||||
let values = {};
|
let values = {};
|
||||||
values["edge_fw_version"] = FLOW.OMS_edge_fw_version;
|
values["edge_fw_version"] = SETTINGS.edge_fw_version;
|
||||||
values["maintenance_mode"] = FLOW.OMS_maintenance_mode;
|
values["maintenance_mode"] = SETTINGS.maintenance_mode;
|
||||||
|
|
||||||
edgeName = relaysData[0].tbname;
|
sendTelemetry(values, rvoTbName);
|
||||||
FLOW.OMS_edgeName = edgeName;
|
|
||||||
|
|
||||||
dataToTb = {
|
|
||||||
[edgeName]: [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values": values
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
instance.send(SEND_TO.tb, dataToTb);
|
|
||||||
|
|
||||||
let time = 5*1000;
|
let time = 5*1000;
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "buildTasks"});
|
instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "buildTasks"});
|
||||||
|
|
||||||
sendNotification("rsPort.open()", edgeName, "flow_start", {}, "", SEND_TO.tb, instance );
|
sendNotification("rsPort.open()", rvoTbName, "flow_start", {}, "", SEND_TO.tb, instance);
|
||||||
monitor.info("-->FLOW bol spustený", edgeName, FLOW.OMS_edge_fw_version);
|
monitor.info("-->FLOW bol spustený", rvoTbName, SETTINGS.edge_fw_version);
|
||||||
|
|
||||||
}, time);
|
}, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,20 +261,16 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
//set port
|
//set port
|
||||||
rsPort.write(Buffer.from(setRSPortData), function(err) {
|
rsPort.write(Buffer.from(setRSPortData), function(err) {
|
||||||
|
if(!err) {
|
||||||
monitor.info(exports.title + "--->Digital in_out has been set (runSyncExec was sucessfull)");
|
monitor.info(exports.title + "--->Digital in_out has been set (runSyncExec was sucessfull)");
|
||||||
|
|
||||||
turnOffAlarm();
|
turnAlarm("off");
|
||||||
|
|
||||||
//useTurnOffCounter = true;
|
|
||||||
//turnOffCounter = relaysData.length - 1;
|
|
||||||
|
|
||||||
initialSetting();
|
initialSetting();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}).catch(function(reason) {
|
}).catch(function(reason) {
|
||||||
//instance.send(SEND_TO.debug, exports.title + " runSyncExec - promise rejected:" + reason);
|
|
||||||
errLogger.error(exports.title + " runSyncExec - promise rejected:" + reason);
|
errLogger.error(exports.title + " runSyncExec - promise rejected:" + reason);
|
||||||
|
|
||||||
errorHandler.sendMessageToService(exports.title + " runSyncExec - promise rejected:" + reason);
|
errorHandler.sendMessageToService(exports.title + " runSyncExec - promise rejected:" + reason);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -402,7 +320,6 @@ exports.install = function(instance) {
|
||||||
})
|
})
|
||||||
|
|
||||||
rsPort.open();
|
rsPort.open();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -417,7 +334,7 @@ exports.install = function(instance) {
|
||||||
ws.onopen = function open() {
|
ws.onopen = function open() {
|
||||||
|
|
||||||
instance.send(0, exports.title + " running");
|
instance.send(0, exports.title + " running");
|
||||||
turnOffAlarm();
|
turnAlarm("off");
|
||||||
|
|
||||||
// useTurnOffCounter = true;
|
// useTurnOffCounter = true;
|
||||||
// turnOffCounter = relaysData.length - 1;
|
// turnOffCounter = relaysData.length - 1;
|
||||||
|
|
@ -480,7 +397,7 @@ exports.install = function(instance) {
|
||||||
{
|
{
|
||||||
previousValues["temperature"]["value"] = value;
|
previousValues["temperature"]["value"] = value;
|
||||||
values['temperature'] = value;
|
values['temperature'] = value;
|
||||||
sendTelemetry(values, FLOW.OMS_rvo_tbname);
|
sendTelemetry(values, rvoTbName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -516,24 +433,11 @@ exports.install = function(instance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! do we need requests every minute ???
|
|
||||||
// const startRequests = () => {
|
|
||||||
// console.log("startRequest function called");
|
|
||||||
// start = setInterval(() => {
|
|
||||||
// // console.log("data from evok requested");
|
|
||||||
// ws.send(JSON.stringify({"cmd":"filter", "devices": "neuron"}));
|
|
||||||
// // ws.send(JSON.stringify({"cmd":"filter", "devices":["input", "relay"]}));
|
|
||||||
// }, 150000)
|
|
||||||
// }
|
|
||||||
|
|
||||||
instance.on("close", () => {
|
instance.on("close", () => {
|
||||||
if(rsPort) rsPort.close();
|
if(rsPort) rsPort.close();
|
||||||
if(ws) ws.close();
|
if(ws) ws.close();
|
||||||
clearInterval(sendRebuildTasksAt11);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
loadAllDb();
|
|
||||||
|
|
||||||
|
|
||||||
function getPin(line)
|
function getPin(line)
|
||||||
{
|
{
|
||||||
|
|
@ -556,52 +460,32 @@ exports.install = function(instance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function turnOnAlarm()
|
function turnAlarm(onOrOff)
|
||||||
{
|
{
|
||||||
if(FLOW.OMS_maintenance_mode) return;
|
let value = 0;
|
||||||
|
if(onOrOff == "on") value = 1;
|
||||||
|
|
||||||
alarmStatus = "ON";
|
if(value == 1 && SETTINGS.maintenance_mode) return;
|
||||||
|
|
||||||
if(rsPort)
|
|
||||||
{
|
|
||||||
let arr = [0x55];
|
|
||||||
arr.push( 13 );
|
|
||||||
arr.push( 0 );
|
|
||||||
arr.push( 1 );
|
|
||||||
|
|
||||||
rsPort.write(Buffer.from(arr), function(err) {
|
|
||||||
logger.debug("sirena zapnuta");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if(ws)
|
|
||||||
{
|
|
||||||
let cmd = {"cmd": "set", "dev": "relay", "circuit": "1_01", "value": 1};
|
|
||||||
ws.send(JSON.stringify(cmd));
|
|
||||||
logger.debug("sirena zapnuta");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function turnOffAlarm()
|
|
||||||
{
|
|
||||||
alarmStatus = "OFF";
|
alarmStatus = "OFF";
|
||||||
|
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( 0 );
|
arr.push(value);
|
||||||
|
|
||||||
rsPort.write(Buffer.from(arr), function(err) {
|
rsPort.write(Buffer.from(arr), function(err) {
|
||||||
logger.debug("sirena vypnuta");
|
logger.debug(`sirena - ${onOrOff}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if(ws)
|
else if(ws)
|
||||||
{
|
{
|
||||||
let cmd = {"cmd": "set", "dev": "relay", "circuit": "1_01", "value": 0};
|
let cmd = {"cmd": "set", "dev": "relay", "circuit": "1_01", "value": value};
|
||||||
ws.send(JSON.stringify(cmd));
|
ws.send(JSON.stringify(cmd));
|
||||||
logger.debug("sirena vypnuta");
|
logger.debug(`sirena - ${onOrOff}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -609,9 +493,7 @@ exports.install = function(instance) {
|
||||||
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).
|
//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 tbname = relaysData[line].tbname;
|
||||||
|
|
||||||
let bits = [];
|
let bits = [];
|
||||||
|
|
||||||
if(deviceStatus["state_of_breaker"][line] == "On")
|
if(deviceStatus["state_of_breaker"][line] == "On")
|
||||||
|
|
@ -631,130 +513,35 @@ exports.install = function(instance) {
|
||||||
let byte = bitwise.byte.write(bits.reverse());
|
let byte = bitwise.byte.write(bits.reverse());
|
||||||
|
|
||||||
//console.log("line", line, bits, byte);
|
//console.log("line", line, bits, byte);
|
||||||
|
sendTelemetry({statecode: byte}, tbname);
|
||||||
let values = {
|
|
||||||
statecode: byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataToTb = {
|
|
||||||
[tbname]: [
|
// turn line on or off
|
||||||
|
function turnLine(onOrOff, line, pin, force, info)
|
||||||
{
|
{
|
||||||
"ts": Date.now(),
|
//onOrOff => "on" or "off"
|
||||||
"values": values
|
let value = 0;
|
||||||
}
|
if(onOrOff == "on") value = 1;
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log(values);
|
|
||||||
|
|
||||||
instance.send(SEND_TO.tb, dataToTb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function turnOnLine(line, pin, force, info)
|
|
||||||
{
|
|
||||||
|
|
||||||
instance.send(SEND_TO.debug, "turn on line " + line );
|
|
||||||
if(force == undefined) force = false;
|
if(force == undefined) force = false;
|
||||||
|
|
||||||
if(line == 0)
|
if(line == 0)
|
||||||
{
|
{
|
||||||
if(alarmStatus == "ON") turnOffAlarm();
|
if(value == 1 && alarmStatus == "ON") turnAlarm("off");
|
||||||
FLOW.OMS_maintenance_mode = true;
|
SETTINGS.maintenance_mode = value? true: false;
|
||||||
|
|
||||||
let values = {};
|
let values = {};
|
||||||
values["statecode"] = calculateStateCode();
|
values["statecode"] = calculateStateCode();
|
||||||
values["power_mode"] = "maintenance";
|
values["power_mode"] = value ? "maintenance": "Automatic";
|
||||||
let tbname = relaysData[line].tbname;
|
sendTelemetry(values, rvoTbName);
|
||||||
sendTelemetry(values, tbname);
|
|
||||||
|
|
||||||
monitor.info("turnOnLine (line, FLOW.OMS_maintenance_mode)", line, FLOW.OMS_maintenance_mode, info);
|
|
||||||
|
|
||||||
|
monitor.info(`turnLine ${onOrOff} - (line, SETTINGS.maintenance_mode)`, line, SETTINGS.maintenance_mode, info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pin === undefined) pin = getPin(line);
|
if(pin === undefined) pin = getPin(line);
|
||||||
|
|
||||||
monitor.info("turnOnLine (line, pin, force)", line, pin, force, info);
|
|
||||||
|
|
||||||
if( pin === undefined)
|
|
||||||
{
|
|
||||||
monitor.info("pin is undefined!", line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!force)
|
|
||||||
{
|
|
||||||
if(relaysData[line].contactor == 1)
|
|
||||||
{
|
|
||||||
instance.send(SEND_TO.debug, "line is already on " + line );
|
|
||||||
logger.debug("turnOnLine: line is already on: ", line);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(!rsPort.isOpen && !ws)
|
|
||||||
if(!rsPort && !ws)
|
|
||||||
{
|
|
||||||
errLogger.error("dido controller - port or websocket is not opened");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rsPort)
|
|
||||||
{
|
|
||||||
let arr = [0x55];
|
|
||||||
arr.push( pin );
|
|
||||||
arr.push( 0 );
|
|
||||||
arr.push( 1 );
|
|
||||||
|
|
||||||
rsPort.write(Buffer.from(arr), function(err) {
|
|
||||||
if(err === undefined)
|
|
||||||
{
|
|
||||||
console.log("turnONLine zapisal do rsPortu", line, arr);
|
|
||||||
switchLogic(arr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
monitor.info("turnOnLine WRITE error", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(ws)
|
|
||||||
{
|
|
||||||
console.log("turnONLine pin (relay)", pin);
|
|
||||||
//pin = "relay1_03" or "input1_01" ... we must make just "1_01" with slice method
|
|
||||||
let cmd = {"cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": 1};
|
|
||||||
ws.send(JSON.stringify(cmd));
|
|
||||||
switchLogic(pin, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function turnOffLine(line, pin, force, info)
|
|
||||||
{
|
|
||||||
if(force == undefined) force = false;
|
|
||||||
|
|
||||||
if(line == 0)
|
|
||||||
{
|
|
||||||
FLOW.OMS_maintenance_mode = false;
|
|
||||||
|
|
||||||
let values = {};
|
|
||||||
values["statecode"] = calculateStateCode();
|
|
||||||
values["power_mode"] = "automatic";
|
|
||||||
let tbname = relaysData[line].tbname;
|
|
||||||
sendTelemetry(values, tbname);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pin === undefined) pin = getPin(line);
|
|
||||||
|
|
||||||
monitor.info("turnOffLine (line, pin, force)", line, pin, force, info);
|
|
||||||
|
|
||||||
if(pin === undefined)
|
if(pin === undefined)
|
||||||
{
|
{
|
||||||
errLogger.error("pin is undefined!", line);
|
errLogger.error("pin is undefined!", line);
|
||||||
|
|
@ -763,11 +550,10 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
if(!force)
|
if(!force)
|
||||||
{
|
{
|
||||||
if(relaysData[line].contactor == 0)
|
if(relaysData[line].contactor == value)
|
||||||
{
|
{
|
||||||
instance.send(SEND_TO.debug, "line is already off " + line );
|
instance.send(SEND_TO.debug, `line is already ${onOrOff} ` + line );
|
||||||
logger.debug("turnOffLine: line already off:", line);
|
logger.debug(`turnLine: line is already ${onOrOff} `, line);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -784,33 +570,38 @@ exports.install = function(instance) {
|
||||||
let arr = [0x55];
|
let arr = [0x55];
|
||||||
arr.push(pin);
|
arr.push(pin);
|
||||||
arr.push(0);
|
arr.push(0);
|
||||||
arr.push( 0 );
|
arr.push(value);
|
||||||
|
|
||||||
rsPort.write(Buffer.from(arr), function(err) {
|
rsPort.write(Buffer.from(arr), function(err) {
|
||||||
if(err === undefined)
|
if(err === undefined)
|
||||||
{
|
{
|
||||||
console.log("turnOffLine zapisal do rsPort-u", line, arr);
|
monitor.info(`turnLine ${onOrOff} zapisal do rsPort-u`, line, pin, arr, info);
|
||||||
switchLogic(arr);
|
switchLogic(arr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
monitor.info("turnOffLine WRITE error", err);
|
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
|
//pin = "relay1_03" or "input1_01" ... we must make just "1_01" with slice method
|
||||||
//monitor.info("turnOffLine pin (relay)", pin);
|
monitor.info(`turnLine ${onOrOff} - (line, pin, force)`, line, pin, force, info);
|
||||||
let cmd = {"cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": 0};
|
let cmd = {"cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": value};
|
||||||
ws.send(JSON.stringify(cmd));
|
ws.send(JSON.stringify(cmd));
|
||||||
switchLogic(pin, 0)
|
switchLogic(pin, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// main opening
|
||||||
|
instance.on("2", _ => {
|
||||||
|
main();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
//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 => {
|
||||||
|
|
||||||
|
|
@ -820,7 +611,7 @@ exports.install = function(instance) {
|
||||||
instance.send(SEND_TO.debug, flowdata.data);
|
instance.send(SEND_TO.debug, flowdata.data);
|
||||||
|
|
||||||
// we handle nok status from modbus_reader component and thermometer
|
// we handle nok status from modbus_reader component and thermometer
|
||||||
if(flowdata.data?.status)
|
if("status" in flowdata.data)
|
||||||
{
|
{
|
||||||
const status = flowdata.data.status;
|
const status = flowdata.data.status;
|
||||||
if(status == "NOK-twilight_sensor")
|
if(status == "NOK-twilight_sensor")
|
||||||
|
|
@ -838,7 +629,7 @@ exports.install = function(instance) {
|
||||||
deviceStatus["temperature"] = "NOK";
|
deviceStatus["temperature"] = "NOK";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(flowdata.data?.values)
|
else if("values" in flowdata.data)
|
||||||
{
|
{
|
||||||
const values = flowdata.data.values;
|
const values = flowdata.data.values;
|
||||||
if(values.hasOwnProperty("twilight_sensor"))
|
if(values.hasOwnProperty("twilight_sensor"))
|
||||||
|
|
@ -856,10 +647,10 @@ exports.install = function(instance) {
|
||||||
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";
|
deviceStatus["em"] = "OK";
|
||||||
FLOW.OMS_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, FLOW.OMS_rvo_tbname);
|
sendTelemetry(values, rvoTbName);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRvoStatus();
|
sendRvoStatus();
|
||||||
|
|
@ -878,10 +669,10 @@ exports.install = function(instance) {
|
||||||
let force = obj.force;
|
let force = obj.force;
|
||||||
let info = obj.info;
|
let info = obj.info;
|
||||||
|
|
||||||
if(obj.command == "turnOn") turnOnLine(line, undefined, force, info);
|
if(obj.command == "turnOn") turnLine("on", line, undefined, force, info);
|
||||||
else if(obj.command == "turnOff") turnOffLine(line, undefined, force, info);
|
else if(obj.command == "turnOff") turnLine("off", line, undefined, force, info);
|
||||||
else if(obj.command == "turnOnAlarm") turnOnAlarm();
|
else if(obj.command == "turnOnAlarm") turnAlarm("on");
|
||||||
else if(obj.command == "turnOffAlarm") turnOffAlarm();
|
else if(obj.command == "turnOffAlarm") turnAlarm("off");
|
||||||
|
|
||||||
//! ake data prichadzaju z cmd_manager.js ???
|
//! ake data prichadzaju z cmd_manager.js ???
|
||||||
//TODO transform to websocket
|
//TODO transform to websocket
|
||||||
|
|
@ -899,11 +690,9 @@ exports.install = function(instance) {
|
||||||
function calculateStateCode()
|
function calculateStateCode()
|
||||||
{
|
{
|
||||||
|
|
||||||
let bytes = [];
|
|
||||||
let bits = [];
|
let bits = [];
|
||||||
|
|
||||||
//Hlavný istič - state_of_main_switch
|
//Hlavný istič - state_of_main_switch => v rvo senica je to druhy door pre silovu cast (EM)
|
||||||
//TODO state_of main_switch is door contact in senica rvo - values should be "open" and "closed"
|
|
||||||
if(deviceStatus["state_of_main_switch"] == "closed")
|
if(deviceStatus["state_of_main_switch"] == "closed")
|
||||||
{
|
{
|
||||||
bits.push(0);
|
bits.push(0);
|
||||||
|
|
@ -914,7 +703,7 @@ exports.install = function(instance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Prevádzkový mód - Manual, Off, Automatic, maintenance_mode = true/false // DAVA 2 BITY
|
//Prevádzkový mód - Manual, Off, Automatic, maintenance_mode = true/false // DAVA 2 BITY
|
||||||
if(!FLOW.OMS_maintenance_mode)
|
if(!SETTINGS.maintenance_mode)
|
||||||
{
|
{
|
||||||
if(deviceStatus["rotary_switch_state"] == "Manual")
|
if(deviceStatus["rotary_switch_state"] == "Manual")
|
||||||
{
|
{
|
||||||
|
|
@ -1040,6 +829,10 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
async function sendRvoStatus() {
|
async function sendRvoStatus() {
|
||||||
|
|
||||||
|
// test if dbLoaded is ok to check
|
||||||
|
//if(!FLOW.dbLoaded) return;
|
||||||
|
if(SETTINGS === undefined) return;
|
||||||
|
|
||||||
const table = {
|
const table = {
|
||||||
"OK": 1,
|
"OK": 1,
|
||||||
"NOK": 0
|
"NOK": 0
|
||||||
|
|
@ -1055,7 +848,7 @@ exports.install = function(instance) {
|
||||||
"master_node_status": table[deviceStatus["master_node"]]
|
"master_node_status": table[deviceStatus["master_node"]]
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const phase of FLOW.OMS_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
|
//thermometer did not send data for more than a hour. Time in seconds
|
||||||
if(deviceStatus["temperature"] === "OK")
|
if(deviceStatus["temperature"] === "OK")
|
||||||
|
|
@ -1071,7 +864,7 @@ exports.install = function(instance) {
|
||||||
dataToTb["status"] = checkRvoStatus();
|
dataToTb["status"] = checkRvoStatus();
|
||||||
dataToTb["statecode"] = calculateStateCode();
|
dataToTb["statecode"] = calculateStateCode();
|
||||||
|
|
||||||
sendTelemetry(dataToTb, FLOW.OMS_rvo_tbname);
|
sendTelemetry(dataToTb, rvoTbName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1083,7 +876,8 @@ 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")
|
||||||
|
|
@ -1093,7 +887,7 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
for (const pinIndex of pinIndexes) {
|
for (const pinIndex of pinIndexes) {
|
||||||
if (previousValues[pinIndex] === 0) {
|
if (previousValues[pinIndex] === 0) {
|
||||||
if ((pinIndex === 6 || pinIndex === 'input1_01' || pinIndex === 'input1_05') && FLOW.OMS_maintenance_mode) continue;
|
if ((pinIndex === 6 || pinIndex === 'input1_01' || pinIndex === 'input1_05') && SETTINGS.maintenance_mode) continue;
|
||||||
status = "NOK";
|
status = "NOK";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1102,8 +896,8 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
// battery status. If value is 1 - battery is NOK
|
// battery status. If value is 1 - battery is NOK
|
||||||
if (previousValues[5] === 1) status = "NOK";
|
if (previousValues[5] === 1) status = "NOK";
|
||||||
if(!FLOW.OMS_masterNodeIsResponding) status = "NOK";
|
if(!SETTINGS.masterNodeIsResponding) status = "NOK";
|
||||||
if(FLOW.OMS_no_voltage.size > 0) status = "NOK";
|
if(SETTINGS.no_voltage.size > 0) status = "NOK";
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -1135,7 +929,7 @@ exports.install = function(instance) {
|
||||||
if(obj == undefined)
|
if(obj == undefined)
|
||||||
{
|
{
|
||||||
previousValues[pinIndex] = newPinValue;
|
previousValues[pinIndex] = newPinValue;
|
||||||
logger.debug("dido-switchLogic ==> no pinIndex", pinIndex);
|
//logger.debug("dido-switchLogic ==> no pinIndex", pinIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1155,14 +949,14 @@ exports.install = function(instance) {
|
||||||
// {
|
// {
|
||||||
// if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
// if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
||||||
// {
|
// {
|
||||||
// sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_off", {}, "", SEND_TO.tb, instance , "state_of_main_switch");
|
// sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_off", {}, "", SEND_TO.tb, instance , "state_of_main_switch");
|
||||||
// values["status"] = "NOK";
|
// values["status"] = "NOK";
|
||||||
|
|
||||||
// deviceStatus["state_of_main_switch"] = "Off";
|
// deviceStatus["state_of_main_switch"] = "Off";
|
||||||
// }
|
// }
|
||||||
// else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
// else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
||||||
// {
|
// {
|
||||||
// sendNotification("switchLogic", edgeName, "main_switch_has_been_turned_on", {}, "", SEND_TO.tb, instance , "state_of_main_switch");
|
// sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_on", {}, "", SEND_TO.tb, instance , "state_of_main_switch");
|
||||||
|
|
||||||
// deviceStatus["state_of_main_switch"] = "On";
|
// deviceStatus["state_of_main_switch"] = "On";
|
||||||
// }
|
// }
|
||||||
|
|
@ -1211,73 +1005,71 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
//console.log("rotary_switch_state pin", pin2, pin3, value);
|
//console.log("rotary_switch_state pin", pin2, pin3, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Zdroj - pin 4
|
//Zdroj - pin 4
|
||||||
else if (type === "power_supply")
|
else if (type === "power_supply")
|
||||||
{
|
{
|
||||||
if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.ALERT, "Power supply is not OK", "", SEND_TO.tb, instance);
|
sendNotification("switchLogic", rvoTbName, "power_supply_has_disconnected_input", {}, "", SEND_TO.tb, instance, "power_supply");
|
||||||
sendNotification("switchLogic", edgeName, "power_supply_has_disconnected_input", {}, "", SEND_TO.tb, instance, "power_supply");
|
|
||||||
|
|
||||||
deviceStatus["power_supply"] = "NOK";
|
deviceStatus["power_supply"] = "NOK";
|
||||||
}
|
}
|
||||||
else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Power supply is is OK", "", SEND_TO.tb, instance);
|
sendNotification("switchLogic", rvoTbName, "power_supply_works_correctly", {}, "", SEND_TO.tb, instance, "power_supply");
|
||||||
sendNotification("switchLogic", edgeName, "power_supply_works_correctly", {}, "", SEND_TO.tb, instance, "power_supply");
|
|
||||||
|
|
||||||
deviceStatus["power_supply"] = "OK";
|
deviceStatus["power_supply"] = "OK";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Batéria - pin 5
|
//Batéria - pin 5
|
||||||
else if (type === "battery")
|
else if (type === "battery")
|
||||||
{
|
{
|
||||||
if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
if (newPinValue === 1 && newPinValue !== previousValues[pinIndex])
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Battery is not OK", "", SEND_TO.tb, instance);
|
sendNotification("switchLogic", rvoTbName, "battery_level_is_low", {}, "", SEND_TO.tb, instance, "battery_level");
|
||||||
sendNotification("switchLogic", edgeName, "battery_level_is_low", {}, "", SEND_TO.tb, instance, "battery_level");
|
|
||||||
|
|
||||||
deviceStatus["battery"] = "NOK";
|
deviceStatus["battery"] = "NOK";
|
||||||
}
|
}
|
||||||
else if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
else if (newPinValue === 0 && newPinValue !== previousValues[pinIndex])
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Battery is OK", "", SEND_TO.tb, instance);
|
sendNotification("switchLogic", rvoTbName, "battery_level_is_ok", {}, "", SEND_TO.tb, instance, "battery_level");
|
||||||
sendNotification("switchLogic", edgeName, "battery_level_is_ok", {}, "", SEND_TO.tb, instance, "battery_level");
|
|
||||||
|
|
||||||
deviceStatus["battery"] = "OK";
|
deviceStatus["battery"] = "OK";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Dverový kontakt - pin 6
|
//Dverový kontakt - pin 6
|
||||||
//! Po novom mame dva dverove kontakty, nie jeden. Druhy je teraz tam, kde bol digital input "state_of_main_switch"
|
//! 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'
|
//! 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";
|
newPinValue === 0 ? value = "open" : value = "closed";
|
||||||
if (value === "open" && FLOW.OMS_maintenance_mode)
|
|
||||||
|
if (value === "open" && SETTINGS.maintenance_mode)
|
||||||
{
|
{
|
||||||
sendNotification("switchLogic", edgeName, "door_has_been_open", {}, "", SEND_TO.tb, instance, "rvo_door");
|
sendNotification("switchLogic", rvoTbName, "door_opened", {}, "", SEND_TO.tb, instance, "rvo_door");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === "open" && !FLOW.OMS_maintenance_mode)
|
if (value === "open" && !SETTINGS.maintenance_mode)
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.WARNING, "RVO open door out of maintenance mode", "", SEND_TO.tb, instance);
|
sendNotification("switchLogic", rvoTbName, "door_opened_without_permission", {}, "", SEND_TO.tb, instance, "rvo_door");
|
||||||
sendNotification("switchLogic", edgeName, "door_has_been_open_without_permision_alarm_is_on", {}, "", SEND_TO.tb, instance, "rvo_door");
|
|
||||||
|
|
||||||
// zapneme sirenu
|
// 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")
|
// 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") turnOnAlarm();
|
if(type === "door_condition") turnAlarm("on");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === "closed")
|
if (value === "closed")
|
||||||
{
|
{
|
||||||
if(alarmStatus == "ON") turnOffAlarm();
|
if(alarmStatus == "ON") turnAlarm("off");
|
||||||
//turnOffAlarm();
|
sendNotification("switchLogic", rvoTbName, "door_closed", {}, "", SEND_TO.tb, instance, "rvo_door");
|
||||||
|
|
||||||
sendNotification("switchLogic", edgeName, "door_has_been_closed", {}, "", SEND_TO.tb, instance, "rvo_door");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceStatus[type] = value;
|
deviceStatus[type] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//lux sensor
|
//lux sensor
|
||||||
else if(type == "twilight_sensor")
|
else if(type == "twilight_sensor")
|
||||||
{
|
{
|
||||||
|
|
@ -1309,14 +1101,15 @@ exports.install = function(instance) {
|
||||||
{
|
{
|
||||||
twilightError = true;
|
twilightError = true;
|
||||||
let value = twilight_sensor_array.shift();
|
let value = twilight_sensor_array.shift();
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.ERROR, "Lux sensor error", {"Repeating value": value}, SEND_TO.tb, instance );
|
|
||||||
newPinValue = 0;
|
newPinValue = 0;
|
||||||
}
|
}
|
||||||
else if (set.size !== 1 && twilightError)
|
else if (set.size !== 1 && twilightError)
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.NOTICE, "Lux sensor is working again", "", SEND_TO.tb, instance );
|
//sendNotification("switchLogic", rvoTbName, ERRWEIGHT.NOTICE, "Lux sensor is working again", "", SEND_TO.tb, instance );
|
||||||
twilightError = false;
|
twilightError = false;
|
||||||
twilight_sensor_array.shift();
|
twilight_sensor_array.shift();
|
||||||
|
|
||||||
newPinValue = value;
|
newPinValue = value;
|
||||||
}
|
}
|
||||||
else if (set.size === 1 && twilightError)
|
else if (set.size === 1 && twilightError)
|
||||||
|
|
@ -1339,12 +1132,12 @@ exports.install = function(instance) {
|
||||||
//else console.log("lux_sensor", value, diff);
|
//else console.log("lux_sensor", value, diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(type == "state_of_contactor")
|
else if(type == "state_of_contactor")
|
||||||
{
|
{
|
||||||
//sendNotification("switchLogic", edgeName, ERRWEIGHT.INFO, `State of contactor ${line} is now ${value}`, "", SEND_TO.tb, instance );
|
|
||||||
if(!(deviceStatus["state_of_contactor"][line] == value))
|
if(!(deviceStatus["state_of_contactor"][line] == value))
|
||||||
{
|
{
|
||||||
sendNotification("switchLogic", edgeName, "state_of_contactor_for_line", {line: line, value: value}, "", SEND_TO.tb, instance );
|
sendNotification("switchLogic", rvoTbName, "state_of_contactor_for_line", {line: line, value: value}, "", SEND_TO.tb, instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceStatus["state_of_contactor"][line] = value;
|
deviceStatus["state_of_contactor"][line] = value;
|
||||||
|
|
@ -1353,34 +1146,45 @@ exports.install = function(instance) {
|
||||||
if(value === "On") value = true;
|
if(value === "On") value = true;
|
||||||
else if(value === "Off") value = false;
|
else if(value === "Off") value = false;
|
||||||
|
|
||||||
//modify table relays
|
//TODO do we need to modify relays table with contactor value, if we do not use it on startup ??
|
||||||
dbRelays.modify({ contactor: newPinValue }).where("line", line).make(function(builder) {
|
|
||||||
builder.callback(function(err, response) {
|
|
||||||
if(!err)
|
|
||||||
{
|
|
||||||
let time = 0;
|
|
||||||
if(value) time = 1000 * 10;//10 sekund
|
|
||||||
|
|
||||||
let dataChanged = false;
|
let dataChanged = false;
|
||||||
if(relaysData[line].contactor != value) dataChanged = true;
|
if(relaysData[line].contactor !== newPinValue) {
|
||||||
relaysData[line].contactor = value;
|
dataChanged = true;
|
||||||
|
relaysData[line].contactor = newPinValue;
|
||||||
//ak bola predchadzajuci stav off a novy stav je on, budu sa nastavovat nespracovane node profiles
|
}
|
||||||
//a budu sa odosielat commandy, tie vsak mozu zlyhat, a preto potrebujeme ich spusti trochu neskor
|
|
||||||
setTimeout(function(){
|
|
||||||
instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, time: time, value: value, dataChanged: dataChanged});
|
|
||||||
}, time);
|
|
||||||
|
|
||||||
|
instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, value: value, dataChanged: dataChanged});
|
||||||
reportLineStatus(line);
|
reportLineStatus(line);
|
||||||
}
|
|
||||||
else
|
//modify table relays
|
||||||
{
|
// dbRelays.modify({ contactor: newPinValue }).where("line", line).make(function(builder) {
|
||||||
errLogger.error("modify table relays failed", err);
|
// builder.callback(function(err, response) {
|
||||||
|
// if(!err)
|
||||||
|
// {
|
||||||
|
// let time = 0;
|
||||||
|
// if(value) time = 1000 * 10;//10 sekund
|
||||||
|
|
||||||
|
// let dataChanged = false;
|
||||||
|
// if(relaysData[line].contactor != newPinValue) dataChanged = true;
|
||||||
|
// relaysData[line].contactor = newPinValue; // 0,1
|
||||||
|
|
||||||
|
// //ak bola predchadzajuci stav off a novy stav je on, budu sa nastavovat nespracovane node profiles
|
||||||
|
// //a budu sa odosielat commandy, tie vsak mozu zlyhat, a preto potrebujeme ich spusti trochu neskor
|
||||||
|
// setTimeout(function(){
|
||||||
|
// instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, time: time, value: value, dataChanged: dataChanged});
|
||||||
|
// }, time);
|
||||||
|
|
||||||
|
// reportLineStatus(line);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// errLogger.error("modify table relays failed", err);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// });
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if(type === "state_of_breaker")
|
else if(type === "state_of_breaker")
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -1448,28 +1252,27 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
if(type == "rotary_switch_state")
|
if(type == "rotary_switch_state")
|
||||||
{
|
{
|
||||||
if(FLOW.OMS_maintenance_mode) value = "maintenance";
|
if(SETTINGS.maintenance_mode) value = "maintenance";
|
||||||
value = value.toLowerCase();
|
value = value.toLowerCase();
|
||||||
values["power_mode"] = value;
|
values["power_mode"] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue;
|
if(newPinValue != previousValues[pinIndex]) previousValues[pinIndex] = newPinValue;
|
||||||
if(FLOW.OMS_rvo_tbname == tbname) sendRvoStatus();
|
if(rvoTbName == tbname) sendRvoStatus();
|
||||||
if(Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname);
|
if(Object.keys(values).length > 0 && tbname) sendTelemetry(values, tbname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sendTelemetry(values, tbname) {
|
function sendTelemetry(values, tbname, date=Date.now()) {
|
||||||
let dataToTb = {
|
let dataToTb = {
|
||||||
[tbname]: [
|
[tbname]: [
|
||||||
{
|
{
|
||||||
"ts": Date.now(),
|
"ts": date,
|
||||||
"values": values
|
"values": values
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
// instance.send(SEND_TO.tb, dataToTb);
|
|
||||||
tbHandler.sendToTb(dataToTb, instance);
|
tbHandler.sendToTb(dataToTb, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1496,8 +1299,6 @@ exports.install = function(instance) {
|
||||||
return (typeof item === "object" && !Array.isArray(item) && item !== null);
|
return (typeof item === "object" && !Array.isArray(item) && item !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} //end of instance
|
} //end of instance
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,8 @@ class DataToTbHandler {
|
||||||
for(let i = 0; i < arrayOfValues.length; i++)
|
for(let i = 0; i < arrayOfValues.length; i++)
|
||||||
{
|
{
|
||||||
ts = arrayOfValues[i].ts;
|
ts = arrayOfValues[i].ts;
|
||||||
|
|
||||||
//console.log("sendToTb------------>before", arrayOfValues[i].values, tbname);
|
|
||||||
|
|
||||||
let values = this.prepareValuesForTb(tbname, ts, arrayOfValues[i].values);
|
let values = this.prepareValuesForTb(tbname, ts, arrayOfValues[i].values);
|
||||||
|
|
||||||
//console.log("sendToTb------------>after", values);
|
|
||||||
|
|
||||||
if(!this.isEmptyObject(values))
|
if(!this.isEmptyObject(values))
|
||||||
{
|
{
|
||||||
arrayOfValuesToSend.push({ts: ts, values: values});
|
arrayOfValuesToSend.push({ts: ts, values: values});
|
||||||
|
|
@ -68,17 +63,6 @@ class DataToTbHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
let dataToTb = {
|
|
||||||
[tbname]: [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values": values
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
this.messageCounter++;
|
this.messageCounter++;
|
||||||
|
|
||||||
let dataToTbModified = {
|
let dataToTbModified = {
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class ErrorToServiceHandler
|
||||||
console.log("ErrorToServiceHandler------------------------>send to service", dataToInfoSender);
|
console.log("ErrorToServiceHandler------------------------>send to service", dataToInfoSender);
|
||||||
|
|
||||||
//TODO UGLY!!!
|
//TODO UGLY!!!
|
||||||
if(this.projects_id === undefined) this.projects_id = FLOW.OMS_projects_id;
|
if(this.projects_id === undefined) this.projects_id = FLOW.GLOBALS.settings.project_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(this.projects_id === undefined)
|
if(this.projects_id === undefined)
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
|
|
||||||
//key is device, value = str
|
|
||||||
let sentValues= {};
|
|
||||||
|
|
||||||
function sendError(func, device, weight, str, extra, tb_output, instance, type) {
|
|
||||||
// if ((weight === ERRWEIGHT.DEBUG) && (instance.CONFIG.debug === false)){
|
|
||||||
// return; // Allow debug messages only if CONFIG.debug is active
|
|
||||||
// }
|
|
||||||
|
|
||||||
let key = device;
|
|
||||||
if(type != undefined) key = type;
|
|
||||||
|
|
||||||
if(sentValues.hasOwnProperty(key))
|
|
||||||
{
|
|
||||||
if(sentValues[key] == str)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sentValues[key] = str;
|
|
||||||
|
|
||||||
let content = {
|
|
||||||
"type": weight,
|
|
||||||
"status": "new",
|
|
||||||
"source": {
|
|
||||||
"func":func,
|
|
||||||
"component":instance.id,
|
|
||||||
"component_name":instance.name,
|
|
||||||
"edge":device
|
|
||||||
},
|
|
||||||
"message":str,
|
|
||||||
"message_data": extra
|
|
||||||
};
|
|
||||||
|
|
||||||
let msg = {};
|
|
||||||
msg[device] = [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values": {
|
|
||||||
"_event":content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// Msg can be outputted from components only after configuration
|
|
||||||
/*if (canSendErrData()){
|
|
||||||
sendBufferedErrors();
|
|
||||||
} else {
|
|
||||||
bufferError(msg);
|
|
||||||
}*/
|
|
||||||
instance.send(tb_output, msg); // Even if error server is unavailable, send this message to output, for other possible component connections
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let ERRWEIGHT = {
|
|
||||||
EMERGENCY: "emergency", // System unusable
|
|
||||||
ALERT: "alert", // Action must be taken immidiately
|
|
||||||
CRITICAL: "critical", // Component unable to function
|
|
||||||
ERROR: "error", // Error, but component able to recover from it
|
|
||||||
WARNING: "warning", // Possibility of error, system running futher
|
|
||||||
NOTICE: "notice", // Significant message but not an error, things user might want to know about
|
|
||||||
INFO: "informational", // Info
|
|
||||||
DEBUG: "debug" // Debug - only if CONFIG.debug is enabled
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
sendError,
|
|
||||||
ERRWEIGHT
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
const ERRWEIGHT = {
|
|
||||||
EMERGENCY: "emergency", // System unusable
|
|
||||||
ALERT: "alert", // Action must be taken immidiately
|
|
||||||
CRITICAL: "critical", // Component unable to function
|
|
||||||
ERROR: "error", // Error, but component able to recover from it
|
|
||||||
WARNING: "warning", // Possibility of error, system running futher
|
|
||||||
NOTICE: "notice", // Significant message but not an error, things user might want to know about
|
|
||||||
INFO: "informational", // Info
|
|
||||||
DEBUG: "debug" // Debug - only if CONFIG.debug is enabled
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function sendError(func, device, weight, str, extra){
|
|
||||||
if ((weight === ERRWEIGHT.DEBUG) && (instance.CONFIG.debug === false)){
|
|
||||||
return; // Allow debug messages only if CONFIG.debug is active
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = {
|
|
||||||
"type": weight,
|
|
||||||
"status": "new",
|
|
||||||
"source": {
|
|
||||||
"func":func,
|
|
||||||
"component":instance.id,
|
|
||||||
"component_name":instance.name,
|
|
||||||
"edge":myEdge
|
|
||||||
},
|
|
||||||
"message":str,
|
|
||||||
"message_data": extra
|
|
||||||
};
|
|
||||||
let msg = {};
|
|
||||||
msg[device] = [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values": {
|
|
||||||
"_event":content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
// Msg can be outputted from components only after configuration
|
|
||||||
/*if (canSendErrData()){
|
|
||||||
sendBufferedErrors();
|
|
||||||
} else {
|
|
||||||
bufferError(msg);
|
|
||||||
}*/
|
|
||||||
instance.send(0, msg); // Even if error server is unavailable, send this message to output, for other possible component connections
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
sendError,
|
|
||||||
ERRWEIGHT,
|
|
||||||
}
|
|
||||||
30
flow/helper/logger.js
Normal file
30
flow/helper/logger.js
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
//https://github.com/log4js-node/log4js-node/blob/master/examples/example.js
|
||||||
|
//file: { type: 'file', filename: path.join(__dirname, 'log/file.log') }
|
||||||
|
|
||||||
|
var log4js = require("log4js");
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
log4js.configure({
|
||||||
|
appenders: {
|
||||||
|
errLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../../", 'err.txt') },
|
||||||
|
monitorLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../../", 'monitor.txt') },
|
||||||
|
console: { type: 'console' }
|
||||||
|
},
|
||||||
|
categories: {
|
||||||
|
errLogs: { appenders: ['console', 'errLogs'], level: 'error' },
|
||||||
|
monitorLogs: { appenders: ['console', 'monitorLogs'], level: 'trace' },
|
||||||
|
//another: { appenders: ['console'], level: 'trace' },
|
||||||
|
default: { appenders: ['console'], level: 'trace' }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const errLogger = log4js.getLogger("errLogs");
|
||||||
|
const logger = log4js.getLogger();
|
||||||
|
const monitor = log4js.getLogger("monitorLogs");
|
||||||
|
|
||||||
|
//USAGE
|
||||||
|
//logger.debug("text")
|
||||||
|
//monitor.info('info');
|
||||||
|
//errLogger.error("some error");
|
||||||
|
|
||||||
|
module.exports = { errLogger, logger, monitor };
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
|
|
||||||
const { promisifyBuilder, makeMapFromDbResult } = require('./db_helper.js');
|
|
||||||
const dbNotifications = TABLE("notifications");
|
|
||||||
|
|
||||||
//key is device, value = str
|
//key is device, value = str
|
||||||
let sentValues= {};
|
let sentValues= {};
|
||||||
let notificationsData = {};
|
let notificationsData = null;
|
||||||
|
|
||||||
let ERRWEIGHT = {
|
let ERRWEIGHT = {
|
||||||
EMERGENCY: "emergency", // System unusable
|
EMERGENCY: "emergency", // System unusable
|
||||||
|
|
@ -24,12 +20,9 @@ function getKey(map, val) {
|
||||||
//https://stackoverflow.com/questions/41117799/string-interpolation-on-variable
|
//https://stackoverflow.com/questions/41117799/string-interpolation-on-variable
|
||||||
var template = (tpl, args) => tpl.replace(/\${(\w+)}/g, (_, v) => args[v]);
|
var template = (tpl, args) => tpl.replace(/\${(\w+)}/g, (_, v) => args[v]);
|
||||||
|
|
||||||
async function initNotifications()
|
|
||||||
{
|
|
||||||
let response = await promisifyBuilder(dbNotifications.find());
|
|
||||||
notificationsData = makeMapFromDbResult(response, "key");
|
|
||||||
|
|
||||||
console.log("initNotifications done" );
|
function initNotification() {
|
||||||
|
notificationsData = FLOW.GLOBALS.notificationsData;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendNotification(func, device, key, params, extra, tb_output, instance, saveKey) {
|
function sendNotification(func, device, key, params, extra, tb_output, instance, saveKey) {
|
||||||
|
|
@ -39,7 +32,7 @@ function sendNotification(func, device, key, params, extra, tb_output, instance,
|
||||||
let storeToSendValues = true;
|
let storeToSendValues = true;
|
||||||
if(saveKey == undefined) storeToSendValues = false;
|
if(saveKey == undefined) storeToSendValues = false;
|
||||||
|
|
||||||
let lang = FLOW.OMS_language;
|
let lang = FLOW.GLOBALS.settings.language;
|
||||||
if(lang != "en" || lang != "sk") lang = "en";
|
if(lang != "en" || lang != "sk") lang = "en";
|
||||||
|
|
||||||
let tpl = key;
|
let tpl = key;
|
||||||
|
|
@ -55,7 +48,8 @@ function sendNotification(func, device, key, params, extra, tb_output, instance,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
console.error("sendNotification: Notifications: undefined key", key, func, notificationsData);
|
//console.error("sendNotification: Notifications: undefined key", key, func, notificationsData);
|
||||||
|
console.error("sendNotification: Notifications: undefined key", key, func );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +85,7 @@ function sendNotification(func, device, key, params, extra, tb_output, instance,
|
||||||
|
|
||||||
if(storeToSendValues) sentValues[saveKey] = tpl;
|
if(storeToSendValues) sentValues[saveKey] = tpl;
|
||||||
|
|
||||||
let str = FLOW.OMS_rvo_name;
|
let str = FLOW.GLOBALS.settings.rvo_name;
|
||||||
if(str != "") str = str + ": ";
|
if(str != "") str = str + ": ";
|
||||||
str = str + tpl;
|
str = str + tpl;
|
||||||
|
|
||||||
|
|
@ -132,6 +126,6 @@ function sendNotification(func, device, key, params, extra, tb_output, instance,
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sendNotification,
|
sendNotification,
|
||||||
initNotifications,
|
ERRWEIGHT,
|
||||||
ERRWEIGHT
|
initNotification
|
||||||
}
|
}
|
||||||
|
|
@ -40,18 +40,17 @@ async function writeData(port, data, readbytes, timeout){
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
// If first item in data array is 255, we just write broadcast command to rsPort
|
// If first item in data array is 255, we just write broadcast command to rsPort
|
||||||
// We wait 3 seconds and resolve([ "b", "r", "o", "a", "d", "c", "a", "s", "t" ])
|
// We wait 3 seconds and resolve(["broadcast"])
|
||||||
// It is important to resolve with array
|
// It is important to resolve with array
|
||||||
if(data[0] == 255) {
|
if(data[0] == 255) {
|
||||||
|
|
||||||
port.write(Buffer.from(data), function(err) {
|
port.write(Buffer.from(data), function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
port.removeListener('data', callback);
|
|
||||||
reject(err.message);
|
reject(err.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(resolve, 3000, [ "b", "r", "o", "a", "d", "c", "a", "s", "t" ]);
|
setTimeout(resolve, 3000, ["broadcast"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,9 @@ exports.title = 'Info sender';
|
||||||
exports.version = '1.0.0';
|
exports.version = '1.0.0';
|
||||||
exports.group = 'Worksys';
|
exports.group = 'Worksys';
|
||||||
exports.color = '#2134B0';
|
exports.color = '#2134B0';
|
||||||
exports.input = 1;
|
exports.input = 2;
|
||||||
exports.output = 1
|
exports.output = 1
|
||||||
exports.click = false;
|
|
||||||
exports.author = 'oms-is';
|
|
||||||
exports.icon = 'bolt';
|
exports.icon = 'bolt';
|
||||||
exports.options = { edge: "undefined" };
|
|
||||||
|
|
||||||
const { networkInterfaces } = require('os');
|
const { networkInterfaces } = require('os');
|
||||||
|
|
||||||
|
|
@ -22,13 +19,12 @@ exports.html = `<div class="padding">
|
||||||
|
|
||||||
exports.readme = `# send all data to projects.worksys.io, required to monitor status of controller(unipi)`;
|
exports.readme = `# send all data to projects.worksys.io, required to monitor status of controller(unipi)`;
|
||||||
|
|
||||||
const fs = require('fs');
|
exports.install = function(instance) {
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
exports.install = async function(instance) {
|
|
||||||
|
|
||||||
|
let id;
|
||||||
let allValues = {};
|
let allValues = {};
|
||||||
let sendAllValuesInterval;
|
let sendAllValuesInterval;
|
||||||
|
let configured = false;
|
||||||
|
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
console.log(exports.title, "INSTALLED", now.toLocaleString("sk-SK"));
|
console.log(exports.title, "INSTALLED", now.toLocaleString("sk-SK"));
|
||||||
|
|
@ -48,22 +44,18 @@ exports.install = async function(instance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sendValues()
|
function sendValues()
|
||||||
{
|
{
|
||||||
const id = FLOW.OMS_projects_id;
|
if(!configured) return;
|
||||||
|
|
||||||
if(Object.keys(allValues).length > 0)
|
if(Object.keys(allValues).length > 0)
|
||||||
{
|
{
|
||||||
if(id !== undefined)
|
if(id)
|
||||||
{
|
{
|
||||||
delete allValues.__force__;
|
delete allValues.__force__;
|
||||||
let dataToSend = {...allValues};
|
let dataToSend = {...allValues};
|
||||||
dataToSend.id = id;
|
dataToSend.id = id;
|
||||||
dataToSend.ipAddresses = ipAddresses;
|
dataToSend.ipAddresses = ipAddresses;
|
||||||
//dataToSend.notify_date = new Date().toISOString().slice(0, 19).replace('T', ' ');
|
|
||||||
|
|
||||||
//console.log(exports.title, "------------>sendValues", dataToSend);
|
|
||||||
|
|
||||||
instance.send(0, dataToSend);
|
instance.send(0, dataToSend);
|
||||||
|
|
||||||
|
|
@ -71,7 +63,7 @@ exports.install = async function(instance) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
console.log(exports.title, "unable to send data, id is undefined");
|
console.log(exports.title, "unable to send data, no id");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -81,10 +73,14 @@ exports.install = async function(instance) {
|
||||||
clearInterval(sendAllValuesInterval);
|
clearInterval(sendAllValuesInterval);
|
||||||
})
|
})
|
||||||
|
|
||||||
instance.on("data", (flowdata) => {
|
instance.on("0", _ => {
|
||||||
|
id = FLOW.GLOBALS.settings.project_id;
|
||||||
|
configured = true;
|
||||||
|
})
|
||||||
|
|
||||||
|
instance.on("1", flowdata => {
|
||||||
|
|
||||||
allValues = { ...allValues, ...flowdata.data};
|
allValues = { ...allValues, ...flowdata.data};
|
||||||
|
|
||||||
//console.log("DATA RECEIVED", flowdata.data);
|
//console.log("DATA RECEIVED", flowdata.data);
|
||||||
|
|
||||||
//__force__
|
//__force__
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ exports.title = 'Modbus reader';
|
||||||
exports.version = '2.0.0';
|
exports.version = '2.0.0';
|
||||||
exports.group = 'Worksys';
|
exports.group = 'Worksys';
|
||||||
exports.color = '#2134B0';
|
exports.color = '#2134B0';
|
||||||
|
exports.input = 1;
|
||||||
exports.output = ["red", "white", "yellow"];
|
exports.output = ["red", "white", "yellow"];
|
||||||
exports.click = false;
|
exports.click = false;
|
||||||
exports.author = 'Rastislav Kovac';
|
exports.author = 'Rastislav Kovac';
|
||||||
|
|
@ -31,7 +32,10 @@ const SEND_TO = {
|
||||||
const numberOfNotResponding = {};
|
const numberOfNotResponding = {};
|
||||||
let tbName = null;
|
let tbName = null;
|
||||||
let mainSocket;
|
let mainSocket;
|
||||||
|
//number of phases inRVO
|
||||||
|
let phases;
|
||||||
|
//phases where voltage is 0 (set)
|
||||||
|
let noVoltage;
|
||||||
|
|
||||||
exports.install = function(instance) {
|
exports.install = function(instance) {
|
||||||
|
|
||||||
|
|
@ -55,10 +59,19 @@ exports.install = function(instance) {
|
||||||
// lampSwitchNotification helper variables
|
// lampSwitchNotification helper variables
|
||||||
this.onNotificationSent = false;
|
this.onNotificationSent = false;
|
||||||
this.offNotificationSent = false;
|
this.offNotificationSent = false;
|
||||||
|
this.phases = this.buildPhases();
|
||||||
|
|
||||||
this.startSocket();
|
this.startSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildPhases = () => {
|
||||||
|
let a = [];
|
||||||
|
for (let i = 1; i<= phases; i++) {
|
||||||
|
a.push(`Phase_${i}_voltage`)
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
startSocket = () => {
|
startSocket = () => {
|
||||||
|
|
||||||
let obj = this;
|
let obj = this;
|
||||||
|
|
@ -228,9 +241,7 @@ exports.install = function(instance) {
|
||||||
this.allValues = {};
|
this.allValues = {};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setNewStream = () =>
|
setNewStream = () =>
|
||||||
|
|
@ -282,7 +293,7 @@ exports.install = function(instance) {
|
||||||
if(!(values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_2_voltage") || values.hasOwnProperty("Phase_3_voltage"))) return;
|
if(!(values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_2_voltage") || values.hasOwnProperty("Phase_3_voltage"))) return;
|
||||||
|
|
||||||
Object.keys(values).map(singleValue => {
|
Object.keys(values).map(singleValue => {
|
||||||
if (["Phase_1_voltage", "Phase_2_voltage", "Phase_3_voltage"].includes(singleValue))
|
if (this.phases.includes(singleValue))
|
||||||
{
|
{
|
||||||
let l = singleValue.split("_");
|
let l = singleValue.split("_");
|
||||||
let phase = parseInt(l[1]);
|
let phase = parseInt(l[1]);
|
||||||
|
|
@ -291,13 +302,13 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
if(values[singleValue] == 0)
|
if(values[singleValue] == 0)
|
||||||
{
|
{
|
||||||
FLOW.OMS_no_voltage.add(phase);
|
noVoltage.add(phase);
|
||||||
sendNotification("modbus_reader: 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')
|
// console.log('no voltage')
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLOW.OMS_no_voltage.delete(phase);
|
noVoltage.delete(phase);
|
||||||
// console.log('voltage detected')
|
// console.log('voltage detected')
|
||||||
sendNotification("modbus_reader: 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);
|
||||||
}
|
}
|
||||||
|
|
@ -333,15 +344,20 @@ exports.install = function(instance) {
|
||||||
return Object.keys(objectName).length === 0 && objectName.constructor === Object;
|
return Object.keys(objectName).length === 0 && objectName.constructor === Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
function main() {
|
||||||
|
|
||||||
|
phases = FLOW.GLOBALS.settings.phases;
|
||||||
|
tbName = FLOW.GLOBALS.settings.rvoTbName;
|
||||||
|
noVoltage = FLOW.GLOBALS.settings.no_voltage;
|
||||||
mainSocket = new SocketWithClients();
|
mainSocket = new SocketWithClients();
|
||||||
tbName = FLOW.OMS_rvo_tbname;
|
|
||||||
|
|
||||||
// this notification is to show, that flow (unipi) has been restarted
|
// this notification is to show, that flow (unipi) has been restarted
|
||||||
sendNotification("modbus_reader", tbName, "flow_restart", {}, "", SEND_TO.slack, instance);
|
sendNotification("modbus_reader", tbName, "flow_restart", {}, "", SEND_TO.slack, instance);
|
||||||
|
}
|
||||||
|
|
||||||
}, 25000);
|
instance.on("0", function(_) {
|
||||||
|
main();
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
241
flow/show_dbdata.js
Normal file
241
flow/show_dbdata.js
Normal file
|
|
@ -0,0 +1,241 @@
|
||||||
|
exports.id = 'showdb';
|
||||||
|
exports.title = 'Show db data';
|
||||||
|
exports.group = 'Worksys';
|
||||||
|
exports.color = '#888600';
|
||||||
|
exports.version = '1.0.2';
|
||||||
|
exports.icon = 'sign-out';
|
||||||
|
exports.input = 7;
|
||||||
|
exports.output = 1;
|
||||||
|
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
|
exports.install = function(instance) {
|
||||||
|
|
||||||
|
instance.on("0", _ => {
|
||||||
|
instance.send(0, FLOW.GLOBALS.settings);
|
||||||
|
})
|
||||||
|
instance.on("1", _ => {
|
||||||
|
instance.send(0, FLOW.GLOBALS.relaysData);
|
||||||
|
})
|
||||||
|
instance.on("2", _ => {
|
||||||
|
instance.send(0, FLOW.GLOBALS.nodesData);
|
||||||
|
})
|
||||||
|
instance.on("3", _ => {
|
||||||
|
instance.send(0, FLOW.GLOBALS.pinsData);
|
||||||
|
})
|
||||||
|
instance.on("4", _ => {
|
||||||
|
instance.send(0, {rpcSwitchOffLine, rpcSetNodeDimming, rpcLineProfile, rpcNodeProfile, sunCalcExample, dataFromTerminalBroadcast})
|
||||||
|
})
|
||||||
|
instance.on("5", _ => {
|
||||||
|
exec("sudo tail -n 25 monitor.txt" , (err, stdout, stderr) => {
|
||||||
|
if (err || stderr) instance.send(0,{err, stderr});
|
||||||
|
else instance.send(0,stdout);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
instance.on("6", _ => {
|
||||||
|
exec("sudo tail -n 25 err.txt" , (err, stdout, stderr) => {
|
||||||
|
if (err || stderr) instance.send(0,{err, stderr});
|
||||||
|
else instance.send(0,stdout);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const rpcSwitchOffLine =
|
||||||
|
{
|
||||||
|
"topic": "v1/gateway/rpc",
|
||||||
|
"content": {
|
||||||
|
"device": "jbN4q7JPZmexgdnz2yKbWGDYAWwO0Q3BMX6ERLoV",
|
||||||
|
"data": {
|
||||||
|
"id": 8,
|
||||||
|
"method": "set_command",
|
||||||
|
"params": {
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity_type": "edb_line",
|
||||||
|
"tb_name": "MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"command": "switch",
|
||||||
|
"payload": {
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rpcSetNodeDimming =
|
||||||
|
{
|
||||||
|
"topic": "v1/gateway/rpc",
|
||||||
|
"content": {
|
||||||
|
"device": "jbN4q7JPZmexgdnz2yKbWGDYAWwO0Q3BMX6ERLoV",
|
||||||
|
"data": {
|
||||||
|
"id": 10,
|
||||||
|
"method": "set_command",
|
||||||
|
"params": {
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity_type": "street_luminaire",
|
||||||
|
"tb_name": "jbN4q7JPZmexgdnz2yKbWdDYAWwO0Q3BMX6ERLoV"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"command": "dimming",
|
||||||
|
"payload": {
|
||||||
|
"value": 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rpcLineProfile =
|
||||||
|
{
|
||||||
|
"topic": "v1/gateway/rpc",
|
||||||
|
"content": {
|
||||||
|
"device": "jbN4q7JPZmexgdnz2yKbWGDYAWwO0Q3BMX6ERLoV",
|
||||||
|
"data": {
|
||||||
|
"id": 9,
|
||||||
|
"method": "set_profile",
|
||||||
|
"params": {
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity_type": "edb_line",
|
||||||
|
"tb_name": "MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payload": {
|
||||||
|
"intervals": [
|
||||||
|
{
|
||||||
|
"value": 0,
|
||||||
|
"end_time": "20:00",
|
||||||
|
"start_time": "13:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": 1,
|
||||||
|
"end_time": "05:30",
|
||||||
|
"start_time": "20:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": 0,
|
||||||
|
"end_time": "13:00",
|
||||||
|
"start_time": "05:30"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"astro_clock": true,
|
||||||
|
"dawn_lux_sensor": false,
|
||||||
|
"dusk_lux_sensor": false,
|
||||||
|
"dawn_lux_sensor_value": 5,
|
||||||
|
"dusk_lux_sensor_value": 5,
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const rpcNodeProfile =
|
||||||
|
{
|
||||||
|
"topic": "v1/gateway/rpc",
|
||||||
|
"content": {
|
||||||
|
"device": "jbN4q7JPZmexgdnz2yKbWGDYAWwO0Q3BMX6ERLoV",
|
||||||
|
"data": {
|
||||||
|
"id": 11,
|
||||||
|
"method": "set_profile",
|
||||||
|
"params": {
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"entity_type": "street_luminaire",
|
||||||
|
"tb_name": "jbN4q7JPZmexgdnz2yKbWdDYAWwO0Q3BMX6ERLoV"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payload": {
|
||||||
|
"intervals": [
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 0,
|
||||||
|
"end_time": "17:50",
|
||||||
|
"start_time": "13:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 100,
|
||||||
|
"end_time": "21:30",
|
||||||
|
"start_time": "17:50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 0,
|
||||||
|
"end_time": "13:00",
|
||||||
|
"start_time": "07:10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 50,
|
||||||
|
"end_time": "00:00",
|
||||||
|
"start_time": "21:30"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 10,
|
||||||
|
"end_time": "04:30",
|
||||||
|
"start_time": "00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cct": 3000,
|
||||||
|
"value": 100,
|
||||||
|
"end_time": "07:10",
|
||||||
|
"start_time": "04:30"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"astro_clock": true,
|
||||||
|
"dawn_lux_sensor": false,
|
||||||
|
"dusk_lux_sensor": false,
|
||||||
|
"dawn_lux_sensor_value": 5,
|
||||||
|
"dusk_lux_sensor_value": 5,
|
||||||
|
"dawn_astro_clock_offset": 30,
|
||||||
|
"dusk_astro_clock_offset": 20,
|
||||||
|
"dawn_lux_sensor_time_window": 30,
|
||||||
|
"dusk_lux_sensor_time_window": 30,
|
||||||
|
"dawn_astro_clock_time_window": 60,
|
||||||
|
"dusk_astro_clock_time_window": 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sunCalcExample = {
|
||||||
|
dusk_no_offset: '20:18',
|
||||||
|
dawn_no_offset: '05:19',
|
||||||
|
dusk: '20:18',
|
||||||
|
dusk_hours: 20,
|
||||||
|
dusk_minutes: 18,
|
||||||
|
dawn: '05:19',
|
||||||
|
dawn_hours: 5,
|
||||||
|
dawn_minutes: 19,
|
||||||
|
dusk_time: 1715278688962,
|
||||||
|
dawn_time: 1715224744357,
|
||||||
|
dusk_astro_clock_offset: 0,
|
||||||
|
dawn_astro_clock_offset: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const dataFromTerminalBroadcast = {
|
||||||
|
address: 4294967295,
|
||||||
|
byte1: 0,
|
||||||
|
byte2: 0,
|
||||||
|
byte3: 0,
|
||||||
|
byte4: 96,
|
||||||
|
name: "Time Schedule settings",
|
||||||
|
recipient: 2,
|
||||||
|
register: 8,
|
||||||
|
rw: 1
|
||||||
|
}
|
||||||
|
|
@ -11,9 +11,6 @@ exports.options = { 'name':'', 'types': '["emergency", "critical", "error", "ale
|
||||||
|
|
||||||
exports.html = `<div class="padding">
|
exports.html = `<div class="padding">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
|
||||||
<div data-jc="textbox" data-jc-path="name" data-jc-config="required:true">@(Name of this server)</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div data-jc="textbox" data-jc-path="slack_channel" data-jc-config="required:false">@(Slack channel to receive the alerts)</div>
|
<div data-jc="textbox" data-jc-path="slack_channel" data-jc-config="required:false">@(Slack channel to receive the alerts)</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -170,11 +167,12 @@ exports.install = function(instance) {
|
||||||
FLOW["savedSlackMessages"] = [];
|
FLOW["savedSlackMessages"] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance.options.name = FLOW.GLOBALS.settings.rvo_name;
|
||||||
if (instance.options.name) {
|
if (instance.options.name) {
|
||||||
instance.status('Running');
|
instance.status('Running');
|
||||||
running = true;
|
running = true;
|
||||||
} else {
|
} else {
|
||||||
instance.status('Please enter name', 'red');
|
instance.status('Please run options again', 'red');
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -183,5 +181,7 @@ exports.install = function(instance) {
|
||||||
};
|
};
|
||||||
|
|
||||||
instance.on('options', instance.reconfigure);
|
instance.on('options', instance.reconfigure);
|
||||||
instance.reconfigure();
|
setTimeout(instance.reconfigure, 10000);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -2,6 +2,7 @@ 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.version = '1.0.3';
|
exports.version = '1.0.3';
|
||||||
exports.output = ["red", "white", "blue"];
|
exports.output = ["red", "white", "blue"];
|
||||||
exports.author = 'Rastislav Kovac';
|
exports.author = 'Rastislav Kovac';
|
||||||
|
|
@ -9,7 +10,9 @@ 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 instanceSendTo = {
|
const { errLogger, logger, monitor } = require('./helper/logger');
|
||||||
|
|
||||||
|
const SEND_TO = {
|
||||||
debug: 0,
|
debug: 0,
|
||||||
tb: 1,
|
tb: 1,
|
||||||
dido_controller: 2
|
dido_controller: 2
|
||||||
|
|
@ -18,56 +21,16 @@ const instanceSendTo = {
|
||||||
//read temperature - frequency
|
//read temperature - frequency
|
||||||
let timeoutMin = 5;//minutes
|
let timeoutMin = 5;//minutes
|
||||||
|
|
||||||
var path = require('path');
|
|
||||||
var log4js = require("log4js");
|
|
||||||
|
|
||||||
log4js.configure({
|
|
||||||
appenders: {
|
|
||||||
errLogs: { type: 'file', filename: path.join(__dirname + "/../", 'err.txt') },
|
|
||||||
monitorLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../", 'monitor.txt') },
|
|
||||||
console: { type: 'console' }
|
|
||||||
},
|
|
||||||
categories: {
|
|
||||||
errLogs: { appenders: ['console', 'errLogs'], level: 'error' },
|
|
||||||
monitorLogs: { appenders: ['console', 'monitorLogs'], level: 'trace' },
|
|
||||||
//another: { appenders: ['console'], level: 'trace' },
|
|
||||||
default: { appenders: ['console'], level: 'trace' }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const errLogger = log4js.getLogger("errLogs");
|
|
||||||
const logger = log4js.getLogger();
|
|
||||||
const monitor = log4js.getLogger("monitorLogs");
|
|
||||||
|
|
||||||
//logger.debug("text")
|
|
||||||
//monitor.info('info');
|
|
||||||
//errLogger.error("some error");
|
|
||||||
|
|
||||||
const { promisifyBuilder, makeMapFromDbResult } = require('./helper/db_helper');
|
|
||||||
const dbSettings = TABLE("settings");
|
|
||||||
let temperatureAddress = "";
|
|
||||||
|
|
||||||
async function loadSettings()
|
|
||||||
{
|
|
||||||
//todo global FLOW.OMS_edgeName is making problem, so we load it here as well, it should not be
|
|
||||||
let responseSettings = await promisifyBuilder(dbSettings.find());
|
|
||||||
temperatureAddress = responseSettings[0]["temperature_adress"];
|
|
||||||
}
|
|
||||||
|
|
||||||
loadSettings();
|
|
||||||
|
|
||||||
|
|
||||||
exports.install = function(instance) {
|
exports.install = function(instance) {
|
||||||
|
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const { sendNotification, ERRWEIGHT } = require('./helper/notification_reporter');
|
const { sendNotification } = require('./helper/notification_reporter');
|
||||||
|
|
||||||
let startRead;
|
let startRead;
|
||||||
let dataToTb;
|
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
let rvoTbName = "";
|
||||||
let edgeName = "";
|
let temperatureAddress = "";
|
||||||
|
|
||||||
|
|
||||||
logger.debug(exports.title, "installed");
|
logger.debug(exports.title, "installed");
|
||||||
|
|
||||||
|
|
@ -76,11 +39,11 @@ exports.install = function(instance) {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const start = function() {
|
const main = function() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if(FLOW.OMS_controller_type === "unipi")
|
if(FLOW.GLOBALS.settings.controller_type === "unipi")
|
||||||
{
|
{
|
||||||
clearInterval(startRead);
|
clearInterval(startRead);
|
||||||
return;
|
return;
|
||||||
|
|
@ -88,71 +51,23 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
if(temperatureAddress === "") throw "gettemperature: temperatureAddress is not defined";
|
if(temperatureAddress === "") throw "gettemperature: temperatureAddress is not defined";
|
||||||
|
|
||||||
logger.debug("FLOW.OMS_temperature_adress", FLOW.OMS_temperature_adress);
|
|
||||||
|
|
||||||
exec(`owread -C ${temperatureAddress}/temperature`, (error, stdout, stderr) => {
|
exec(`owread -C ${temperatureAddress}/temperature`, (error, stdout, stderr) => {
|
||||||
|
|
||||||
edgeName = FLOW.OMS_edgeName;
|
if(!error)
|
||||||
|
|
||||||
if(edgeName !== "")
|
|
||||||
{
|
{
|
||||||
if(error)
|
parseData(stdout)
|
||||||
{
|
|
||||||
|
|
||||||
if(FLOW.OMS_brokerready == undefined)
|
|
||||||
{
|
|
||||||
logger.debug("gettemparature - FLOW.OMS_brokerready is undefined");
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
start();
|
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FLOW.OMS_brokerready)
|
sendNotification("main", rvoTbName, "thermometer_is_not_responding", {}, {"Error": error}, SEND_TO.tb, instance, "thermometer");
|
||||||
{
|
monitor.info("Thermometer is not responding", error);
|
||||||
//sendNotification("start", edgeName, ERRWEIGHT.WARNING, "Thermometer is not responding", {"Error": error}, instanceSendTo.tb, instance, "thermometer");
|
instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"});
|
||||||
sendNotification("start", edgeName, "thermometer_is_not_responding", {}, {"Error": error}, instanceSendTo.tb, instance, "thermometer");
|
|
||||||
}
|
|
||||||
|
|
||||||
let status = "NOK";
|
|
||||||
dataToTb = {
|
|
||||||
[edgeName]: [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values": {
|
|
||||||
"status": status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor.info("Thermometer is not responding", error, FLOW.OMS_brokerready);
|
|
||||||
|
|
||||||
// instance.send(instanceSendTo.tb, dataToTb); // poslat stav nok do tb, ak to handluje dido_controller ??
|
|
||||||
instance.send(instanceSendTo.dido_controller, {status: "NOK-thermometer"});
|
|
||||||
}
|
|
||||||
else parseData(stdout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
monitor.info("gettemperature: edgeName is not defined", FLOW.OMS_edgeName);
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
start();
|
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//instance.send({"Temp":stdout,"stderr":stderr,"err":error});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(err) {
|
catch(err) {
|
||||||
errLogger.error(exports.title, err);
|
errLogger.error(exports.title, err);
|
||||||
|
clearInterval(startRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,30 +81,17 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
if(counter > 290)
|
if(counter > 290)
|
||||||
{
|
{
|
||||||
instance.send(instanceSendTo.debug, "[Get temperature component] - temperature data are comming again from RVO after more than 1 day break");
|
instance.send(SEND_TO.debug, "[Get temperature component] - temperature data are comming again from RVO after more than 1 day break");
|
||||||
|
sendNotification("parseData", rvoTbName, "thermometer_is_responding_again", {}, "", SEND_TO.tb, instance, "thermometer");
|
||||||
//sendNotification("parseData", edgeName, ERRWEIGHT.NOTICE, "Thermometer is working again", "", instanceSendTo.tb, instance, "thermometer");
|
|
||||||
if(FLOW.OMS_brokerready) sendNotification("parseData", edgeName, "thermometer_is_responding_again", {}, "", instanceSendTo.tb, instance, "thermometer");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("gettemperature", data);
|
logger.debug("gettemperature", data);
|
||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
"temperature": Number(data.toFixed(2)),
|
"temperature": Number(data.toFixed(2)),
|
||||||
"status": "OK"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dataToTb = {
|
instance.send(SEND_TO.dido_controller, {values: values});
|
||||||
[edgeName]: [
|
|
||||||
{
|
|
||||||
"ts": Date.now(),
|
|
||||||
"values":values
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
instance.send(instanceSendTo.tb, dataToTb);
|
|
||||||
instance.send(instanceSendTo.dido_controller, values);
|
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -200,24 +102,21 @@ exports.install = function(instance) {
|
||||||
//ked je problem 1 den
|
//ked je problem 1 den
|
||||||
let day = 24 * 60 / timeoutMin;
|
let day = 24 * 60 / timeoutMin;
|
||||||
if ( counter > day && counter < day + 2 ) {
|
if ( counter > day && counter < day + 2 ) {
|
||||||
//sendNotification("parseData", edgeName, ERRWEIGHT.WARNING, "Thermometer receives invalid data", "", instanceSendTo.tb, instance, "thermometer");
|
//sendNotification("parseData", rvoTbName, ERRWEIGHT.WARNING, "Thermometer receives invalid data", "", SEND_TO.tb, instance, "thermometer");
|
||||||
sendNotification("parseData", edgeName, "thermometer_sends_invalid_data", {}, "", instanceSendTo.tb, instance, "thermometer");
|
sendNotification("parseData", rvoTbName, "thermometer_sends_invalid_data", {}, "", SEND_TO.tb, instance, "thermometer");
|
||||||
|
|
||||||
instance.send(instanceSendTo.debug, "[Get temperature component] - no temperature data from RVO for more than 1 day");
|
instance.send(SEND_TO.debug, "[Get temperature component] - no temperature data from RVO for more than 1 day");
|
||||||
instance.send(instanceSendTo.dido_controller, {status: "NOK-thermometer"});
|
instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(function(){
|
instance.on("data", _ => {
|
||||||
start();
|
temperatureAddress = FLOW.GLOBALS.settings.temperature_address;
|
||||||
}, 10000);
|
rvoTbName = FLOW.GLOBALS.settings.rvoTbName;
|
||||||
|
startRead = setInterval(main, timeoutMin * 1000 * 60);
|
||||||
startRead = setInterval(start, timeoutMin * 1000 * 60);
|
main();
|
||||||
|
})
|
||||||
//testing
|
|
||||||
//setInterval(() => {instance.send(instanceSendTo.dido_controller, {status: "NOK-thermometer"})}, 180000);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -4,12 +4,9 @@ exports.group = 'MQTT';
|
||||||
exports.color = '#888600';
|
exports.color = '#888600';
|
||||||
exports.version = '1.0.2';
|
exports.version = '1.0.2';
|
||||||
exports.icon = 'sign-out';
|
exports.icon = 'sign-out';
|
||||||
exports.input = 1;
|
exports.input = 2;
|
||||||
exports.output = ["red", "white", "blue"];
|
exports.output = 4;
|
||||||
exports.author = 'Daniel Segeš';
|
|
||||||
exports.options = { host: 'tb-stage.worksys.io', port: 1883, clientid: "", username: "" };
|
exports.options = { host: 'tb-stage.worksys.io', port: 1883, clientid: "", username: "" };
|
||||||
exports.npm = ['mqtt'];
|
|
||||||
|
|
||||||
|
|
||||||
exports.html = `<div class="padding">
|
exports.html = `<div class="padding">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -41,21 +38,22 @@ Added:
|
||||||
- rpc response
|
- rpc response
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const instanceSendTo = {
|
const { promisifyBuilder } = require('./helper/db_helper');
|
||||||
|
const { errLogger, monitor } = require('./helper/logger');
|
||||||
|
const fs = require('fs');
|
||||||
|
const mqtt = require('mqtt');
|
||||||
|
|
||||||
|
const SEND_TO = {
|
||||||
debug: 0,
|
debug: 0,
|
||||||
rpcCall: 1,
|
rpcCall: 1,
|
||||||
services: 2
|
services: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
const { promisifyBuilder, makeMapFromDbResult } = require('./helper/db_helper.js');
|
|
||||||
|
|
||||||
//CONFIG
|
//CONFIG
|
||||||
let useLog4js = true;
|
|
||||||
let createTelemetryBackup = true;
|
let createTelemetryBackup = true;
|
||||||
let saveTelemetryOnError = true;//backup_on_failure overrides this value
|
let saveTelemetryOnError = true;//backup_on_failure overrides this value
|
||||||
//------------------------
|
//------------------------
|
||||||
|
|
||||||
var fs = require('fs');
|
|
||||||
let rollers;
|
let rollers;
|
||||||
if(createTelemetryBackup) rollers = require('streamroller');
|
if(createTelemetryBackup) rollers = require('streamroller');
|
||||||
|
|
||||||
|
|
@ -64,56 +62,18 @@ let insertNoSqlCounter = 0;
|
||||||
let insertBackupNoSqlCounter = 0;
|
let insertBackupNoSqlCounter = 0;
|
||||||
let processingData = false;
|
let processingData = false;
|
||||||
|
|
||||||
let backup_on_failure = false;//== saveTelemetryOnError - create backup broker send failure
|
let backup_on_failure = false;//== saveTelemetryOnError - create backup client send failure
|
||||||
let restore_from_backup = 0; //how many rows process at once?
|
let restore_from_backup = 0; //how many rows process at once?
|
||||||
let restore_backup_wait = 0;//wait seconds
|
let restore_backup_wait = 0;//wait seconds
|
||||||
let lastRestoreTime = 0;
|
let lastRestoreTime = 0;
|
||||||
|
|
||||||
let errLogger;
|
// if there is an error in client connection, flow logs to monitor.txt. Not to log messages every second, we use sendClientError variable
|
||||||
let logger;
|
let sendClientError = true;
|
||||||
let monitor;
|
|
||||||
|
|
||||||
//TODO brokerready and sendBrokerError seems to be the same. Moreover, we use FLOW_OMS_brokerready variable!!
|
|
||||||
//
|
|
||||||
// if there is an error in broker connection, flow logs to monitor.txt. Not to log messages every second, we use sendBrokerError variable
|
|
||||||
let sendBrokerError = true;
|
|
||||||
|
|
||||||
if(useLog4js)
|
|
||||||
{
|
|
||||||
var path = require('path');
|
|
||||||
var log4js = require("log4js");
|
|
||||||
|
|
||||||
log4js.configure({
|
|
||||||
appenders: {
|
|
||||||
errLogs: { type: 'file', filename: path.join(__dirname + "/../", 'err.txt') },
|
|
||||||
monitorLogs: { type: 'file', compress:true, daysToKeep: 2, maxLogSize: 1048576, backups: 1, keepFileExt: true, filename: path.join(__dirname + "/../", 'monitor.txt') },
|
|
||||||
console: { type: 'console' }
|
|
||||||
},
|
|
||||||
categories: {
|
|
||||||
errLogs: { appenders: ['console', 'errLogs'], level: 'error' },
|
|
||||||
monitorLogs: { appenders: ['console', 'monitorLogs'], level: 'trace' },
|
|
||||||
//another: { appenders: ['console'], level: 'trace' },
|
|
||||||
default: { appenders: ['console'], level: 'trace' }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
errLogger = log4js.getLogger("errLogs");
|
|
||||||
logger = log4js.getLogger();
|
|
||||||
monitor = log4js.getLogger("monitorLogs");
|
|
||||||
|
|
||||||
//USAGE
|
|
||||||
//logger.debug("text");
|
|
||||||
//monitor.info('info');
|
|
||||||
//errLogger.error("some error");
|
|
||||||
}
|
|
||||||
|
|
||||||
process.on('uncaughtException', function (err) {
|
process.on('uncaughtException', function (err) {
|
||||||
|
|
||||||
if(errLogger)
|
|
||||||
{
|
|
||||||
errLogger.error('uncaughtException:', err.message)
|
errLogger.error('uncaughtException:', err.message)
|
||||||
errLogger.error(err.stack);
|
errLogger.error(err.stack);
|
||||||
}
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
//send to service
|
//send to service
|
||||||
|
|
@ -127,13 +87,9 @@ const nosqlBackup = NOSQL('/backup/tbdata');
|
||||||
|
|
||||||
exports.install = function(instance) {
|
exports.install = function(instance) {
|
||||||
|
|
||||||
var broker;
|
var client;
|
||||||
var opts;
|
var opts;
|
||||||
var brokerready = false;
|
var clientReady = false;
|
||||||
|
|
||||||
instance.on('options', loadSettings);
|
|
||||||
|
|
||||||
mqtt = require('mqtt');
|
|
||||||
|
|
||||||
// wsmqtt status for notification purposes on projects.worksys.io database
|
// wsmqtt status for notification purposes on projects.worksys.io database
|
||||||
let wsmqttName = null;
|
let wsmqttName = null;
|
||||||
|
|
@ -149,14 +105,21 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
function sendWsStatus()
|
function sendWsStatus()
|
||||||
{
|
{
|
||||||
instance.send(instanceSendTo.services, {[wsmqttName]: wsmqtt_status});
|
instance.send(SEND_TO.services, {[wsmqttName]: wsmqtt_status});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendWsStatusVar = setInterval(sendWsStatus, 180000);
|
|
||||||
|
|
||||||
|
function main()
|
||||||
|
{
|
||||||
|
if(!FLOW.dbLoaded) return;
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
|
clearInterval(sendWsStatus);
|
||||||
|
sendWsStatusVar = setInterval(sendWsStatus, 180000);
|
||||||
|
}
|
||||||
|
|
||||||
//set opts according to db settings
|
//set opts according to db settings
|
||||||
async function loadSettings()
|
function loadSettings()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(instance.options.host !== "")
|
if(instance.options.host !== "")
|
||||||
|
|
@ -179,21 +142,17 @@ exports.install = function(instance) {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
const dbSettings = TABLE("settings");
|
const SETTINGS = FLOW.GLOBALS.settings;
|
||||||
let responseSettings = await promisifyBuilder(dbSettings.find());
|
backup_on_failure = SETTINGS.backup_on_failure;
|
||||||
|
|
||||||
backup_on_failure = responseSettings[0]["backup_on_failure"];
|
|
||||||
saveTelemetryOnError = backup_on_failure;
|
saveTelemetryOnError = backup_on_failure;
|
||||||
|
|
||||||
restore_from_backup = responseSettings[0]["restore_from_backup"];
|
restore_from_backup = SETTINGS.restore_from_backup;
|
||||||
restore_backup_wait = responseSettings[0]["restore_backup_wait"];
|
restore_backup_wait = SETTINGS.restore_backup_wait;
|
||||||
|
|
||||||
let mqtt_host = responseSettings[0]["mqtt_host"];
|
let mqtt_host = SETTINGS.mqtt_host;
|
||||||
let mqtt_clientid = responseSettings[0]["mqtt_clientid"];
|
let mqtt_clientid = SETTINGS.mqtt_clientid;
|
||||||
let mqtt_username = responseSettings[0]["mqtt_username"];
|
let mqtt_username = SETTINGS.mqtt_username;
|
||||||
let mqtt_port = responseSettings[0]["mqtt_port"];
|
let mqtt_port = SETTINGS.mqtt_port;
|
||||||
|
|
||||||
console.log("wsmqttpublich -> loadSettings from db", responseSettings[0]);
|
|
||||||
|
|
||||||
opts = {
|
opts = {
|
||||||
host: mqtt_host,
|
host: mqtt_host,
|
||||||
|
|
@ -216,27 +175,23 @@ exports.install = function(instance) {
|
||||||
var url = "mqtt://" + opts.host + ":" + opts.port;
|
var url = "mqtt://" + opts.host + ":" + opts.port;
|
||||||
console.log("MQTT URL: ", url);
|
console.log("MQTT URL: ", url);
|
||||||
|
|
||||||
broker = mqtt.connect(url, opts);
|
client = mqtt.connect(url, opts);
|
||||||
|
|
||||||
broker.on('connect', function() {
|
client.on('connect', function() {
|
||||||
instance.status("Connected", "green");
|
instance.status("Connected", "green");
|
||||||
monitor.info("MQTT broker connected");
|
monitor.info("MQTT client connected");
|
||||||
|
|
||||||
sendBrokerError = true;
|
sendClientError = true;
|
||||||
|
clientReady = true;
|
||||||
brokerready = true;
|
|
||||||
FLOW.OMS_brokerready = brokerready;
|
|
||||||
wsmqtt_status = 'connected';
|
wsmqtt_status = 'connected';
|
||||||
});
|
});
|
||||||
|
|
||||||
broker.on('reconnect', function() {
|
client.on('reconnect', function() {
|
||||||
instance.status("Reconnecting", "yellow");
|
instance.status("Reconnecting", "yellow");
|
||||||
brokerready = false;
|
clientReady = false;
|
||||||
|
|
||||||
FLOW.OMS_brokerready = brokerready;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
broker.on('message', function(topic, message) {
|
client.on('message', function(topic, message) {
|
||||||
// message is type of buffer
|
// message is type of buffer
|
||||||
message = message.toString();
|
message = message.toString();
|
||||||
if (message[0] === '{') {
|
if (message[0] === '{') {
|
||||||
|
|
@ -244,50 +199,53 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
message = JSON.parse(message);
|
message = JSON.parse(message);
|
||||||
if (message.hasOwnProperty("device") && message.hasOwnProperty("data") && message.data.hasOwnProperty("id")) {
|
if (message.hasOwnProperty("device") && message.hasOwnProperty("data") && message.data.hasOwnProperty("id")) {
|
||||||
broker.publish(topic, `{"device": ${message.device}, "id": ${message.data.id}, "data": {"success": true}}`, {qos:1});
|
client.publish(topic, `{"device": ${message.device}, "id": ${message.data.id}, "data": {"success": true}}`, {qos:1});
|
||||||
instance.send(instanceSendTo.rpcCall, {"device": message.device, "id": message.data.id, "RPC response": {"success": true}});
|
instance.send(SEND_TO.rpcCall, {"device": message.device, "id": message.data.id, "RPC response": {"success": true}});
|
||||||
}
|
}
|
||||||
|
|
||||||
}, () => instance.debug('MQTT: Error parsing data', message));
|
}, () => instance.debug('MQTT: Error parsing data', message));
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.send(instanceSendTo.rpcCall, {"topic":topic, "content":message });
|
instance.send(SEND_TO.rpcCall, {"topic":topic, "content":message });
|
||||||
});
|
});
|
||||||
|
|
||||||
broker.on('close', function(err) {
|
client.on('close', function(err) {
|
||||||
brokerready = false;
|
clientReady = false;
|
||||||
FLOW.OMS_brokerready = brokerready;
|
|
||||||
wsmqtt_status = 'disconnected';
|
wsmqtt_status = 'disconnected';
|
||||||
|
|
||||||
if (err && err.toString().indexOf('Error')) {
|
if (err && err.toString().indexOf('Error')) {
|
||||||
instance.status("Err: "+err.code, "red");
|
instance.status("Err: "+err.code, "red");
|
||||||
instance.send(instanceSendTo.debug, {"message":"Broker CLOSE signal received !", "error":err, "opt":opts });
|
instance.send(SEND_TO.debug, {"message":"Client CLOSE signal received !", "error":err, "opt":opts });
|
||||||
} else {
|
} else {
|
||||||
instance.status("Disconnected", "red");
|
instance.status("Disconnected", "red");
|
||||||
instance.send(instanceSendTo.debug, {"message":"Broker CLOSE signal received !", "error":err, "opt":opts });
|
instance.send(SEND_TO.debug, {"message":"Client CLOSE signal received !", "error":err, "opt":opts });
|
||||||
}
|
}
|
||||||
|
|
||||||
broker.reconnect();
|
client.reconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
broker.on('error', function(err) {
|
client.on('error', function(err) {
|
||||||
instance.status("Err: "+ err.code, "red");
|
instance.status("Err: "+ err.code, "red");
|
||||||
instance.send(instanceSendTo.debug, {"message":"Broker ERROR signal received !", "error":err, "opt":opts });
|
instance.send(SEND_TO.debug, {"message":"Client ERROR signal received !", "error":err, "opt":opts });
|
||||||
if(sendBrokerError) {
|
if(sendClientError) {
|
||||||
monitor.info('MQTT broker error', err);
|
monitor.info('MQTT client error', err);
|
||||||
sendBrokerError = false;
|
sendClientError = false;
|
||||||
}
|
}
|
||||||
brokerready = false;
|
clientReady = false;
|
||||||
FLOW.OMS_brokerready = brokerready;
|
|
||||||
wsmqtt_status = 'disconnected';
|
wsmqtt_status = 'disconnected';
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.on('data', function(data) {
|
|
||||||
|
|
||||||
if (brokerready)
|
instance.on("0", _ => {
|
||||||
|
main();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
instance.on('1', function(data) {
|
||||||
|
|
||||||
|
if(clientReady)
|
||||||
{
|
{
|
||||||
//do we have some data in backup file?
|
//do we have some data in backup file?
|
||||||
//if any, process data from database
|
//if any, process data from database
|
||||||
|
|
@ -296,13 +254,14 @@ exports.install = function(instance) {
|
||||||
//read telemetry data and send back to server
|
//read telemetry data and send back to server
|
||||||
if(!processingData) processDataFromDatabase();
|
if(!processingData) processDataFromDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brokerready)
|
if(clientReady)
|
||||||
{
|
{
|
||||||
let stringifiedJson = JSON.stringify(data.data);
|
let stringifiedJson = JSON.stringify(data.data);
|
||||||
broker.publish("v1/gateway/telemetry", stringifiedJson, {qos: 1});
|
client.publish("v1/gateway/telemetry", stringifiedJson, {qos: 1});
|
||||||
|
|
||||||
|
instance.send(3, stringifiedJson);
|
||||||
|
|
||||||
//backup telemetry
|
//backup telemetry
|
||||||
if(createTelemetryBackup)
|
if(createTelemetryBackup)
|
||||||
|
|
@ -327,8 +286,8 @@ exports.install = function(instance) {
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if(logger) logger.debug("Broker unavailable. Data not sent !", JSON.stringify(data.data));
|
//logger.debug("Client unavailable. Data not sent !", JSON.stringify(data.data));
|
||||||
instance.send(instanceSendTo.debug, {"message":"Broker unavailable. Data not sent !", "data": data.data });
|
instance.send(SEND_TO.debug, {"message":"Client unavailable. Data not sent !", "data": data.data });
|
||||||
|
|
||||||
if(saveTelemetryOnError)
|
if(saveTelemetryOnError)
|
||||||
{
|
{
|
||||||
|
|
@ -345,8 +304,8 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
|
|
||||||
instance.close = function(done) {
|
instance.close = function(done) {
|
||||||
if (brokerready){
|
if(clientReady){
|
||||||
broker.end();
|
client.end();
|
||||||
clearInterval(sendWsStatusVar);
|
clearInterval(sendWsStatusVar);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -443,10 +402,7 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
const processDataFromDatabase = async () => {
|
const processDataFromDatabase = async () => {
|
||||||
|
|
||||||
if(restore_from_backup <= 0)
|
if(restore_from_backup <= 0) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//calculate diff
|
//calculate diff
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
@ -478,7 +434,7 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
for(let i = 0; i < records.length; i++)
|
for(let i = 0; i < records.length; i++)
|
||||||
{
|
{
|
||||||
if (brokerready) {
|
if(clientReady) {
|
||||||
|
|
||||||
let item = records[i];
|
let item = records[i];
|
||||||
let id = item.id;
|
let id = item.id;
|
||||||
|
|
@ -493,7 +449,8 @@ exports.install = function(instance) {
|
||||||
delete o.id;
|
delete o.id;
|
||||||
let message = JSON.stringify(o);
|
let message = JSON.stringify(o);
|
||||||
|
|
||||||
broker.publish("v1/gateway/telemetry", message, {qos:1});
|
client.publish("v1/gateway/telemetry", message, {qos:1});
|
||||||
|
instance.send(3, message);
|
||||||
|
|
||||||
//remove from database
|
//remove from database
|
||||||
await promisifyBuilder(nosql.remove().where("id", id));
|
await promisifyBuilder(nosql.remove().where("id", id));
|
||||||
|
|
@ -533,8 +490,6 @@ exports.install = function(instance) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSettings();
|
instance.on('options', main);
|
||||||
|
|
||||||
//instance.on('options', instance.reconfigure);
|
|
||||||
//instance.reconfigure();
|
//instance.reconfigure();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue