Understanding Nodered: "main" method?

Hi,

I am coming from C++ / Java.

I have a setup with different flows, which I assume is a bit like a static class. I create "flow" variables to ensure they are local, secure and do not slow down other flows. F.e. an array:

var testArr = flow.get('testArr') || [1,15,30];

from what I have read, this is a common way to read a variable if defined, or define it otherwise.
The problem is, I´d like to have all variables in one place at the flow: define them there, change them there.
Normally I´d create an object or call a static initial function from the main method, or just declare inside the class.
My question here is: how do I handle it? How can I ensure the variable is created first f.e. after a reboot?

I would probably use an object stored as a global in settings.js, this will ensure it is created before the flows start. Check functionGlobalContext

I understand that you're coming from (more) classical languages and likely have solid programming skills however coming to javascript/node/node-red requires a slightly different mind set.

Its hard to explain however you will come to realise other ways of managing state (or realising there is not always a need to manage state) as you continue your adventure into node-red.

That said, you could always create an object and store vars in that (so only one object to maintain).

There are other options too, like file backed context storage (search the docs) however, I have yet to design a flow that required file backed storage.

Good luck on your adventure.

First try to avoid flow and global data. The node red way is to pass data via messages, in fact I have never used flow or global data for this sort of purpose. One exception may be to remember system state such as whether a switch is off or on, as this needs to be saved over a restart. However I find MQTT retained values to be more convenient for that.
Others are less zealous than myself at avoiding flow and global data but I think most would agree that one should always look for a message oriented technique first before resorting to another solution.
If you cannot see how to avoid it for your situation then if you explain what you are trying to do someone may be able to suggest an alternative.

1 Like

First off, thanks for all the responses :slight_smile:

Globals would be my last option, but it is good to know it could be an option if everything else fails.

My attemp is to manage all aspects of my smart home. Therefor, I am using short time variables, f.e. I have a remote which controls TV and AVR and so on. When I switch the mode f.e. to AVR, I set a variable which manages that all other buttons now are mapped to the AVR. After 10 seconds it should set back to default, every time I press a button, the 10 seconds start again. Also for Sleep and Wakeup functions and a lot of other stuff^^. These are variables which are created on demand, no problem.

I also manage all my LED stuff here - here comes the funny part^^. I save all states of all brightness level for different colors here on NodeRed.
Primary I have switched from Domoticz Home Automation over to NodeRed, because Domoticz took around 500ms from a button press to a change of my light level. NodeRed is almost instant. Saving to and reading from a file would cause another delay :frowning:
So my idea is to have a LED flow, which has pre-stored all the light stuff as arrays (also which level, state and so on temporary). No matter if I switch by remote, by a Luxmeter, a button, or by time, I read from the arrays and can set the light almost instantly. For that, I have to ensure that also after a crash or reboot, these arrays are available.
If I set them as mentioned on my question, I would have to rewrite them in every function node they are used. Makes it hard to change some stuff fast, and especally after a few months, it´s not fun to make changes^^.

Saving these color states to my ESP32s would result in lots of traffic or would make the program and the small changes very complicated, also I would be the only one who is able at all to change some stuff.

So I search for a way to declare them once all together after starting / rebooting nodeRed, and then having access from the one flow they are used on (hoping it won´t slow down other nodes :wink: )

Flow context or Global context is what you need, it can also be persisted across restarts using the persistent context option in settings.js
Think of the global/flow context as a mini database. There's nothing wrong about using it when messages going through flows need to be remembered or persisted.

1 Like

All of the things you describe are ideal candidates for using MQTT. So for example, with your first example, when you use a UI component to switch to AVR mode send that out to MQTT, then any nodes that needs to know that you are in AVR will automatically get informed of the change and can take whatever action is necessary. If you need the AVR state to persist over a restart then make it a Retained topic in MQTT so that on startup all those nodes will automatically get informed of the current state and can setup the UI and so on.
For the example of a lookup table for colour setting I suggest that there is only one point in the code that should be using that, and that is in the node that controls the LED. Therefore it can just be a static array inside that function node. Any UI or other nodes that need to change the colour can just send the request to that node, or probably better send it to MQTT for the LED control node to action. That way you keep the UI code separate from the logic of LED driving. In fact the UI code need not even be running in the same computer as the LED logic.
Start here to find out about MQTT, it really will make your life simpler.
https://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt/

@nlecaude
Flow context sounds as it could be exactly what I am searching for.
I will directly take a look at that first this evening :star_struck:

@Colin
Thanks for the input, I am already using MQTT for the communication of the nodes :blush:

" { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 5 , "red" : 10, "green" : 2, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 6 , "red" : 0, "green" : 0, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 7 , "red" : 10, "green" : 2, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 4 , "red" : 30, "green" : 8, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 1 , "red" : 0, "green" : 0, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 3 , "red" : 0, "green" : 0, "blue" : 0} { "dtype" : "Stripe", "mode" : "dimTo", "whichStripe" : 2 , "red" : 30, "green" : 8, "blue" : 0} { "dtype" : "Display", "mode" : "staticText", "showText" : "br 4", "bright" : 1, "forMillis" : 3000, "howOften" : 1 }"

is for example the message sent to one of the four nodes in the room when pressing bright+ on my remote :slight_smile: Theres also a display which shows the state. I know it could be shortened, using arrays and so on, but I like to have it easily readable and expandable^^.
I have "cut" the stripes software-side in several parts, so I can adjust the light perfectly. Within the sketch, every LED gets driven seperately to ensure a very smooth change.
My class just for on / off / dimming and modes (sleep, wakeup, fire, color flow..) has around 1300 lines on my ESP32 - without the fastled libary, or any other stuff as display, ota and so on :crazy_face:.
Problem is: I would like to have the light easily editable at one point.
F.e.:Walk through the room, motion sensor puts light on, I think I need an adjust at stripe 6: phone, klick bookmark, open, change, update directly, see the change, maybe adjust again.
Especially when also the light level gets changed by lux automatically, and by time (very white at day to more orange in the night) there has to be so much fine tuning, I would get crazy changing the sketch every time I want to make a small adjust. Additional, I already have also some Arduino on other rooms running where ESPs are oversized (hall f.e.), using NRF24 and no option to update them ota - I´d have to update them by cable every time I change a value. Would drive me crazy I think :sweat_smile:

Sorry for not being that precise the answer before :wink:

This could also be realized easy with a retained mqtt msg...

is this supposed to be good or bad?

sure, sounds like a nice hobby :slight_smile: