MQTT and Environment Variables

Hi.
I've been running node-red on a BeagleBone Black Wireless for some time now and am trying to make some upgrades to the software, mainly to parameterize the MQTT connection.

According to https://nodered.org/docs/user-guide/environment-variables "Any node property can be set with an environment variable by setting its value to a string of the form ${ENV_VAR} ."

I've set some shell variables
MQTT_BROKER
MQTT_CLIENT
MQTT_PORT
MQTT_QOS
MQTT_TOPIC
MQTT_NAME
to values that currently are known to work. I then changed the MQTT out node and its broker node to try to use these values as ${MQTT_BROKER}, etc. I've had several problems in this endeavor:

  1. it's not clear how to set these variables before node-red starts automatically, so it's not clear to me whether these the values of these variables are even being set. To get past this problem for the time being, I've stopped node-red, set the variables, tested that they are indeed set by examining the output of
    set | grep MQTT
    and then restarted node-red.
  2. Nevertheless, it doesn't appear that the values are used. Indeed, I can't even deploy with the broker's port set to ${MQTT_PORT}, so I have set it to 1883 for the time being.
  3. After restarting node-red, the log shows
    29 Feb 15:46:35 - [info] Starting flows
    29 Feb 15:46:36 - [info] [wifiscan:e07da6ad.5061d8] wifiscan - Initialized
    29 Feb 15:46:36 - [info] Started flows
    29 Feb 15:46:36 - [info] serial port /dev/ttyO4 opened at 2400 baud 8N1
    29 Feb 15:46:36 - [info] [mqtt-broker:BBBW] Connection failed to broker: {MQTT_CLIENTID}@mqtt://{MQTT_HOST}:1883
    29 Feb 15:46:51 - [info] [mqtt-broker:BBBW] Connection failed to broker: {MQTT_CLIENTID}@mqtt://{MQTT_HOST}:1883
    29 Feb 15:47:06 - [info] [mqtt-broker:BBBW] Connection failed to broker: {MQTT_CLIENTID}@mqtt://{MQTT_HOST}:1883
    etc.

The failed attempts continue even after moving a node (to activate the "deploy" option) and then deploying.

Suggestions, please! Thanks,
Richard

Hi, welcome to the forum. Posting your actual flow would help us to help you.

Are you starting node red in the same environment that you have set the vars? Or to put it another way exactly how are you setting them then starting node-red?

Hi. Thanks for asking. Here's a listing of the session (with some obfuscation for privacy). The obscured values are ones known to work both before and after this experiment.

root@beaglebone:/home/me# set | grep MQTT
MQTT_BROKER=[---]
MQTT_CLIENT_ID=[---]
MQTT_PORT=1883
MQTT_QOS=1
MQTT_TOPIC=[---]
root@beaglebone:/home/me# service node-red stop
root@beaglebone:/home/me# service node-red start
root@beaglebone:/home/me# journalctl -f -u node-red -o cat

Oh, maybe I should mention that I ended up using neither the MQTT_PORT nor the MQTT_QOS value, as neither was possible.

Thanks, Richard

hmm - that looks like the MQTT node is expecting numerics... and of course all env variables are strings...

The [---] are strings (without quotes), such as (not the real values)
MQTT_BROKER=alpha.beta.gamma
MQTT_CLIENT_ID=Whoever
MQTT_TOPIC=Whatever

And the broker, client, and topic should be strings.

indeed - and expected to be so... I suspect the node is not handling a port of "1883" when it expects 1883.

Right, but as I said, I'm not using the MQTT_PORT environment variable. It happens to be set, but couldn't be used in defining the node.

Actually looking at the code they can be strings just fine.

Not quite. The editor side tries to validate the node configuration port value as a number, but the value is "${MQTT...}". That will cause it to flag it up as being invalid, but you can still deploy. But you'd have to manually edit the flow file to add that value anyway.

How are you setting the env vars in the first place? Just because they are set in your local root shell, it doesn't mean they will be set when running NR as a service.

You could add some console.log lines in your settings.js file to print out the values of process.env.MQTT_BROKER etc.

1 Like

I'm confused. The reason I stopped the node-red service and then restarted it was to be sure that the variables were defined when the service started.

OK. I've got the settings.js file open, and near the end I see
// configure the logging output
logging: {
...
}

Where do I put console.log lines, and what would one of them look like:
printf("process.env.MQTT_BROKER = %s\n", process.env.MQTT_BROKER)
or what?

Thanks.

At the start of the file (ie, very first line) add:

console.log(process.env.MQTT_BROKER);
1 Like

And to answer your question about how I'm setting the variables, I'm sourcing a file with lines like
export MQTT_BROKER=alpha.beta.com
export MQTT_CLIENT_ID=Whatever

and then I check that the settings took by running

set | grep MQTT

with the results I expected.

OK. I've done that, and get the result "undefined"

Now what?

Thanks.

It looks like one possibility is to modify
/lib/systemd/system/node-red.service
to export the environment variables I want.

Seems a bit brutal, but maybe that's what's needed.

Or is there something I could put into settings.js that would do the trick?

Thanks.

(Oops...just saw the time. I'll have to duck out for a supper invitation for the next few hours, but I'll be back.)

You can set env vars via process.env in your settings file. So yes that would be a way of doing it.

It's midnight here. I'll be asleep when you're back from supper. But hopefully you have enough to make some progress.

I think the problem is that you are setting the env vars in your terminal session but the service gets a new environment so they are not set. This is as it should be because you wouldn't want a service start to behave differently dependent on what env vars happen to be set in the session you start it from. I think you will need to set them up in the service or settings, or read them from a file in the service start, or something else along those lines.

This might be the best way to do it, if it is appropriate. It overrides the service file in a way that will survive updates as the original service file is not changed.

2 Likes

I have that configured in my alternate installer as well if you want an example.