Tag Archives: Node-Red variables and file saving – Peter Scargill’s thermostat

Some thoughts on Node Red variables

In learning how to use Node-Red I’ve changed my coding countless times as I’ve found better ways to do things.

Please note that in 2017, the way I use global variables here is out of date. It still works but for example context.global.fred=1 is now written as global.set("fred",1). Read this later article on using globals and context variables.

I’m currently working on my thermostat code using a Nextion touch-sensitive display, Raspberry Pi2 as controller and ESP8266s for relay and temperature/humidity sensing. This was a slow-running project until my old Arduino-based heating controller packed in yesterday without warning and so now the fate of the household heating is in the hands of an on-going project.

So the general idea is easy enough – lots of settings for weekdays and weekends, read sensor, control relay. That’s pretty much it in a nutshell except that on my first attempt I didn’t take into account power cuts – and when the power was restored to the Pi, hardcoded defaults took over instead of the settings I’d put in using the display.

So there’s a need for lots of variables and a means to store them permanently. This is what I’ve come up with and the logic behind it:

In order to pass variables around in Node-Red, you need to use “context.global” variables as these are the only ones that will work from page to page (i.e. from powering up node-red to powering down across all pages of your project). This can make for messy variable names for those of us who like to keep things short because we’re lazy or developing typists finger.

context.global.stat_inside_temperature

etc..

I’m a C person and so a struct is ideal for me – keeps everything together.  The nearest I get to that in JavaScript is an object and that’s fine.

A global object containing everything to do with my stat.

   var stat = {
display_temperature : 22,
display_humidity : 45,
heating : 0,
display_external_temperature : 14,
display_external_humidity : 54,
display_status : "Normal",
display_target_temperature : 20,
display_enabled : 0,
display_last_page : "home",
display_last_colour : 0,
pass : "",
display_dim : 60,
peak : 21,
night : 16,
frost : 12,
hold : 0,
weekon : 480,
weekoff : 720,
weon : 480,
weoff : 720,
week2on : 780,
week2off : 1380,
we2on : 780,
we2off : 1380,
temperature_manual_override : 0,
update : 0
};

That stat var of course is only valid while the relevant function is in use and is invisible outside of that particular page hence…

context.global.stat=stat;

So now we have a nice but somewhat longwinded way to access the variables..

context.global.stat.display_temperature;

(I know I should probably use displayTemperature but there’s no global replace in the Node-Red editor (hint)).

Because JavaScript objects are passed by reference – you can use a reference to this in other pages which makes things a little more readable.

var stat=context.global.stat

Hence

stat.display_temperature;

That’s more like it and you can write to that new variable and it will update the original as they are one and the same.

The obvious solution for storing variables permanently, is a database, but I’m trying to minimise that to keep writes down for the time when I run all of this and much more on an SD (currently using a little 2.5” drive with the Pi2).

The file node lets you read and write text files and so the next challenge was how to get that object into a text file – easy:

msg.payload=JSON.stringify(context.global.stat);

That JSON string can be saved directly to disk and the inverse is true of course…

context.global.stat=JSON.parse(msg.payload);

The good part of that is that the string saved to disk is readable and if need be directly writeable.

Thankfully when the file node reads a file if the file is not there, it returns “undefined” so in my function I check for undefined and if so – create a new one with defaults in it. I added a timeout variable in there and whenever I update any item in the object I also set a counter to 10.  That counter is decremented every second and when it reaches zero, the object is updated on disk. That means I can do all sorts of adjusting of controls on the Nextion display and only when I’m done will there be a single block write to the disk. The READ is only done once when Node-Red powers up.

Seems like a reasonable solution and it’s nice and warm in here.

In an earlier blog you’ll see my Nextion display solution which is quite pretty ( created my own imagery because built-in Nextion options are currently not that good) – here just for reference is the current Node-Red block controlling the display and the stat itself including disk reading and writing.

tmp7866

Facebooktwittergoogle_pluspinterestlinkedin