Beginner questions on IF expressions and wildcard usage in function node

That is not necessary. Just view your context variables in the context viewer on the RH sidebar

1 Like

I never even saw that.

Detail question:
I do not want to connect the function initializing the variables to the mqtt in. Otherwise they will be initialized on every message.

If I initialize them once everytime I make a change, will they remain available forever? Or will I need to initialize again after e.g. a Node-RED reboot?

I now use an inject node set to "once after 0.1 s", but I am not sure if this will only be "everytime I manually deploy" or "everytime the flow is started"=mqtt in receives a message or "everytime Node-RED is started" aka on reboot/restart of Node-RED which should also be kind of a deployment, I hope.

EDIT:
And where are flow variables and context variables stored? In RAM or written to drive?

It depends on what you set in settings.js. You should read the documentation here:
https://nodered.org/docs/user-guide/context

1 Like

Somehow, and I mean no offense, I have so far not found the information I was looking for in the docs.
Maybe it is the colorful nature of the docs or the idea that visual flow nodes should be used in a basic way and everything more complex does not belong in the general docs.
Plus I usually don't search for anything that is already in the node docs.

But when I searched for variables I landed on the environment variables page. Which was not helpful. Google then found me the flow etc. variables but I did not realize that Node-RED distinguishes between variables (environment) and context (what I would consider variables).

It is learning in progress, I guess :slight_smile:

The devs are always looking (hoping?!) for people to contribute to the docs. :wink:

1 Like

I have to admit that the name "context" for what most other languages would call a variable seems bizarre.
Then there is "global context" - available globally, "flow context" - available througout a flow and just plain "context" - available to a single node. What? Maybe "node context" has some other meaning.

I have seen a lot of mentions of environment variables too, yet they seem almost totally useless since they are not variable (!) but fixed at Node-red startup and have to be defined in settings.js (I'm running NR as a service on Linux)
What I understand by "environment variables" eg $PATH are accessible in the editor but only via an exec node echo $PATH

Every programming language comes with it's own names: pointers, dictionaries, tuples, objects.
It is frustrating though when the designers overload a well understood word with a new meaning.

PATH should be available in exactly the same way as any other environment variable. Try this in a function node

msg.payload = env.get("PATH")
return msg;

Variables is a generic term. There are environment variables (which are OS level things), global, flow and node context variables, variables in functions declared by, for example,
let myVar = 1
and probably also others I can't immediately bring to mind.

Yes you are right Colin! :grinning:

What does this mean then?

Running as a service

When Node-RED is running as a service having been installed using the provided script, it will not have access to environment variables that are defined only in the calling process. ...

There is no env.set()
I'm not sure if I would expect one given the shells within shells nature of Linux

Environment variables are actually available in multiple ways in Node-RED:

Using environment variables : Node-RED (nodered.org)

They are variable but only in the context of the OS environment. Except where they are not! Since Node-RED has now introduced several places where you can set what it calls environment variables that really aren't :slight_smile: Those being in groups, flows and sub-flows.

That is correct. Because the whole point of them is that they are set in the OS environment (or context if you prefer that term). At the OS level, env variables are defined BEFORE a service starts. Changing them from within a service therefore makes no sense.

Their use in this way is a tradition I suppose but that's the way everyone now expects them to work.

This is why you can use them to control things like Node-RED's port, userDir and other settings global to Node-RED.

They are also often used to dynamically set id's and passcodes when starting a service. However, that really should not be done since it means that the information is in memory - unencrypted - and so available to malware.

General purpose computing is a complex topic of course so not surprising that terminology is also complex.

All the names you've mentioned could be included in variables but also in constants. They are examples of STRUCTURES. Well, maybe not pointers but hopefully they are fairly obvious. You could think of them as an alias to some actual data.

When you run a command window in Linux the OS sets up a number of environment variables (such as PATH) in order to make life easier. I think that what the above is trying to say (arguably unsuccessfully) is that when it is run as a service node-red will only have access to env vars that are automatically made available to all services, plus any setup in the node red service script.
So for example, if you run echo $PATH and compare that with the output of the function node which shows the PATH value in node-red you will see they are different.
That is why, when running a command via an exec node it is often necessary to provide the full path to the command, as PATH may not include that folder.

1 Like

Yes, that is an excellent point, well made.

Specifically, if you run Node-RED manually (from a terminal command line), you are logged in with a specific user and Node-RED will inherit the USERS env variables that are set by the users profile script.

Whereas, when you run Node-RED as a service via systemd, you specify the user id in the systemd script and unless you specify some env variables, you don't get any unless they are set by the global OS startup. Specifically, you don't get a path, etc. You can adjust the systemd script to include env variables. Indeed, in my alt installer, I set up a local env file that the systemd script will automatically incorporate which makes it easier to manage them.

I think you do get a basic path. On my Ubuntu system I see
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin.

I am thoroughly enjoying reading along :slight_smile:

1 Like

Sorry, we seem to have strayed off topic rather.

1 Like

Fair point, it may depend on the OS.

Actually, this thread is not for a specific topic anymore.

I long linked the answers to the original questions in the first post.
Everything since then is education and follow up.

And I find this discussion quite interesting. I don't have a use case for system variables (or env var in Node-RED), but hey, I might some day.

I will try to write compare function node next (since the filter does not have the functionality I need).
I am sure this will cause some new questions to pop up also.

Can you explain in words what you are trying to achieve?

I will hopefully show you in Node-RED code soon :smiley:

I am essentially doing

IF power > 1000 W and value has changed since last time Then publish whenever power changes by 50 W
ELSEIF power > 100 W and value has changed since last time Then publish whenever power changes by 10 W
.
.

So depending on what the absolute power value is, change the threshold.

EDIT: Solved my own problem. An uninitialized context is not considered 0 but undefined. So it will not be usable without initalizing it first.

P.S.: Where do you enable word wrap in the code editor?

That's true.

Syntax to provide a default value:

let something = context.get("something") ?? 0
msg.payload = something + 42
return msg
1 Like