Switching between two flows.json programatically

I have two .json flow files, flowA.json and flowB.json. At the front-end when certain drop down selection has happened I would like to load node-red editor with flowA.json / flowB. json, what would be the best approach to achieve this ?

Can you put FlowA in the first tab of the Editor, and FlowB into the second tab? This causes both bits of json to exist in a single flow_ab.json file, but you can at least work on either flow just by switching tabs.

If you need to have only one of the flows active at a time, you have several choices:

  1. run separate instances of node-red on different ports (can be individually started/stopped, and can have different nodes/versions installed)
  2. Enable the Projects feature (saves each flow in a git repo, so you can switch from one to the other easily)
  3. Use a separate "controller" flow to select which flow file to make active -- then push the selected flow's json to the admin api (below).

Are you familiar with the /admin/flows api? By sending the json for FlowA or FlowB, you can tell the node-red runtime to switch to using that flow.

Keep in mind that whatever flow is active in the runtime is also what you will see in the Editor (they are 1-to-1, and only 1 flow can be active at a time). Switching flows causes the other one to stop -- so you cannot edit one flow while the other is running.

2 Likes

Thank you for the quick reply Steve, Can you please point me to an example or documentation of admin flows which shows the steps to make changes to the flows.json. Also can you please confirm if .node-red folder that is created in my Users directory in Windows is created at the server-end right but, not the client side where I included the node-red editor as iframe ?

Could you provide a bit more detail of how to accomplish this. I have my flow start on bootup and I can see how having multiple instances could be useful. Obviously how this is accomplished is system dependent which is why I'm asking for a bit more detail or an example.

On RaspberryPi and Ubuntu node-red starts on boot via systemd, I expect I can poke around and maybe figure that out, but I could be missing a better way.

You can make a copy of the systemd file (probably /lib/systemd/system/nodered.service) with a different name and tweak the contents to start the other instance of node-red. It is fairly obvious what to do I think.

2 Likes

When you ask if you can have two flows and how to start them I have to ask a question via a explanation.

Within a node-red instance (like a version running on a rpi) you could have a flow reading , storing in a db and graphing temperature and humidity sensors. You could also be monitoring a website for some kind of data - day energy prices. And another flow that monitors the humidity of the soil of your tomato plants and turns on s pump to add water if the plant needs it.

Or any number of other things all in one node-red instance with multiple flows in multiple flow tabs.

Is that what you are asking about

Thanks for providing the systemd file info, Colin -- I've only used the init.d services on aws linux.

The way I have set it up was to link the secondary service scripts to the first one, like so:

$ ll /etc/init.d/nodered*
-rwxr-xr-x 1 root root 2407 Mar 27 11:57 /etc/init.d/nodered*
lrwxrwxrwx 1 root root    7 Mar 27 11:04 /etc/init.d/nodered-draw -> nodered*
lrwxrwxrwx 1 root root    7 Mar 27 11:04 /etc/init.d/nodered-logs -> nodered*

Inside the nodered script, I use the invoked name of the script as the unique service name. This way, I can start/stop different services by name from a single script. Here is the shell variable magic that lets me direct each named service to its own userdir and settings.js file:

    # This runs as the user called 'nodered' - please change as you require
    USER=nodered
    FILE="$(basename $0)"   # init.d script filename
    NAME="${FILE##nodered}" # remove any 'nodered' prefix
    NAME="${NAME##-}"       # remove leading '-' (if found)
    NAME="${NAME:-admin}"   # default to 'admin' if name is empty
    
    # The log is written to here - please make sure your user has write permissions.
    LOG="/var/log/${USER}-${NAME}.log"

then I can invoke the nodered command with some code like this:

start)
    if pgrep ^${USER}-${NAME}$ > /dev/null
    then
        echo "Node-RED: ${NAME} service is already running."
    else
        echo "Starting Node-Red.."
        touch $LOG
        chown $USER:$USER $LOG
        echo "" >> $LOG
        echo "Node-RED service start: "$(date) >> $LOG

        ### Run on a Pi or other low-memory device
        #su -l $USER -c "node-red-pi --max-old-space-size=128 -u ~/.node-red >> $LOG &"

        ### Run the production version of Node-RED
        #su -l $USER -c "node-red -v -u ~/.node-red >> $LOG &"

        ### Run the development version of Node-RED
        CMD="cd data/${NAME}/ && NODE_ENV=development node /opt/nodered/reddev/red.js -v -u . --title ${USER}-${NAME} flows_${NAME}.json >> $LOG &"
        su -l $USER -c "$CMD"

        echo "Logging to" $LOG
    fi
;;

There are also some sample scripts for running services on different platforms at the bottom of this page... please reply with your solution once you figure it out so we can all know next time someone asks...

1 Like

Thanks I hadn't yet figured out where that systemd stuff is, but looking at it now, I don't see anything about setting the port the node-red instance would use, so I'm still unclear on how to accomplish this

I'm not sure how useful this will really be as node red is usually just above mosquitto in my process CPU and/or memory usage.

That is in settings.js
Not sure what you mean about it being useful. If you want two instances of node-red running from boot then this is the way to do it.

1 Like

.node-red folder that is created in the Users directory is created by the node-red server right but not embedded node-red editor ?

or you can use the command line option -p 1880 to set it

2 Likes

Yes it is created in the server. Nothing permanent resides on the machine running the browser (other than the normal browser related stuff). It is just a browser accessing a web page.

1 Like

That is what I was expecting, this is not something I need to do right now, but the idea is interesting, would each instance need its own settings file? Presumably that could be a command line option as well.

The more I use node-red the mor impressed I am with its efficiency.

The built-in help shows all of the options that are available on the command line:

$ /opt/nodered/reddev/red.js -?
Node-RED v0.19.5
Usage: node-red [-v] [-?] [--settings settings.js] [--userDir DIR]
[--port PORT] [--title TITLE] [flows.json]

Options:
-p, --port PORT port to listen on
-s, --settings FILE use specified settings file
--title TITLE process window title
-u, --userDir DIR use specified user directory
-v, --verbose enable verbose output
-?, --help show this help

Documentation can be found at http://nodered.org

Thanks for this information, but the installation paths are system dependent Mine is most definitely not in /opt, and red.js -? is "command not found.

However, node-red -? gives me the options. So that is a start.

But that link to the generic top level node-red.org doesn't really give me any clue as to how to find out what I need to change or can keep the same in the settings file for a second instance. The information may be there somewhere, but it sure isn't easy to find.

Right now its only academic for me so I'm not going to scour a website looking for answers, but it also could be a good tool for the toolbox somewhere down the road, so I'd like to learn more about how to actually accomplishing it.

Tops from anyone who has actually run multiple instances on a single machine would be most welcome and helpful.

I confirm the admin/flows api calls to set the flows works like charm, I followed the documentation here - https://nodered.org/docs/api/admin/methods/post/flows/, thanks @shrickus for the suggestions