Tag Archives: flows and context

Node-RED Global Flow and Context

There’s a mouthful. This short article is about the various kinds of variables used in Node-Red and more importantly how to initialise them and how to view them.

So in Node-Red when you want to use variables – there are three basic types as well as local variables.

So for example – you’ve opened up a FUNCTION block and you want to use some variables. VAR is always a good start.

var fred=1;

A way to get a variable to PERSIST behind that simply function invocation to the next time around, use this;

context.set(“fred”,1);

If you’d like that var to be available to any other function in that flow (or page if you like) - use:

flow.set(“fred”,1);

and if you need a global variable that can be accessed anywhere within Node-Red including other flows  – I use them all the time for things like thermostat objects etc… use global.

global.set(“fred”,1);

Of course you can recall said variables as global.get(“fred”); etc. Don't use the old method (example global.context.fred) - there's a reason the Node-Red guys are steering us in this direction.

This is not meant as a course on programming – you can read all about this on the Node-Red site – just look up variables.

So three useful types of variable.

But there’s a problem. Node-Red runs asynchronously and in my first efforts I would have an INIT tab and initialise my global variables there. Once in a blue moon I would see a non-destructive failure with the logs showing that I’d tried to use a variable before it had been initialised (created, even).  So in a platform where everything is running asynchronously how do you ensure (without checking every single time you use it) that a variable has been initialised…. especially important for globals.

One way which I don’t really like is to ensure that the variable is initialised in the left most tab. as that runs first… ok… kind of….

Well it turns out “there’s a node for that”.  Node-Red-Contrib-Config does that – you can set up a variable – which could be a whole object – an no matter where you put this node – it will run BEFORE the main flows start up – I tested it, it works. My only niggle might be that the VALUE field needs to be expandable – a single line is not much use for large objects.

npm install node-red-contrib-config

So that’s one side of it.

The other side is – would it not be nice if you could have a tab to show you the current status, names and values of all of your global variables – and more. Well, now you can.

This needs a SLIGHT mod to Node-Red so if you’re new you might want to back stuff up.

In the directory you normally (hopefully locally) npm install stuff –

https://www.npmjs.com/package/node-red-contrib-contextbrowser

So the install is:

npm install node-red-contrib-contextbrowser

Stop Node-Red and in (in my case) and make a slight edit

nano /usr/lib/node_modules/node-red/red/runtime/nodes/context.js

This is the function you need to alter - very carefully add one line as I have in bold. That’s it – don’t make any other changes.….and this IS case-sensitive.

function createContext(id,seed) {
var data = seed || {};
var obj = seed || {};
obj.get = function get(key) {
return util.getMessageProperty(data,key);
};
obj.set = function set(key, value) {
util.setMessageProperty(data,key,value);
}
  obj.getKeys = function() { return Object.getOwnPropertyNames(data); }
return obj;
}

If you're something that does not show bold, the line starting "obj.getKeys" is the addition.

(NODE RED GUYS – any chance of making the above standard???)

Start up Node-Red (this works even if you use HTTPS and have password on Node-Red)

And lo – you should have a new tab on the right… click in the editor on a node or function you know has variables initialised…

and then use the refresh in that new tab..

My test..

tmp6E51

The contents of that orange function

tmpD029

 

And..

tmp65A3

As you can see, you must select the particular node or function with the mouse first – then hit the little refresh in the contextbrowser tab - you then see above freddy and the value in the tab – along with any others you’ve defined in that node or function. Ok it’s not quite debugging but better than nothing.

Now moving to the Global tab is another matter as I have several globals including some big objects – if they are very big – you might have to hit the little … indicator to expand them.

tmp3C87

So for me this is marvellous – I can now set up global vars with the confidence that they will be initialised properly at the start – and I can also get a nice overall view of the globals I’ve used – something I could not easily do before.


If you like this post – please share a link to it by social media, by email with friends or on your website.
More readers means more feedback means more answers for all of us. Thank you!

Facebooktwittergoogle_pluspinterestlinkedin