HomeHome AutomationPreserving variables in NodeRED

Preserving variables in NodeRED

From time to time, my NodeRED server demands a reboot. In fact, I have a scheduled reboot each night in conjuction with linux auto-updates. When this happens, all data saved in global and flow variables will get wiped. This can lead to unexpected errors and flows not functioning correctly. Let’s talk about preserving variables in NodeRED.

Preserving variables in NodeRED (flow|global)

If you are not familiar with global|flow|context variables, take a look part 4 of my tutorial for beginners. These variables get wiped when the NodeRED stops. Not having these defined, can lead to unexpected errors in NodeRED flows. Before I show you how to save these, let’s mention error proofing.

“undefined”

When the variable is wiped, the content of the “container” will be replaced with the “undefined” message. This will replace all the variable types (bool, string, int) and it can cause an annoyance in the string at best, and “NaN” in maths calculations or JS errors in the worst case scenarios.

There are a couple of things we can do to protect our flows. A simple IF statement can set default values before our function or flow returns an unwanted error:

if(x === undefined){
    x = "default value";
}

Preserving variables in NodeRED

Loading default values is great, but it won’t save us from the data loss. To protect the data, we have to save it somewhere for the duration of the NodeRED restart. Before v19 of the NodeRED you would simply save these values to a file and load it back as variables once the server is online again. (a big thank you to u/frygod)

This is the “old way” of doing things. It’s probably simpler and quicker if you only going to do this a couple of times. If your NodeRED flows are ever expanding, you may consider moving to the new solution.

The old way

Save to file

An inject node has an interval built in. This can be used to save our variables every X sec/min/hours. The flow is very simple, but before you save the data to a file, consider writing it as JSON. Trust me, you will thank me later. It may not be a problem if you want to store single information, but that’s rarely the case.

var x = flow.get("ImportantData1");
var y = flow.get("ImportantData2");
var z = flow.get("ImportantData3");

msg.payload = {
    "data1": x,
    "data2": y,
    "data3": z
};
return msg;

This JSON is then written to file. Avoid storing sensitive credentials this way, as the file can be opened by anyone who has the access to that machine. There is no encryption. Setting a strong passwords for SSH access is recommended.

Read from file

To restore the data from file, I’m going through the reversed process. The file is read and converted into a JSON, then appropriate entries are saved as variables. To trigger this after NodeRED reboot, you will need an inject node configured to Started! I would recommend you to add a couple of seconds of delay as well.

flow.set("ImportantData1",msg.payload.data1); 
flow.set("ImportantData2",msg.payload.data2); 
flow.set("ImportantData3",msg.payload.data3);

return msg;

Preserving variables in NodeRED v19

The new version of the NodeRED introduces a new way of storing the variables. By default, the variables are stored in the memory, and get wiped when the server is restarted. Now we can specify where we would like to store the variables.

  • keep variable in the memory
  • store it in a context store

What is the context store?

We can enable a new way of storing the data in variables. NodeRED v19 can save the data stored in the variables to a local file structure. These are saved automatically every 30 sec. It’s not enabled by default and we have to configure settings.js file to enable this.

contextStorage: { 
    storeName : { module: "storeModule" } 
}

This is the entry in the settings.js that we have to modify.

  • storeName – a custom name for your “bank” of information (“default” is, well the defaul “bank”)
  • storeModule – type of storage: (memory|localfilesystem)

Let me show you on the example how to configure the file

Default – store everything in memory
contextStorage: { 
 default: { module: "memory" } 
},

In this configuration, the variables are not saved to file but kept in the memory only. This is the default NodeRED behaviour.

Store everything- store everything in a local file
contextStorage: { 
 default: { module: "localfilesystem" } 
},

In this configuration, every variable is saved to a local file structure.

Mixed mode – using context storage
contextStorage: { 
 default: { module: "memory" }, 
 bank1: { module: "localfilesystem" } 
},

In this mode, you can choose where your variable is stored. To specify the context storage used, we have to define it in the variable command:

flow.set("DayOfTheWeek", "Monday", "bank1") 
\\content of the variable "DayOfTheWeek" is stored in the context store called "bank1"
flow.set("DayOfTheWeek", "Monday", "default") 
OR
flow.set("DayOfTheWeek", "Monday") 
\\content of the variable "DayOfTheWeek" is stored in the memory

You can create multiple context stores and save the variables to different “banks”.  These are organised in the ~/.node-red/context folder. The file structure will correspond with your flow structure with exeption of global variables, which are all stored in the same folder (which makes sense as these are available across the flows).

Conclusion

Preserving variables in NodeRED can save you from manually opening the dashboard and setting everything correctly. The data will survive the server restart. You can also store the copy of that file to create an additional backup and synchronise it using a method I created earlier. Got questions? Here is a Reddit post for you!

Project Download

Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.

PayPal

Nothing says "Thank you" better than keeping my coffee jar topped up!

Patreon

Support me on Patreon and get an early access to tutorial files and videos.

image/svg+xml

Bitcoin (BTC)

Use this QR to keep me caffeinated with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU

Smart Ideas with

Automate your space in with these ecosystems and integrate it with other automation services

client-image
client-image
client-image
client-image
client-image
client-image
client-image
client-image
client-image

Learn NodeRED

NodeRED for beginners: 1. Why do you need a NodeRED server?

0
To server or not to server? That's a very silly question!

Best Automation Projects

Tuya SDK for beginners: Intro to Tuya Cloud API

0
Working with Tuya Cloud API. A guide to Cloud automation for beginners, get started with REST!

NEST your old thermostat under $5

0
Nest-ing up your older thermostat under $5

Nora – Google Assistant in NodeRED

0
Integrate Google Assistant with NodeRED thanks to Nora - NodeRED home automation

Sonoff Zigbee Bridge – review

0
Sonoff line up will soon include Sonoff Zigbee Bridge and more Zigbee sensors - here is the first look

DIY Smart Washing Machine – for about 15 bucks!

0
Learn how to add washing machine notifications to your Google Home on the cheap

Smart Home

We’ve seen this before: SwitchBot K10+ PRO

0
This is an odd one. Building on the success of SwitchBot K10+ they released SwitchBot K10+ PRO - but is the experience actually better?

Is this the smart panel we have waited for?

0
ITEAD has released a new smart panel: Sonoff NSPanel Pro 120 - have they learned the lesson from the terrible launch of the original Pro? Let's see what's new.

Aqara FP1E detects motionless humans

0
This isn't exactly a new device, it's an interaction of the original Aqara presence sensor. Aqara FP1E brings Matter, ZigBee and new triggers to your smart home

SwitchBot S10: cleaning re-imagined!

0
SwitchBot S10 promises unattended vacuuming and mopping so you can focus on things you love and care for. Does it deliver?

Sonoff for households and gardens

0
ITEAD released two ZigBee devices to manage water in your household and gardens. Now you can monitor the flow and dispense water with Sonoff SWV and prevent water damage using the Sonoff Water Leak sensor with a twist.