2024-05-07 16:28:43 +02:00
exports . id = 'cmd_manager' ;
exports . title = 'CMD Manager' ;
exports . group = 'Worksys' ;
exports . color = '#5D9CEC' ;
exports . version = '0.0.3' ;
exports . output = [ 'red' , 'blue' , 'yellow' , 'blue' , 'white' ] ;
//blue - send message to relays
exports . input = true ;
exports . author = 'Daniel Segeš' ;
exports . icon = 'cloud-upload' ;
//exports.npm = ['serialport' , 'child_process'];
exports . html = `
< div class = "padding" >
< div class = "row" >
< div class = "col-md-12" >
< div > RPC - run RPC calls < / d i v > < b r >
< / d i v >
< / d i v >
2024-05-14 16:29:11 +02:00
< div data - jc = "textbox" data - jc - path = "username" class = "m" data - jc - config = "required:true" > @ ( User ) < / d i v >
< div class = "row" >
< div class = "col-md-6 m" >
< div data - jc = "textbox" data - jc - path = "userpassword" data - jc - config = "required:true" > @ ( Password ) < / d i v >
< / d i v >
< div class = "col-md-6 m" >
< div data - jc = "textbox" data - jc - path = "edge" data - jc - config = "required:true" > @ ( My edge ) < / d i v >
< / d i v >
< / d i v >
2024-05-07 16:28:43 +02:00
< / d i v >
` ;
exports . readme = ` Manager for CMD calls ` ;
const SerialPort = require ( 'serialport' ) ;
const { exec } = require ( 'child_process' ) ;
const { crc8 , crc16 , crc32 } = require ( 'easy-crc' ) ;
const { openPort , runSyncExec , writeData } = require ( './helper/serialport_helper.js' ) ;
const { bytesToInt , longToByteArray , addZeroBefore , isEmptyObject , convertUTCDateToLocalDate } = require ( './helper/utils' ) ;
const bitwise = require ( 'bitwise' ) ;
var SunCalc = require ( './helper/suncalc.js' ) ;
const DataToTbHandler = require ( './helper/DataToTbHandler.js' ) ;
const ErrorToServiceHandler = require ( './helper/ErrorToServiceHandler.js' ) ;
2024-05-14 16:29:11 +02:00
const { promisifyBuilder , makeMapFromDbResult } = require ( './helper/db_helper.js' ) ;
2024-05-07 16:28:43 +02:00
const { sendNotification , initNotifications , ERRWEIGHT } = require ( './helper/notification_reporter.js' ) ;
2024-05-14 16:29:11 +02:00
const dbNodes = TABLE ( "nodes" ) ;
const dbRelays = TABLE ( "relays" ) ;
const dbSettings = TABLE ( "settings" ) ;
2024-05-07 16:28:43 +02:00
//https://github.com/log4js-node/log4js-node/blob/master/examples/example.js
//file: { type: 'file', filename: path.join(__dirname, 'log/file.log') }
var path = require ( 'path' ) ;
var log4js = require ( "log4js" ) ;
const process = require ( 'process' ) ;
2024-05-14 16:29:11 +02:00
//TODO - to remove?
// runTasks intervals
const SHORT _INTERVAL = 50 ;
const LONG _INTERVAL = 500 ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//send data to following instances:
const SEND _TO = {
debug : 0 ,
tb : 1 ,
http _response : 2 ,
dido _controller : 3 ,
infoSender : 4
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
const PRIORITY _TYPES = {
terminal : 0 ,
fw _detection : 1 , //reserved only for FW detection - FLOW.OMS_masterNodeIsResponding
high _priority : 2 , //reserverd only for: read dimming / brightness (after set dimming from platform)
relay _profile : 3 ,
node _broadcast : 4 ,
node _profile : 5 ,
node _cmd : 6
}
//list of command calls to process. Processing in runTasks function
let tasks = [ ] ;
let interval = null ; //timeout for procesing tasks
let refFlowdata = null ; //holds reference to httprequest flowdata
let refFlowdataObj = { } ;
2024-05-07 16:28:43 +02:00
//load from settings
let latitude = 48.70826502 ; //48.682255758;
let longitude = 17.28455203 ; //17.278910807;
const gmtOffset = 0 ;
//ak nie je nastaveny
//https://www.tecmint.com/set-time-timezone-and-synchronize-time-using-timedatectl-command/
//https://stackoverflow.com/questions/16086962/how-to-get-a-time-zone-from-a-location-using-latitude-and-longitude-coordinates
//priorities for registers
let priorities = [ ] ;
let minutes = 1 ;
priorities [ "0" ] = minutes ;
priorities [ "1" ] = minutes ;
minutes = 5 ;
priorities [ "74" ] = minutes ;
priorities [ "75" ] = minutes ;
priorities [ "76" ] = minutes ;
priorities [ "77" ] = minutes ;
priorities [ "78" ] = minutes ;
priorities [ "79" ] = minutes ;
priorities [ "84" ] = minutes ;
minutes = 10 ;
priorities [ "87" ] = minutes ;
priorities [ "6" ] = minutes ;
priorities [ "7" ] = minutes ;
priorities [ "80" ] = minutes ;
priorities [ "8" ] = minutes ;
priorities [ "3" ] = minutes ;
priorities [ "89" ] = minutes ;
2024-05-14 16:29:11 +02:00
//prikazy kt sa budu spustat na dany node - see config.js in terminal-oms.app. (1 - dimming)
2024-05-07 16:28:43 +02:00
let listOfCommands = [ 0 , 1 , 3 , 6 , 7 , 8 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 84 , 87 , 89 ] ;
const errorHandler = new ErrorToServiceHandler ( ) ;
let rotary _switch _state = "Off" ;
let lux _sensor ;
let state _of _breaker = { } ; //key is line, value is On/Off
let disconnectedReport = { } ; //key is tbname, value true/false
let relaysData = { } ; //key is line, value is data from db
let nodesData = { } ; //key is node, value data from db
//helper container for counting resolved group of commands (commands related to set profile)
let cmdCounter = { } ; //key is node, value is counter
let cmdNOKNodeCounter = { } ; //key is node, value is counter
2024-05-14 16:29:11 +02:00
//END OF VARIABLE SETTINGS
//--------------------------------
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");
2024-05-07 16:28:43 +02:00
function cmdCounterResolve ( address )
{
if ( cmdCounter . hasOwnProperty ( address ) )
{
cmdCounter [ address ] = cmdCounter [ address ] - 1 ;
let result = cmdCounter [ address ] ;
if ( result == 0 ) delete cmdCounter [ address ] ;
return result ;
}
return - 1 ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function getParams ( priority )
{
let params = { } ;
//core rpc values
params . address = 0 ; //if(recipient === 0) address = 0;
params . byte1 = 0 ; //msb, podla dokumentacie data3
params . byte2 = 0 ; //podla dokumentacie data2
params . byte3 = 0 ; //podla dokumentacie data1
params . byte4 = 0 ; //lsb, podla dokumentacie data0
params . recipient = 0 ; //0: Master, 1: Slave, 2: Broadcast
params . register = - 1 ; //register number
params . rw = 0 ; //0: read, 1: write
//other values
2024-05-14 16:29:11 +02:00
//params.type = "cmd"; "relay" "cmd-terminal" "set_node_profile" "process_profiles" "edge_date_time" "number_of_luminaires"
2024-05-07 16:28:43 +02:00
//params.tbname = tbname;
2024-05-14 16:29:11 +02:00
params . priority = PRIORITY _TYPES . node _cmd ; //default priority - if more tasks with the same timestamp, we sort them based on priority
params . timestamp = 0 ; //execution time - if timestamp < Date.now(), the task is processed
2024-05-07 16:28:43 +02:00
if ( priority != undefined )
{
params . timestamp = priority ;
params . priority = priority ;
}
2024-05-14 16:29:11 +02:00
params . addMinutesToTimestamp = 0 ; //repeat task if value is > 0,
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//params.timePointName = "luxOff" // "luxOn", "dusk", "dawn", "profileTimepoint"
2024-05-07 16:28:43 +02:00
//params.info = "";
return params ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
async function loadSettings ( )
{
let responseSettings = await promisifyBuilder ( dbSettings . find ( ) ) ;
latitude = responseSettings [ 0 ] [ "latitude" ] ;
longitude = responseSettings [ 0 ] [ "longitude" ] ;
//globals
FLOW . OMS _language = responseSettings [ 0 ] [ "lang" ] ;
FLOW . OMS _rvo _name = responseSettings [ 0 ] [ "rvo_name" ] ;
FLOW . OMS _projects _id = responseSettings [ 0 ] [ "projects_id" ] ;
//FLOW.OMS_rvo_tbname = responseSettings[0]["tbname"];
FLOW . OMS _temperature _adress = responseSettings [ 0 ] [ "temperature_adress" ] ;
FLOW . OMS _controller _type = responseSettings [ 0 ] [ "controller_type" ] ;
FLOW . OMS _serial _port = responseSettings [ 0 ] [ "serial_port" ] ;
//logger.debug('settings', responseSettings[0]);
initNotifications ( ) ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
//nastav profil nodu
function processNodeProfile ( node )
{
if ( rotary _switch _state != "Automatic" )
{
logger . debug ( "unable to process profile for node" , node , "rotary_switch_state != Automatic" ) ;
return ;
}
let nodeObj = nodesData [ node ] ;
let line = nodeObj . line ;
if ( relaysData [ line ] . contactor == 0 )
{
logger . debug ( "line line is off" , line , node ) ;
return ;
}
if ( nodeObj . processed == 1 )
{
logger . debug ( "node was already processed" , node ) ;
return ;
}
let profile = nodeObj . profile ;
logger . debug ( "processNodeProfile: start - set profile for " , node , profile ) ;
let nodeProfile ;
try {
nodeProfile = JSON . parse ( profile ) ;
if ( Object . keys ( nodeProfile ) . length === 0 ) throw ( "profile is not defined" ) ;
} catch ( error ) { }
//test reset profilu
//nodeProfile = undefined;
logger . debug ( "processNodeProfile" , node , line , nodeObj , nodeProfile ) ;
//return;
2024-05-14 16:29:11 +02:00
//let timestamp = PRIORITY_TYPES.node_cmd;
2024-05-07 16:28:43 +02:00
//let now = new Date();
//now.setSeconds(now.getSeconds() + 10);
//let timestamp = now.getTime();
2024-05-14 16:29:11 +02:00
let timestamp = PRIORITY _TYPES . node _cmd ;
2024-05-07 16:28:43 +02:00
//nodeProfile = undefined;
removeTask ( { type : "set_node_profile" , address : node } ) ;
cmdNOKNodeCounter [ node ] = 0 ;
//co ked sa prave spracovava?
//if(cmdNOKNodeCounter[params.address] < 5) saveToTb = false;
if ( nodeProfile === undefined )
{
//vypneme profil nodu, posleme cmd
//Pokiaľ je hodnota rovná 1 – Profil sa zapne, ostatné bity sa nezmenia.
//Pokiaľ sa hodnota rovná 2 – profil sa vypne, ostatné bity sa nezmenia
logger . debug ( "turn off profile" ) ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . byte1 = 0 ;
params . byte2 = 0 ;
params . byte3 = 0 ;
params . byte4 = 32 ;
params . recipient = 1 ;
params . register = 8 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = 'turn off/reset node profile' ;
cmdCounter [ node ] = 1 ;
tasks . push ( params ) ;
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.NOTICE, "Master node is working again", "", SEND_TO.tb, instance );
2024-05-07 16:28:43 +02:00
}
else
{
let tasksProfile = [ ] ;
//cmdCounter[node] = tasksProfile.length;
//tasks.push(tasksProfile);
2024-05-14 16:29:11 +02:00
//let timestamp = PRIORITY_TYPES.node_cmd;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//vypneme profil - Zapísať hodnotu 32 do registra Time Schedule Settings – reset profilu
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . byte1 = 0 ;
params . byte2 = 0 ;
params . byte3 = 0 ;
params . byte4 = 32 ;
params . recipient = 1 ;
params . register = 8 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = 'turn off node profile' ;
tasksProfile . push ( params ) ;
timestamp ++ ;
logger . debug ( "processNodeProfile: TS1 Time point a TS1 Time Point Levels " , node ) ;
//TS1 Time point a TS1 Time Point Levels
let register = 9 ;
for ( let i = 0 ; i < nodeProfile . intervals . length ; i ++ )
{
let obj = nodeProfile . intervals [ i ] ;
//let timePoint = obj.time_point;
let dim _value = obj . value ;
//Reg 9 až Reg 40
/ *
Samotný profil sa zapisuje do max . 16 párov – časový bod a úroveň .
Prázdny profil je vtedy keď časový bod obsahuje hodnotu 0xFFFFFFFF ( táto hodnota sa zapíše do registrov keď sa aktivuje reset profilu do registru 8 ) .
Páry sa prechádzajú časovo zoradené takže teoreticky je jedno v akom poradí sa zapisujú ale je lepšie ich zapisovať v chronologickom poradí od 13 : 00.
Časový bod má formát :
2024-05-14 16:29:11 +02:00
Byte 3 : hodiny Byte 2 : minúty Byte 1 : sekundy Byte 0 – rezervované
2024-05-07 16:28:43 +02:00
Register úrovne má rovnaký formát ako dimming register ( Reg 1 ) .
* /
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//params.byte1 = 0;//msb, podla dokumentacie data3
//params.byte2 = 0;//podla dokumentacie data2
//params.byte3 = 0;//podla dokumentacie data1
//params.byte4 = 0;//lsb, podla dokumentacie data0
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
let start _time = obj . start _time ;
let t = start _time . split ( ":" ) ;
//if(timePoint != undefined) t = timePoint.split(":");
//else t = [0,0];
logger . debug ( "processNodeProfile: TS1 Time point " , ( i + 1 ) , node ) ;
2024-05-14 16:29:11 +02:00
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . byte1 = parseInt ( t [ 0 ] ) ; //hh
params . byte2 = parseInt ( t [ 1 ] ) ; //mm
params . byte3 = 0 ; //ss
params . byte4 = 0 ; //
params . recipient = 1 ;
params . register = register ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = 'TS1 Time point ' + ( i + 1 ) ;
tasksProfile . push ( params ) ;
register ++ ;
timestamp ++ ;
2024-05-14 16:29:11 +02:00
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . byte1 = 0 ;
params . byte2 = 0 ;
params . byte3 = 0 ; //ss
params . byte4 = parseInt ( dim _value ) + 128 ; //
params . recipient = 1 ;
params . register = register ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = 'TS1 Time point Levels ' + ( i + 1 ) ;
tasksProfile . push ( params ) ;
register ++ ;
timestamp ++ ;
}
//Threshold lux level for DUSK/DAWN
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//params.byte1 = 0;//msb, podla dokumentacie data3
//params.byte2 = 0;//podla dokumentacie data2
//params.byte3 = 0;//podla dokumentacie data1
//params.byte4 = 0;//lsb, podla dokumentacie data0
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Time schedule settings na koniec
//if(nodeProfile.dusk_lux_sensor || nodeProfile.dawn_lux_sensor)
{
logger . debug ( "processNodeProfile: Threshold lux level for DUSK/DAWN" , node ) ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 96 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = "Threshold lux level for DUSK/DAWN" ;
if ( nodeProfile . dusk _lux _sensor )
{
let v = nodeProfile . dusk _lux _sensor _value ;
let ba = longToByteArray ( v ) ;
params . byte1 = ba [ 1 ] ; //msb
params . byte2 = ba [ 0 ] ;
}
if ( nodeProfile . dawn _lux _sensor )
{
let v = nodeProfile . dawn _lux _sensor _value ;
let ba = longToByteArray ( v ) ;
params . byte3 = ba [ 1 ] ; //msb
params . byte4 = ba [ 0 ] ;
}
tasksProfile . push ( params ) ;
timestamp ++ ;
}
//DUSK/DAWN max. adjust period
{
logger . debug ( "processNodeProfile: DUSK/DAWN max. adjust period" , node ) ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 97 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = "DUSK/DAWN max. adjust period" ;
if ( nodeProfile . astro _clock )
{
let v = nodeProfile . dusk _lux _sensor _time _window ;
let ba = longToByteArray ( v ) ;
params . byte1 = ba [ 1 ] ; //msb
params . byte2 = ba [ 0 ] ;
}
if ( nodeProfile . astro _clock )
{
let v = nodeProfile . dawn _lux _sensor _time _window ;
let ba = longToByteArray ( v ) ;
params . byte3 = ba [ 1 ] ; //msb
params . byte4 = ba [ 0 ] ;
}
tasksProfile . push ( params ) ;
timestamp ++ ;
}
//Static offset
{
//Statický offset pre časy úsvitu a súmraku. Byte 1 je pre DUSK, Byte 0 je pre DAWN. Formát:
2024-05-14 16:29:11 +02:00
//Bity 0 – 6: hodnota v minútach
//Bit 7: znamienko (1 – mínus)
2024-05-07 16:28:43 +02:00
logger . debug ( "processNodeProfile: Static offset" , node ) ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 98 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . addMinutesToTimestamp = 0 ;
params . info = "Static offset" ;
if ( nodeProfile . astro _clock )
{
let dusk _astro _clock _offset = parseInt ( nodeProfile . dusk _astro _clock _offset ) ;
let dawn _astro _clock _offset = parseInt ( nodeProfile . dawn _astro _clock _offset ) ;
if ( dusk _astro _clock _offset < 0 )
{
params . byte3 = ( dusk _astro _clock _offset * - 1 ) + 128 ;
}
else
{
params . byte3 = dusk _astro _clock _offset ;
}
if ( dawn _astro _clock _offset < 0 )
{
params . byte4 = ( dawn _astro _clock _offset * - 1 ) + 128 ;
}
else
{
params . byte4 = dawn _astro _clock _offset ;
}
}
tasksProfile . push ( params ) ;
timestamp ++ ;
}
logger . debug ( "Time schedule settings - turn on" , node ) ;
2024-05-14 16:29:11 +02:00
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 8 ;
params . recipient = 1 ;
params . rw = 1 ; //write
//Time schedule settings
let bits = [ ] ;
//Byte 0 (LSB):
//Bit 0 (LSB) – zapnutie/vypnutie profilov ako takých (1 – zapnuté).
bits . push ( 1 ) ;
//Bit 1 – 3 - zatiaľ nepoužité (zapisovať 0)
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
if ( nodeProfile . astro _clock == true )
{
//Bit 4 – ak je nastavený profil sa riadi podľa astrohodín, a je 0 tak profil je jednoduchý
bits . push ( 1 ) ;
}
else bits . push ( 0 ) ;
//Bit 5 – zápis 1 spôsobí reset nastavení profilu (nastavenie prázdneho profilu)
bits . push ( 0 ) ;
2024-05-14 16:29:11 +02:00
//Bity 6-7 - zatiaľ nepoužité
2024-05-07 16:28:43 +02:00
bits . push ( 0 ) ;
bits . push ( 0 ) ;
params . byte4 = bitwise . byte . write ( bits . reverse ( ) ) ;
//Byte 2 – nastavenie pre lux senzor:
bits = [ ] ;
//Bit 0 (LSB) – riadenie súmraku podľa lux senzoru (1 – zapnuté). Súmrak sa môže posúvať v rámci času v registri 97 podľa intenzity osvetlenia
if ( nodeProfile . dusk _lux _sensor == true ) //sumrak
{
bits . push ( 1 ) ;
}
else bits . push ( 0 ) ;
//Bit 1 - riadenie úsvitu podľa lux senzoru (1 – zapnuté). Úsvit sa môže posúvať v rámci času v registri 97 podľa intenzity osvetlenia
if ( profile . dawn _lux _sensor == true ) //usvit
{
bits . push ( 1 ) ;
}
else bits . push ( 0 ) ;
//Bit 2 – zdroj pre hodnotu luxov – 0 – RVO posiela hodnoty zo svojho luxmetra, 1 – node má pripojený svoj vlastný lux meter.
bits . push ( 0 ) ; //zatial neimplementovane
//Bit 3 – 7 - nepoužité
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
params . byte2 = bitwise . byte . write ( bits . reverse ( ) ) ;
params . timestamp = timestamp ;
params . info = "Time schedule settings - turn on" ;
tasksProfile . push ( params ) ;
//zaver
cmdCounter [ node ] = tasksProfile . length ;
//tasks.push(tasksProfile);
tasks = tasks . concat ( tasksProfile ) ;
}
logger . debug ( "finished set profile for " , node ) ;
}
function cleanUpRefFlowdataObj ( )
{
2024-05-14 16:29:11 +02:00
let now = new Date ( ) ;
let timestamp = now . getTime ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//clear old refFlowdata references
let keys = Object . keys ( refFlowdataObj ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let timestampKey = keys [ i ] ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( ( timestamp - timestampKey ) > 60 * 1000 )
{
console . log ( "cleanUpRefFlowdataObj delete" , timestampKey ) ;
delete refFlowdataObj [ timestampKey ] ;
}
}
2024-05-07 16:28:43 +02:00
}
function removeTask ( obj )
{
let keys = Object . keys ( obj ) ;
tasks = tasks . filter ( ( task ) => {
let counter = 0 ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let key = keys [ i ] ;
if ( task . hasOwnProperty ( key ) && obj . hasOwnProperty ( key ) )
{
if ( task [ key ] == obj [ key ] ) counter ++ ;
}
}
if ( counter == keys . length ) return false ;
return true ;
} ) ;
}
loadSettings ( ) ;
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
exports . install = function ( instance ) {
2024-05-14 16:29:11 +02:00
let now = new Date ( ) ;
console . log ( "CMD Manager installed" , now . toLocaleString ( "sk-SK" ) ) ;
const tbHandler = new DataToTbHandler ( SEND _TO . tb ) ;
tbHandler . setSender ( exports . title ) ;
//FLOW.OMS_projects_id, name: FLOW.OMS_rvo_name
//const errorHandler = new ErrorToServiceHandler(instance, SEND_TO.infoSender);
errorHandler . setProjectsId ( FLOW . OMS _projects _id ) ;
//const errorHandler = new ErrorToServiceHandler(instance);
//errorHandler.sendMessageToService("ahoj", 0);
let sunCalcResult = calculateDuskDawn ( ) ;
let reportDuskDawn = {
dusk _time : sunCalcResult . dusk _time ,
dawn _time : sunCalcResult . dawn _time ,
dusk _time _reported : undefined ,
dawn _time _reported : undefined
} ;
2024-05-07 16:28:43 +02:00
process . on ( 'uncaughtException' , function ( err ) {
//TODO send to service
errLogger . error ( 'uncaughtException:' , err . message )
errLogger . error ( err . stack ) ;
errorHandler . sendMessageToService ( err . message + "\n" + err . stack , 0 , "js_error" ) ;
//process.exit(1);
} )
//te();//force error
2024-05-14 16:29:11 +02:00
function processAllNodeProfilesOnLine ( line )
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
for ( let k in nodesData ) {
//node:number|tbname:string|line:number|profile:string|processed:boolean
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( line == nodesData [ k ] . line )
{
let node = nodesData [ k ] . node ;
let processed = nodesData [ k ] . processed ;
if ( ! processed )
{
processNodeProfile ( node ) ;
}
else
{
logger . debug ( ` Node ${ node } profile for line ${ nodesData [ k ] . line } was already processed ` ) ;
}
}
}
}
async function loadRelaysData ( line ) {
relaysData = await promisifyBuilder ( dbRelays . find ( ) ) ;
relaysData = makeMapFromDbResult ( relaysData , "line" ) ;
for ( const [ key , value ] of Object . entries ( relaysData ) )
{
if ( key == "0" ) continue ;
if ( line != undefined )
{
//ak sa jedna o update profilu linie - pozor di_co_controller posiela command pre loadRelaysData
if ( line != value . line ) continue ;
}
if ( value . contactor == 1 ) processAllNodeProfilesOnLine ( value . line ) ;
}
// console.log('.........', relaysData);
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function reportOnlineNodeStatus ( line )
{
2024-05-14 16:29:11 +02:00
//broadcast cas, o 3 sek neskor - status, brightness
2024-05-07 16:28:43 +02:00
//Po zapnutí línie broadcastovo aktualizovať predtým čas.
logger . debug ( "--->reportOnlineNodeStatus for line" , line ) ;
//return;
2024-05-14 16:29:11 +02:00
//run broadcast //Actual time
addMinutesToTimestamp = 0 ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let params = { } ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let recipient = 2 ; //2 broadcast, address = 0
let address = 0 ; //0
if ( recipient === 2 )
{
address = 0xffffffff ; //Broadcast
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
var d = new Date ( ) ;
let hours = d . getHours ( ) ;
let minutes = d . getMinutes ( ) ;
let seconds = d . getSeconds ( ) ;
params . address = address ; //broadcast
params . byte1 = hours ; //h
params . byte2 = minutes ; //m
params . byte3 = seconds ; //s
params . byte4 = 0 ;
params . recipient = recipient ;
params . register = 87 ; //Actual time
params . rw = 1 ; //write
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _broadcast ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//other values
params . type = "cmd" ;
//params.tbname = tbname;
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "run broadcast: Actual time" ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
tasks . push ( params ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let sec = 3 ;
setTimeout ( function ( ) {
//Po zapnutí línie - spraviť hromadný refresh stavu práve zapnutých svietidiel
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
for ( let k in nodesData ) {
//potrebujem nody k danej linii
if ( line == nodesData [ k ] . line || line == undefined )
{
let tbname = nodesData [ k ] . tbname ;
let node = nodesData [ k ] . node ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//prud, vykon - current, input power pre liniu pre vsetky nody
//a pridame aj vyreportovanie dimmingu
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 1 ; //dimming
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read dimming' ;
//params.debug = true;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//Prúd
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 75 ; //prud
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read current' ;
//params.debug = true;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//výkon
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 76 ; //výkon
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read power' ;
//params.debug = true;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
tasks . push ( params ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
} , sec * 1000 ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function reportOfflineNodeStatus ( line )
{
logger . debug ( "--->reportOfflineNodeStatus for line" , line ) ;
values = { } ;
values [ "dimming" ] = 0 ; //brightness
values [ "power" ] = 0 ; //výkon
values [ "current" ] = 0 ; //prúd
values [ "status" ] = "OFFLINE" ; //prúd
for ( let k in nodesData ) {
//potrebujem nody k danej linii
if ( line == nodesData [ k ] . line || line == undefined )
{
let tbname = nodesData [ k ] . tbname ;
//logger.debug("node:", tbname);
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
}
}
//report OFFLINE for line
//relaysData[line].tbname;
//values = {};
//values["status"] = "OFFLINE";//prúd
}
function turnOnLine ( line , info )
{
let obj = {
2024-05-14 16:29:11 +02:00
line : line ,
command : "turnOn" ,
info : info
2024-05-07 16:28:43 +02:00
} ;
logger . debug ( "linia" , line , obj ) ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . dido _controller , obj ) ;
2024-05-07 16:28:43 +02:00
}
function turnOffLine ( line , info )
{
let obj = {
2024-05-14 16:29:11 +02:00
line : line ,
command : "turnOff" ,
info : info
} ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( "linia" , line , obj ) ;
instance . send ( SEND _TO . dido _controller , obj ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function detectIfResponseIsValid ( bytes )
{
//ak sa odpoved zacina 0 - je to v poriadku, inak je NOK
let type = "RESPONSE" ;
if ( bytes [ 4 ] == 0 ) type = "RESPONSE" ;
else if ( bytes [ 4 ] == 1 ) type = "ERROR" ;
else if ( bytes [ 4 ] == 2 ) type = "EVENT" ;
else type = "UNKNOWN" ;
let crc = crc16 ( 'ARC' , bytes . slice ( 0 , 9 ) ) ;
let c1 = ( crc >> 8 ) & 0xFF ;
let c2 = crc & 0xFF ;
let message = "OK" ;
let error = "" ;
if ( c1 != bytes [ 9 ] )
{
//CRC_ERROR
message = "NOK" ;
error = "CRC_ERROR c1" ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "CRC_ERROR c1" ) ;
2024-05-07 16:28:43 +02:00
}
if ( c2 != bytes [ 10 ] )
{
//CRC_ERROR
message = "NOK" ;
error = "CRC_ERROR c2" ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "CRC_ERROR c2" ) ;
2024-05-07 16:28:43 +02:00
}
//crc error
if ( type != "RESPONSE" )
{
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , bytes ) ;
instance . send ( SEND _TO . debug , "RESPONSE " + type + " - " + bytes [ 4 ] ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//logger.debug(SEND_TO.debug, "RESPONSE " + type + " - " + bytes[4], bytes);
2024-05-07 16:28:43 +02:00
error = "type is: " + type ;
message = "NOK" ;
}
return { message : message , type : type , error : error } ;
}
2024-05-14 16:29:11 +02:00
//BUILD TASKS//
2024-05-07 16:28:43 +02:00
function buildTasks ( params )
{
//report FLOW.OMS_edge_fw_version as fw_version
//report date as startdate
monitor . info ( "buildTasks - params" , params ) ;
let processLine ; //defined line
let init = false ;
let processLineProfiles = true ;
let processBroadcast = true ;
let processNodes = true ;
if ( params == undefined )
{
init = true ;
tasks = [ ] ;
logger . debug ( "-->buildTasks clear tasks" ) ;
}
else
{
processLineProfiles = false ;
processBroadcast = false ;
processNodes = false ;
processLineProfiles = params . processLineProfiles ;
processLine = params . line ;
}
//load profiles pre linie
//relaysData[ record["line"] ]
let now = new Date ( ) ;
if ( processLineProfiles )
{
//process line profiles
let keys = Object . keys ( relaysData ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
2024-05-14 16:29:11 +02:00
let line = parseInt ( keys [ i ] ) ; //line is turned off by default
2024-05-07 16:28:43 +02:00
let profilestr = relaysData [ line ] . profile ;
//Reset linii
let resetLine = false ;
2024-05-14 16:29:11 +02:00
if ( FLOW . OMS _rvo _name == "Kovalov RVO 2" && line != 0 && init == true ) resetLine = true ;
2024-05-07 16:28:43 +02:00
if ( resetLine )
{
/ *
Takže v Koválove sú nastavené offesty pre dusk a dawn nasledovne :
2024-05-14 16:29:11 +02:00
DUSK : offset + 20 minút – teda napr . namiesto 17 : 00 bude 17 : 20 a reštart by sa robil v čase 17 : 19 , teda o minútu skôr . Tak aby keď budeš robiť zapnutie o 17 : 20 tak na RVO1 sa svietidlá zapnú v rovnakom čase .
Teda : vypnutie v čase DUSK _TIME + 19 minút , zapnutie v čase DUSK _TIME + 20 minút
2024-05-07 16:28:43 +02:00
DAWN : offset - 30 minút – teda napr . namiesto 7 : 00 bude 6 : 30 a reštart by sa robil v čase 6 : 30 , tak aby sa svietidlá zhasli rovnako s RVO1 . Zapnutie by bolo 6 : 31.
2024-05-14 16:29:11 +02:00
Teda : vypnutie v čase DAWN _TIME - 30 minút , zapnutie v čase DAWN _TIME - 29 minút
2024-05-07 16:28:43 +02:00
Vždy po reštarte asi 30 sekúnd po zapnutí treba poslať aktuálny čas na nody .
* /
2024-05-14 16:29:11 +02:00
//function calculateDuskDawn(date, line, duskOffset = 0, dawnOffset = 0)
2024-05-07 16:28:43 +02:00
let duskOffset = 20 ;
let dawnOffset = - 30 ;
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( new Date ( ) , undefined , duskOffset , dawnOffset ) ;
2024-05-07 16:28:43 +02:00
console . log ( sunCalcResult ) ;
monitor . info ( "--> dusk - dawn" , sunCalcResult ) ;
//if(isDusk) time_points[t].value = 1;//sumrak - zapneme svetlo
//if(isDawn) time_points[t].value = 0;//vychod - vypneme svetlo
//DUSK - sumrak
{
//vypneme liniu a o minitu zapneme
{
let value = 0 ; //vypneme liniu
let dusk _time = sunCalcResult . dusk _time ;
if ( dusk _time < now . getTime ( ) ) dusk _time = dusk _time + 24 * 60 * 60 * 1000 ; //1den
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . relay _profile ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = line ;
params . value = value ;
params . tbname = relaysData [ line ] . tbname ;
params . timestamp = dusk _time ;
params . duskOffset = duskOffset ;
params . useProfile = false ;
//once a day
params . addMinutesToTimestamp = 24 * 60 ;
//this will be recalculated
2024-05-14 16:29:11 +02:00
params . timePointName = "dusk"
2024-05-07 16:28:43 +02:00
if ( params . value == 0 ) params . info = "reset - KOVALOV - force turn off line: " + line ;
else if ( params . value == 1 ) params . info = "reset - KOVALOV - force turn on line: " + line ;
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
console . log ( params ) ;
}
//a o minutu zapneme
{
let value = 1 ; //zapneme liniu
let dusk _time = sunCalcResult . dusk _time + 60 * 1000 ; //o minutu neskor po vypnuti zapneme
if ( dusk _time < now . getTime ( ) ) dusk _time = dusk _time + 24 * 60 * 60 * 1000 ; //1den
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . relay _profile ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = line ;
params . value = value ;
params . tbname = relaysData [ line ] . tbname ;
params . timestamp = dusk _time ;
params . duskOffset = duskOffset + 1 ;
params . useProfile = false ;
//once a day
params . addMinutesToTimestamp = 24 * 60 ;
//this will be recalculated
2024-05-14 16:29:11 +02:00
params . timePointName = "dusk"
2024-05-07 16:28:43 +02:00
if ( params . value == 0 ) params . info = "reset - KOVALOV - force turn off line: " + line ;
else if ( params . value == 1 ) params . info = "reset - KOVALOV - force turn on line: " + line ;
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
console . log ( params ) ;
}
}
//DAWN - vychod
{
//vypneme liniu a o minitu zapneme
{
let value = 0 ; //vypneme liniu
let dawn _time = sunCalcResult . dawn _time ;
if ( dawn _time < now . getTime ( ) ) dawn _time = dawn _time + 24 * 60 * 60 * 1000 ; //1den
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . relay _profile ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = line ;
params . value = value ;
params . tbname = relaysData [ line ] . tbname ;
params . timestamp = dawn _time ;
params . dawnOffset = dawnOffset ;
params . useProfile = false ;
//once a day
params . addMinutesToTimestamp = 24 * 60 ;
//this will be recalculated
2024-05-14 16:29:11 +02:00
params . timePointName = "dawn" ;
2024-05-07 16:28:43 +02:00
if ( params . value == 0 ) params . info = "reset - KOVALOV - force turn off line: " + line ;
else if ( params . value == 1 ) params . info = "reset - KOVALOV - force turn on line: " + line ;
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
console . log ( params ) ;
}
//a o minitu zapneme
{
let value = 1 ; //vypneme liniu
let dawn _time = sunCalcResult . dawn _time + 1000 * 60 ; //o minutu neskor po vypnuti zapneme
if ( dawn _time < now . getTime ( ) ) dawn _time = dawn _time + 24 * 60 * 60 * 1000 ; //1den
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . relay _profile ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = line ;
params . value = value ;
params . tbname = relaysData [ line ] . tbname ;
params . timestamp = dawn _time ;
params . dawnOffset = dawnOffset + 1 ;
params . useProfile = false ;
//once a day
params . addMinutesToTimestamp = 24 * 60 ;
//this will be recalculated
2024-05-14 16:29:11 +02:00
params . timePointName = "dawn" ;
2024-05-07 16:28:43 +02:00
if ( params . value == 0 ) params . info = "reset - KOVALOV - force turn off line: " + line ;
else if ( params . value == 1 ) params . info = "reset - KOVALOV - force turn on line: " + line ;
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
console . log ( params ) ;
}
}
//console.log("-------------------------Kovalov RVO 2----");
}
if ( processLine != undefined )
{
if ( processLine != line ) continue ;
}
2024-05-14 16:29:11 +02:00
try {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( profilestr === "" ) throw ( "Profile is not defined" ) ;
2024-05-07 16:28:43 +02:00
let profile = JSON . parse ( profilestr ) ;
2024-05-14 16:29:11 +02:00
if ( Object . keys ( profile ) . length === 0 ) throw ( "Profile is empty" ) ;
2024-05-07 16:28:43 +02:00
monitor . info ( "buildTasks: profile for line" , line ) ;
monitor . info ( "profile:" , profile ) ;
let time _points = profile . time _points ;
if ( time _points == undefined ) time _points = profile . intervals ;
2024-05-14 16:29:11 +02:00
// add name to regular profile timepoint and delete unused end_time key:
time _points . forEach ( point => {
point . name = "profileTimepoint"
delete point . end _time ;
} ) ;
2024-05-07 16:28:43 +02:00
//monitor.info("buildTasks: time_points", time_points);
let currentValue = 0 ;
2024-05-14 16:29:11 +02:00
if ( time _points . length > 0 ) currentValue = time _points [ time _points . length - 1 ] . value ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
/ * *
* if astro _clock is true , we create timepoints , that switch on / off relays accordingly .
* we need to manage , astro clock timepoints has the greatest priority - normal timepoints will not switch off / on lines before dusk or dawn
* if dawn / dusk _lux _sensor is true , it has higher priority than astro _clock switching
* /
2024-05-07 16:28:43 +02:00
if ( profile . astro _clock == true )
{
2024-05-14 16:29:11 +02:00
// if astro clock true, we remove all regular profile points
time _points = [ ] ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( new Date ( ) , line ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
// adding dusk dawn to timpoints
if ( profile . dawn _lux _sensor == false ) time _points . push ( { "start_time" : sunCalcResult [ "dawn" ] , "value" : 0 , "name" : "dawn" } ) ;
if ( profile . dusk _lux _sensor == false ) time _points . push ( { "start_time" : sunCalcResult [ "dusk" ] , "value" : 1 , "name" : "dusk" } ) ;
//if dusk/dawn is true, lines will switch on/off according to lux_sensor value. In case it fails, we create lux_timepoints, to make sure lines will switch on/off (aby nam to nezostalo svietit)
//force to turn off after timestamp: dawn + dawn_lux_sensor_time_window
2024-05-07 16:28:43 +02:00
if ( profile . dawn _lux _sensor == true )
{
let [ ahours , aminutes , aseconds ] = sunCalcResult [ "dawn" ] . split ( ':' ) ;
let ad = new Date ( ) ;
2024-05-14 16:29:11 +02:00
ad . setHours ( parseInt ( ahours ) ) ;
ad . setMinutes ( parseInt ( aminutes ) + profile . dawn _lux _sensor _time _window ) ;
2024-05-07 16:28:43 +02:00
ad . setSeconds ( 0 ) ;
let strDate = ad . getHours ( ) + ":" + ad . getMinutes ( ) ;
2024-05-14 16:29:11 +02:00
time _points . push ( { "value" : 0 , "start_time" : strDate , "name" : "luxOff" } ) ;
2024-05-07 16:28:43 +02:00
}
if ( profile . dusk _lux _sensor == true )
{
let [ ahours , aminutes , aseconds ] = sunCalcResult [ "dusk" ] . split ( ':' ) ;
let ad = new Date ( ) ;
2024-05-14 16:29:11 +02:00
ad . setHours ( parseInt ( ahours ) ) ;
ad . setMinutes ( parseInt ( aminutes ) + profile . dusk _lux _sensor _time _window ) ;
2024-05-07 16:28:43 +02:00
ad . setSeconds ( 0 ) ;
let strDate = ad . getHours ( ) + ":" + ad . getMinutes ( ) ;
2024-05-14 16:29:11 +02:00
time _points . push ( { "value" : 1 , "start_time" : strDate , "name" : "luxOn" } ) ;
//time_points.push({"value": 1, "start_time": "15:19", "name": "luxOn"}); //testing
2024-05-07 16:28:43 +02:00
}
}
//sort time_points
time _points . sort ( function ( a , b ) {
let [ ahours , aminutes , aseconds ] = a . start _time . split ( ':' ) ;
let [ bhours , bminutes , bseconds ] = b . start _time . split ( ':' ) ;
let ad = new Date ( ) ;
ad . setHours ( parseInt ( ahours ) ) ;
ad . setMinutes ( parseInt ( aminutes ) ) ;
ad . setSeconds ( 0 ) ;
let bd = new Date ( ) ;
bd . setHours ( parseInt ( bhours ) ) ;
bd . setMinutes ( parseInt ( bminutes ) ) ;
ad . setSeconds ( 0 ) ;
return ad . getTime ( ) - bd . getTime ( ) ;
} ) ;
2024-05-14 16:29:11 +02:00
console . log ( "line timepoints ........" , time _points ) ;
2024-05-07 16:28:43 +02:00
monitor . info ( "-->comming events turn on/off lines:" ) ;
for ( let t = 0 ; t < time _points . length ; t ++ )
{
let start _time = new Date ( ) ;
2024-05-14 16:29:11 +02:00
let [ hours , minutes , seconds ] = time _points [ t ] . start _time . split ( ':' ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
start _time . setHours ( parseInt ( hours ) ) ;
start _time . setMinutes ( parseInt ( minutes ) ) ;
start _time . setSeconds ( 0 ) ;
2024-05-07 16:28:43 +02:00
//task is the past
if ( now . getTime ( ) > start _time . getTime ( ) )
{
currentValue = time _points [ t ] . value ;
2024-05-14 16:29:11 +02:00
//timepoint is in past, we add 24 hours
2024-05-07 16:28:43 +02:00
start _time . setDate ( start _time . getDate ( ) + 1 ) ;
}
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . relay _profile ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
2024-05-14 16:29:11 +02:00
params . line = parseInt ( line ) ;
2024-05-07 16:28:43 +02:00
params . value = time _points [ t ] . value ;
params . tbname = relaysData [ line ] . tbname ;
params . timestamp = start _time . getTime ( ) ;
params . addMinutesToTimestamp = 0 ;
2024-05-14 16:29:11 +02:00
// it timepoints are not calculated (dawn, dusk, lux_timepoint), but static points in line profile, we just repeat the task every day
if ( time _points [ t ] . name == "profileTimepoint" ) params . addMinutesToTimestamp = 24 * 60 ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//astro timepoints will be recalculated dynamically:
params . timePointName = time _points [ t ] . name ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
// if astro timepoint, we save time window:
if ( [ 'luxOn' , 'luxOff' , 'dusk' , 'dawn' ] . includes ( params . timePointName ) )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
params . dawn _lux _sensor _time _window = profile . dawn _lux _sensor _time _window ;
params . dusk _lux _sensor _time _window = profile . dusk _lux _sensor _time _window ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
if ( params . value == 0 ) params . info = ` ${ params . timePointName } : turn off line: ` + line ;
else if ( params . value == 1 ) params . info = ` ${ params . timePointName } : turn on line: ` + line ;
2024-05-07 16:28:43 +02:00
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
monitor . info ( params . info , start _time ) ;
}
monitor . info ( "-->time_points final" , line , time _points ) ;
//ensure to turn on/off according to calculated value
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . terminal ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = parseInt ( line ) ;
params . tbname = relaysData [ line ] . tbname ;
params . value = currentValue ;
2024-05-14 16:29:11 +02:00
params . timestamp = PRIORITY _TYPES . terminal ;
2024-05-07 16:28:43 +02:00
params . addMinutesToTimestamp = 0 ;
params . debug = true ;
//logger.debug(now.toLocaleString("sk-SK"));
monitor . info ( "-->currentValue for relay" , line , currentValue ) ;
//turn on/off line
if ( params . value == 0 ) params . info = "turn off line on startup: " + line ;
else if ( params . value == 1 ) params . info = "turn on line on startup: " + line ;
tasks . push ( params ) ;
} catch ( error ) {
if ( profilestr !== "" )
{
//errLogger.error(profilestr, error);
errorHandler . sendMessageToService ( profilestr + "-" + error , 0 , "js_error" ) ;
}
}
}
//logger.debug("tasks:");
//logger.debug(tasks);
}
//PROCESS DEFAULT BROADCASTS
//RPC pre nody / broadcast
//Time of dusk, Time of dawn
//Actual Time
if ( processBroadcast )
{
let addMinutesToTimestamp = 5 ;
{
//run broadcast Time of dusk
// addMinutesToTimestamp = 60*5;
addMinutesToTimestamp = 60 * 3 ; //kazde 3 hodiny zisti novy dusk
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _broadcast ) ;
2024-05-07 16:28:43 +02:00
let recipient = 2 ; //2 broadcast, address = 0
let address = 0 ; //0
if ( recipient === 2 )
{
address = 0xffffffff ; //Broadcast
}
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
let dusk _hours = sunCalcResult [ "dusk_hours" ] ;
let dusk _minutes = sunCalcResult [ "dusk_minutes" ] ;
params . address = address ; //broadcast
params . byte1 = dusk _hours ; //h
params . byte2 = dusk _minutes ; //m
params . byte3 = 0 ; //s
params . byte4 = 0 ;
params . recipient = recipient ;
params . register = 6 ; //Time of dusk - Reg 6
params . rw = 1 ; //write
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _broadcast ;
2024-05-07 16:28:43 +02:00
//other values
params . type = "cmd" ;
//params.tbname = tbname;
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "Broadcast-duskTime" ;
tasks . push ( params ) ;
}
{
//run broadcast Time of dawn
// addMinutesToTimestamp = 60*5;
addMinutesToTimestamp = 60 * 3 ; //kazde 3 hodiny zisti novy dawn
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _broadcast ) ;
2024-05-07 16:28:43 +02:00
let recipient = 2 ; //2 broadcast, address = 0
let address = 0 ; //0
if ( recipient === 2 )
{
address = 0xffffffff ; //Broadcast
}
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
let dawn _hours = sunCalcResult [ "dawn_hours" ] ;
let dawn _minutes = sunCalcResult [ "dawn_minutes" ] ;
params . address = address ; //broadcast
params . byte1 = dawn _hours ; //h
params . byte2 = dawn _minutes ; //m
params . byte3 = 0 ; //s
params . byte4 = 0 ;
params . recipient = recipient ;
params . register = 7 ; //Time of dawn - Reg 6
params . rw = 1 ; //write
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _broadcast ;
2024-05-07 16:28:43 +02:00
//other values
params . type = "cmd" ;
//params.tbname = tbname;
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "Broadcast-dawnTime" ;
tasks . push ( params ) ;
}
{
//run broadcast //Actual time
addMinutesToTimestamp = 5 ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _broadcast ) ;
2024-05-07 16:28:43 +02:00
let recipient = 2 ; //2 broadcast, address = 0
let address = 0 ; //0
if ( recipient === 2 )
{
address = 0xffffffff ; //Broadcast
}
var d = new Date ( ) ;
let hours = d . getHours ( ) ;
let minutes = d . getMinutes ( ) ;
let seconds = d . getSeconds ( ) ;
params . address = address ; //broadcast
params . byte1 = hours ; //h
params . byte2 = minutes ; //m
params . byte3 = seconds ; //s
params . byte4 = 0 ;
params . recipient = recipient ;
params . register = 87 ; //Actual time
params . rw = 1 ; //write
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _broadcast ;
2024-05-07 16:28:43 +02:00
//other values
params . type = "cmd" ;
//params.tbname = tbname;
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "run broadcast: Actual time" ;
tasks . push ( params ) ;
}
{
//run broadcast Actual Lux level from cabinet
//Do tohto registra posiela riadiaca jednotka hodnotu intenzity osvetlenia ktorú meria jej senzor pre potreby riadenia časov súmraku resp. úsvitu podľa intenzity osvetlenia.
//Byty 0 (LSB) a 1 obsahujú 16 bitový integer s luxami.
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _broadcast ) ;
2024-05-07 16:28:43 +02:00
addMinutesToTimestamp = 15 ;
let recipient = 2 ; //2 broadcast, address = 0
let address = 0 ; //0
if ( recipient === 2 )
{
address = 0xffffffff ; //Broadcast
}
//TODO
//16 bitový integer s luxami
params . byte3 = lux _sensor ;
params . byte4 = lux _sensor ;
2024-05-14 16:29:11 +02:00
params . timestamp = PRIORITY _TYPES . node _broadcast ;
2024-05-07 16:28:43 +02:00
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "run broadcast: Actual Lux level from cabinet" ;
params . register = 95 ; //Actual Lux level from cabinet
params . rw = 1 ; //write
}
}
//process nodes & tasks
//reportovanie pre platformu
if ( processNodes )
{
for ( let k in nodesData ) {
let address = parseInt ( k ) ;
let tbname = nodesData [ k ] . tbname ;
let register = 0 ;
//logger.debug("generated cmd - buildTasks for node:", address);
//listOfCommands - READ
for ( let i = 0 ; i < listOfCommands . length ; i ++ )
{
register = listOfCommands [ i ] ;
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
//core rpc values
params . address = address ;
params . byte1 = 0 ;
params . byte2 = 0 ;
params . byte3 = 0 ;
params . byte4 = 0 ;
params . recipient = 1 ;
params . register = register ;
params . rw = 0 ;
let addMinutesToTimestamp = priorities [ register ] ;
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _cmd ; //run imediatelly in function runTasks
2024-05-07 16:28:43 +02:00
if ( addMinutesToTimestamp > 1 )
{
timestampStart = timestampStart + addMinutesToTimestamp * 60000 ;
}
//other values
params . type = "cmd" ;
params . tbname = tbname ;
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = addMinutesToTimestamp ;
params . info = "generated cmd - buildTasks (node)" ;
//monitor last node && last command
/ *
if ( register == listOfCommands [ listOfCommands . length - 1 ] )
{
//if(k == 632) params.debug = true;
if ( k == 698 ) params . debug = true ;
}
* /
tasks . push ( params ) ;
}
}
}
//niektore ulohy sa vygeneruju iba 1x pri starte!!!
if ( ! init ) return ;
//Priebežne (raz za cca 5 minút) je potrebné vyčítať z Master nodu verziu jeho FW.
//Jedná sa o register 10. Rovnaká interpretácia ako pri FW verzii nodu.
//Adresa mastera je 0. V prípade že kedykoľvek nastane situácia že Master Node neodpovedá (napríklad pri vyčítaní telemetrie z nodu nevráti žiadne dáta),
//tak treba vyreportovať string "NOK".
{
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . fw _detection ) ;
2024-05-07 16:28:43 +02:00
params . type = "cmd" ;
params . register = 4 ;
params . address = 0 ;
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . fw _detection ;
2024-05-07 16:28:43 +02:00
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = 5 ;
params . tbname = FLOW . OMS _edgeName ;
params . info = "Master node FW verzia" ;
//params.debug = true;
//this will set FLOW.OMS_masterNodeIsResponding
tasks . push ( params ) ;
}
//kazdu hodinu skontrolovat nastavenie profilov
{
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . fw _detection ) ;
2024-05-07 16:28:43 +02:00
params . type = "process_profiles" ;
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . relay _profile ;
2024-05-07 16:28:43 +02:00
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = 60 ; //60 = every hour
params . info = "detekcia nespracovaných profilov linie a nodov" ;
//params.debug = true;
tasks . push ( params ) ;
}
{
//edge_date_time
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "edge_date_time" ;
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _cmd ;
2024-05-07 16:28:43 +02:00
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = 1 ;
params . tbname = FLOW . OMS _edgeName ;
params . info = "reportovanie aktuálneho času na LM - EDGE-Date Time" ;
//logger.debug("BUILD Master node FW verzia");
tasks . push ( params ) ;
}
{
//edge_date_time
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "number_of_luminaires" ;
2024-05-14 16:29:11 +02:00
let timestampStart = PRIORITY _TYPES . node _cmd + 1 ;
2024-05-07 16:28:43 +02:00
params . timestamp = timestampStart ;
params . addMinutesToTimestamp = 1 ;
params . tbname = FLOW . OMS _edgeName ;
params . info = "reportovanie number_of_luminaires" ;
tasks . push ( params ) ;
}
monitor . info ( "tasks created:" , tasks . length ) ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function turnOnOffLinesAccordingToLuxSensor ( lux _sensor _value )
{
//let dusk_hours = sunCalcResult["dusk_hours"];
//let dusk_minutes = sunCalcResult["dusk_minutes"];
let duskTimeStamp ;
let downTimeStamp ;
//prejedme si line s profilom, kde mame "astro_clock": true
/ *
"dawn_lux_sensor" : true ,
"dusk_lux_sensor" : true ,
"dawn_lux_sensor_value" : 5 ,
"dusk_lux_sensor_value" : 5 ,
"dawn_astro_clock_offset" : 0 ,
"dusk_astro_clock_offset" : 10 ,
"dawn_lux_sensor_time_window" : 30 ,
"dusk_lux_sensor_time_window" : 30 ,
"dawn_astro_clock_time_window" : 60 ,
"dusk_astro_clock_time_window" : 60
* /
//ak sme pred/po vychode a lux value <= lux_sensor_value, liniu zapneme
//ak sme pred/po zapade a lux_value <= lux_sensor_value, liniu zapneme
let now = new Date ( ) ;
let currentTimestamp = now . getTime ( ) ;
let keys = Object . keys ( relaysData ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let line = keys [ i ] ; //line is turned off by default
let profilestr = relaysData [ line ] . profile ;
let contactor = relaysData [ line ] . contactor ; // 0 or 1 - vypnuta/zapnuta
try {
let profile = JSON . parse ( profilestr ) ;
if ( Object . keys ( profile ) . length === 0 ) throw ( "profile is not defined" ) ;
if ( profile . astro _clock == true )
{
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( now , line ) ;
2024-05-07 16:28:43 +02:00
//dawn: usvit/vychod - lux je nad hranicou - vypnem
//dusk: zapad pod hranicou - zapnem
//"dawn_lux_sensor_time_window": 30,
//"dusk_lux_sensor_time_window": 30,
//vychod
// LUX_SENSOR_TIME_WINDOW x 1000 x 60 --> dostaneme odpocet/pripocitanie minut
if ( profile . dawn _lux _sensor == true )
{
let lux _sensor _time _window1 = sunCalcResult . dawn _time - ( parseInt ( profile . dawn _lux _sensor _time _window ) * 1000 * 60 ) ;
let lux _sensor _time _window2 = sunCalcResult . dawn _time + ( parseInt ( profile . dawn _lux _sensor _time _window ) * 1000 * 60 ) ;
//console.log('------>>>', new Date(lux_sensor_time_window1), new Date(lux_sensor_time_window2), lux_sensor_time_window1, lux_sensor_time_window2)
//console.log('++++-->>>', new Date(sunCalcResult.dusk_time), new Date(sunCalcResult.dawn_time))
if ( currentTimestamp >= lux _sensor _time _window1 && currentTimestamp <= lux _sensor _time _window2 )
{
//dawn: usvit/vychod - lux je nad hranicou - vypnem
if ( lux _sensor _value > profile . dawn _lux _sensor _value )
{
//vypnem
if ( contactor ) turnOffLine ( line , "profile: dawn - turnOff line according to lux sensor" ) ;
}
// else
// {
// //zapnem
// if(!contactor) turnOnLine(line, "profile: dawn - turnOn line according to lux sensor");
// }
}
//ak sme po vychode
if ( currentTimestamp > lux _sensor _time _window2 )
{
//vypneme
//urobime jednorazovy prikaz
}
}
//zapad
if ( profile . dusk _lux _sensor == true )
{
let lux _sensor _time _window1 = sunCalcResult . dusk _time - ( parseInt ( profile . dusk _lux _sensor _time _window ) * 1000 * 60 ) ;
let lux _sensor _time _window2 = sunCalcResult . dusk _time + ( parseInt ( profile . dusk _lux _sensor _time _window ) * 1000 * 60 ) ;
if ( currentTimestamp >= lux _sensor _time _window1 && currentTimestamp <= lux _sensor _time _window2 )
{
//dusk: zapad pod hranicou - zapnem
if ( lux _sensor _value < profile . dusk _lux _sensor _value )
{
//zapnem
if ( ! contactor ) turnOnLine ( line , "profile: dusk - turnOn line according to lux sensor" ) ;
}
// else
// {
// //vypnem
// if(contactor) turnOffLine(line, "profile: dusk - turnOff line according to lux sensor");
// }
}
}
}
} catch ( error ) {
//if(profilestr !=="" ) logger.debug(profilestr, error);
}
}
}
async function upateNodeStatus ( node , status )
{
//MASTER
if ( node == 0 ) return ;
let nodeObj = nodesData [ node ] ;
if ( nodeObj == undefined ) return ;
if ( status )
{
cmdNOKNodeCounter [ node ] = 0 ;
}
else cmdNOKNodeCounter [ node ] ++ ;
if ( nodeObj . status !== status )
{
await dbNodes . modify ( { status : status } ) . where ( "node" , node ) . make ( function ( builder ) {
builder . callback ( function ( err , response ) {
if ( err == null ) nodesData [ node ] . status = status ;
} ) ;
} ) ;
}
}
2024-05-14 16:29:11 +02:00
async function runTasks ( ) {
2024-05-07 16:28:43 +02:00
clearInterval ( interval ) ;
let currentTimestamp = Date . now ( ) ;
//report dusk, dawn---------------------------------
if ( reportDuskDawn . dusk _time < currentTimestamp )
{
//vyreportuj iba ak nie je velky rozdiel napr. 60 sekund
if ( ( currentTimestamp - reportDuskDawn . dusk _time ) < 60 * 1000 )
{
//reportovali sme?
if ( reportDuskDawn . dusk _time _reported != sunCalcResult . dusk _time )
{
2024-05-14 16:29:11 +02:00
sendNotification ( "CMD Manager: calculated Time of dusk" , FLOW . OMS _edgeName , "dusk_has_occured" , { value : sunCalcResult [ "dusk" ] } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
reportDuskDawn . dusk _time _reported = sunCalcResult . dusk _time ;
}
}
var nextDay = new Date ( ) ;
nextDay . setDate ( nextDay . getDate ( ) + 1 ) ;
2024-05-14 16:29:11 +02:00
sunCalcResult = calculateDuskDawn ( nextDay ) ;
2024-05-07 16:28:43 +02:00
reportDuskDawn . dusk _time = sunCalcResult . dusk _time ;
}
if ( reportDuskDawn . dawn _time < currentTimestamp )
{
//vyreportuj iba ak nie je velky rozdiel napr. 60 sekund
if ( ( currentTimestamp - reportDuskDawn . dawn _time ) < 60 * 1000 )
{
//reportovali sme?
if ( reportDuskDawn . dawn _time _reported != sunCalcResult . dawn _time )
{
2024-05-14 16:29:11 +02:00
sendNotification ( "CMD Manager: calculated Time of dawn" , FLOW . OMS _edgeName , "dawn_has_occured" , { value : sunCalcResult [ "dawn" ] } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
reportDuskDawn . dawn _time _reported = sunCalcResult . dawn _time ;
}
}
var nextDay = new Date ( ) ;
nextDay . setDate ( nextDay . getDate ( ) + 1 ) ;
2024-05-14 16:29:11 +02:00
sunCalcResult = calculateDuskDawn ( nextDay ) ;
2024-05-07 16:28:43 +02:00
reportDuskDawn . dawn _time = sunCalcResult . dawn _time ;
}
//--------------------------------------------------------
2024-05-14 16:29:11 +02:00
//sort tasks based on timestamp
2024-05-07 16:28:43 +02:00
tasks . sort ( function ( a , b ) {
if ( a . timestamp <= currentTimestamp && b . timestamp <= currentTimestamp )
{
return a . priority - b . priority ;
}
return a . timestamp - b . timestamp ;
} ) ;
if ( tasks . length == 0 )
{
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "no tasks created" ) ;
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
if ( ! rsPort . isOpen )
{
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "!rsPort.isOpen" ) ;
2024-05-07 16:28:43 +02:00
//await rsPort.open();
}
let currentTask = tasks [ 0 ] ;
if ( currentTask . debug )
{
//logger.debug("--->task to process", currentTask);
}
if ( currentTask . timestamp <= currentTimestamp )
{
let params = { ... tasks [ 0 ] } ;
2024-05-14 16:29:11 +02:00
//allow terminal commands
if ( FLOW . OMS _maintenance _mode && params . type !== "cmd-terminal" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
return ;
2024-05-07 16:28:43 +02:00
}
let type = params . type ;
let tbname = params . tbname ;
let nodeKey = params . address ;
let line = null ;
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
//rpc related
if ( nodesData [ nodeKey ] !== undefined ) line = nodesData [ nodeKey ] . line ;
if ( params . line !== undefined ) line = params . line ;
let repeatTask = false ;
2024-05-14 16:29:11 +02:00
if ( params . addMinutesToTimestamp > 0 || params . timePointName ) repeatTask = true ;
2024-05-07 16:28:43 +02:00
if ( repeatTask )
{
2024-05-14 16:29:11 +02:00
if ( type === "cmd" )
2024-05-07 16:28:43 +02:00
{
//set next start time automatically
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
}
else
{
tasks . shift ( ) ;
}
//custom tasks
if ( type == "number_of_luminaires" )
{
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
//treba reportovat node status
{
//number_of_luminaires
//number_of_ok_luminaires
//number_of_nok_luminaires
let keys = Object . keys ( nodesData ) ;
let number _of _luminaires = keys . length ;
let number _of _ok _luminaires = 0 ;
let number _of _nok _luminaires = 0 ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let key = keys [ i ] ;
let nodeObj = nodesData [ key ] ;
if ( nodeObj . tbname == undefined ) continue ;
if ( nodeObj . status ) number _of _ok _luminaires ++ ;
else number _of _nok _luminaires ++ ;
}
let values = {
number _of _luminaires : number _of _luminaires ,
number _of _ok _luminaires : number _of _ok _luminaires ,
number _of _nok _luminaires : number _of _nok _luminaires
} ;
let dataToTb = {
[ FLOW . OMS _edgeName ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
}
//kontrola nespracovanych profilov nodov
if ( type == "process_profiles" )
{
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
//select nespracovane nody
//node:number|tbname:string|line:number|profile:string|processed:boolean|status:boolean
//buildTasks({processLineProfiles: true, line: line});
/ *
let keys = Object . keys ( nodesData ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let node = keys [ i ] ;
let line = node . line ;
if ( node . processed ) continue ;
if ( relaysData [ line ] != undefined )
{
let relayStatus = relaysData [ line ] . contactor ;
if ( relayStatus == 1 )
{
//linia je zapnuta
//await loadRelaysData(flowdata.data.line);
}
}
}
* /
//vsetky linie kt. su zapnute, a spracuju sa nespracovane profily nodov
loadRelaysData ( ) ;
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
if ( type == "edge_date_time" )
{
//var d = new Date();
//let hours = addZeroBefore(d.getHours());
//let minutes = addZeroBefore(d.getMinutes());
//let seconds = addZeroBefore(d.getSeconds());
//let values = {"edge_date_time": `${hours}:${minutes}:${seconds}`};
let values = { "edge_date_time" : Date . now ( ) } ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
//relay
if ( type == "relay" )
{
2024-05-14 16:29:11 +02:00
const timePointName = params . timePointName ;
const value = params . value ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
// used just in Kovalov RVO 2
const useProfile = params . useProfile ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let date = new Date ( ) ;
date . setDate ( date . getDate ( ) + 1 ) ; //next day
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let sunCalcResult ;
if ( ! useProfile )
{
sunCalcResult = calculateDuskDawn ( date , params . line ) ;
2024-05-07 16:28:43 +02:00
}
else
{
2024-05-14 16:29:11 +02:00
//do not use profile, line is there for undefined
sunCalcResult = calculateDuskDawn ( date , undefined , params . duskOffset , params . dawnOffset ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
if ( timePointName == "dawn" )
{
tasks [ 0 ] . timestamp = sunCalcResult . dawn _time ;
}
else if ( timePointName == "dusk" )
{
tasks [ 0 ] . timestamp = sunCalcResult . dusk _time ;
}
else if ( timePointName == "luxOn" )
{
tasks [ 0 ] . timestamp = sunCalcResult . dusk _time + params . dusk _lux _sensor _time _window * 60000 ;
}
else if ( timePointName == "luxOff" )
{
tasks [ 0 ] . timestamp = sunCalcResult . dawn _time + params . dawn _lux _sensor _time _window * 60000 ;
}
else if ( timePointName == "profileTimepoint" )
{
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
}
//monitor.info("new relay timepoint sunCalcResult ,,,,,,,,,,", sunCalcResult);
2024-05-07 16:28:43 +02:00
let info ;
2024-05-14 16:29:11 +02:00
if ( ! useProfile ) info = "aplikovaný bod profilu" ;
else info = params . info ; //kovalov rvo params.info
2024-05-07 16:28:43 +02:00
let message = "" ;
2024-05-14 16:29:11 +02:00
if ( value == 1 )
2024-05-07 16:28:43 +02:00
{
turnOnLine ( params . line , info ) ;
message = "on" ;
}
2024-05-14 16:29:11 +02:00
else if ( value == 0 )
2024-05-07 16:28:43 +02:00
{
turnOffLine ( params . line , info ) ;
message = "off" ;
}
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.INFO, "aplikovaný bod profilu línie " + params.line + " - stav: " + message, "", SEND_TO.tb, instance, null );
if ( ! useProfile ) sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "switching_profile_point_applied_to_line" , { line : params . line , value : message } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
//zhodeny hlavny istic
let disconnected = false ;
//if(rotary_switch_state == "Off") disconnected = true;
//state_of_breaker[line] - alebo istic linie
if ( state _of _breaker . hasOwnProperty ( line ) )
{
//if(state_of_breaker[line] == "Off") disconnected = true;
}
2024-05-14 16:17:58 +02:00
//toto sa reportuje po prijati dat z dido_controlera
2024-05-07 16:28:43 +02:00
if ( disconnected )
{
let values = { "status" : "OFFLINE" } ;
logger . debug ( "disconnected" , values ) ;
logger . debug ( "rotary_switch_state" , rotary _switch _state ) ;
logger . debug ( "state_of_breaker" , state _of _breaker [ line ] ) ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
//report only once!
if ( ! disconnectedReport . hasOwnProperty ( tbname ) ) disconnectedReport [ tbname ] = false ;
if ( ! disconnectedReport [ tbname ] )
{
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
}
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
disconnectedReport [ tbname ] = false ;
//high_priority
if ( ! FLOW . OMS _masterNodeIsResponding )
{
//ak neodpoveda, nebudeme vykonavat ziadne commands, okrem cmd-terminal, a fw version
errorHandler . sendMessageToService ( "Master node is not responding" ) ;
let stop = true ;
if ( params . type == "cmd-terminal" ) stop = false ;
//fw version - register == 4
if ( params . type == "cmd" && params . register == 4 && params . address == 0 ) stop = false ;
if ( stop )
{
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
}
let relayStatus = 1 ;
if ( relaysData [ line ] != undefined )
{
relayStatus = relaysData [ line ] . contactor ;
}
if ( line == 0 ) relayStatus = 0 ;
if ( params . type == "cmd-terminal" ) relayStatus = 1 ;
//check if rotary_switch_state == "Off"
if ( relayStatus == 0 )
{
//console.log("------------------------------------relayStatus", relayStatus, line);
let values = { "status" : "OFFLINE" } ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
if ( ! rsPort . isOpen )
{
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
//RE-CALCULATE VALUES
//set actual time for broadcast
if ( params . register == 87 && params . recipient === 2 )
{
var d = new Date ( ) ;
let hours = d . getHours ( ) ;
let minutes = d . getMinutes ( ) ;
let seconds = d . getSeconds ( ) ;
params . byte1 = hours ; //h
params . byte2 = minutes ; //m
params . byte3 = seconds ; //s
params . byte4 = 0 ;
}
2024-05-14 16:29:11 +02:00
//SET DUSK/DAWN FOR BROADCAST
2024-05-07 16:28:43 +02:00
//Time of dusk
if ( params . register == 6 && params . recipient === 2 )
{
if ( params . type != "cmd-terminal" )
{
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
let dusk _hours = sunCalcResult [ "dusk_hours" ] ;
let dusk _minutes = sunCalcResult [ "dusk_minutes" ] ;
params . byte1 = dusk _hours ; //h
params . byte2 = dusk _minutes ; //m
params . byte3 = 0 ; //s
params . byte4 = 0 ;
//TODO astrohodiny
let dusk = "Time of dusk: " + sunCalcResult [ "dusk" ] ;
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: calculated Time of dusk", relaysData[0].tbname, ERRWEIGHT.INFO, dusk, "", SEND_TO.tb, instance, null );
2024-05-07 16:28:43 +02:00
}
}
//Time of dawn
if ( params . register == 7 && params . recipient === 2 )
{
if ( params . type != "cmd-terminal" )
{
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
let dawn _hours = sunCalcResult [ "dawn_hours" ] ;
let dawn _minutes = sunCalcResult [ "dawn_minutes" ] ;
params . byte1 = dawn _hours ; //h
params . byte2 = dawn _minutes ; //m
params . byte3 = 0 ; //s
params . byte4 = 0 ;
//TODO astrohodiny
let dawn = "Time of dawn: " + sunCalcResult [ "dawn" ] ;
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: calculated Time of dusk", relaysData[0].tbname, ERRWEIGHT.INFO, dawn, "", SEND_TO.tb, instance, null );
2024-05-07 16:28:43 +02:00
}
}
//-----------------------
let register = params . register ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "address: " + params . address + " register:" + params . register + "type: " + params . type ) ;
2024-05-07 16:28:43 +02:00
var startTime , endTime ;
startTime = new Date ( ) ;
let resp = com _generic ( params . address , params . recipient , params . rw , params . register , params . name , params . byte1 , params . byte2 , params . byte3 , params . byte4 ) ;
let readBytes = 11 ;
await writeData ( rsPort , resp , readBytes ) . then ( function ( data ) {
endTime = new Date ( ) ;
var timeDiff = endTime - startTime ;
//--1-4 adresa, 5 status ak je status 0 - ok, nasleduju 4 byty data
//let bytes = data.slice(0);
let bytes = data ;
let dataBytes = data . slice ( 5 , 9 ) ;
let result = detectIfResponseIsValid ( bytes ) ;
let message = result . message ;
let type = result . type ;
let error = result . error ;
//ak sa odpoved zacina 0 - je to v poriadku, inak je NOK
if ( params . debug != "generated cmd" )
{
//debug("writeData: done " + type + " duration: " + timeDiff + " type: " + params.debug, params);
}
if ( params . hasOwnProperty ( "debug" ) )
{
if ( params . debug )
{
console . log ( "detected response:" , result ) ;
logger . debug ( "writeData: done " + type + " duration: " + timeDiff + " type: " + params . debug , params , result ) ;
}
}
//debug("writeData: done " + type + " duration: " + timeDiff + " type: " + params.debug);
//debug("writeData done", type, "duration", timeDiff, "type", params.debug, result);
let tbname = params . tbname ;
let saveToTb = true ;
if ( tbname == null || tbname == undefined || tbname == "" ) saveToTb = false ;
//--
//CMD FINISHED
if ( message == "OK" )
{
upateNodeStatus ( params . address , true ) ;
//write
if ( params . type == "set_node_profile" )
{
let result = cmdCounterResolve ( params . address ) ;
if ( result == 0 )
{
dbNodes . modify ( { processed : true } ) . where ( "node" , params . address ) . make ( function ( builder ) {
builder . callback ( function ( err , response ) {
2024-05-14 16:29:11 +02:00
sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "dimming_profile_was_successfully_received_by_node" , { node : params . address } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
logger . debug ( "--> profil úspešne odoslaný na node č. " + params . address ) ;
nodesData [ params . address ] . processed = true ;
} ) ;
} ) ;
}
}
//parse read response
let values = { } ;
if ( params . rw == 0 ) {
values = processResponse ( register , dataBytes ) ; //read
}
if ( params . rw == 1 )
{ //write command
//set command dimming
if ( params . register == 1 ) values = { "comm_status" : message } ;
}
if ( params . register == 0 ) values [ "status" ] = message ;
//fw version - register == 4
if ( params . register == 4 ) values [ "edge_fw_version" ] = FLOW . OMS _edge _fw _version ;
if ( params . address == 0 )
{
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.NOTICE, "Master node is working again", "", SEND_TO.tb, instance, "rvo_status" );
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, "master_node_is_responding_again", {}, "", SEND_TO.tb, instance, "rvo_status" );
sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "master_node_is_responding_again" , { } , "" , SEND _TO . tb , instance , "rvo_status" ) ;
2024-05-07 16:28:43 +02:00
FLOW . OMS _masterNodeIsResponding = true ;
}
//odoslanie príkazu z terminálu - dáta
if ( params . type == "cmd-terminal" )
{
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.DEBUG, "odoslanie príkazu z terminálu", params, SEND_TO.tb, instance, null );
sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "command_was_sent_from_terminal_interface" , { } , params , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
}
if ( params . debug )
{
logger . debug ( "saveToTb" , saveToTb , tbname , values ) ;
}
if ( saveToTb )
{
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
}
else
{
if ( params . type == "cmd-terminal" )
{
if ( params . refFlowdataKey != undefined )
{
logger . debug ( "cmd-terminal SUCCESS" ) ;
logger . debug ( currentTask ) ;
//make http response
let responseObj = { } ;
responseObj [ "type" ] = "SUCESS" ;
responseObj [ "bytes" ] = data ;
//params.refFlowdata.data = responseObj;
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.http_response, params.refFlowdata);
2024-05-07 16:28:43 +02:00
let refFlowdata = refFlowdataObj [ params . refFlowdataKey ] ;
refFlowdata . data = responseObj ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . http _response , refFlowdata ) ;
2024-05-07 16:28:43 +02:00
}
else
{
console . log ( "params.refFlowdataKey is undefined" , params ) ;
}
}
}
}
else
{
upateNodeStatus ( params . address , false ) ;
if ( params . refFlowdataKey != undefined )
{
logger . debug ( "cmd-terminal FAILED" ) ;
logger . debug ( currentTask ) ;
//make http response
let responseObj = { } ;
responseObj [ "type" ] = "ERROR" ;
responseObj [ "bytes" ] = data ;
//params.refFlowdata.data = responseObj;
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.http_response, params.refFlowdata);
2024-05-07 16:28:43 +02:00
let refFlowdata = refFlowdataObj [ params . refFlowdataKey ] ;
if ( refFlowdata !== undefined )
{
refFlowdata . data = responseObj ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . http _response , refFlowdata ) ;
2024-05-07 16:28:43 +02:00
}
}
/ *
if ( params . type == "cmd-terminal" )
{
if ( params . refFlowdata != undefined )
{
logger . debug ( "cmd-terminal FAILED" ) ;
logger . debug ( currentTask ) ;
//make http response
let responseObj = { } ;
responseObj [ "type" ] = "ERROR" ;
responseObj [ "bytes" ] = data ;
params . refFlowdata . data = responseObj ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . http _response , params . refFlowdata ) ;
2024-05-07 16:28:43 +02:00
}
}
* /
if ( params . address == 0 )
{
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.ALERT, "Master node not responding", "", SEND_TO.tb, instance, "rvo_status");
sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "master_node_is_not_responding" , { } , "" , SEND _TO . tb , instance , "rvo_status" ) ;
2024-05-07 16:28:43 +02:00
logger . debug ( "master_node_is_not_responding" , params ) ;
FLOW . OMS _masterNodeIsResponding = false ;
}
if ( params . type == "set_node_profile" )
{
delete cmdCounter [ params . address ] ;
let tbname = nodesData [ params . address ] . tbname ;
logger . debug ( "profil nebol úspešne odoslaný na node č. " , params , result , resp ) ;
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", tbname, ERRWEIGHT.ALERT, "profil nebol úspešne odoslaný na node č. " + params.address, "", SEND_TO.tb, instance, null );
sendNotification ( "CMD Manager: process cmd" , tbname , "configuration_of_dimming_profile_to_node_failed" , { node : params . address } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
}
//is it node?
if ( nodesData . hasOwnProperty ( params . address ) )
{
if ( cmdNOKNodeCounter [ params . address ] < 5 ) saveToTb = false ;
}
//Master node version
//if(params.register == 4 && saveToTb)
if ( saveToTb )
{
let values = {
"status" : "NOK"
} ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.debug, result);
2024-05-07 16:28:43 +02:00
if ( params . hasOwnProperty ( "debug" ) )
{
if ( params . debug )
{
logger . debug ( "writeData err: " , error , result , params ) ;
}
}
//logger.debug(error, result, params);
}
} ) . catch ( function ( reason ) {
console . log ( "writeData catch exception" , reason ) ;
logger . debug ( currentTask ) ;
if ( params . refFlowdataKey != undefined )
{
logger . debug ( "catch: cmd-terminal FAILED" ) ;
logger . debug ( currentTask ) ;
//make http response
let responseObj = { } ;
responseObj [ "type" ] = "ERROR" ; //
responseObj [ "message" ] = "ERROR WRITE FAILED: " + reason ; //
//params.refFlowdata.data = responseObj;
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.http_response, params.refFlowdata);
2024-05-07 16:28:43 +02:00
let refFlowdata = refFlowdataObj [ params . refFlowdataKey ] ;
if ( refFlowdata !== undefined )
{
refFlowdata . data = responseObj ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . http _response , refFlowdata ) ;
2024-05-07 16:28:43 +02:00
}
}
/ *
if ( params . type == "cmd-terminal" )
{
if ( params . refFlowdata != undefined )
{
logger . debug ( "cmd-terminal FAILED" ) ;
logger . debug ( currentTask ) ;
//make http response
let responseObj = { } ;
responseObj [ "type" ] = "ERROR WRITE FAILED: " + reason ;
//responseObj["bytes"] = data;
params . refFlowdata . data = responseObj ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . http _response , params . refFlowdata ) ;
2024-05-07 16:28:43 +02:00
//refFlowdata = undefined;
}
}
* /
if ( params . hasOwnProperty ( "debug" ) )
{
if ( params . debug )
{
logger . debug ( "-->WRITE FAILED: " + reason , params . debug , params ) ;
}
}
upateNodeStatus ( params . address , false ) ;
let tbname = params . tbname ;
let saveToTb = true ;
if ( tbname == null || tbname == undefined || tbname == "" ) saveToTb = false ;
if ( params . address == 0 )
{
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", relaysData[0].tbname, ERRWEIGHT.ALERT, "Master node not responding", "", SEND_TO.tb, instance, "rvo_status");
sendNotification ( "CMD Manager: process cmd" , FLOW . OMS _edgeName , "master_node_is_not_responding" , { } , "" , SEND _TO . tb , instance , "rvo_status" ) ;
2024-05-07 16:28:43 +02:00
logger . debug ( "master_node_is_not_responding" , params ) ;
FLOW . OMS _masterNodeIsResponding = false ;
}
if ( params . type == "set_node_profile" )
{
delete cmdCounter [ params . address ] ;
let tbname = nodesData [ params . address ] . tbname ;
logger . debug ( "profil nebol úspešne odoslaný na node č. " , params , resp ) ;
2024-05-14 16:29:11 +02:00
//sendNotification("CMD Manager: process cmd", tbname, ERRWEIGHT.ALERT, "odosielanie profilu na node č. " + params.address + " zlyhalo", "", SEND_TO.tb, instance, null );
sendNotification ( "CMD Manager: process cmd" , tbname , "configuration_of_dimming_profile_to_node_failed" , { node : params . address } , "" , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
}
//is it node?
if ( nodesData . hasOwnProperty ( params . address ) )
{
if ( cmdNOKNodeCounter [ params . address ] < 5 ) saveToTb = false ;
}
//Master node version
if ( params . register == 4 && saveToTb )
{
let values = {
"status" : "NOK" ,
"master_node_version" : "NOK"
} ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
2024-05-07 16:28:43 +02:00
tbHandler . sendToTb ( dataToTb , instance ) ;
FLOW . OMS _masterNodeIsResponding = false ;
}
//treba?
/ *
else if ( saveToTb )
{
let values = {
"comm_status" : "no_comm"
} ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
}
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . tb , dataToTb ) ;
2024-05-07 16:28:43 +02:00
}
* /
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , reason ) ;
2024-05-07 16:28:43 +02:00
} ) ;
}
else
{
if ( currentTask . debug )
{
//currentTask.timestamp <= currentTimestamp
logger . debug ( "currentTask is not processed - task is in the future" , currentTask ) ;
}
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
//console.log("----->runTasks - setInterval", new Date());
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
//! rsPort LM = "/dev/ttymxc4", rsPort UNIPI = "/dev/ttyUSB0"
2024-05-14 16:29:11 +02:00
// const rsPort = new SerialPort("/dev/ttymxc4", { autoOpen: false }); //LM
// const rsPort = new SerialPort("/dev/ttyUSB0", { autoOpen: false }); // UNIPI
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( FLOW . OMS _serial _port == "" || FLOW . OMS _serial _port == undefined || FLOW . OMS _serial _port . length === 1 ) FLOW . OMS _serial _port = "ttymxc4" ;
const rsPort = new SerialPort ( ` /dev/ ${ FLOW . OMS _serial _port } ` , { autoOpen : false } ) ;
2024-05-07 16:28:43 +02:00
//(node:16372) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 13 data listeners added to [SerialPort]. Use emitter.setMaxListeners() to increase limit
//rsPort.setMaxListeners(0);
2024-05-14 16:29:11 +02:00
rsPort . on ( 'open' , async function ( ) {
2024-05-07 16:28:43 +02:00
logger . debug ( "CMD manager - rsPort opened sucess" ) ;
2024-05-14 16:29:11 +02:00
loadRelaysData ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
await runSyncExec ( ` stty -F /dev/ ${ FLOW . OMS _serial _port } 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke ` ) . then ( function ( status ) {
instance . send ( SEND _TO . debug , "RPC runSyncExec - Promise Resolved:" + status ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( 0 , "RPC runSyncExec - Promise Resolved:" + status ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//APP START
let dataToInfoSender = { id : FLOW . OMS _projects _id , name : FLOW . OMS _rvo _name } ;
dataToInfoSender . fw _version = FLOW . OMS _edge _fw _version ;
dataToInfoSender . startdate = new Date ( ) . toISOString ( ) . slice ( 0 , 19 ) . replace ( 'T' , ' ' ) ;
dataToInfoSender . _ _force _ _ = true ;
instance . send ( SEND _TO . infoSender , dataToInfoSender ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( 0 , "---------------------------->START message send to service" , dataToInfoSender ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
} ) . catch ( function ( reason ) {
instance . send ( SEND _TO . debug , "CMD manager - RPC runSyncExec - promise rejected:" + reason ) ;
} ) ;
} ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
rsPort . on ( 'error' , function ( err ) {
2024-05-07 16:28:43 +02:00
//TODO report to service!!!
//errLogger.error(exports.title, "unable to open port", FLOW.OMS_serial_port, err.message);
errorHandler . sendMessageToService ( [ exports . title , "unable to open port" , FLOW . OMS _serial _port , err . message ] , 0 ) ;
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , err . message ) ;
2024-05-07 16:28:43 +02:00
} ) ;
2024-05-14 16:29:11 +02:00
rsPort . on ( "close" , ( ) => {
rsPort . close ( ) ;
} ) ;
2024-05-07 16:28:43 +02:00
//loadRelaysData();
rsPort . open ( ) ;
2024-05-14 16:29:11 +02:00
instance . on ( "close" , ( ) => {
2024-05-07 16:28:43 +02:00
clearInterval ( interval ) ;
2024-05-14 16:29:11 +02:00
rsPort . close ( ) ;
} ) ;
2024-05-07 16:28:43 +02:00
instance . on ( "data" , async function ( flowdata ) {
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.debug, "on Data");
//instance.send(SEND_TO.debug, flowdata);
//logger.debug(flowdata.data);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//just testing functions
if ( flowdata . data == "open" )
{
if ( ! rsPort . isOpen ) rsPort . open ( ) ;
return ;
}
else if ( flowdata . data == "close" )
{
rsPort . close ( ) ;
return ;
}
else if ( flowdata . data == "clean" )
{
tasks = [ ] ;
return ;
}
else if ( flowdata . data == "buildtasks" )
{
//build & run
return ;
}
else if ( flowdata . data == "run" )
{
//durations = [];
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( tasks . length == 0 )
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
buildTasks ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( rsPort . isOpen )
{
interval = setInterval ( runTasks , 100 ) ;
}
else
{
instance . send ( SEND _TO . debug , "port is not opened!!!" ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
else
{
//terminal data - object
//logger.debug("flowdata", flowdata.data);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( typeof flowdata . data === 'object' )
{
//logger.debug("dido", flowdata.data);
if ( flowdata . data . hasOwnProperty ( "sender" ) )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
//data from dido_controller
if ( flowdata . data . sender == "dido_controller" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
if ( flowdata . data . hasOwnProperty ( "cmd" ) )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
let cmd = flowdata . data . cmd ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( cmd == "buildTasks" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
clearInterval ( interval ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( "-->CMD MANAGER - BUILD TASKS" ) ;
buildTasks ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//logger.debug("tasks:");
//logger.debug(tasks);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( "-->CMD MANAGER - RUN TASKS" ) ;
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
}
else if ( cmd == "reload_relays" )
{
loadRelaysData ( flowdata . data . line ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( flowdata . data . dataChanged )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
if ( ! flowdata . data . value )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
reportOfflineNodeStatus ( flowdata . data . line ) ;
}
else
{
reportOnlineNodeStatus ( flowdata . data . line ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
else if ( cmd == "rotary_switch_state" )
{
//state was changed
if ( rotary _switch _state != flowdata . data . value )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
if ( rotary _switch _state == "Off" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
//vyreportovat vsetky svietdla
reportOfflineNodeStatus ( ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
else reportOnlineNodeStatus ( ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
rotary _switch _state = flowdata . data . value ;
}
else if ( cmd == "lux_sensor" )
{
lux _sensor = parseInt ( flowdata . data . value ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//process profiles
turnOnOffLinesAccordingToLuxSensor ( lux _sensor ) ;
}
else if ( cmd == "state_of_breaker" )
{
//istic linie
let value = flowdata . data . value ;
let line = parseInt ( flowdata . data . line ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let dataChanged = false ;
if ( state _of _breaker [ line ] != value ) dataChanged = true ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
state _of _breaker [ line ] = value ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let status = "OK" ;
let weight = ERRWEIGHT . NOTICE ;
let message = ` zapnutý istič línie č. ${ line } ` ;
if ( value == "Off" )
{
weight = ERRWEIGHT . ERROR ;
message = ` vypnutý istič línie č. ${ line } ` ;
status = "NOK" ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( dataChanged ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( relaysData . hasOwnProperty ( line ) )
{
let tbname = relaysData [ line ] . tbname ;
if ( value == "Off" ) sendNotification ( "CMD Manager: onData" , tbname , "circuit_breaker_was_turned_off_line" , { line : line } , "" , SEND _TO . tb , instance , "circuit_breaker" ) ;
else sendNotification ( "CMD Manager: onData" , tbname , "circuit_breaker_was_turned_on_line" , { line : line } , "" , SEND _TO . tb , instance , "circuit_breaker" ) ;
//report status liniu
let values = {
"status" : status
} ;
let dataToTb = {
[ tbname ] : [
{
"ts" : Date . now ( ) ,
"values" : values
}
]
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.tb, dataToTb);
tbHandler . sendToTb ( dataToTb , instance ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//current value
if ( value == "Off" )
{
//vyreportovat vsetky svietdla na linii
reportOfflineNodeStatus ( line ) ;
}
else reportOnlineNodeStatus ( line ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
}
else {
logger . debug ( "undefined cmd" , cmd ) ;
2024-05-07 16:28:43 +02:00
}
}
}
2024-05-14 16:29:11 +02:00
return ;
}
//data from worksys
if ( flowdata . data . hasOwnProperty ( "topic" ) )
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let data = flowdata . data . content . data ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let command = data . params . command ;
let method = data . method ;
let profile = data . params . payload ;
if ( profile == undefined ) profile = "" ;
let entity = data . params . entities [ 0 ] ;
let entity _type = entity . entity _type ;
let tbname = entity . tb _name ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , flowdata . data ) ;
logger . debug ( "--->worksys" , flowdata . data , data . params , entity , entity _type , command , method ) ;
logger . debug ( "----------------------------" ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( entity _type == "street_luminaire" || entity _type === "street_luminaire_v4_1" || entity _type === "street_luminaire_v4_1cez" || entity _type === "street_luminaire_v4" )
{
if ( method == "set_command" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
//let command = data.params.command;
let value = data . params . payload . value ;
if ( command == "dimming" )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
let nodeWasFound = false ;
let keys = Object . keys ( nodesData ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//logger.debug("-----", keys);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
for ( let i = 0 ; i < keys . length ; i ++ )
{
let node = keys [ i ] ;
//logger.debug( node, nodesData[node], tbname);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( tbname == nodesData [ node ] . tbname . trim ( ) )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
value = parseInt ( value ) ;
if ( value > 0 ) value = value + 128 ;
//set dimming - LUM1_13 - 647 je node linie 1 kt. dobre vidime
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 1 ; //dimming
params . recipient = 1 ; //slave
params . byte4 = value ;
params . rw = 1 ; //write
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'set dimming from platform' ;
//params.debug = true;
//ak linia je
//debug(params);
logger . debug ( "dimming" , params ) ;
tasks . push ( params ) ;
setTimeout ( function ( ) {
//spustime o 4 sekundy neskor, s prioritou PRIORITY_TYPES.high_priority
//a pridame aj vyreportovanie dimmingu
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 1 ; //dimming
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read dimming (after set dimming from platform)' ;
params . debug = true ;
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//pridame aj vyreportovanie - vykon
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 76 ;
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read Input Power (after set dimming from platform)' ;
params . debug = true ;
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//pridame aj vyreportovanie - prud svietidla
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 75 ;
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read Input Current (after set dimming from platform)' ;
params . debug = true ;
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//pridame aj vyreportovanie - power faktor - ucinnik
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
params . type = "cmd" ;
params . tbname = tbname ;
params . address = node ;
params . register = 77 ;
params . recipient = 1 ; //slave
params . rw = 0 ; //read
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read power factor - Cos phi (after set dimming from platform)' ;
params . debug = true ;
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
} , 4000 ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
nodeWasFound = true ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
break ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
if ( ! nodeWasFound )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
logger . debug ( "set dimming from platform" , "unable to find tbname" , tbname ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
else
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "undefined command " + command ) ;
logger . debug ( "undefined command" , command ) ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
return ;
}
else if ( method == "set_profile" )
{
//nastav profil nodu
logger . debug ( "-->set_profile for node" , data . params ) ;
logger . debug ( "------profile data" , profile ) ;
//instance.send(SEND_TO.debug, "set_profile" + command);
let keys = Object . keys ( nodesData ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let node = keys [ i ] ;
if ( tbname == nodesData [ node ] . tbname . trim ( ) )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
if ( profile != "" ) profile = JSON . stringify ( profile ) ;
dbNodes . modify ( { processed : false , profile : profile } ) . where ( "node" , node ) . make ( function ( builder ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
builder . callback ( function ( err , response ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( "worksys - update node profile done" , profile ) ;
if ( profile === "" ) logger . debug ( "worksys - update node profile done - profile is empty" ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//profil úspešne prijatý pre node č. xx
//sendNotification("CMD manager", tbname, ERRWEIGHT.INFO, `profil úspešne poslaný z platformy na RVO pre node č. ${node}`, profile, SEND_TO.tb, instance, null );
sendNotification ( "CMD manager" , tbname , "dimming_profile_was_processed_for_node" , { node : node } , profile , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
nodesData [ node ] . processed = false ;
nodesData [ node ] . profile = profile ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let line = nodesData [ node ] . line ;
processNodeProfile ( node ) ;
2024-05-07 16:28:43 +02:00
} ) ;
2024-05-14 16:29:11 +02:00
} ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
else
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "unknown method " + method ) ;
logger . debug ( "unknown method" , method ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
return ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//nastav profil linie z platformy
else if ( entity _type == "edb_line" || entity _type == "edb" || entity _type == "edb_line_ver4" || entity _type == "edb_ver4_se" )
{
//profil linie
//relays.table line:number|tbname:string|contactor:number|profile:string
//najdeme line relaysData
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( method == "set_profile" )
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
logger . debug ( "-->set_profile for line" , data . params ) ;
logger . debug ( "profile data:" , profile ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let keys = Object . keys ( relaysData ) ;
for ( let i = 0 ; i < keys . length ; i ++ )
{
let line = keys [ i ] ;
if ( tbname == relaysData [ line ] . tbname )
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
//zmazeme tasky
removeTask ( { type : "relay" , line : line } ) ;
if ( profile != "" ) profile = JSON . stringify ( profile ) ;
dbRelays . modify ( { profile : profile } ) . where ( "line" , line ) . make ( function ( builder ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
builder . callback ( function ( err , response ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//update profile
logger . debug ( "worksys - update relay profile done:" , profile ) ;
instance . send ( SEND _TO . debug , "worksys - update relay profile done" ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
loadRelaysData ( line ) . then ( function ( data ) {
logger . debug ( "loadRelaysData DONE for line" , line ) ;
buildTasks ( { processLineProfiles : true , line : line } ) ;
2024-05-07 16:28:43 +02:00
} ) ;
2024-05-14 16:29:11 +02:00
sendNotification ( "CMD manager - set profile from worksys" , tbname , "switching_profile_was_processed_for_line" , { line : line } , profile , SEND _TO . tb , instance ) ;
} ) ;
} ) ;
break ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
else if ( method == "set_command" )
{
let value = data . params . payload . value ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( command === "switch" )
{
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
// if we receive rpc from platform, to switch maintenance mode, we set OMS_maintenance_mode flow variable to value;
if ( entity _type === "edb" || entity _type === "edb_ver4_se" ) FLOW . variables . OMS _maintenance _mode = value ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let responseRelays = await promisifyBuilder ( dbRelays . find ( ) . where ( "tbname" , tbname ) ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let line = 0 ;
if ( responseRelays . length == 1 ) line = responseRelays [ 0 ] . line ;
if ( value == false ) turnOffLine ( line , "command received form platform" ) ;
else turnOnLine ( line , "command received form platform" ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
else
{
instance . send ( SEND _TO . debug , "undefined method " + method ) ;
logger . debug ( "undefined method" , method ) ;
2024-05-07 16:28:43 +02:00
}
return ;
}
2024-05-14 16:29:11 +02:00
else
2024-05-07 16:28:43 +02:00
{
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "UNKNOW entity_type " + entity _type ) ;
logger . debug ( "UNKNOW entity_type" , entity _type ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
return ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//terminal
if ( ! rsPort . isOpen ) await rsPort . open ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let params = flowdata . data . body ;
if ( params == undefined )
{
//logger.debug("CMD manager flowdata.data.body is undefined");
return ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
params . priority = PRIORITY _TYPES . terminal ;
params . type = "cmd-terminal" ;
params . tbname = "" ;
params . timestamp = PRIORITY _TYPES . terminal ;
params . addMinutesToTimestamp = 0 ; // do not repeat task!!!
params . debug = true ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let timestamp = Date . now ( ) ;
params . refFlowdataKey = timestamp ;
//params.refFlowdata = flowdata;
//refFlowdata = flowdata;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//console.log("flowdata", flowdata);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
cleanUpRefFlowdataObj ( ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
refFlowdataObj [ timestamp ] = flowdata ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//fix
//params.address = params.adress;
logger . debug ( "received from terminal" , params ) ;
logger . debug ( "date/time:" , new Date ( ) ) ;
logger . debug ( "tasks length:" , tasks . length ) ;
//tasks = [];
//add to tasks
tasks . push ( params ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
}
} )
2024-05-07 16:28:43 +02:00
} // end of instance.export
/ * *
* setCorrectTime function runs once per hour
* If it is 3 o ' clock , it sets actual time , which is got from services
* https : //service-prod01.worksys.io/gettime
* If also detects Read Only Filesystem once a day
* /
function setCorrectPlcTimeOnceADay ( )
{
const currentTime = new Date ( ) ;
if ( currentTime . getHours ( ) != 3 ) return ;
RESTBuilder . make ( function ( builder ) {
if ( ! builder ) return ;
builder . method ( 'GET' ) ;
builder . url ( 'http://192.168.252.2:8004/gettime?projects_id=1' ) ;
builder . callback ( function ( err , response , output ) {
if ( err ) {
console . log ( err ) ;
return ;
}
const res = output . response ;
try {
const obj = JSON . parse ( res ) ;
let d = new Date ( obj . date ) ;
const now = new Date ( ) ;
let diffInMinutes = now . getTimezoneOffset ( ) ;
console . log ( "---->TimezoneOffset" , diffInMinutes ) ;
if ( d instanceof Date )
{
// monitor.info("----------->setCorrectPlcTimeOnceADay() current js date:", d, d.getHours());
let year = d . getFullYear ( ) ;
let month = addZeroBefore ( d . getMonth ( ) + 1 ) ;
let day = addZeroBefore ( d . getDate ( ) ) ;
let hours = addZeroBefore ( d . getHours ( ) ) ;
let minutes = addZeroBefore ( d . getMinutes ( ) ) ;
let seconds = addZeroBefore ( d . getSeconds ( ) ) ;
let dateStr = ` ${ year } - ${ month } - ${ day } ${ hours } : ${ minutes } : ${ seconds } ` ;
exec ( ` sudo timedatectl set-time " ${ dateStr } " ` , ( err , stdout , stderr ) => {
if ( err || stderr ) {
console . error ( err ) ;
console . log ( stderr ) ;
console . log ( dateStr ) ;
monitor . info ( "failed timedatectl set-time" , err , stderr ) ;
}
else
{
monitor . info ( "setCorrectPlcTimeOnceADay() --> Nastaveny cas na: " , dateStr ) ;
}
} ) ;
}
} catch ( error ) {
logger . debug ( "setCorrectPlcTimeOnceADay - function error" , error , res ) ;
monitor . info ( "setCorrectPlcTimeOnceADay - function error" , error , res ) ;
}
// we detect readOnlyFileSystem once an hour as well
detectReadOnlyFilesystem ( ) ;
} ) ;
} ) ;
}
function detectReadOnlyFilesystem ( )
{
exec ( ` sudo egrep " ro,|,ro " /proc/mounts ` , ( err , stdout , stderr ) => {
if ( err || stderr ) {
console . error ( err ) ;
console . log ( stderr ) ;
} else {
//console.log("Read-only", stdout);
let lines = stdout + "" ;
lines = lines . split ( "\n" ) ;
let readOnlyDetected = "" ;
for ( let i = 0 ; i < lines . length ; i ++ )
{
if ( lines [ i ] . startsWith ( "/dev/mmcblk0p2" ) )
{
readOnlyDetected = lines [ i ] ;
}
}
if ( readOnlyDetected !== "" )
{
errorHandler . sendMessageToService ( "Detected: Read-only file system: " + readOnlyDetected ) ;
monitor . info ( "Read only filesystem detected" ) ;
}
}
} ) ;
}
let setCorrectTime = setInterval ( setCorrectPlcTimeOnceADay , 60000 * 60 ) ; // 1 hour
setCorrectPlcTimeOnceADay ( ) ;
///helper functions
2024-05-14 16:29:11 +02:00
function calculateDuskDawn ( date , line , duskOffset = 0 , dawnOffset = 0 )
2024-05-07 16:28:43 +02:00
{
if ( date === undefined ) date = new Date ( ) ;
//if(duskOffset === undefined) duskOffset = 0;
//if(dawnOffset === undefined) dawnOffset = 0;
//let line = keys[i];
let profilestr = "" ;
if ( relaysData [ line ] != undefined ) profilestr = relaysData [ line ] . profile ;
let result = { } ;
var times = SunCalc . getTimes ( date , latitude , longitude ) ;
let dawn = new Date ( times . sunrise ) ; //usvit
let dusk = new Date ( times . sunset ) ; //sumrak
//http://suncalc.net/#/48.5598,18.169,11/2021.04.07/11:06
//https://mapa.zoznam.sk/zisti-gps-suradnice-m6
let dusk _astro _clock _offset = duskOffset ; //minutes
let dawn _astro _clock _offset = dawnOffset ; //minutes
2024-05-14 16:29:11 +02:00
try {
2024-05-07 16:28:43 +02:00
let profile = JSON . parse ( profilestr ) ;
if ( Object . keys ( profile ) . length === 0 ) throw ( "profile is not defined" ) ;
//Jednoduchý režim
if ( profile . astro _clock == false && profile . dusk _lux _sensor == false && profile . dawn _lux _sensor == false )
{
}
//Režim astrohodín
if ( profile . astro _clock == true )
{
//if(profile.dusk_lux_sensor == false)
{
if ( profile . hasOwnProperty ( "dusk_astro_clock_offset" ) ) dusk _astro _clock _offset = parseInt ( profile . dusk _astro _clock _offset ) ;
}
//if(profile.dawn_lux_sensor == false)
{
if ( profile . hasOwnProperty ( "dawn_astro_clock_offset" ) ) dawn _astro _clock _offset = parseInt ( profile . dawn _astro _clock _offset ) ;
}
}
//dusk - súmrak
//down, sunrise - svitanie
} catch ( error ) {
if ( profilestr != "" )
{
logger . debug ( profilestr ) ;
logger . debug ( error ) ;
}
}
result . dusk _no _offset = addZeroBefore ( dusk . getHours ( ) ) + ":" + addZeroBefore ( dusk . getMinutes ( ) ) ;
result . dawn _no _offset = addZeroBefore ( dawn . getHours ( ) ) + ":" + addZeroBefore ( dawn . getMinutes ( ) ) ;
dusk = new Date ( dusk . getTime ( ) + gmtOffset + dusk _astro _clock _offset * 60000 ) ;
dawn = new Date ( dawn . getTime ( ) + gmtOffset + dawn _astro _clock _offset * 60000 ) ;
result . dusk = addZeroBefore ( dusk . getHours ( ) ) + ":" + addZeroBefore ( dusk . getMinutes ( ) ) ;
result . dusk _hours = dusk . getHours ( ) ;
result . dusk _minutes = dusk . getMinutes ( ) ;
result . dawn = addZeroBefore ( dawn . getHours ( ) ) + ":" + addZeroBefore ( dawn . getMinutes ( ) ) ;
result . dawn _hours = dawn . getHours ( ) ;
result . dawn _minutes = dawn . getMinutes ( ) ;
result . dusk _time = dusk . getTime ( ) ;
result . dawn _time = dawn . getTime ( ) ;
result . dusk _astro _clock _offset = dusk _astro _clock _offset ;
result . dawn _astro _clock _offset = dawn _astro _clock _offset ;
return result ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
function processResponse ( register , bytes )
{
let values = { } ;
let byte3 = bytes [ 0 ] ;
let byte2 = bytes [ 1 ] ;
let byte1 = bytes [ 2 ] ;
let byte0 = bytes [ 3 ] ;
//status
if ( register == 0 )
{
let statecode = bytesToInt ( bytes ) ;
values = { "statecode" : statecode } ;
return values ;
}
//Dimming, CCT
if ( register == 1 )
{
let brightness = 0 ;
let dimming = byte0 ;
if ( dimming > 128 ) {
//dimming = -128;
brightness = dimming - 128 ;
}
//cct
//Ak Byte3 == 1: CCT = (Byte2*256)+Byte1
let cct ;
if ( byte3 == 1 ) cct = byte2 * 256 + byte1 ;
else cct = bytesToInt ( bytes . slice ( 0 , 3 ) ) ;
//cct podla auditu
values [ "dimming" ] = brightness ;
return values ;
}
//
if ( register == 4 )
{
values [ "master_node_version" ] = bytes [ 1 ] + "." + bytes [ 2 ] ;
//logger.debug("FW Version", register, bytes);
}
//Napätie
if ( register == 74 )
{
let voltage = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 1 ) ;
values [ "voltage" ] = Number ( voltage ) ;
}
//Prúd
if ( register == 75 )
{
let current = bytesToInt ( bytes ) ;
values [ "current" ] = current ;
}
//výkon
if ( register == 76 )
{
let power = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "power" ] = Number ( power ) ;
}
//účinník
if ( register == 77 )
{
let power _factor = Math . cos ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "power_factor" ] = Number ( power _factor ) ;
}
//frekvencia
if ( register == 78 )
{
let frequency = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "frequency" ] = Number ( frequency ) ;
}
//energia
if ( register == 79 )
{
let energy = bytesToInt ( bytes ) ;
//Energiu treba reportovať v kWh. Teda číslo, ktoré príde treba podeliť 1000. Toto som ti možno zle napísal.
values [ "energy" ] = energy / 1000 ;
}
//doba života
if ( register == 80 )
{
let lifetime = ( bytesToInt ( bytes ) / 60 ) . toFixed ( 2 ) ;
values [ "lifetime" ] = Number ( lifetime ) ;
}
//nastavenie profilu
if ( register == 8 )
{
let time _schedule _settings = bytesToInt ( bytes ) ;
values [ "time_schedule_settings" ] = time _schedule _settings ;
}
//skupinová adresa 1
if ( register == 3 )
{
let gr _add _1 = bytesToInt ( byte0 ) ;
values [ "gr_add_1" ] = gr _add _1 ;
let gr _add _2 = bytesToInt ( byte1 ) ;
values [ "gr_add_2" ] = gr _add _2 ;
let gr _add _3 = bytesToInt ( byte2 ) ;
values [ "gr_add_3" ] = gr _add _3 ;
let gr _add _4 = bytesToInt ( byte3 ) ;
values [ "gr_add_4" ] = gr _add _4 ;
}
//naklon
if ( register == 84 )
{
2024-05-14 16:29:11 +02:00
let temp ;
if ( byte3 >= 128 )
{
temp = ( byte3 - 128 ) * ( - 1 ) ;
}
else
{
temp = byte3 ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let inclination _x ;
if ( byte2 >= 128 )
{
inclination _x = ( byte2 - 128 ) * ( - 1 ) ;
}
else
{
inclination _x = byte2 ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let inclination _y ;
if ( byte1 >= 128 )
{
inclination _y = ( byte1 - 128 ) * ( - 1 ) ;
}
else
{
inclination _y = byte1 ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
let inclination _z ;
if ( byte0 >= 128 )
{
inclination _z = ( byte0 - 128 ) * ( - 1 ) ;
}
else
{
inclination _z = byte0 ;
}
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
values [ "temperature" ] = temp ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//náklon x
values [ "inclination_x" ] = inclination _x ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//náklon y
values [ "inclination_y" ] = inclination _y ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//náklon z
values [ "inclination_z" ] = inclination _z ;
2024-05-07 16:28:43 +02:00
}
let h = byte3 ;
let m = byte2 ;
let s = byte1 ;
let timestamp ;
if ( register == 87 || register == 6 || register == 7 )
{
//if(byte3 < 10) h = "0" + byte3;
//if(byte2 < 10) m = "0" + byte2;
//if(byte1 < 10) s = "0" + byte1;
var d = new Date ( ) ;
d . setHours ( h ) ;
d . setMinutes ( m ) ;
d . setSeconds ( s ) ;
timestamp = d . getTime ( ) ;
}
//aktuálny čas
if ( register == 87 )
{
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["actual_time"] = h + ":" + m + ":" + s;
values [ "actual_time" ] = timestamp ;
}
//čas súmraku
if ( register == 6 )
{
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["dusk_time"] = h + ":" + m + ":" + s;
values [ "dusk_time" ] = timestamp ;
}
//čas úsvitu
if ( register == 7 )
{
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["dawn_time"] = h + ":" + m + ":" + s;
values [ "dawn_time" ] = timestamp ;
}
//FW verzia
if ( register == 89 )
{
//formát: "Byte3: Byte2.Byte1 (Byte0)"
values [ "fw_version" ] = byte3 + ":" + byte2 + "." + byte1 + "(" + byte0 + ")" ;
}
return values ;
}
2024-05-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
//byte1 MSB = data3, byte2 = data2, byte3 = data1, byte4 = data0 LSB
function com _generic ( adresa , rec , rw , register , name , byte1 , byte2 , byte3 , byte4 ) {
let resp = [ ] ;
let cmd = register ;
if ( typeof adresa === 'string' ) adresa = parseInt ( adresa ) ;
if ( typeof byte1 === 'string' ) byte1 = parseInt ( byte1 ) ;
if ( typeof byte2 === 'string' ) byte2 = parseInt ( byte2 ) ;
if ( typeof byte3 === 'string' ) byte3 = parseInt ( byte3 ) ;
if ( typeof byte4 === 'string' ) byte4 = parseInt ( byte4 ) ;
if ( rw === 0 )
{
2024-05-14 16:29:11 +02:00
cmd = cmd + 0x8000 ;
2024-05-07 16:28:43 +02:00
}
//master
if ( rec === 0 ) adresa = 0 ;
if ( rec === 2 )
{
adresa = 0xffffffff ; //Broadcast
}
//recipient
if ( rec === 3 )
{
2024-05-14 16:29:11 +02:00
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( adresa & 0xFF ) ; //band
2024-05-07 16:28:43 +02:00
}
else
{
2024-05-14 16:29:11 +02:00
resp . push ( ( adresa >> 24 ) & 0xFF ) ; //rshift
resp . push ( ( adresa >> 16 ) & 0xFF ) ;
resp . push ( ( adresa >> 8 ) & 0xFF ) ;
resp . push ( adresa & 0xFF ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
if ( rec === 2 )
{
resp . push ( 0xFF ) ;
}
else resp . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
}
resp . push ( ( cmd >> 8 ) & 0xFF ) ; //rshift
resp . push ( cmd & 0xFF ) ; //band
resp . push ( byte1 & 0xFF ) ; //band
resp . push ( byte2 & 0xFF ) ; //band
resp . push ( byte3 & 0xFF ) ; //band
resp . push ( byte4 & 0xFF ) ; //band
//let data = '12345';
let crc = crc16 ( 'ARC' , resp ) ;
let c1 = ( crc >> 8 ) & 0xFF ;
let c2 = crc & 0xFF ;
resp . push ( c1 ) ;
resp . push ( c2 ) ;
//logger.debug("checksum", crc);
//logger.debug("resp", resp);
return resp ;
}
2024-05-14 16:29:11 +02:00
const lineTimepointsExample1 =
[
{ start _time : '05:17' , value : 0 , name : 'dawn' } ,
{ value : 0 , end _time : '13:00' , start _time : '05:30' } ,
{ value : 0 , end _time : '20:00' , start _time : '13:00' } ,
{ value : 1 , end _time : '05:30' , start _time : '20:00' } ,
{ start _time : '20:19' , value : 1 , name : 'dusk' }
]
const lineTimepointsExample2 =
[
{ value : 0 , end _time : '13:00' , start _time : '05:30' } ,
{ value : 0 , start _time : '5:47' , name : 'luxOff' } ,
{ value : 0 , end _time : '20:00' , start _time : '13:00' } ,
{ value : 1 , end _time : '05:30' , start _time : '20:00' } ,
{ value : 1 , start _time : '20:49' , name : 'luxOn' }
]
// SAMPLE DATA
const relaysDataExample =
{
'0' : {
line : 0 ,
tbname : 'jbN4q7JPZmexgdnz2yKbWGDYAWwO0Q3BMX6ERLoV' ,
contactor : 1 ,
profile : ''
} ,
'1' : {
line : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
contactor : 1 ,
profile : '{"intervals":[{"value":1,"end_time":"13:00","start_time":"13:00"}],"astro_clock":false,"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}'
} ,
'2' : {
line : 2 ,
tbname : 'jBL12pg63eX4N9P7zy0lJLyEJKmlbkGwZMx0avQV' ,
contactor : 1 ,
profile : '{"intervals":[{"value":1,"end_time":"13:00","start_time":"13:00"}],"astro_clock":false,"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}'
} ,
'3' : {
line : 3 ,
tbname : 'aAOzENGrvpbe0VoK7D6E1a819PZmdg3nl24JLQMk' ,
contactor : 1 ,
profile : '{"intervals":[{"value":1,"end_time":"13:00","start_time":"13:00"}],"astro_clock":false,"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}'
}
}
// [2024-05-08T11:43:33.055] [DEBUG] default - --->reportOfflineNodeStatus for line 2
// [2024-05-08T11:43:33.055] [DEBUG] default - --->reportOfflineNodeStatus for line 3
// [2024-05-08T11:43:35.737] [DEBUG] default - -->CMD MANAGER - BUILD TASKS
// [2024-05-08T11:43:35.742] [INFO] monitorLogs - buildTasks - params undefined
// [2024-05-08T11:43:35.743] [DEBUG] default - -->buildTasks clear tasks
// [2024-05-08T11:43:35.744] [INFO] monitorLogs - buildTasks: profile for line 1
// [2024-05-08T11:43:35.745] [INFO] monitorLogs - profile: {
// intervals: [ { value: 1, end_time: '13:00', start_time: '13:00' } ],
// astro_clock: false,
// 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
// }
// [2024-05-08T11:43:35.747] [INFO] monitorLogs - -->comming events turn on/off lines:
// [2024-05-08T11:43:35.748] [INFO] monitorLogs - turn on line: 1 2024-05-08T11:00:00.747Z
// [2024-05-08T11:43:35.749] [INFO] monitorLogs - -->time_points final 1 [ { value: 1, end_time: '13:00', start_time: '13:00' } ]
// [2024-05-08T11:43:35.751] [INFO] monitorLogs - -->currentValue for relay 1 1
//
//
// typ paramu ...... / cmd
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
}
// TODO - in runTasks function, when processing tasks, wrong task gets updated
/ *
[ 2024 - 05 - 09 T20 : 48 : 00.200 ] [ DEBUG ] default - currentTask is not processed - task is in the future {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 3 ,
timestamp : 1715280480204 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 1 ,
value : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
timePointName : 'luxOn' ,
dawn _lux _sensor _time _window : 30 ,
dusk _lux _sensor _time _window : 30 ,
info : 'luxOn: turn on line: 1' ,
debug : true
}
[ 2024 - 05 - 09 T20 : 48 : 00.302 ] [ INFO ] monitorLogs - pparrams * * * * * * * * * * * * * {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 3 ,
timestamp : 1715280480204 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 1 ,
value : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
timePointName : 'luxOn' ,
dawn _lux _sensor _time _window : 30 ,
dusk _lux _sensor _time _window : 30 ,
info : 'luxOn: turn on line: 1' ,
debug : true
}
new relay task ... ... ... ... {
address : 4292 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 1 ,
register : 1 ,
rw : 0 ,
priority : 6 ,
timestamp : 1715280540301 ,
addMinutesToTimestamp : 1 ,
type : 'cmd' ,
tbname : 'jbN4q7JPZmexgdnz2yKbWdDYAWwO0Q3BMX6ERLoV' ,
info : 'generated cmd - buildTasks (node)'
}
[ 2024 - 05 - 09 T20 : 48 : 00.304 ] [ INFO ] monitorLogs - new relay task ... ... ... ... . {
address : 4292 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 1 ,
register : 1 ,
rw : 0 ,
priority : 6 ,
timestamp : 1715280540301 ,
addMinutesToTimestamp : 1 ,
type : 'cmd' ,
tbname : 'jbN4q7JPZmexgdnz2yKbWdDYAWwO0Q3BMX6ERLoV' ,
info : 'generated cmd - buildTasks (node)'
}
* /
/ *
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ pp {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 0 ,
timestamp : 0 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
value : 0 ,
debug : true ,
info : 'turn off line on startup: 1'
}
deleting task from tasks ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 0 ,
timestamp : 0 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
value : 0 ,
debug : true ,
info : 'turn off line on startup: 1'
}
[ 2024 - 05 - 10 T09 : 31 : 36.629 ] [ INFO ] monitorLogs - pparrams * * * * * * * * * * * * * {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 0 ,
timestamp : 0 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 1 ,
tbname : 'MgnK93rkoAazbqdQ4yB2Q0yZ1YXGx6pmwBeVEP2O' ,
value : 0 ,
debug : true ,
info : 'turn off line on startup: 1'
}
else task in relay ? ? ? ? ? should be ? ? ?
[ 2024 - 05 - 10 T09 : 31 : 36.631 ] [ INFO ] monitorLogs - new relay task ... ... ... ... . {
address : 0 ,
byte1 : 0 ,
byte2 : 0 ,
byte3 : 0 ,
byte4 : 0 ,
recipient : 0 ,
register : - 1 ,
rw : 0 ,
priority : 0 ,
timestamp : 0 ,
addMinutesToTimestamp : 0 ,
type : 'relay' ,
line : 2 ,
tbname : 'jBL12pg63eX4N9P7zy0lJLyEJKmlbkGwZMx0avQV' ,
value : 1 ,
debug : true ,
info : 'turn on line on startup: 2'
}
* /