How to access global variables and modify their state

2,924 views
Skip to first unread message

boris runakov

unread,
Jan 12, 2017, 4:53:34 AM1/12/17
to Node-RED
Hello !
What is the best cleanest way to access global variables / or variables with state in general ? Currently I am trying with global.get/set methods but the code gets convoluted.
For example a simple countdown I have wrote in js , and tried to implement it in a function node gets something like this :
var timer = flow.get('timer') || {
   
"running": false,
   
"startTime": 0,
   
"endTime": 0,
   
"ms": 0,
   
"sec": 0,
   
"min": 0,
   
"shift": 0
}
var time = flow.get('time') || 0;

if (msg.topic == "timer_status") {
    node
.warn({
        payload
: timer
   
});
}
if (msg.topic == "start") {
    node
.warn({
        payload
: "start pressed"
   
});

    start
();
}
if (msg.topic == "stop") {
    node
.warn({
        payload
: "stop pressed"
   
});

    stop
();
}
if (msg.topic == "value") {

    flow
.set('time', msg.payload);
    node
.warn({
        payload
: flow.get('time')
   
})
}

function start() {
   
var timer = flow.get('timer');
    timer
.running = true;
    flow
.set('timer', timer);

    configTimer
();

    node
.warn({
        payload
: timer
   
})
}

function stop() {
   
var timer = flow.get('timer');
    timer
.running = false;
    flow
.set('timer', timer);
    node
.warn({
        payload
: timer
   
});
}

function configTimer() {
   
var timer = flow.get('timer');
    timer
.startTime = Date.now();
    flow
.set('timer', timer)
   
if (timer.running) {
        checkTime
();
   
}
}

function checkTime() {
   
var timer = flow.get('timer');

   
if (timer.running) {
       
var seconds = 0,
            minutes
= time,
            hours
= 0,
            remaining
= 0,
            shift
= timer.shift;

        timer
.endTime = (seconds * 1000) + (minutes * 60 * 1000) + (hours * 60 * 60 * 1000) + shift;

       
if (timer.startTime + timer.endTime >= Date.now()) {

            timer
.ms = timer.startTime + timer.endTime - Date.now();
            timer
.min = (timer.ms / 1000 / 60) << 0,
            timer
.sec = (timer.ms / 1000) % 60 << 0;
            remaining
= timer.min + ':' + timer.sec;

            node
.send({
                time
: remaining
           
});

            setTimeout
(checkTime, 1000);
       
} else {
            stop
();
       
}
        flow
.set('timer', timer);
   
}
}

Is there a way I can define timer and time variables in a different node and access/modify them directly without using get/set methods like in the code above ?
Thank you in advance

Nicholas O'Leary

unread,
Jan 12, 2017, 4:56:15 AM1/12/17
to Node-RED Mailing List
You have two choices.

You either pass data in the messages going between nodes or you use flow/global context as you are doing.

The context objects are there specifically to enable state to be shared between nodes.

Nick



--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/70d2b0e5-1cf1-49a0-9f67-2617429acec7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

boris runakov

unread,
Jan 12, 2017, 5:01:26 AM1/12/17
to Node-RED
Can you give me an example on how I could change an object property by passing data in the messages ?
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.

Nicholas O'Leary

unread,
Jan 12, 2017, 5:08:58 AM1/12/17
to Node-RED Mailing List
Can you give me an example on how I could change an object property by passing data in the messages ?

Sorry, I was answering a slightly different question - how to share state between nodes. An alternative to using the context objects is, for some uses, to just pass data between nodes using the messages flowing between them. But that isn't appropriate in many cases - which is why the context objects exist.

To answer you specific question:

What is the best cleanest way to access global variables / or variables with state in general ?

The get/set functions are the way you access the flow/global context.

Nick


To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

boris runakov

unread,
Jan 12, 2017, 5:34:02 AM1/12/17
to Node-RED
So I suppose I can omit the flow.get() in every function I am using , since I declare the timer and time variables on top of the function node.
Also is there an option to instantiate nodes on deploy or restart of nodered?
Appreciate your feedback !
Reply all
Reply to author
Forward
0 new messages