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' ;
2024-12-02 16:57:26 +01:00
exports . output = [ 'red' , 'blue' , 'yellow' , 'blue' , 'white' ] ;
exports . input = 3 ;
2024-05-07 16:28:43 +02:00
exports . icon = 'cloud-upload' ;
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 ` ;
2024-12-02 16:57:26 +01:00
exports . install = function ( instance ) {
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
const SerialPort = require ( 'serialport' ) ;
const { exec } = require ( 'child_process' ) ;
const { crc16 } = require ( 'easy-crc' ) ;
const { runSyncExec , writeData } = require ( './helper/serialport_helper' ) ;
const { bytesToInt , longToByteArray , addZeroBefore } = require ( './helper/utils' ) ;
const bitwise = require ( 'bitwise' ) ;
var SunCalc = require ( './helper/suncalc' ) ;
const DataToTbHandler = require ( './helper/DataToTbHandler' ) ;
const ErrorToServiceHandler = require ( './helper/ErrorToServiceHandler' ) ;
const { sendNotification } = require ( './helper/notification_reporter' ) ;
const process = require ( 'process' ) ;
const { errLogger , logger , monitor } = require ( './helper/logger' ) ;
const dbNodes = TABLE ( "nodes" ) ;
const dbRelays = TABLE ( "relays" ) ;
let GLOBALS ;
let SETTINGS ;
let rsPort ;
let tbHandler ;
// runTasks intervals
const SHORT _INTERVAL = 30 ;
const LONG _INTERVAL = 300 ;
//send data to following instances:
const SEND _TO = {
debug : 0 ,
tb : 1 ,
http _response : 2 ,
dido _controller : 3 ,
infoSender : 4
2024-05-14 16:29:11 +02:00
}
2024-12-02 16:57:26 +01:00
const PRIORITY _TYPES = {
terminal : 0 ,
fw _detection : 1 , //reserved only for FW detection - SETTINGS.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
}
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
const TIME _AFTER _WE _UPDATE _LAST _NODE _COMMUNICATION = 600000 ; // 10 minutes
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
//list of command calls to process. Processing in runTasks function
let tasks = [ ] ;
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
let interval = null ; //timeout for procesing tasks
let customTasksInterval = null ; // interval for reportEdgeDateTimeAndNumberOfLuminaires();
let setCorrectTime = null ; // interval for setting a correct edgeTime
2025-02-04 18:45:06 +01:00
let sendNodeReadout = null ; // interval for sending agregate data from node
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let refFlowdataObj = { } ;
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
//load from settings
let latitude = 48.70826502 ; //48.682255758;
let longitude = 17.28455203 ; //17.278910807;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
const gmtOffset = 0 ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//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
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//priorities for registers
let priorities = [ ] ;
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
let minutes = 1 ;
priorities [ "0" ] = minutes ;
priorities [ "1" ] = minutes ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
minutes = 5 ;
priorities [ "74" ] = minutes ;
priorities [ "75" ] = minutes ;
priorities [ "76" ] = minutes ;
priorities [ "77" ] = minutes ;
priorities [ "78" ] = minutes ;
priorities [ "79" ] = minutes ;
priorities [ "84" ] = minutes ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
minutes = 10 ;
2024-12-02 16:57:26 +01:00
priorities [ "87" ] = minutes ;
priorities [ "6" ] = minutes ;
priorities [ "7" ] = minutes ;
priorities [ "80" ] = minutes ;
priorities [ "8" ] = minutes ;
priorities [ "89" ] = minutes ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//prikazy kt sa budu spustat na dany node - see config.js in terminal-oms.app. (1 - dimming)
2025-01-13 15:39:53 +01:00
let listOfCommands = [ 0 , 1 , 6 , 7 , 8 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 84 , 87 , 89 ] ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
const errorHandler = new ErrorToServiceHandler ( ) ;
2024-05-21 15:49:42 +02:00
2024-12-02 16:57:26 +01:00
let rotary _switch _state ;
let lux _sensor ;
let state _of _breaker = { } ; //key is line, value is On/Off
let disconnectedReport = { } ; //key is tbname, value true/false
2024-05-21 15:49:42 +02:00
2024-12-02 16:57:26 +01:00
let relaysData ;
let nodesData ;
2024-05-21 15:49:42 +02:00
2024-12-02 16:57:26 +01:00
let sunCalcResult ;
let reportDuskDawn ;
2024-05-21 15:49:42 +02:00
2024-12-02 16:57:26 +01:00
//helper container for counting resolved group of commands (commands related to set profile)
let cmdCounter = { } ; //key is node, value is counter
2025-01-09 14:55:53 +01:00
2025-01-01 13:12:02 +01:00
//if sending of profile to node fails, we send notification and push node into set, so we do not send notification twice
const nodeProfileSendFail = new Set ( ) ;
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
//END OF VARIABLE SETTINGS
//--------------------------------
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function main ( ) {
2024-12-02 16:57:26 +01:00
GLOBALS = FLOW . GLOBALS ;
SETTINGS = FLOW . GLOBALS . settings ;
relaysData = GLOBALS . relaysData ;
nodesData = GLOBALS . nodesData ;
latitude = GLOBALS . settings . latitude ;
longitude = GLOBALS . settings . longitude ;
tbHandler = new DataToTbHandler ( SEND _TO . tb ) ;
tbHandler . setSender ( exports . title ) ;
errorHandler . setProjectsId ( SETTINGS . project _id ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let now = new Date ( ) ;
console . log ( "CMD Manager installed" , now . toLocaleString ( "sk-SK" ) ) ;
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
reportDuskDawn = {
dusk _time : sunCalcResult . dusk _time ,
dawn _time : sunCalcResult . dawn _time ,
dusk _time _reported : undefined ,
dawn _time _reported : undefined
} ;
2024-09-23 17:57:23 +02:00
2024-12-02 16:57:26 +01:00
handleRsPort ( ) ;
customTasksInterval = setInterval ( function ( ) {
2025-02-04 18:45:06 +01:00
reportEdgeDateTimeAndNumberOfLuminaires ( ) ;
} , 120000 ) ;
reportEdgeDateTimeAndNumberOfLuminaires ( ) ;
2024-09-23 17:57:23 +02:00
2024-12-02 16:57:26 +01:00
setCorrectTime = setInterval ( setCorrectPlcTimeOnceADay , 60000 * 60 ) ; // 1 hour
setCorrectPlcTimeOnceADay ( ) ;
2025-02-04 18:45:06 +01:00
sendNodeReadout = setInterval ( sendNodesData , 150000 ) ;
2024-09-23 17:57:23 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function cmdCounterResolve ( address ) {
if ( cmdCounter . hasOwnProperty ( address ) ) {
2024-12-02 16:57:26 +01:00
cmdCounter [ address ] = cmdCounter [ address ] - 1 ;
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
let result = cmdCounter [ address ] ;
2024-12-02 17:06:49 +01:00
if ( result == 0 ) delete cmdCounter [ address ] ;
2024-12-02 16:57:26 +01:00
return result ;
}
return - 1 ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function getParams ( priority ) {
2024-12-02 16:57:26 +01:00
let params = { } ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//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
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//other values
//params.type = "cmd"; "relay" "cmd-terminal" "set_node_profile" "process_profiles"
//params.tbname = tbname;
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-12-02 17:06:49 +01:00
if ( priority != undefined ) {
2024-12-02 16:57:26 +01:00
params . timestamp = priority ;
params . priority = priority ;
}
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
params . addMinutesToTimestamp = 0 ; //repeat task if value is > 0,
//params.timePointName = "luxOff" // "luxOn", "dusk", "dawn", "profileTimepoint"
//params.info = "";
//params.debug = true; // will console.log params in writeData response
return params ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
//nastav profil nodu
2024-12-02 17:06:49 +01:00
function processNodeProfile ( node ) {
if ( rotary _switch _state != "Automatic" ) {
2024-12-02 16:57:26 +01:00
logger . debug ( "unable to process profile for node" , node , "rotary_switch_state != Automatic" ) ;
return ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let nodeObj = nodesData [ node ] ;
let line = nodeObj . line ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( relaysData [ line ] . contactor == 0 ) {
2024-12-02 16:57:26 +01:00
logger . debug ( "line line is off" , line , node ) ;
return ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( nodeObj . processed == 1 ) {
2024-12-02 16:57:26 +01:00
//logger.debug("node was already processed", node);
return ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let nodeProfile = nodeObj . profile ;
logger . debug ( "processNodeProfile: start - set profile for " , node , nodeProfile ) ;
2024-12-02 17:06:49 +01:00
if ( nodeProfile ) {
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
try {
nodeProfile = JSON . parse ( nodeProfile ) ;
} catch ( error ) {
logger . debug ( "Cmd_manager - Error parsing node profile" , error ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( "processNodeProfile" , node , line , nodeObj , nodeProfile ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let timestamp = PRIORITY _TYPES . node _cmd ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
removeTask ( { type : "set_node_profile" , address : node } ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( nodeProfile === "" ) {
2024-12-02 16:57:26 +01:00
//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
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( "turn off profile" ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
2024-05-07 16:28:43 +02:00
params . type = "set_node_profile" ;
params . address = node ;
2024-12-02 16:57:26 +01:00
params . byte4 = 96 ;
2024-05-07 16:28:43 +02:00
params . recipient = 1 ;
2024-12-02 16:57:26 +01:00
params . register = 8 ;
2024-05-07 16:28:43 +02:00
params . rw = 1 ; //write
params . timestamp = timestamp ;
2024-12-02 16:57:26 +01:00
params . info = 'turn off/reset node profile' ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
cmdCounter [ node ] = 1 ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasks . push ( params ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
else {
2024-12-02 16:57:26 +01:00
let tasksProfile = [ ] ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//vypneme profil - Zapísať hodnotu 32 do registra Time Schedule Settings – reset profilu
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 ;
2024-12-02 16:57:26 +01:00
params . byte4 = 96 ;
2024-05-07 16:28:43 +02:00
params . recipient = 1 ;
2024-12-02 16:57:26 +01:00
params . register = 8 ;
2024-05-07 16:28:43 +02:00
params . rw = 1 ; //write
params . timestamp = timestamp ;
2024-12-02 16:57:26 +01:00
params . info = 'turn off node profile' ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
timestamp ++ ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( "processNodeProfile: TS1 Time point a TS1 Time Point Levels " , node ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//TS1 Time point a TS1 Time Point Levels
let register = 9 ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < nodeProfile . intervals . length ; i ++ ) {
2024-12-02 16:57:26 +01:00
let obj = nodeProfile . intervals [ i ] ;
//let timePoint = obj.time_point;
2024-12-02 17:06:49 +01:00
let dim _value = obj . value ;
2024-12-02 16:57:26 +01:00
//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 :
Byte 3 : hodiny Byte 2 : minúty Byte 1 : sekundy Byte 0 – rezervované
Register úrovne má rovnaký formát ako dimming register ( Reg 1 ) .
* /
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 ) ;
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
params . type = "set_node_profile" ;
params . address = node ;
params . byte1 = parseInt ( t [ 0 ] ) ; //hh
params . byte2 = parseInt ( t [ 1 ] ) ; //mm
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 ++ ;
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
params . type = "set_node_profile" ;
params . address = node ;
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 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
register ++ ;
timestamp ++ ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Threshold lux level for DUSK/DAWN
2024-05-07 16:28:43 +02:00
{
2024-12-02 16:57:26 +01:00
logger . debug ( "processNodeProfile: Threshold lux level for DUSK/DAWN" , node ) ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
let params = getParams ( ) ;
2024-12-02 16:57:26 +01:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 96 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . info = "Threshold lux level for DUSK/DAWN" ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( nodeProfile . dusk _lux _sensor ) {
2024-12-02 16:57:26 +01:00
let v = nodeProfile . dusk _lux _sensor _value ;
let ba = longToByteArray ( v ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
params . byte1 = ba [ 1 ] ; //msb
params . byte2 = ba [ 0 ] ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( nodeProfile . dawn _lux _sensor ) {
2024-12-02 16:57:26 +01:00
let v = nodeProfile . dawn _lux _sensor _value ;
let ba = longToByteArray ( v ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
params . byte3 = ba [ 1 ] ; //msb
params . byte4 = ba [ 0 ] ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
timestamp ++ ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//DUSK/DAWN max. adjust period
2024-05-07 16:28:43 +02:00
{
2024-12-02 16:57:26 +01:00
logger . debug ( "processNodeProfile: DUSK/DAWN max. adjust period" , node ) ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
let params = getParams ( ) ;
2024-12-02 16:57:26 +01:00
params . type = "set_node_profile" ;
params . address = node ;
params . register = 97 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . info = "DUSK/DAWN max. adjust period" ;
2024-12-02 17:06:49 +01:00
if ( nodeProfile . astro _clock ) {
2024-12-02 16:57:26 +01:00
let v = nodeProfile . dusk _lux _sensor _time _window ;
let ba = longToByteArray ( v ) ;
params . byte1 = ba [ 1 ] ; //msb
params . byte2 = ba [ 0 ] ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
2024-12-02 17:06:49 +01:00
if ( nodeProfile . astro _clock ) {
2024-12-02 16:57:26 +01:00
let v = nodeProfile . dawn _lux _sensor _time _window ;
let ba = longToByteArray ( v ) ;
params . byte3 = ba [ 1 ] ; //msb
params . byte4 = ba [ 0 ] ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
timestamp ++ ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
//Static offset
{
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Statický offset pre časy úsvitu a súmraku. Byte 1 je pre DUSK, Byte 0 je pre DAWN. Formát:
//Bity 0 – 6: hodnota v minútach
//Bit 7: znamienko (1 – mínus)
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
logger . debug ( "processNodeProfile: Static offset" , node ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let params = getParams ( PRIORITY _TYPES . node _cmd ) ;
params . type = "set_node_profile" ;
params . address = node ;
params . register = 98 ;
params . recipient = 1 ;
params . rw = 1 ; //write
params . timestamp = timestamp ;
params . info = "Static offset" ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( nodeProfile . astro _clock ) {
2024-12-02 16:57:26 +01:00
let dusk _astro _clock _offset = parseInt ( nodeProfile . dusk _astro _clock _offset ) ;
let dawn _astro _clock _offset = parseInt ( nodeProfile . dawn _astro _clock _offset ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( dusk _astro _clock _offset < 0 ) {
2024-12-02 16:57:26 +01:00
params . byte3 = ( dusk _astro _clock _offset * - 1 ) + 128 ;
}
2024-12-02 17:06:49 +01:00
else {
2024-12-02 16:57:26 +01:00
params . byte3 = dusk _astro _clock _offset ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( dawn _astro _clock _offset < 0 ) {
2024-12-02 16:57:26 +01:00
params . byte4 = ( dawn _astro _clock _offset * - 1 ) + 128 ;
}
2024-12-02 17:06:49 +01:00
else {
2024-12-02 16:57:26 +01:00
params . byte4 = dawn _astro _clock _offset ;
}
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
timestamp ++ ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( "Time schedule settings - turn on" , node ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
params = getParams ( PRIORITY _TYPES . node _cmd ) ;
params . type = "set_node_profile" ;
params . address = node ;
params . register = 8 ;
params . recipient = 1 ;
params . rw = 1 ; //write
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Time schedule settings
let bits = [ ] ;
//Byte 0 (LSB):
//Bit 0 (LSB) – zapnutie/vypnutie profilov ako takých (1 – zapnuté).
2024-05-07 16:28:43 +02:00
bits . push ( 1 ) ;
2024-12-02 16:57:26 +01:00
//Bit 1 – 3 - zatiaľ nepoužité (zapisovať 0)
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
2024-12-02 17:06:49 +01:00
if ( nodeProfile . astro _clock == true ) {
2024-12-02 16:57:26 +01:00
//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 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Bit 5 – zápis 1 spôsobí reset nastavení profilu (nastavenie prázdneho profilu)
bits . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Bity 6-7 - zatiaľ nepoužité
bits . push ( 0 ) ;
bits . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
params . byte4 = bitwise . byte . write ( bits . reverse ( ) ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Byte 2 – nastavenie pre lux senzor:
bits = [ ] ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//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
2024-12-02 17:06:49 +01:00
if ( nodeProfile . dusk _lux _sensor == true ) //sumrak
2024-12-02 16:57:26 +01:00
{
bits . push ( 1 ) ;
}
else bits . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//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
2024-12-02 17:06:49 +01:00
if ( nodeProfile . dawn _lux _sensor == true ) //usvit
2024-12-02 16:57:26 +01:00
{
bits . push ( 1 ) ;
}
else bits . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//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
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//Bit 3 – 7 - nepoužité
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
bits . push ( 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
params . byte2 = bitwise . byte . write ( bits . reverse ( ) ) ;
params . timestamp = timestamp ;
params . info = "Time schedule settings - turn on" ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
tasksProfile . push ( params ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//zaver
cmdCounter [ node ] = tasksProfile . length ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//tasks.push(tasksProfile);
2024-12-02 17:06:49 +01:00
tasks = tasks . concat ( tasksProfile ) ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
}
2024-12-02 16:57:26 +01:00
logger . debug ( "finished set profile for " , node ) ;
console . log ( "proces profile finished *********************" )
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function cleanUpRefFlowdataObj ( ) {
2024-12-02 16:57:26 +01:00
let now = new Date ( ) ;
let timestamp = now . getTime ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//clear old refFlowdata references
let keys = Object . keys ( refFlowdataObj ) ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-12-02 16:57:26 +01:00
let timestampKey = keys [ i ] ;
2024-12-02 17:06:49 +01:00
if ( ( timestamp - timestampKey ) > 60 * 1000 ) {
2024-12-02 16:57:26 +01:00
console . log ( "cleanUpRefFlowdataObj delete" , timestampKey ) ;
2024-12-02 17:06:49 +01:00
delete refFlowdataObj [ timestampKey ] ;
2024-05-07 16:28:43 +02:00
}
}
2024-12-02 16:57:26 +01:00
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
function removeTask ( obj ) {
2024-12-02 16:57:26 +01:00
let keys = Object . keys ( obj ) ;
tasks = tasks . filter ( ( task ) => {
2024-05-14 16:29:11 +02:00
2024-12-02 16:57:26 +01:00
let counter = 0 ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-12-02 16:57:26 +01:00
let key = keys [ i ] ;
2024-12-02 17:06:49 +01:00
if ( task . hasOwnProperty ( key ) && obj . hasOwnProperty ( key ) ) {
if ( task [ key ] == obj [ key ] ) counter ++ ;
2024-12-02 16:57:26 +01:00
}
}
2024-12-02 17:06:49 +01:00
if ( counter == keys . length ) return false ;
2024-12-02 16:57:26 +01:00
return true ;
} ) ;
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
process . on ( 'uncaughtException' , function ( err ) {
2024-05-07 16:28:43 +02:00
//TODO send to service
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
errLogger . error ( 'uncaughtException:' , err . message )
errLogger . error ( err . stack ) ;
errorHandler . sendMessageToService ( err . message + "\n" + err . stack , 0 , "js_error" ) ;
//process.exit(1);
} )
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
//te();//force error
2024-12-02 17:06:49 +01:00
function processAllNodeProfilesOnLine ( line ) {
2024-05-14 16:29:11 +02:00
for ( let k in nodesData ) {
2024-12-02 17:06:49 +01:00
if ( line == nodesData [ k ] . line ) {
2024-05-14 16:29:11 +02:00
let node = nodesData [ k ] . node ;
let processed = nodesData [ k ] . processed ;
2024-12-02 17:06:49 +01:00
if ( ! processed ) processNodeProfile ( node ) ;
2024-12-02 16:57:26 +01:00
//else logger.debug( `Node ${node} profile for line ${nodesData[k].line} was already processed`);
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
}
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
function loadRelaysData ( line ) {
for ( const [ key , value ] of Object . entries ( relaysData ) ) {
if ( key == "0" ) continue ;
if ( line != undefined ) {
2024-09-09 12:32:34 +02:00
//ak sa jedna o update profilu linie - pozor dido_controller posiela command pre loadRelaysData
2024-12-02 17:06:49 +01:00
if ( line != value . line ) continue ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
if ( value . contactor == 1 ) processAllNodeProfilesOnLine ( value . line ) ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
function reportOnlineNodeStatus ( line ) {
2025-01-13 15:39:53 +01:00
//Po zapnutí línie broadcastovo aktualizovať predtým čas a o 3 sek neskor - status, brightness
2024-05-07 16:28:43 +02:00
logger . debug ( "--->reportOnlineNodeStatus for line" , line ) ;
2025-01-25 14:50:44 +01:00
const d = new Date ( ) ;
2024-09-09 17:50:17 +02:00
2025-02-04 18:45:06 +01:00
// broadcast actual time
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-09-09 17:50:17 +02:00
params . address = 0xffffffff ; //Broadcast
2025-01-25 14:50:44 +01:00
params . byte1 = d . getHours ( ) ;
params . byte2 = d . getMinutes ( ) ;
2024-12-02 17:06:49 +01:00
params . recipient = 2 ; //2 broadcast, address = 0
2024-05-14 16:29:11 +02:00
params . register = 87 ; //Actual time
params . rw = 1 ; //write
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-write" ;
2025-01-25 14:50:44 +01:00
params . timestamp = d . getTime ( ) + 30000 ;
2024-05-14 16:29:11 +02:00
params . info = "run broadcast: Actual time" ;
2025-02-04 18:45:06 +01:00
//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
let sec = 3 ;
2024-12-02 17:06:49 +01:00
setTimeout ( function ( ) {
2024-05-14 16:29:11 +02:00
//Po zapnutí línie - spraviť hromadný refresh stavu práve zapnutých svietidiel
2024-05-07 16:28:43 +02:00
2025-01-25 14:50:44 +01:00
let time = Date . now ( ) ;
2024-05-14 16:29:11 +02:00
for ( let k in nodesData ) {
2024-12-02 17:06:49 +01:00
2024-05-14 16:29:11 +02:00
//potrebujem nody k danej linii
2024-12-02 17:06:49 +01:00
if ( line == nodesData [ k ] . line || line == undefined ) {
2025-01-25 14:50:44 +01:00
2024-05-14 16:29:11 +02:00
let tbname = nodesData [ k ] . tbname ;
let node = nodesData [ k ] . node ;
2024-09-09 17:50:17 +02:00
let status = "NOK" ;
// if status of node was "OK" before switching it off, we set the node's time_of_last_communication on time, it was switched on again and send OK status to tb.
2025-01-25 14:50:44 +01:00
if ( nodesData [ k ] . node _status _before _offline == true || nodesData [ k ] . status === true ) {
2024-09-09 17:50:17 +02:00
status = "OK" ;
nodesData [ k ] . time _of _last _communication = time ;
}
2024-12-02 17:06:49 +01:00
2025-02-04 18:45:06 +01:00
nodesData [ k ] . readout . status = status ;
2025-01-25 14:50:44 +01:00
updateNodeStatus ( k , status === "OK" ? true : false ) ;
if ( nodesData [ k ] . hasOwnProperty ( "node_status_before_offline" ) ) delete nodesData [ k ] . node _status _before _offline ;
2024-12-02 17:06:49 +01:00
sendTelemetry ( { status : status } , tbname , time ) ;
2024-05-07 16:28:43 +02:00
2025-01-25 14:50:44 +01:00
//vyreportovanie dimming, current, input power pre liniu pre vsetky nody
//Prud
2024-05-07 16:28:43 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-05-14 16:29:11 +02:00
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-05-14 16:29:11 +02:00
params . tbname = tbname ;
params . address = node ;
2025-01-25 14:50:44 +01:00
params . register = 75 ; //prud
2024-05-14 16:29:11 +02:00
params . recipient = 1 ; //slave
params . rw = 0 ; //read
2025-02-04 18:45:06 +01:00
params . timestamp = time + 4000 ;
2025-01-25 14:50:44 +01:00
params . info = 'read current' ;
2024-05-14 16:29:11 +02:00
//params.debug = true;
tasks . push ( params ) ;
}
2024-05-07 16:28:43 +02:00
2025-01-25 14:50:44 +01:00
//vykon
2024-05-14 16:29:11 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-05-14 16:29:11 +02:00
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-05-14 16:29:11 +02:00
params . tbname = tbname ;
params . address = node ;
2025-01-25 14:50:44 +01:00
params . register = 76 ; //výkon
2024-05-14 16:29:11 +02:00
params . recipient = 1 ; //slave
params . rw = 0 ; //read
2025-02-04 18:45:06 +01:00
params . timestamp = time + 4100 ;
2025-01-25 14:50:44 +01:00
params . info = 'read power' ;
2024-05-14 16:29:11 +02:00
//params.debug = true;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
tasks . push ( params ) ;
}
2025-01-25 14:50:44 +01:00
//dimming
2024-05-14 16:29:11 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-05-14 16:29:11 +02:00
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-05-14 16:29:11 +02:00
params . tbname = tbname ;
params . address = node ;
2025-01-25 14:50:44 +01:00
params . register = 1 ; //dimming
2024-05-14 16:29:11 +02:00
params . recipient = 1 ; //slave
params . rw = 0 ; //read
2025-02-04 18:45:06 +01:00
params . timestamp = time + 4200 ;
2025-01-25 14:50:44 +01:00
params . info = 'read dimming' ;
2024-05-14 16:29:11 +02:00
//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
}
2025-01-25 14:50:44 +01:00
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
}
2025-01-25 14:50:44 +01:00
2024-12-02 17:06:49 +01:00
} , sec * 1000 ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
function reportOfflineNodeStatus ( line ) {
2024-05-07 16:28:43 +02:00
logger . debug ( "--->reportOfflineNodeStatus for line" , line ) ;
values = { } ;
values [ "dimming" ] = 0 ; //brightness
values [ "power" ] = 0 ; //výkon
values [ "current" ] = 0 ; //prúd
2024-09-09 17:50:17 +02:00
values [ "status" ] = "OFFLINE" ;
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
const date = Date . now ( ) ;
2024-10-02 18:21:31 +02:00
Object . keys ( nodesData ) . forEach ( ( node , index ) => {
2024-12-02 17:06:49 +01:00
2024-10-02 18:21:31 +02:00
setTimeout ( function ( ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//potrebujem nody k danej linii
if ( line == nodesData [ node ] . line || line == undefined ) {
2025-01-17 15:09:02 +01:00
2024-12-02 17:06:49 +01:00
let tbname = nodesData [ node ] . tbname ;
2025-01-25 14:50:44 +01:00
let nodeStatus = nodesData [ node ] . status ;
2025-01-17 15:09:02 +01:00
2025-01-25 14:50:44 +01:00
nodesData [ node ] . node _status _before _offline = nodeStatus === true ? true : false ;
nodesData [ node ] . status = "OFFLINE" ;
2025-02-04 18:45:06 +01:00
nodesData [ node ] . readout = { } ;
2025-01-25 14:50:44 +01:00
sendTelemetry ( { ... values } , tbname , date ) ;
2024-12-02 17:06:49 +01:00
}
2025-01-15 22:17:14 +01:00
} , ( index + 1 ) * 300 ) ;
2024-10-02 18:21:31 +02:00
} )
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
function turnLine ( onOrOff , line , info ) {
2024-05-07 16:28:43 +02:00
let obj = {
2024-05-14 16:29:11 +02:00
line : line ,
2024-12-02 17:06:49 +01:00
command : onOrOff ,
2024-05-14 16:29:11 +02:00
info : info
2024-05-07 16:28:43 +02:00
} ;
2025-01-25 14:50:44 +01: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
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
function detectIfResponseIsValid ( bytes ) {
2024-05-07 16:28:43 +02:00
//ak sa odpoved zacina 0 - je to v poriadku, inak je NOK
let type = "RESPONSE" ;
2024-12-02 17:06:49 +01:00
if ( bytes . length == 1 ) type = "BROADCAST" ; // odpoved z rsPortu na broadcast command: ["broadcast"]
else if ( bytes [ 4 ] == 0 ) type = "RESPONSE" ;
else if ( bytes [ 4 ] == 1 ) type = "ERROR" ;
else if ( bytes [ 4 ] == 2 ) type = "EVENT" ;
2024-05-07 16:28:43 +02:00
else type = "UNKNOWN" ;
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
let message = "OK" ;
let error = "" ;
2024-12-02 17:06:49 +01:00
if ( type == "BROADCAST" ) return { message , type , error } ;
2024-12-02 16:57:26 +01:00
2024-05-07 16:28:43 +02:00
let crc = crc16 ( 'ARC' , bytes . slice ( 0 , 9 ) ) ;
let c1 = ( crc >> 8 ) & 0xFF ;
let c2 = crc & 0xFF ;
2024-12-02 17:06:49 +01:00
if ( c1 != bytes [ 9 ] ) {
2024-05-07 16:28:43 +02:00
//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
}
2024-12-02 17:06:49 +01:00
if ( c2 != bytes [ 10 ] ) {
2024-05-07 16:28:43 +02:00
//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
}
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
//crc error
2024-12-02 17:06:49 +01:00
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" ;
}
2024-12-02 17:06:49 +01:00
return { message , type , error } ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
//BUILD TASKS//
2024-12-02 17:06:49 +01:00
function buildTasks ( params ) {
2024-05-07 16:28:43 +02:00
2024-05-21 15:49:42 +02:00
//return;
2024-12-02 16:57:26 +01:00
console . log ( "buidTAaasks start ****************" , params ) ;
2024-05-07 16:28:43 +02:00
monitor . info ( "buildTasks - params" , params ) ;
let processLine ; //defined line
let init = false ;
let processLineProfiles = true ;
let processBroadcast = true ;
let processNodes = true ;
2024-12-02 17:06:49 +01:00
if ( params == undefined ) {
2024-05-07 16:28:43 +02:00
init = true ;
tasks = [ ] ;
logger . debug ( "-->buildTasks clear tasks" ) ;
}
2024-12-02 17:06:49 +01:00
else {
2024-05-07 16:28:43 +02:00
processLineProfiles = false ;
processBroadcast = false ;
processNodes = false ;
processLineProfiles = params . processLineProfiles ;
processLine = params . line ;
}
let now = new Date ( ) ;
2025-01-25 14:50:44 +01:00
//process line profiles
2024-12-02 17:06:49 +01:00
if ( processLineProfiles ) {
2025-01-25 14:50:44 +01:00
2024-05-07 16:28:43 +02:00
let keys = Object . keys ( relaysData ) ;
2025-01-25 14:50:44 +01:00
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2025-01-25 14:50:44 +01:00
let line = parseInt ( keys [ i ] ) ;
2024-05-07 16:28:43 +02:00
let profilestr = relaysData [ line ] . profile ;
2024-12-02 17:06:49 +01:00
if ( processLine != undefined ) {
if ( processLine != line ) continue ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
try {
2024-05-07 16:28:43 +02:00
2024-05-21 15:49:42 +02:00
/ * *
* we process line profiles : timepoints , astro clock , lux _sensor , offsets ...
* /
2024-12-02 17:06:49 +01:00
if ( profilestr === "" ) throw ( "Profile is not defined" ) ;
2024-05-07 16:28:43 +02:00
let profile = JSON . parse ( profilestr ) ;
2024-12-02 17:06:49 +01: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 ) ;
2024-12-02 17:06:49 +01:00
let time _points = profile . intervals ;
2024-05-07 16:28:43 +02:00
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);
2024-05-21 15:49:42 +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-12-02 17:06:49 +01:00
if ( profile . astro _clock == true ) {
2024-05-07 16:28:43 +02:00
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
2024-12-02 17:06:49 +01:00
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" } ) ;
2024-05-14 16:29:11 +02:00
//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-12-02 17:06:49 +01:00
if ( profile . dawn _lux _sensor == true ) {
let [ ahours , aminutes ] = sunCalcResult [ "dawn" ] . split ( ':' ) ;
let ad = new Date ( ) ;
ad . setHours ( parseInt ( ahours ) , parseInt ( aminutes ) + profile . dawn _lux _sensor _time _window , 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let strDate = ad . getHours ( ) + ":" + ad . getMinutes ( ) ;
time _points . push ( { "value" : 0 , "start_time" : strDate , "name" : "luxOff" } ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
if ( profile . dusk _lux _sensor == true ) {
let [ ahours , aminutes ] = sunCalcResult [ "dusk" ] . split ( ':' ) ;
let ad = new Date ( ) ;
ad . setHours ( parseInt ( ahours ) , parseInt ( aminutes ) + profile . dusk _lux _sensor _time _window , 0 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let strDate = ad . getHours ( ) + ":" + ad . getMinutes ( ) ;
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
2024-12-02 17:06:49 +01:00
time _points . sort ( function ( a , b ) {
let [ ahours , aminutes ] = a . start _time . split ( ':' ) ;
let [ bhours , bminutes ] = b . start _time . split ( ':' ) ;
2024-05-07 16:28:43 +02:00
let ad = new Date ( ) ;
2024-12-02 17:06:49 +01:00
ad . setHours ( parseInt ( ahours ) , parseInt ( aminutes ) , 0 ) ;
2024-05-07 16:28:43 +02:00
let bd = new Date ( ) ;
2024-12-02 17:06:49 +01:00
bd . setHours ( parseInt ( bhours ) , parseInt ( bminutes ) , 0 ) ;
2024-05-07 16:28:43 +02:00
return ad . getTime ( ) - bd . getTime ( ) ;
} ) ;
2024-05-14 16:29:11 +02:00
console . log ( "line timepoints ........" , time _points ) ;
2024-12-02 17:06:49 +01:00
let currentValue = 0 ;
if ( time _points . length > 0 ) currentValue = time _points [ time _points . length - 1 ] . value ;
2024-05-07 16:28:43 +02:00
monitor . info ( "-->comming events turn on/off lines:" ) ;
2024-12-02 17:06:49 +01:00
for ( let t = 0 ; t < time _points . length ; t ++ ) {
2024-05-07 16:28:43 +02:00
let start _time = new Date ( ) ;
2024-12-02 17:06:49 +01:00
let [ hours , minutes ] = time _points [ t ] . start _time . split ( ':' ) ;
start _time . setHours ( parseInt ( hours ) , parseInt ( minutes ) , 0 ) ;
//task is in the past
if ( now . getTime ( ) > start _time . getTime ( ) ) {
2024-05-07 16:28:43 +02:00
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-12-02 16:57:26 +01:00
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
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 ( ) ;
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
2024-12-02 17:06:49 +01:00
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:
2024-12-02 17:06:49 +01:00
if ( [ 'luxOn' , 'luxOff' , 'dusk' , 'dawn' ] . includes ( params . timePointName ) ) {
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-12-02 17:06:49 +01: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-14 16:29:11 +02:00
2024-05-07 16:28:43 +02:00
params . debug = true ;
//turn on/off line
tasks . push ( params ) ;
2024-12-02 17:06:49 +01:00
monitor . info ( "TimePoint params: " , params . info , start _time ) ;
2024-05-07 16:28:43 +02:00
}
monitor . info ( "-->time_points final" , line , time _points ) ;
2024-12-02 17:06:49 +01:00
//ensure to turn on/off according to calculated currentValue
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-05-07 16:28:43 +02:00
params . type = "relay" ;
params . line = parseInt ( line ) ;
params . tbname = relaysData [ line ] . tbname ;
params . value = currentValue ;
2025-01-25 14:50:44 +01:00
params . timestamp = i ;
2024-05-07 16:28:43 +02:00
params . debug = true ;
//logger.debug(now.toLocaleString("sk-SK"));
monitor . info ( "-->currentValue for relay" , line , currentValue ) ;
//turn on/off line
2024-12-02 17:06:49 +01:00
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 ;
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
} catch ( error ) {
2024-12-02 17:06:49 +01:00
if ( profilestr !== "" ) {
2024-05-07 16:28:43 +02:00
//errLogger.error(profilestr, error);
2025-01-25 14:50:44 +01:00
console . log ( ` Cmd_manager: Unable to process line profile ${ line } . Error: ` , error ) ;
2024-05-07 16:28:43 +02:00
errorHandler . sendMessageToService ( profilestr + "-" + error , 0 , "js_error" ) ;
2025-01-25 14:50:44 +01:00
} else {
turnLine ( "off" , line , "No line profile. Switching it off on startup" ) ;
2024-05-07 16:28:43 +02:00
}
}
}
//logger.debug("tasks:");
//logger.debug(tasks);
}
2025-02-04 18:45:06 +01:00
//NOTE: PROCESS DEFAULT BROADCASTS - Time of dusk, Time of dawn, Actual Time
2024-12-02 17:06:49 +01:00
if ( processBroadcast ) {
2025-01-25 14:50:44 +01:00
let d = new Date ( ) ;
let time = d . getTime ( ) ;
let sunCalcResult = calculateDuskDawn ( ) ;
2024-05-07 16:28:43 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-12-02 17:06:49 +01:00
2024-09-09 12:32:34 +02:00
params . address = 0xffffffff ; //broadcast
2025-01-25 14:50:44 +01:00
params . byte1 = sunCalcResult [ "dusk_hours" ] ;
params . byte2 = sunCalcResult [ "dusk_minutes" ] ;
2024-12-02 17:06:49 +01:00
params . recipient = 2 ; //2 broadcast,
2025-02-04 18:45:06 +01:00
params . register = 6 ; //Time of dusk
2024-05-07 16:28:43 +02:00
params . rw = 1 ; //write
2025-02-04 18:45:06 +01:00
params . type = "node-regular-write" ;
2025-01-25 14:50:44 +01:00
params . timestamp = time + 60000 ;
params . addMinutesToTimestamp = 60 * 3 ; //kazde 3 hodiny zisti novy dusk
2024-05-07 16:28:43 +02:00
params . info = "Broadcast-duskTime" ;
tasks . push ( params ) ;
}
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-12-02 17:06:49 +01:00
2024-09-09 12:32:34 +02:00
params . address = 0xffffffff ; //broadcast
2025-01-25 14:50:44 +01:00
params . byte1 = sunCalcResult [ "dawn_hours" ] ;
params . byte2 = sunCalcResult [ "dawn_minutes" ] ;
2024-09-09 12:32:34 +02:00
params . recipient = 2 ; //2 broadcast
2025-02-04 18:45:06 +01:00
params . register = 7 ; //Time of dawn
2024-05-07 16:28:43 +02:00
params . rw = 1 ; //write
2025-02-04 18:45:06 +01:00
params . type = "node-regular-write" ;
2025-01-25 14:50:44 +01:00
params . timestamp = time + 60001 ;
params . addMinutesToTimestamp = 60 * 3 ; //kazde 3 hodiny zisti novy dawn
2024-05-07 16:28:43 +02:00
params . info = "Broadcast-dawnTime" ;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
}
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-12-02 17:06:49 +01:00
2024-09-09 12:32:34 +02:00
params . address = 0xffffffff ; //broadcast
2025-01-25 14:50:44 +01:00
params . byte1 = d . getHours ( ) ;
params . byte2 = d . getMinutes ( ) ;
2024-09-09 12:32:34 +02:00
params . recipient = 2 ; //2 broadcast
2024-05-07 16:28:43 +02:00
params . register = 87 ; //Actual time
params . rw = 1 ; //write
2025-02-04 18:45:06 +01:00
params . type = "node-regular-write" ;
2025-01-25 14:50:44 +01:00
params . timestamp = time + 60002 ;
params . addMinutesToTimestamp = 5 ;
2024-05-07 16:28:43 +02:00
params . info = "run broadcast: Actual time" ;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
}
}
2025-02-04 18:45:06 +01:00
//process nodes & tasks - read node's data
2024-12-02 17:06:49 +01:00
if ( processNodes ) {
2025-01-25 14:50:44 +01:00
let time = Date . now ( ) ;
2024-05-07 16:28:43 +02:00
for ( let k in nodesData ) {
let address = parseInt ( k ) ;
let tbname = nodesData [ k ] . tbname ;
let register = 0 ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < listOfCommands . length ; i ++ ) {
2025-01-25 14:50:44 +01:00
2024-05-07 16:28:43 +02:00
register = listOfCommands [ i ] ;
2025-01-25 14:50:44 +01:00
let addMinutesToTimestamp = priorities [ register ] ;
2024-12-02 17:06:49 +01:00
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
params . address = address ;
params . recipient = 1 ;
params . register = register ;
2025-02-04 18:45:06 +01:00
params . type = register == 1 ? "node-dimming-read" : "node-regular-read" ;
2024-05-07 16:28:43 +02:00
params . tbname = tbname ;
2025-01-25 14:50:44 +01:00
params . timestamp = time + 5000 + i * 500 + addMinutesToTimestamp * 1000 ; //to make slight time difference
2024-05-07 16:28:43 +02:00
params . addMinutesToTimestamp = addMinutesToTimestamp ;
2025-02-04 18:45:06 +01:00
params . info = "Node regular read command" ;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
}
2025-01-25 14:50:44 +01:00
2024-05-07 16:28:43 +02:00
}
}
//niektore ulohy sa vygeneruju iba 1x pri starte!!!
2024-12-02 17:06:49 +01:00
if ( ! init ) return ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
//Master node FW version - modifies SETTINGS.masterNodeIsResponding
2024-05-07 16:28:43 +02:00
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-09-09 17:50:17 +02:00
params . type = "cmd-master" ;
2024-05-07 16:28:43 +02:00
params . register = 4 ;
params . address = 0 ;
2024-09-09 17:50:17 +02:00
params . timestamp = Date . now ( ) + 60000 ;
2024-05-07 16:28:43 +02:00
params . addMinutesToTimestamp = 5 ;
2025-01-09 22:21:50 +01:00
params . tbname = SETTINGS . rvoTbName ;
2024-05-07 16:28:43 +02:00
params . info = "Master node FW verzia" ;
//params.debug = true;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
}
//kazdu hodinu skontrolovat nastavenie profilov
{
2025-01-25 14:50:44 +01:00
let params = getParams ( ) ;
2024-05-07 16:28:43 +02:00
params . type = "process_profiles" ;
2025-02-04 18:45:06 +01:00
params . timestamp = Date . now ( ) + 60001 ;
2024-05-07 16:28:43 +02:00
params . addMinutesToTimestamp = 60 ; //60 = every hour
params . info = "detekcia nespracovaných profilov linie a nodov" ;
//params.debug = true;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
tasks . push ( params ) ;
}
monitor . info ( "tasks created:" , tasks . length ) ;
}
2024-05-14 16:29:11 +02:00
2024-05-21 15:49:42 +02:00
/ * *
* We process line profile , where "astro_clock" : true
* example profile :
*
"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
* if dawn : if currentTimestamp is in timewindow "dawnTime + and - dawn_lux_sensor_time_window" and lux value >= lux _sensor _value , we switch off the line .
* if dusk : we do oposite
*
* dawn : usvit - lux je nad hranicou - vypnem
* dusk : sumrak - lux je pod hranicou - zapnem
* /
2024-12-02 17:06:49 +01:00
function turnOnOffLinesAccordingToLuxSensor ( lux _sensor _value ) {
2024-05-07 16:28:43 +02:00
let now = new Date ( ) ;
let currentTimestamp = now . getTime ( ) ;
let keys = Object . keys ( relaysData ) ;
2024-05-21 15:49:42 +02:00
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-05-21 15:49:42 +02:00
let line = keys [ i ] ; //line is turned off by default
2024-05-07 16:28:43 +02:00
let profilestr = relaysData [ line ] . profile ;
2024-05-21 15:49:42 +02:00
const contactor = relaysData [ line ] . contactor ;
2024-05-07 16:28:43 +02:00
2024-05-21 15:49:42 +02:00
try {
2024-05-07 16:28:43 +02:00
let profile = JSON . parse ( profilestr ) ;
2024-12-02 17:06:49 +01:00
if ( Object . keys ( profile ) . length === 0 ) throw ( "turnOnOffLinesAccordingToLuxSensor - profile is not defined" ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( profile . astro _clock == true ) {
2024-05-21 15:49:42 +02:00
let sunCalcResult = calculateDuskDawn ( now , line ) ;
2024-05-07 16:28:43 +02:00
2024-05-21 15:49:42 +02:00
//usvit
2024-12-02 17:06:49 +01:00
if ( profile . dawn _lux _sensor == true ) {
let lux _sensor _time _window1 = sunCalcResult . dawn _time - ( parseInt ( profile . dawn _lux _sensor _time _window ) * 1000 * 60 ) ; // LUX_SENSOR_TIME_WINDOW x 1000 x 60 --> dostaneme odpocet/pripocitanie minut
let lux _sensor _time _window2 = sunCalcResult . dawn _time + ( parseInt ( profile . dawn _lux _sensor _time _window ) * 1000 * 60 ) ;
if ( currentTimestamp >= lux _sensor _time _window1 && currentTimestamp <= lux _sensor _time _window2 ) {
if ( lux _sensor _value > profile . dawn _lux _sensor _value ) {
if ( contactor ) turnLine ( "off" , line , "Profile: dawn - turnOff line according to lux sensor" ) ;
2024-05-21 15:49:42 +02:00
}
2024-05-07 16:28:43 +02:00
}
2024-05-21 15:49:42 +02:00
}
2024-05-07 16:28:43 +02:00
2024-05-21 15:49:42 +02:00
//sumrak
2024-12-02 17:06:49 +01:00
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 ) {
if ( lux _sensor _value < profile . dusk _lux _sensor _value ) {
if ( ! contactor ) turnLine ( "on" , line , "Profile: dusk - turnOn line according to lux sensor" ) ;
2024-05-21 15:49:42 +02:00
}
2024-05-07 16:28:43 +02:00
}
2024-05-21 15:49:42 +02:00
}
2024-05-07 16:28:43 +02:00
}
} catch ( error ) {
2024-12-02 17:06:49 +01:00
if ( profilestr !== "" ) monitor . info ( 'Error parsing profile in turnOnOffLinesAccordingToLuxSensor' , error ) ;
2024-05-07 16:28:43 +02:00
}
2024-05-21 15:49:42 +02:00
2024-05-07 16:28:43 +02:00
}
2024-05-21 15:49:42 +02:00
2024-05-07 16:28:43 +02:00
}
2024-09-09 17:50:17 +02:00
/ * *
* function updates status and time _of _last _communication of node in the dbNodes
* it only updates if conditions are met
* it only updates time _of _last _communication of node , if the last written time was more than 10 minutes ago ( 600000 miliseconds )
2024-12-02 16:57:26 +01:00
* if newStatus of node is always receiving false , and it is already for more than SETTINGS . node _status _nok _time value , we update status to "NOK" in tb
2024-09-09 17:50:17 +02:00
* function returns true , if status of node needs to be updated in TB ( newStatus attribute is false in this case ) .
* /
2024-12-02 17:06:49 +01:00
function updateNodeStatus ( node , newStatus ) {
2024-05-07 16:28:43 +02:00
//MASTER
2024-12-02 17:06:49 +01:00
if ( node == 0 ) return ;
2024-05-07 16:28:43 +02:00
let nodeObj = nodesData [ node ] ;
2024-12-02 17:06:49 +01:00
if ( nodeObj == undefined ) return ;
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
let nodeCurrentStatus = nodeObj . status ;
const now = Date . now ( ) ;
2024-12-02 16:57:26 +01:00
let data = null ;
2024-09-09 17:50:17 +02:00
2025-01-25 14:50:44 +01:00
if ( nodeCurrentStatus === "OFFLINE" ) {
data = { status : newStatus } ;
nodeDbStatusModify ( node , data ) ;
return ;
}
else if ( newStatus == true && nodeCurrentStatus == true && nodeObj . time _of _last _communication > now - TIME _AFTER _WE _UPDATE _LAST _NODE _COMMUNICATION ) return ;
2024-12-02 17:06:49 +01:00
else if ( newStatus == true && nodeCurrentStatus == true && nodeObj . time _of _last _communication < now - TIME _AFTER _WE _UPDATE _LAST _NODE _COMMUNICATION ) {
data = { time _of _last _communication : now } ;
2024-12-02 16:57:26 +01:00
nodeDbStatusModify ( node , data ) ;
2024-09-09 17:50:17 +02:00
return ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
else if ( newStatus == false && nodeCurrentStatus == false ) return true ;
else if ( newStatus == false && nodeCurrentStatus == true ) {
if ( nodeObj . time _of _last _communication + SETTINGS . node _status _nok _time > now ) return ;
2024-09-09 17:50:17 +02:00
else {
2024-12-02 17:06:49 +01:00
data = { status : newStatus } ;
2024-12-02 16:57:26 +01:00
nodeDbStatusModify ( node , data ) ;
2024-09-09 17:50:17 +02:00
return true ;
}
}
2024-12-02 17:06:49 +01:00
else if ( newStatus == true && nodeCurrentStatus == false ) {
data = { status : newStatus , time _of _last _communication : now } ;
2024-12-02 16:57:26 +01:00
nodeDbStatusModify ( node , data ) ;
2024-09-09 17:50:17 +02:00
return ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
}
2024-12-02 17:06:49 +01:00
function nodeDbStatusModify ( node , data ) {
2024-12-02 16:57:26 +01:00
dbNodes . modify ( data ) . where ( "node" , node ) . make ( function ( builder ) {
builder . callback ( function ( err , response ) {
2024-12-02 17:06:49 +01:00
if ( ! err ) {
nodesData [ node ] = { ... nodesData [ node ] , ... data } ;
2024-12-02 16:57:26 +01:00
}
} ) ;
} ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
async function runTasks ( ) {
2024-05-21 15:49:42 +02:00
2024-05-07 16:28:43 +02:00
clearInterval ( interval ) ;
let currentTimestamp = Date . now ( ) ;
//report dusk, dawn---------------------------------
2024-12-02 17:06:49 +01:00
if ( reportDuskDawn . dusk _time < currentTimestamp ) {
2024-05-07 16:28:43 +02:00
//vyreportuj iba ak nie je velky rozdiel napr. 60 sekund
2024-12-02 17:06:49 +01:00
if ( ( currentTimestamp - reportDuskDawn . dusk _time ) < 60 * 1000 ) {
2024-05-07 16:28:43 +02:00
//reportovali sme?
2024-12-02 17:06:49 +01:00
if ( reportDuskDawn . dusk _time _reported != sunCalcResult . dusk _time ) {
2025-01-01 13:12:02 +01:00
//sendNotification("CMD Manager: calculated Time of dusk", SETTINGS.rvoTbName, "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 ;
}
2024-12-02 17:06:49 +01:00
if ( reportDuskDawn . dawn _time < currentTimestamp ) {
2024-05-07 16:28:43 +02:00
//vyreportuj iba ak nie je velky rozdiel napr. 60 sekund
2024-12-02 17:06:49 +01:00
if ( ( currentTimestamp - reportDuskDawn . dawn _time ) < 60 * 1000 ) {
2024-05-07 16:28:43 +02:00
//reportovali sme?
2024-12-02 17:06:49 +01:00
if ( reportDuskDawn . dawn _time _reported != sunCalcResult . dawn _time ) {
2025-01-01 13:12:02 +01:00
//sendNotification("CMD Manager: calculated Time of dawn", SETTINGS.rvoTbName, "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-12-02 17:06:49 +01:00
tasks . sort ( function ( a , b ) {
if ( a . timestamp <= currentTimestamp && b . timestamp <= currentTimestamp ) {
2024-05-07 16:28:43 +02:00
return a . priority - b . priority ;
}
return a . timestamp - b . timestamp ;
} ) ;
2024-12-02 17:06:49 +01:00
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 ;
}
2024-12-02 17:06:49 +01:00
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();
2025-01-01 12:53:20 +01:00
//console.log("Cmd_manager - !rsPort.isOpen");
2024-05-07 16:28:43 +02:00
}
let currentTask = tasks [ 0 ] ;
2024-12-02 17:06:49 +01:00
if ( currentTask . debug ) {
2024-05-07 16:28:43 +02:00
//logger.debug("--->task to process", currentTask);
}
2024-12-02 17:06:49 +01:00
if ( currentTask . timestamp <= currentTimestamp ) {
let params = { ... tasks [ 0 ] } ;
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//allow terminal commands
2024-12-02 17:06:49 +01:00
if ( SETTINGS . maintenance _mode && params . type !== "cmd-terminal" ) {
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 ;
2025-01-01 13:12:02 +01:00
let node = params . address ;
2024-05-07 16:28:43 +02:00
let line = null ;
2025-02-04 18:45:06 +01:00
let itIsNodeCommand ;
2024-05-14 16:29:11 +02:00
2025-02-04 18:45:06 +01:00
if ( nodesData [ node ] !== undefined ) {
line = nodesData [ node ] . line ;
itIsNodeCommand = true ;
}
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
if ( params . line !== undefined ) line = params . line ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
if ( params . addMinutesToTimestamp > 0 || params . timePointName ) {
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
} else {
2024-05-07 16:28:43 +02:00
tasks . shift ( ) ;
}
//kontrola nespracovanych profilov nodov
2024-12-02 17:06:49 +01:00
if ( type == "process_profiles" ) {
2025-01-25 14:50:44 +01:00
//na vsetky zapnutych liniach sa spracuju nespracovane profily nodov
2024-05-07 16:28:43 +02:00
loadRelaysData ( ) ;
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
//relay
2024-12-02 17:06:49 +01:00
if ( type == "relay" ) {
2024-05-07 16:28:43 +02:00
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
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 ;
2024-12-02 17:06:49 +01:00
if ( timePointName ) sunCalcResult = calculateDuskDawn ( date , params . line ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( timePointName == "dawn" ) {
2024-05-14 16:29:11 +02:00
tasks [ 0 ] . timestamp = sunCalcResult . dawn _time ;
}
2024-12-02 17:06:49 +01:00
else if ( timePointName == "dusk" ) {
2024-05-14 16:29:11 +02:00
tasks [ 0 ] . timestamp = sunCalcResult . dusk _time ;
}
2024-12-02 17:06:49 +01:00
else if ( timePointName == "luxOn" ) {
2024-05-14 16:29:11 +02:00
tasks [ 0 ] . timestamp = sunCalcResult . dusk _time + params . dusk _lux _sensor _time _window * 60000 ;
}
2024-12-02 17:06:49 +01:00
else if ( timePointName == "luxOff" ) {
2024-05-14 16:29:11 +02:00
tasks [ 0 ] . timestamp = sunCalcResult . dawn _time + params . dawn _lux _sensor _time _window * 60000 ;
}
2024-12-02 17:06:49 +01:00
else if ( timePointName == "profileTimepoint" ) {
2024-05-14 16:29:11 +02:00
tasks [ 0 ] . timestamp = currentTimestamp + tasks [ 0 ] . addMinutesToTimestamp * 60000 ;
}
2024-09-09 12:32:34 +02:00
let info = "aplikovany bod profilu" ;
2025-01-01 13:12:02 +01:00
let onOrOff = "" ;
value == 1 ? onOrOff = "on" : onOrOff = "off" ;
2024-12-02 17:06:49 +01:00
2025-01-01 13:12:02 +01:00
turnLine ( onOrOff , params . line , info ) ;
2025-01-09 14:55:53 +01:00
2025-01-25 14:50:44 +01:00
interval = setInterval ( runTasks , LONG _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
2024-12-02 17:06:49 +01:00
if ( state _of _breaker . hasOwnProperty ( line ) ) {
2024-05-07 16:28:43 +02:00
//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-12-02 17:06:49 +01:00
if ( disconnected ) {
let values = { "status" : "OFFLINE" } ;
2024-05-07 16:28:43 +02:00
logger . debug ( "disconnected" , values ) ;
logger . debug ( "rotary_switch_state" , rotary _switch _state ) ;
logger . debug ( "state_of_breaker" , state _of _breaker [ line ] ) ;
//report only once!
2024-12-02 17:06:49 +01:00
if ( ! disconnectedReport . hasOwnProperty ( tbname ) ) disconnectedReport [ tbname ] = false ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( ! disconnectedReport [ tbname ] ) {
2024-12-02 16:57:26 +01:00
sendTelemetry ( values , tbname )
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 ;
}
disconnectedReport [ tbname ] = false ;
2024-09-09 17:50:17 +02:00
const register = params . register ;
2024-12-02 17:06:49 +01:00
if ( ! SETTINGS . masterNodeIsResponding ) {
2025-02-04 18:45:06 +01:00
//ak neodpoveda, nebudeme vykonavat ziadne commands, okrem cmd-terminal cmd-master
2024-05-07 16:28:43 +02:00
errorHandler . sendMessageToService ( "Master node is not responding" ) ;
let stop = true ;
2025-02-04 18:45:06 +01:00
if ( type == "cmd-terminal" || type == "cmd-master" ) stop = false ;
2024-12-02 17:06:49 +01:00
if ( stop ) {
2024-05-14 16:29:11 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
2024-05-07 16:28:43 +02:00
return ;
}
}
2025-01-09 22:21:50 +01:00
let contactorStatus = 1 ;
if ( relaysData [ line ] != undefined ) contactorStatus = relaysData [ line ] . contactor ;
if ( line == 0 || contactorStatus == 0 ) {
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
return ;
}
2024-05-07 16:28:43 +02:00
2025-01-09 14:55:53 +01:00
// TODO: -> status offline for rvo if rotary_switch_state is OFF, this is source of errors
//
// let relayStatus = 1;
// if (relaysData[line] != undefined) {
// relayStatus = relaysData[line].contactor;
// }
2024-12-02 16:57:26 +01:00
2025-01-09 14:55:53 +01:00
// if (line == 0) relayStatus = 0;
// if (type == "cmd-terminal") relayStatus = 1;
2024-05-07 16:28:43 +02:00
2025-01-09 14:55:53 +01:00
// //check if rotary_switch_state == "Off"
// if (relayStatus == 0) {
// console.log("------------------------------------relayStatus", relayStatus, line);
// let values = { "status": "OFFLINE" };
2024-05-07 16:28:43 +02:00
2025-01-09 14:55:53 +01:00
// if(tbname) sendTelemetry(values, tbname)
2024-12-02 17:06:49 +01:00
2025-01-09 14:55:53 +01:00
// interval = setInterval(runTasks, SHORT_INTERVAL);
// return;
// }
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
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 ;
}
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
//RE-CALCULATE VALUES
//set actual time for broadcast
2024-12-02 17:06:49 +01:00
if ( register == 87 && params . recipient === 2 ) {
2024-05-07 16:28:43 +02:00
var d = new Date ( ) ;
2025-01-09 22:21:50 +01:00
params . byte1 = d . getHours ( ) ; //h
params . byte2 = d . getMinutes ( ) ; //m
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
//SET DUSK/DAWN FOR BROADCAST
2024-05-07 16:28:43 +02:00
//Time of dusk
2024-12-02 17:06:49 +01:00
if ( register == 6 && params . recipient === 2 ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( type != "cmd-terminal" ) {
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2025-01-09 22:21:50 +01:00
params . byte1 = sunCalcResult [ "dusk_hours" ] ; //h
params . byte2 = sunCalcResult [ "dusk_minutes" ] ; //m
2024-05-07 16:28:43 +02:00
}
}
//Time of dawn
2024-12-02 17:06:49 +01:00
if ( register == 7 && params . recipient === 2 ) {
if ( type != "cmd-terminal" ) {
2024-05-14 16:29:11 +02:00
let sunCalcResult = calculateDuskDawn ( ) ;
2025-01-13 15:39:53 +01:00
params . byte1 = sunCalcResult [ "dawn_hours" ] ; //h
2025-01-09 22:21:50 +01:00
params . byte2 = sunCalcResult [ "dawn_minutes" ] ; //m
2024-05-07 16:28:43 +02:00
}
}
//-----------------------
2025-01-01 13:12:02 +01:00
instance . send ( SEND _TO . debug , "address: " + node + " register:" + register + "type: " + type ) ;
2024-05-07 16:28:43 +02:00
var startTime , endTime ;
startTime = new Date ( ) ;
2024-09-09 17:50:17 +02:00
let saveToTb = true ;
2024-12-02 17:06:49 +01:00
if ( ! tbname ) saveToTb = false ;
2024-09-09 17:50:17 +02:00
2025-01-01 13:12:02 +01:00
let resp = com _generic ( node , params . recipient , params . rw , register , params . name , params . byte1 , params . byte2 , params . byte3 , params . byte4 ) ;
2024-05-07 16:28:43 +02:00
let readBytes = 11 ;
2024-10-02 18:21:31 +02:00
let timeout = 4000 ;
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
// await keyword is important, otherwise incorrect data is returned!
2024-12-02 17:06:49 +01:00
await writeData ( rsPort , resp , readBytes , timeout ) . then ( function ( data ) {
2024-05-07 16:28:43 +02:00
endTime = new Date ( ) ;
var timeDiff = endTime - startTime ;
2024-12-02 16:57:26 +01:00
//data je array z 11 bytov: 1-4 adresa, 5 status ak je status 0 - ok, nasleduju 4 byty data a 2 byty CRC
2024-12-02 17:06:49 +01:00
let dataBytes = data . slice ( 5 , 9 ) ;
2024-12-02 16:57:26 +01:00
let result = detectIfResponseIsValid ( data ) ;
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
//ak sa odpoved zacina 0 - je to v poriadku, inak je NOK
2024-09-09 17:50:17 +02:00
let message = result . message ; // OK, NOK
let message _type = result . type ;
let error = result . error ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
if ( params . hasOwnProperty ( "debug" ) ) {
if ( params . debug ) {
console . log ( "detected response:" , result ) ;
logger . debug ( "Cmd-mngr: writeData done " + message _type + " duration: " + timeDiff + " type: " + params . debug , params , result ) ;
}
2024-05-07 16:28:43 +02:00
}
2024-09-09 17:50:17 +02:00
let values = { } ;
2024-05-07 16:28:43 +02:00
//CMD FINISHED
2024-12-02 17:06:49 +01:00
if ( message == "OK" ) {
2024-05-07 16:28:43 +02:00
2025-01-01 13:12:02 +01:00
updateNodeStatus ( node , true ) ;
2024-05-07 16:28:43 +02:00
//write
2024-12-02 17:06:49 +01:00
if ( type == "set_node_profile" ) {
2025-01-01 13:12:02 +01:00
let result = cmdCounterResolve ( node ) ;
2024-12-02 17:06:49 +01:00
if ( result == 0 ) {
2025-01-01 13:12:02 +01:00
dbNodes . modify ( { processed : true } ) . where ( "node" , node ) . make ( function ( builder ) {
2024-05-07 16:28:43 +02:00
builder . callback ( function ( err , response ) {
2025-01-01 13:12:02 +01:00
sendNotification ( "CMD Manager: process cmd" , SETTINGS . rvoTbName , "dimming_profile_was_successfully_received_by_node" , { node : node } , "" , SEND _TO . tb , instance ) ;
2024-12-02 17:06:49 +01:00
2025-01-01 13:12:02 +01:00
logger . debug ( "--> profil úspešne odoslaný na node č. " + node ) ;
nodesData [ node ] . processed = true ;
nodeProfileSendFail . delete ( node ) ;
2024-05-07 16:28:43 +02:00
} ) ;
2024-09-17 08:54:32 +02:00
} ) ;
2024-05-07 16:28:43 +02:00
}
}
//parse read response
2024-12-02 17:06:49 +01:00
if ( params . rw == 0 ) {
2024-09-09 17:50:17 +02:00
values = processResponse ( register , dataBytes ) ; //read
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
if ( itIsNodeCommand ) {
2024-09-09 17:50:17 +02:00
values . comm _status = "OK" ;
values . status = "OK" ;
2025-02-04 18:45:06 +01:00
nodesData [ node ] . readout = { ... nodesData [ node ] . readout , ... values } ;
2024-09-09 17:50:17 +02:00
}
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
//master node
2025-01-01 13:12:02 +01:00
if ( node == 0 ) {
2024-12-02 17:06:49 +01:00
sendNotification ( "CMD Manager: process cmd" , SETTINGS . rvoTbName , "master_node_is_responding_again" , { } , "" , SEND _TO . tb , instance , "rvo_status" ) ;
2024-12-02 16:57:26 +01:00
SETTINGS . masterNodeIsResponding = true ;
2024-12-02 17:06:49 +01:00
if ( register == 4 ) values [ "edge_fw_version" ] = SETTINGS . edge _fw _version ;
2024-05-07 16:28:43 +02:00
}
//odoslanie príkazu z terminálu - dáta
2024-12-02 17:06:49 +01:00
if ( type == "cmd-terminal" ) {
sendNotification ( "CMD Manager: process cmd" , SETTINGS . rvoTbName , "command_was_sent_from_terminal_interface" , { } , params , SEND _TO . tb , instance ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
if ( params . debug ) {
2024-09-09 17:50:17 +02:00
//logger.debug("saveToTb", saveToTb, tbname, values);
2024-05-07 16:28:43 +02:00
}
2025-02-04 18:45:06 +01:00
if ( saveToTb && type != "node-regular-read" ) {
sendTelemetry ( values , tbname ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
else {
if ( type == "cmd-terminal" ) {
2024-09-09 17:50:17 +02:00
terminalCommandResponse ( params , "SUCCESS" , data ) ;
2024-05-07 16:28:43 +02:00
}
}
}
2024-12-02 17:06:49 +01:00
else {
2024-05-07 16:28:43 +02:00
2025-01-25 14:50:44 +01:00
terminalCommandResponse ( params , "ERROR" , data ) ;
2024-09-09 17:50:17 +02:00
handleNokResponseOnRsPort ( "handleNOK else block" , params , itIsNodeCommand , saveToTb ) ;
2024-12-02 17:06:49 +01:00
if ( params . hasOwnProperty ( "debug" ) ) {
if ( params . debug ) {
2024-09-09 17:50:17 +02:00
//logger.debug("writeData err: ", error, result, params);
2025-01-01 13:12:02 +01:00
logger . debug ( "writeData err: " , tbname , node , register , values ) ;
2024-05-07 16:28:43 +02:00
}
}
//logger.debug(error, result, params);
}
2024-09-09 17:50:17 +02:00
} ) . catch ( function ( reason ) {
2024-05-07 16:28:43 +02:00
console . log ( "writeData catch exception" , reason ) ;
2024-09-09 17:50:17 +02:00
instance . send ( SEND _TO . debug , reason ) ;
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
terminalCommandResponse ( params , "FAILURE" , null , reason ) ;
handleNokResponseOnRsPort ( "handleNOK catch block" , params , itIsNodeCommand , saveToTb ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( params . hasOwnProperty ( "debug" ) ) {
if ( params . debug ) {
2024-05-07 16:28:43 +02:00
logger . debug ( "-->WRITE FAILED: " + reason , params . debug , params ) ;
}
}
2024-09-09 17:50:17 +02:00
} ) ;
2024-12-02 17:06:49 +01:00
2024-09-09 17:50:17 +02:00
}
2024-12-02 17:06:49 +01:00
else {
2025-01-09 14:55:53 +01:00
if ( currentTask . debug ) {
2025-01-01 13:12:02 +01:00
// currentTask.timestamp <= currentTimestamp && logger.debug("currentTask is not processed - task is in the future", currentTask);
}
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
interval = setInterval ( runTasks , LONG _INTERVAL ) ;
return ;
2024-12-02 17:06:49 +01:00
}
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
//console.log("----->runTasks - setInterval", new Date());
interval = setInterval ( runTasks , SHORT _INTERVAL ) ;
2024-12-02 17:06:49 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function handleNokResponseOnRsPort ( message , params , itIsNodeCommand , saveToTb ) {
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
let node = params . address ;
let register = params . register ;
let type = params . type ;
let tbName = params . tbname ;
2024-12-02 17:06:49 +01:00
if ( ! tbName ) return ;
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
let values = { } ;
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
let updateStatus = updateNodeStatus ( node , false ) ;
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
if ( itIsNodeCommand ) {
values . comm _status = "NOK" ;
nodesData [ node ] . readout . comm _status = "NOK" ;
}
if ( updateStatus ) {
values . status = "NOK" ;
nodesData [ node ] . readout . status = "NOK" ;
}
if ( type === "node-regular-read" ) return ;
2024-09-22 22:18:46 +02:00
//master node
2024-12-02 17:06:49 +01:00
if ( node == 0 ) {
2024-12-02 16:57:26 +01:00
sendNotification ( "CMD Manager: process cmd" , SETTINGS . rvoTbName , "master_node_is_not_responding" , { } , "" , SEND _TO . tb , instance , "rvo_status" ) ;
2024-09-09 17:50:17 +02:00
logger . debug ( "master_node_is_not_responding" , params ) ;
2024-12-02 16:57:26 +01:00
SETTINGS . masterNodeIsResponding = false ;
2024-09-22 22:18:46 +02:00
2024-12-02 17:06:49 +01:00
if ( register == 4 ) values [ "master_node_version" ] = "NOK" ;
2024-09-09 17:50:17 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( type == "set_node_profile" ) {
2024-09-09 17:50:17 +02:00
delete cmdCounter [ node ] ;
2024-12-02 17:06:49 +01:00
logger . debug ( "profil nebol úspešne odoslaný na node č. " , params ) ;
2025-01-09 14:55:53 +01:00
if ( ! nodeProfileSendFail . has ( node ) ) {
sendNotification ( "CMD Manager: process cmd" , tbName , "configuration_of_dimming_profile_to_node_failed" , { node : node } , "" , SEND _TO . tb , instance ) ;
nodeProfileSendFail . add ( node ) ;
}
2024-09-09 17:50:17 +02:00
}
2024-05-07 16:28:43 +02:00
2024-09-22 22:18:46 +02:00
// console.log("------",node, register, type, itIsNodeCommand, updateStatus, saveToTb, values);
2025-02-04 18:45:06 +01:00
if ( saveToTb ) {
sendTelemetry ( values , tbName ) ;
2024-09-09 17:50:17 +02:00
}
}
2024-12-02 17:06:49 +01:00
2025-02-04 18:45:06 +01:00
function sendNodesData ( ) {
Object . keys ( nodesData ) . forEach ( node => {
if ( nodesData [ node ] [ "status" ] !== "OFFLINE" ) {
sendTelemetry ( nodesData [ node ] . readout , nodesData [ node ] . tbname ) ;
}
} )
}
2024-12-02 17:06:49 +01:00
2024-09-09 17:50:17 +02:00
/ * *
* function handles requests from terminal
* responseType can be "SUCCESS" , "ERROR" or "FAILURE" , depending on rsPort data .
* FAILURE means , that we got into catch block of writeData function .
* /
2024-12-02 17:06:49 +01:00
function terminalCommandResponse ( params , responseType , data = null , reason = "" ) { //success, error, failure
if ( params . refFlowdataKey == undefined ) {
2024-09-09 17:50:17 +02:00
//console.log("params.refFlowdataKey is undefined", params);
return ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
else {
2024-09-09 17:50:17 +02:00
console . log ( "params.refFlowdataKey: " , params ) ;
}
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
let message = null ;
let type = null ;
switch ( responseType ) {
case "SUCCESS" :
message = "cmd-terminal SUCCESS" ;
type = "SUCCESS" ;
break ;
case "ERROR" :
message = "cmd-terminal FAILED" ;
type = "ERROR" ;
break ;
case "FAILURE" :
message = "ERROR WRITE FAILED: " + reason ;
type = "ERROR" ;
break ;
default :
type = undefined ;
}
2024-05-07 16:28:43 +02:00
2024-09-09 17:50:17 +02:00
logger . debug ( message ) ;
logger . debug ( params ) ;
//make http response
let responseObj = { }
responseObj [ "type" ] = type ;
2024-12-02 17:06:49 +01:00
if ( responseType == "FAILURE" ) responseObj [ "message" ] = "ERROR WRITE FAILED: " + reason ;
2024-09-09 17:50:17 +02:00
else responseObj [ "bytes" ] = data ;
2024-12-02 16:57:26 +01:00
let refFlowdata = refFlowdataObj [ params . refFlowdataKey ] ; //holds reference to httprequest flowdata
2024-12-02 17:06:49 +01:00
if ( refFlowdata ) {
2024-09-09 17:50:17 +02:00
refFlowdata . data = responseObj ;
instance . send ( SEND _TO . http _response , refFlowdata ) ;
}
}
/ * *
* function handles tasks , that are not needed to run through masterNode . To make them run smooth without waiting for other tasks to be completed , we moved them in separate function
* /
2024-12-02 17:06:49 +01:00
function reportEdgeDateTimeAndNumberOfLuminaires ( ) {
2024-09-09 17:50:17 +02:00
2024-09-17 08:54:32 +02:00
//Number of ok and nok nodes on platform does not equals to total number of nodes.
//possible error is, that nodesData object is changing all the time. To make a proper calculation of ok,nok luminaires, we make a copy of it:
let nodesData _clone = JSON . parse ( JSON . stringify ( nodesData ) ) ;
2024-09-09 17:50:17 +02:00
const ts = Date . now ( ) ;
2024-09-17 08:54:32 +02:00
const keys = Object . keys ( nodesData _clone ) ;
2024-09-09 17:50:17 +02:00
const number _of _luminaires = keys . length ;
let number _of _ok _luminaires = 0 ;
let number _of _nok _luminaires = 0 ;
2024-09-17 08:54:32 +02:00
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-09-09 17:50:17 +02:00
let key = keys [ i ] ;
2024-09-17 08:54:32 +02:00
let nodeObj = nodesData _clone [ key ] ;
2024-12-02 17:06:49 +01:00
if ( nodeObj . tbname == undefined ) continue ;
2024-09-09 17:50:17 +02:00
2025-01-25 14:50:44 +01:00
if ( nodeObj . status === "OFFLINE" ) {
nodeObj . node _status _before _offline === true ? number _of _ok _luminaires ++ : number _of _nok _luminaires ++ ;
}
else if ( nodeObj . status == true ) number _of _ok _luminaires ++ ;
2024-09-09 17:50:17 +02:00
else number _of _nok _luminaires ++ ;
2025-01-25 14:50:44 +01:00
2024-09-09 17:50:17 +02:00
}
2024-12-02 17:06:49 +01:00
2024-09-09 17:50:17 +02:00
const values = {
"number_of_luminaires" : number _of _luminaires ,
"number_of_ok_luminaires" : number _of _ok _luminaires ,
"number_of_nok_luminaires" : number _of _nok _luminaires ,
2025-02-04 18:45:06 +01:00
"edge_date_time" : ts - ts % 60000 //round to full minute
2024-09-09 17:50:17 +02:00
} ;
2024-12-02 16:57:26 +01:00
sendTelemetry ( values , SETTINGS . rvoTbName , ts ) ;
2024-09-09 17:50:17 +02:00
}
2024-12-02 16:57:26 +01:00
function handleRsPort ( ) {
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//! rsPort LM = "/dev/ttymxc4", rsPort UNIPI = "/dev/ttyUSB0"
// 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-12-02 17:06:49 +01:00
if ( SETTINGS . serial _port == "" || SETTINGS . serial _port == undefined || SETTINGS . serial _port . length === 1 ) SETTINGS . serial _port = "ttymxc4" ;
2024-12-02 16:57:26 +01:00
rsPort = new SerialPort ( ` /dev/ ${ SETTINGS . serial _port } ` , { autoOpen : false } ) ;
//(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-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
rsPort . on ( 'open' , async function ( ) {
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( "CMD manager - rsPort opened success" ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
await runSyncExec ( ` stty -F /dev/ ${ SETTINGS . serial _port } 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke ` ) . then ( function ( status ) {
2024-12-02 16:57:26 +01:00
instance . send ( SEND _TO . debug , "RPC runSyncExec - Promise Resolved:" + status ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( 0 , "RPC runSyncExec - Promise Resolved:" + status ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
//APP START
2024-12-02 17:06:49 +01:00
let dataToInfoSender = { id : SETTINGS . project _id , name : SETTINGS . rvo _name } ;
2024-12-02 16:57:26 +01:00
dataToInfoSender . fw _version = SETTINGS . edge _fw _version ;
dataToInfoSender . startdate = new Date ( ) . toISOString ( ) . slice ( 0 , 19 ) . replace ( 'T' , ' ' ) ;
dataToInfoSender . _ _force _ _ = true ;
2024-12-02 17:06:49 +01:00
2024-12-02 16:57:26 +01:00
instance . send ( SEND _TO . infoSender , dataToInfoSender ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
logger . debug ( 0 , "---------------------------->START message send to service" , dataToInfoSender ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} ) . catch ( function ( reason ) {
2024-12-02 16:57:26 +01:00
instance . send ( SEND _TO . debug , "CMD manager - RPC runSyncExec - promise rejected:" + reason ) ;
} ) ;
2024-05-14 16:29:11 +02:00
} ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
rsPort . on ( 'error' , function ( err ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//TODO report to service!!!
//errLogger.error(exports.title, "unable to open port", SETTINGS.serial_port, err.message);
errorHandler . sendMessageToService ( [ exports . title , "unable to open port" , SETTINGS . serial _port , err . message ] , 0 ) ;
instance . send ( SEND _TO . debug , err . message ) ;
2024-12-02 16:57:26 +01:00
} ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
rsPort . on ( "close" , ( ) => {
setTimeout ( ( ) => rsPort . open ( ) , 1000 ) ;
} ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
rsPort . open ( ) ;
}
2024-12-02 17:06:49 +01:00
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
instance . on ( "close" , ( ) => {
2024-05-07 16:28:43 +02:00
clearInterval ( interval ) ;
2024-09-09 17:50:17 +02:00
clearInterval ( customTasksInterval ) ;
2024-12-02 16:57:26 +01:00
clearInterval ( setCorrectTime ) ;
2025-02-04 18:45:06 +01:00
clearInterval ( sendNodeReadout ) ;
2024-05-14 16:29:11 +02:00
rsPort . close ( ) ;
} ) ;
2025-02-04 18:45:06 +01:00
instance . on ( "0" , _ => {
2024-12-02 16:57:26 +01:00
main ( ) ;
} )
instance . on ( "1" , async function ( flowdata ) {
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//instance.send(SEND_TO.debug, "on Data");
//instance.send(SEND_TO.debug, flowdata);
2024-12-02 17:06:49 +01:00
2024-05-14 16:29:11 +02:00
//logger.debug(flowdata.data);
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//just testing functions
2024-12-02 17:06:49 +01:00
if ( flowdata . data == "open" ) {
if ( ! rsPort . isOpen ) rsPort . open ( ) ;
2024-05-14 16:29:11 +02:00
return ;
}
2024-12-02 17:06:49 +01:00
else if ( flowdata . data == "close" ) {
2024-05-14 16:29:11 +02:00
rsPort . close ( ) ;
return ;
}
2024-12-02 17:06:49 +01:00
else if ( flowdata . data == "clean" ) {
2024-05-14 16:29:11 +02:00
tasks = [ ] ;
return ;
}
2024-12-02 17:06:49 +01:00
else if ( flowdata . data == "buildtasks" ) {
2024-05-14 16:29:11 +02:00
//build & run
return ;
}
2024-12-02 17:06:49 +01:00
else if ( flowdata . data == "run" ) {
2024-05-14 16:29:11 +02:00
//durations = [];
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01: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-12-02 17:06:49 +01:00
if ( rsPort . isOpen ) {
interval = setInterval ( runTasks , 100 ) ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
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
}
2024-12-02 17:06:49 +01:00
else {
2024-05-14 16:29:11 +02:00
//terminal data - object
//logger.debug("flowdata", flowdata.data);
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( typeof flowdata . data === 'object' ) {
2024-05-14 16:29:11 +02:00
//logger.debug("dido", flowdata.data);
2024-12-02 17:06:49 +01:00
if ( flowdata . data . hasOwnProperty ( "sender" ) ) {
2024-05-14 16:29:11 +02:00
//data from dido_controller
2024-12-02 17:06:49 +01:00
if ( flowdata . data . sender == "dido_controller" ) {
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
if ( flowdata . data . hasOwnProperty ( "cmd" ) ) {
2024-05-14 16:29:11 +02:00
let cmd = flowdata . data . cmd ;
2024-12-02 17:06:49 +01:00
if ( cmd == "buildTasks" ) {
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 ) ;
}
2024-12-02 17:06:49 +01:00
else if ( cmd == "reload_relays" ) {
2024-05-14 16:29:11 +02:00
loadRelaysData ( flowdata . data . line ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( flowdata . data . dataChanged ) {
if ( ! flowdata . data . value ) {
2024-05-14 16:29:11 +02:00
reportOfflineNodeStatus ( flowdata . data . line ) ;
}
2024-12-02 17:06:49 +01:00
else {
2024-05-14 16:29:11 +02:00
reportOnlineNodeStatus ( flowdata . data . line ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-12-02 17:06:49 +01:00
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
else if ( cmd == "rotary_switch_state" ) {
2024-12-02 16:57:26 +01:00
let value = flowdata . data . value ;
2024-05-14 16:29:11 +02:00
//state was changed
2024-12-02 17:06:49 +01:00
if ( rotary _switch _state != value ) {
if ( value == "Off" ) {
2024-05-14 16:29:11 +02:00
//vyreportovat vsetky svietdla
reportOfflineNodeStatus ( ) ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 16:57:26 +01:00
rotary _switch _state = value ;
2024-05-07 16:28:43 +02:00
}
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
else if ( cmd == "lux_sensor" ) {
2024-05-14 16:29:11 +02:00
lux _sensor = parseInt ( flowdata . data . value ) ;
2024-05-07 16:28:43 +02:00
2024-09-09 12:32:34 +02:00
// POSSIBLE SOURCE OF PROBLEMS, IF USER SETS LUX TRESHOLD LEVEL GREATER THAN 100 - WE SHOULD BE CHECKING "DUSK/DAWN_LUX_SENSOR_VALUE" IN PROFILE MAYBE ??
2024-12-02 17:06:49 +01:00
if ( lux _sensor < 100 ) {
2024-09-09 12:32:34 +02:00
// we send lux_sensor value to all nodes:
let params = getParams ( PRIORITY _TYPES . node _broadcast ) ;
params . recipient = 2 ; //2 broadcast, address = 0
params . address = 0xffffffff ; //Broadcast
let ba = longToByteArray ( lux _sensor ) ;
params . byte3 = ba [ 1 ] ; //msb
params . byte4 = ba [ 0 ] ;
params . timestamp = PRIORITY _TYPES . node _broadcast ;
params . info = "run broadcast: Actual Lux level from cabinet" ;
params . register = 95 ; //Actual Lux level from cabinet
params . rw = 1 ; //write
tasks . push ( params ) ;
//process profiles
turnOnOffLinesAccordingToLuxSensor ( lux _sensor ) ;
}
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
else if ( cmd == "state_of_breaker" ) {
2024-05-14 16:29:11 +02:00
//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 ;
2024-12-02 17:06:49 +01:00
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" ;
2024-12-02 17:06:49 +01:00
if ( value == "Off" ) status = "NOK" ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( dataChanged ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( relaysData . hasOwnProperty ( line ) ) {
2024-05-14 16:29:11 +02:00
let tbname = relaysData [ line ] . tbname ;
2024-12-02 17:06:49 +01:00
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" ) ;
2024-05-14 16:29:11 +02:00
//report status liniu
2024-12-02 17:06:49 +01:00
sendTelemetry ( { status : status } , tbname )
2024-05-07 16:28:43 +02:00
2024-05-14 16:29:11 +02:00
//current value
2024-12-02 17:06:49 +01:00
if ( value == "Off" ) reportOfflineNodeStatus ( line ) ; //vyreportovat vsetky svietidla na linii
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
}
2024-12-02 17:06:49 +01:00
else {
2024-05-14 16:29:11 +02:00
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
2024-12-02 17:06:49 +01:00
if ( flowdata . data . hasOwnProperty ( "topic" ) ) {
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
let data = getNested ( flowdata . data , "content" , "data" ) ;
2024-12-02 17:06:49 +01:00
if ( data == undefined ) {
console . log ( "Invalid rpc command came from platform" ) ;
return ;
2024-12-02 16:57:26 +01:00
}
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 ;
2024-12-02 17:06:49 +01:00
if ( profile == undefined ) profile = "" ;
2024-05-14 16:29:11 +02:00
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-12-02 17:06:49 +01: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-14 16:29:11 +02:00
//let command = data.params.command;
let value = data . params . payload . value ;
2024-12-02 17:06:49 +01:00
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-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-05-14 16:29:11 +02:00
let node = keys [ i ] ;
//logger.debug( node, nodesData[node], tbname);
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( tbname == nodesData [ node ] . tbname ) {
2024-12-02 16:57:26 +01:00
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
value = parseInt ( value ) ;
2024-12-02 17:06:49 +01:00
if ( value > 0 ) value = value + 128 ;
2024-12-02 16:57:26 +01:00
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-write" ;
2024-12-02 16:57:26 +01:00
params . tbname = tbname ;
params . address = node ;
2025-02-04 18:45:06 +01:00
params . register = 1 ;
params . recipient = 1 ;
2024-12-02 16:57:26 +01:00
params . byte4 = value ;
2025-02-04 18:45:06 +01:00
params . rw = 1 ;
2024-12-02 16:57:26 +01:00
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'set dimming from platform' ;
//params.debug = true;
//debug(params);
logger . debug ( "dimming" , params ) ;
tasks . push ( params ) ;
2024-12-02 17:06:49 +01:00
setTimeout ( function ( ) {
2024-12-02 16:57:26 +01:00
//spustime o 4 sekundy neskor, s prioritou PRIORITY_TYPES.high_priority
//a pridame aj vyreportovanie dimmingu
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-12-02 16:57:26 +01:00
params . tbname = tbname ;
params . address = node ;
2025-02-04 18:45:06 +01:00
params . register = 1 ;
params . recipient = 1 ;
params . rw = 0 ;
2024-12-02 16:57:26 +01:00
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read dimming (after set dimming from platform)' ;
2025-02-04 18:45:06 +01:00
//params.debug = true;
2024-12-02 16:57:26 +01:00
tasks . push ( params ) ;
}
//pridame aj vyreportovanie - vykon
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-12-02 16:57:26 +01:00
params . tbname = tbname ;
params . address = node ;
params . register = 76 ;
2025-02-04 18:45:06 +01:00
params . recipient = 1 ;
params . rw = 0 ;
2024-12-02 16:57:26 +01:00
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read Input Power (after set dimming from platform)' ;
2025-02-04 18:45:06 +01:00
//params.debug = true;
2024-12-02 16:57:26 +01:00
tasks . push ( params ) ;
}
//pridame aj vyreportovanie - prud svietidla
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-12-02 16:57:26 +01:00
params . tbname = tbname ;
params . address = node ;
params . register = 75 ;
2025-02-04 18:45:06 +01:00
params . recipient = 1 ;
params . rw = 0 ;
2024-12-02 16:57:26 +01:00
params . timestamp = PRIORITY _TYPES . high _priority ;
params . info = 'read Input Current (after set dimming from platform)' ;
2025-02-04 18:45:06 +01:00
//params.debug = true;
2024-12-02 16:57:26 +01:00
tasks . push ( params ) ;
}
//pridame aj vyreportovanie - power faktor - ucinnik
{
let params = getParams ( PRIORITY _TYPES . high _priority ) ;
2025-02-04 18:45:06 +01:00
params . type = "node-onetime-read" ;
2024-12-02 16:57:26 +01:00
params . tbname = tbname ;
params . address = node ;
params . register = 77 ;
2025-02-04 18:45:06 +01:00
params . recipient = 1 ;
params . rw = 0 ;
2024-12-02 16:57:26 +01:00
params . timestamp = PRIORITY _TYPES . high _priority ;
2025-02-04 18:45:06 +01:00
params . info = 'read power factor (after set dimming from platform)' ;
//params.debug = true;
2024-12-02 16:57:26 +01:00
tasks . push ( params ) ;
}
2024-12-02 17:06:49 +01:00
} , 4000 ) ;
2024-12-02 16:57:26 +01:00
nodeWasFound = true ;
break ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
if ( ! nodeWasFound ) {
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-12-02 17:06:49 +01:00
else {
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 ;
}
2024-12-02 17:06:49 +01:00
else if ( method == "set_profile" ) {
2024-05-14 16:29:11 +02:00
//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 ) ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-05-14 16:29:11 +02:00
let node = keys [ i ] ;
2024-12-02 17:06:49 +01:00
if ( tbname == nodesData [ node ] . tbname ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( profile != "" ) profile = JSON . stringify ( profile ) ;
2024-05-14 16:29:11 +02:00
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-12-02 17:06:49 +01: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-12-02 17:06:49 +01:00
//profil úspešne prijatý pre node č. xx
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-12-02 17:06:49 +01:00
nodesData [ node ] . processed = false ;
nodesData [ node ] . profile = profile ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
processNodeProfile ( node ) ;
2024-05-14 16:29:11 +02:00
} ) ;
2024-12-02 16:57:26 +01:00
} ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01: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
2024-12-02 17:06:49 +01:00
else if ( entity _type == "edb_line" || entity _type == "edb" || entity _type == "edb_line_ver4" || entity _type == "edb_ver4_se" ) {
2024-05-14 16:29:11 +02:00
//profil linie
//relays.table line:number|tbname:string|contactor:number|profile:string
//najdeme line relaysData
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01: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 ) ;
2024-12-02 17:06:49 +01:00
for ( let i = 0 ; i < keys . length ; i ++ ) {
2024-05-14 16:29:11 +02:00
let line = keys [ i ] ;
2024-12-02 17:06:49 +01:00
if ( tbname == relaysData [ line ] . tbname ) {
2024-05-14 16:29:11 +02:00
//zmazeme tasky
2024-12-02 17:06:49 +01:00
removeTask ( { type : "relay" , line : line } ) ;
if ( profile != "" ) profile = JSON . stringify ( profile ) ;
2024-05-14 16:29:11 +02:00
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-12-02 16:57:26 +01:00
relaysData [ line ] . profile = profile ;
loadRelaysData ( line )
logger . debug ( "loadRelaysData DONE for line" , line ) ;
2024-12-02 17:06:49 +01:00
buildTasks ( { processLineProfiles : true , line : line } ) ;
2024-12-02 16:57:26 +01:00
2024-12-02 17:06:49 +01:00
sendNotification ( "CMD manager - set profile from worksys" , tbname , "switching_profile_was_processed_for_line" , { line : line } , profile , SEND _TO . tb , instance ) ;
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
}
2024-12-02 17:06:49 +01:00
else if ( method == "set_command" ) {
2024-05-14 16:29:11 +02:00
let value = data . params . payload . value ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( command === "switch" ) {
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
// if we receive rpc from platform, to switch maintenance mode, we set SETTINGS.maintenance_mode flow variable to value;
2024-12-02 17:06:49 +01:00
if ( entity _type === "edb" || entity _type === "edb_ver4_se" ) SETTINGS . maintenance _mode = value ;
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
const relayObject = getObjectByTbValue ( relaysData , tbname ) ;
2024-05-14 16:29:11 +02:00
let line = 0 ;
2024-12-02 17:06:49 +01:00
if ( isObject ( relayObject ) ) line = relayObject . line ;
2024-12-02 16:57:26 +01:00
// v relaysData je contactor bud 0 alebo 1, ale z platformy prichadza true, false;
2024-12-02 17:06:49 +01:00
if ( value == false ) turnLine ( "off" , line , "command received from platform" ) ;
else turnLine ( "on" , line , "command received from platform" ) ;
2024-05-07 16:28:43 +02:00
}
}
2024-12-02 17:06:49 +01:00
else {
2024-05-14 16:29:11 +02:00
instance . send ( SEND _TO . debug , "undefined method " + method ) ;
logger . debug ( "undefined method" , method ) ;
2024-05-07 16:28:43 +02:00
}
return ;
}
2024-12-02 17:06:49 +01:00
else {
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
2024-12-02 17:06:49 +01:00
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 ;
2024-12-02 17:06:49 +01:00
if ( params == undefined ) {
2024-05-14 16:29:11 +02:00
//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-12-02 17:06:49 +01: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
2024-12-02 16:57:26 +01:00
2024-12-02 17:06:49 +01:00
//function gets value of a nested property in an object and returns undefined if it does not exists:
function getNested ( obj , ... args ) {
return args . reduce ( ( obj , level ) => obj && obj [ level ] , obj )
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
/ * *
* 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 ( ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
const currentTime = new Date ( ) ;
if ( currentTime . getHours ( ) != 3 ) return ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
RESTBuilder . make ( function ( builder ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( ! builder ) return ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
builder . method ( 'GET' ) ;
builder . url ( 'http://192.168.252.2:8004/gettime?projects_id=1' ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
builder . callback ( function ( err , response , output ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( err ) {
console . log ( err ) ;
return ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
const res = output . response ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
try {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
const obj = JSON . parse ( res ) ;
let d = new Date ( obj . date ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
const now = new Date ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let diffInMinutes = now . getTimezoneOffset ( ) ;
console . log ( "---->TimezoneOffset" , diffInMinutes ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( d instanceof Date ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
// monitor.info("----------->setCorrectPlcTimeOnceADay() current js date:", d, d.getHours());
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let year = d . getFullYear ( ) ;
let month = addZeroBefore ( d . getMonth ( ) + 1 ) ;
let day = addZeroBefore ( d . getDate ( ) ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let hours = addZeroBefore ( d . getHours ( ) ) ;
let minutes = addZeroBefore ( d . getMinutes ( ) ) ;
let seconds = addZeroBefore ( d . getSeconds ( ) ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let dateStr = ` ${ year } - ${ month } - ${ day } ${ hours } : ${ minutes } : ${ seconds } ` ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
exec ( ` sudo timedatectl set-time " ${ dateStr } " ` , ( err , stdout , stderr ) => {
if ( err || stderr ) {
console . error ( err ) ;
console . log ( stderr ) ;
console . log ( dateStr ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
monitor . info ( "failed timedatectl set-time" , err , stderr ) ;
}
else {
monitor . info ( "setCorrectPlcTimeOnceADay() --> Nastaveny cas na: " , dateStr ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} catch ( error ) {
logger . debug ( "setCorrectPlcTimeOnceADay - function error" , error , res ) ;
monitor . info ( "setCorrectPlcTimeOnceADay - function error" , error , res ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
// we detect readOnlyFileSystem once an hour as well
detectReadOnlyFilesystem ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} ) ;
} ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function detectReadOnlyFilesystem ( ) {
exec ( ` sudo egrep " ro,|,ro " /proc/mounts ` , ( err , stdout , stderr ) => {
if ( err || stderr ) {
console . error ( err ) ;
console . log ( stderr ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} else {
//console.log("Read-only", stdout);
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let lines = stdout + "" ;
lines = lines . split ( "\n" ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let readOnlyDetected = "" ;
for ( let i = 0 ; i < lines . length ; i ++ ) {
if ( lines [ i ] . startsWith ( "/dev/mmcblk0p2" ) ) {
readOnlyDetected = lines [ i ] ;
}
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( readOnlyDetected !== "" ) {
errorHandler . sendMessageToService ( "Detected: Read-only file system: " + readOnlyDetected ) ;
monitor . info ( "Read only filesystem detected" ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
}
2024-12-02 17:06:49 +01:00
} ) ;
2024-12-02 16:57:26 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
///helper functions
function sendTelemetry ( values , tbname , date = Date . now ( ) ) {
const dataToTb = {
[ tbname ] : [
{
"ts" : date ,
"values" : values
}
]
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
tbHandler . sendToTb ( dataToTb , instance ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
function calculateDuskDawn ( date , line , duskOffset = 0 , dawnOffset = 0 ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
if ( date === undefined ) date = new Date ( ) ;
//if(duskOffset === undefined) duskOffset = 0;
//if(dawnOffset === undefined) dawnOffset = 0;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//let line = keys[i];
let profilestr = "" ;
if ( relaysData [ line ] != undefined ) profilestr = relaysData [ line ] . profile ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let result = { } ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
var times = SunCalc . getTimes ( date , latitude , longitude ) ;
let dawn = new Date ( times . sunrise ) ; //usvit
let dusk = new Date ( times . sunset ) ; //sumrak
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//http://suncalc.net/#/48.5598,18.169,11/2021.04.07/11:06
//https://mapa.zoznam.sk/zisti-gps-suradnice-m6
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let dusk _astro _clock _offset = duskOffset ; //minutes
let dawn _astro _clock _offset = dawnOffset ; //minutes
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
try {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let profile = JSON . parse ( profilestr ) ;
if ( Object . keys ( profile ) . length === 0 ) throw ( "profile is not defined" ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//Jednoduchý režim
if ( profile . astro _clock == false && profile . dusk _lux _sensor == false && profile . dawn _lux _sensor == false ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
}
2024-05-14 16:29:11 +02:00
2024-12-02 17:06:49 +01:00
//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 ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//if(profile.dawn_lux_sensor == false)
{
if ( profile . hasOwnProperty ( "dawn_astro_clock_offset" ) ) dawn _astro _clock _offset = parseInt ( profile . dawn _astro _clock _offset ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//dusk - súmrak
//down, sunrise - svitanie
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
} catch ( error ) {
if ( profilestr != "" ) {
logger . debug ( profilestr ) ;
logger . debug ( error ) ;
}
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
result . dusk _no _offset = addZeroBefore ( dusk . getHours ( ) ) + ":" + addZeroBefore ( dusk . getMinutes ( ) ) ;
result . dawn _no _offset = addZeroBefore ( dawn . getHours ( ) ) + ":" + addZeroBefore ( dawn . getMinutes ( ) ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
dusk = new Date ( dusk . getTime ( ) + gmtOffset + dusk _astro _clock _offset * 60000 ) ;
dawn = new Date ( dawn . getTime ( ) + gmtOffset + dawn _astro _clock _offset * 60000 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
result . dusk = addZeroBefore ( dusk . getHours ( ) ) + ":" + addZeroBefore ( dusk . getMinutes ( ) ) ;
result . dusk _hours = dusk . getHours ( ) ;
result . dusk _minutes = dusk . getMinutes ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
result . dawn = addZeroBefore ( dawn . getHours ( ) ) + ":" + addZeroBefore ( dawn . getMinutes ( ) ) ;
result . dawn _hours = dawn . getHours ( ) ;
result . dawn _minutes = dawn . getMinutes ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
result . dusk _time = dusk . getTime ( ) ;
result . dawn _time = dawn . getTime ( ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
result . dusk _astro _clock _offset = dusk _astro _clock _offset ;
result . dawn _astro _clock _offset = dawn _astro _clock _offset ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
return result ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01:00
function processResponse ( register , bytes ) {
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let values = { } ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let byte3 = bytes [ 0 ] ;
let byte2 = bytes [ 1 ] ;
let byte1 = bytes [ 2 ] ;
let byte0 = bytes [ 3 ] ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//status
if ( register == 0 ) {
let statecode = bytesToInt ( bytes ) ;
values = { "statecode" : statecode } ;
return values ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//Dimming, CCT
if ( register == 1 ) {
let brightness = 0 ;
let dimming = byte0 ;
if ( dimming > 128 ) {
//dimming = -128;
brightness = dimming - 128 ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//cct
//Ak Byte3 == 1: CCT = (Byte2*256)+Byte1
let cct ;
if ( byte3 == 1 ) cct = byte2 * 256 + byte1 ;
else cct = bytesToInt ( bytes . slice ( 0 , 3 ) ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//cct podla auditu
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
values [ "dimming" ] = brightness ;
return values ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//
if ( register == 4 ) {
values [ "master_node_version" ] = bytes [ 1 ] + "." + bytes [ 2 ] ;
//logger.debug("FW Version", register, bytes);
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//Napätie
if ( register == 74 ) {
let voltage = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 1 ) ;
values [ "voltage" ] = Number ( voltage ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//Prúd
if ( register == 75 ) {
let current = bytesToInt ( bytes ) ;
values [ "current" ] = current ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
//výkon
if ( register == 76 ) {
let power = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "power" ] = Number ( power ) ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//účinník
if ( register == 77 ) {
let power _factor = Math . cos ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "power_factor" ] = Number ( power _factor ) ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
//frekvencia
if ( register == 78 ) {
let frequency = ( bytesToInt ( bytes ) * 0.1 ) . toFixed ( 2 ) ;
values [ "frequency" ] = Number ( frequency ) ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//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 ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
//doba života
if ( register == 80 ) {
let lifetime = ( bytesToInt ( bytes ) / 60 ) . toFixed ( 2 ) ;
values [ "lifetime" ] = Number ( lifetime ) ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//nastavenie profilu
if ( register == 8 ) {
let time _schedule _settings = bytesToInt ( bytes ) ;
values [ "time_schedule_settings" ] = time _schedule _settings ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
//naklon
if ( register == 84 ) {
let temp ;
if ( byte3 >= 128 ) {
temp = ( byte3 - 128 ) * ( - 1 ) ;
}
else {
temp = byte3 ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01: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-12-02 17:06:49 +01: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-12-02 17:06:49 +01: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-12-02 17:06:49 +01:00
values [ "temperature" ] = temp ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//náklon x
values [ "inclination_x" ] = inclination _x ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//náklon y
values [ "inclination_y" ] = inclination _y ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//náklon z
values [ "inclination_z" ] = inclination _z ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let h = byte3 ;
let m = byte2 ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
let timestamp ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
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;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
var d = new Date ( ) ;
2025-01-01 13:12:02 +01:00
d . setHours ( h , m , 0 , 0 ) ;
2024-12-02 17:06:49 +01:00
timestamp = d . getTime ( ) ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//aktuálny čas
if ( register == 87 ) {
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["actual_time"] = h + ":" + m + ":" + s;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
values [ "actual_time" ] = timestamp ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//čas súmraku
if ( register == 6 ) {
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["dusk_time"] = h + ":" + m + ":" + s;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
values [ "dusk_time" ] = timestamp ;
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//čas úsvitu
if ( register == 7 ) {
//Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek.
//values["dawn_time"] = h + ":" + m + ":" + s;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
values [ "dawn_time" ] = timestamp ;
}
2024-05-07 16:28:43 +02:00
2025-02-04 18:45:06 +01:00
//FW verzia nodu
2024-12-02 17:06:49 +01:00
if ( register == 89 ) {
//formát: "Byte3: Byte2.Byte1 (Byte0)"
values [ "fw_version" ] = byte3 + ":" + byte2 + "." + byte1 + "(" + byte0 + ")" ;
}
return values ;
2024-05-07 16:28:43 +02:00
}
2024-12-02 17:06:49 +01: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 ) {
cmd = cmd + 0x8000 ;
}
//master
if ( rec === 0 ) adresa = 0 ;
if ( rec === 2 ) {
adresa = 0xffffffff ; //Broadcast
}
//recipient
if ( rec === 3 ) {
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( 0xFF ) ;
resp . push ( adresa & 0xFF ) ; //band
}
else {
resp . push ( ( adresa >> 24 ) & 0xFF ) ; //rshift
resp . push ( ( adresa >> 16 ) & 0xFF ) ;
resp . push ( ( adresa >> 8 ) & 0xFF ) ;
resp . push ( adresa & 0xFF ) ;
if ( rec === 2 ) {
2024-05-14 16:29:11 +02:00
resp . push ( 0xFF ) ;
2024-12-02 17:06:49 +01:00
}
else resp . push ( 0 ) ;
2024-05-14 16:29:11 +02:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01: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
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//let data = '12345';
let crc = crc16 ( 'ARC' , resp ) ;
let c1 = ( crc >> 8 ) & 0xFF ;
let c2 = crc & 0xFF ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
resp . push ( c1 ) ;
resp . push ( c2 ) ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
//logger.debug("checksum", crc);
//logger.debug("resp", resp);
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
return resp ;
2024-05-07 16:28:43 +02:00
2024-12-02 17:06:49 +01:00
}
2024-05-07 16:28:43 +02:00
2024-12-02 16:57:26 +01:00
function getObjectByTbValue ( object , tbname ) {
return object [ Object . keys ( object ) . find ( key => object [ key ] . tbname === tbname ) ] ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 17:06:49 +01:00
function isObject ( item ) {
2024-12-02 16:57:26 +01:00
return ( typeof item === "object" && ! Array . isArray ( item ) && item !== null ) ;
2024-05-14 16:29:11 +02:00
}
2024-12-02 16:57:26 +01:00
} // end of instance.export
2024-05-14 16:29:11 +02:00