00:03
Many tasks in Node-RED can be done with the default core node set. And, when
00:08
they're not enough there's often an external package of nodes that you can
00:11
install to fill in the gaps. But, some applications just require more. In this
00:16
workshop I'll talk a little bit about function nodes and what they can do like
00:20
access persistent variables as well as the JavaScript object notation or JSON
00:25
format that the flow message uses. And, finally, I'll talk about some other nodes
00:29
like 'link' and 'exec'. With all of this at your disposal you'll be well equipped to
00:33
build clean, powerful and sophisticated Node-RED applications.
00:41
Having the ability to write your own JavaScript inside a flow is incredibly
00:46
powerful. Just about all the tools of JavaScript are available to you so if
00:50
you already know the language you'll be right at home. Otherwise, there are a ton
00:54
of resources and books on the language for you to learn. Since most other nodes
00:58
are essentially pieces of JavaScript you can use the function node to replicate
01:02
their processes and even do multiple tasks at once from the one function node.
01:06
Of course, you can also go beyond that and make full use of the JavaScript
01:11
language to customize your processing on the fly. As well as the conditional
01:16
statements, loops, functions, string and array manipulation tools that you can
01:20
use in JavaScript there were also some functions specific to Node-RED that are
01:24
very useful. They're all in the documentation on nodered.org. To give
01:28
you a quick outline, function nodes are able to send messages to multiple output
01:33
ports, send out multiple messages on a single port, or send out messages while
01:38
processing before completing the code block and exiting the node. There's also
01:42
the ability to log messages and errors, show status info during runtime, and
01:47
store data persistently between function calls or even between deploys. Context,
01:53
flow and global are the three different levels that you can use to set access
01:57
and modify persistent variables where the range of their access is referred to
02:01
as that variable's 'scope'. lLet's head over to Node-RED and see how this works. Here
02:06
I have a function node that uses 'context get' and 'context set' to keep a rolling
02:11
count of how many times I inject this function node. So, if I click done and
02:16
inject a few times you can see the counter go up in the debug window. If I
02:21
try to access this context account from another function node here where I
02:25
context.get count from below. If I inject this I get undefined since it
02:30
hasn't actually been defined in the scope of this function node, only within
02:35
the one above it. To fix this I can increase the scope of count by going
02:41
into the function and changing 'context' to 'flow'. Now the variable count will be
02:46
available from anywhere within this flow.
02:51
I'll click done and change the other node to use the same. Now if I click done,
02:59
deploy I'll see the number is reset since it is now under a new scope. And,
03:05
every time I inject the count goes up. But, I can also request it from this node.
03:11
Now I'll take it a step further and go over to this other flow and try to
03:15
inject 'flow.count'. Now when I try to do it from here I still get undefined
03:19
and that's because it isn't defined within the scope of this flow only the
03:24
other. To fix this I can level up the flow once more, go into count and edit it
03:29
to be 'global' instead of 'flow'. I'll hit done, change over to the other tab,
03:41
increasing this to get the global count. Now, when I deploy and inject I can get
03:49
the count from any flow that I would like. So, while these global variables are
03:54
universally accessible some applications may be better off using a link node to
03:59
share data between flows. Link nodes not only share variables but can also
04:04
trigger different flows across your project in a sequenced predictable way.
04:08
Here I'll bring in an inject and have it throw in the time stamp. I'll go down
04:14
to the function section and use a delay node to set this off 5 seconds after I
04:18
actually inject the message. I can send this to a link output node.
04:31
I'll call this link 'example' so I can find it later. Now, I'll bring in a link
04:40
input node, wire it to a debug and connect to the 'link to example'. Now, you
04:52
can see the link has found it's pair. And, when I deploy and inject five seconds
04:58
later I will see the timestamp appear in the debug window. And, there it is. If I
05:05
grab these two nodes, cut them and paste them on another flow, then when I deploy
05:11
and inject on this flow five seconds later I can go back to this other tab,
05:18
and when the time appears I can see by the dashed line that it's coming from this
05:23
debug node. When I select the link node I can see it is connected to my other flow.
05:29
While persistent variables can be accessed across flows they will not move
05:34
an inject or flow message only allow you to access your stored values. To move
05:39
the message across flows or to start one flow from another you should use linked
05:43
nodes. So far the messages I've been moving around have been pretty simple
05:48
though mostly a message object containing a single property payload.
05:52
This makes up the majority of Node-RED objects. But, sometimes a node will
05:56
require input or give output that is a much more complex message object. To get
06:01
an idea of what this can look like I'll use this HTTP request node to get a
06:06
Weather Underground API object. I have this debug node set to display the
06:13
complete message object in the debug window so that I can see the full
06:16
structure. So, I'll activate that and inject the node to see the object. Now,
06:22
when I expand it Node-RED is already telling me that payload itself is an
06:26
object not just a variable. So, I can expand that out and see that it contains
06:30
two more objects called a response and forecast. Forecast itself is a pretty
06:36
complex object with text forecasts and simple forecast objects. Simple forecast
06:42
itself expands into an array called 'forecast day' that holds four days worth of
06:47
forecast data. Each of these objects contains a lot of data about that
06:52
forecast. Here I can expand 'high' and 'low' to see Fahrenheit and Celsius for both.
06:58
If I wanted to find the path to this exact object I can use this button on
07:02
the left from the debug pane. To copy the path to my clipboard now if I go down to
07:08
the function section and drag in a function node, wire that in between the
07:13
message and the HTTP request, I can paste that path directly into my function node.
07:22
Now, I'll find out how to reference JSON objects first I use 'msg.' to
07:30
reference the payload and then '.forecast' to get that object then
07:34
'.simple forecast' and '.forecast day'. 'Forecast day' then requires square
07:39
brackets to reference the first item in the list and index zero. Once I have that
07:45
I can reference 'high' and 'Fahrenheit' using the '.operator'. From there if I were to
07:51
return a new object using this as the msg.payload,
08:01
hit done, deploy, and inject on this message I can see that 76 degrees has
08:10
come through. If I wanted to change this to get the low centigrade for example
08:15
all I have to do is change those fields.
08:22
Now when I hit done and deploy and inject I can see the number 15 appear
08:31
from the payload. That's how easy it is to reference different fields of JSON
08:36
objects. Now this weather object is very specifically organized and will be
08:42
consistent with all calls from Weather Underground. But different api's have
08:46
different standards with what they output and even what they may take as
08:50
input. Take for example the email node. You might remember this from the 'email
08:54
alerts' video. I'll go and click on one now so that we can look at what it says
08:59
in the info tab. Here it says that you can set the email body using msg.payload.
09:05
The subject using msg.topic and recipients using to, CC, and BCC.You
09:12
can either apply these using the email node static settings or you can hand
09:17
them in every time you call the node using dynamic message objects. By using
09:23
message properties instead of node settings to supply information you're
09:27
able to use the node dynamically as opposed to being restricted by your
09:31
static settings. Another powerful node is the 'exec node' which allows you to run a
09:37
command line instruction from within Node-RED. Be aware that this node is
09:41
very powerful and if you enter the wrong thing it's possible that you could
09:45
damage your system. Do not execute anything before you understand what it
09:49
does. Here I have an exec node setting off an exec node to read my groov box's
09:55
CPU load using the top command.
10:02
If I activate the debug node and inject on this flow I can see that my cpu load
10:07
of 1.5% appears in the debug tab. Now that it's in Node-RED I could do
10:13
anything with it like plot it in groov, lock it to a database or anything else I
10:18
would like. The possibilities are only limited by what you want to do with your
10:22
application. With these nodes and some understanding of JSON objects and
10:28
JavaScript at your disposal you'll be able to use Node-RED to easily create
10:32
powerful applications that meet your need. You'll be able to do this no matter
10:36
how straightforward or advanced your problem is. Thanks for watching.