Rode-RED 中文文档

Rode-RED 中文文档

Node-RED是一个物联网可视化编程工具

关于

Node-RED是一种基于流程的编程工具,由IBM的新兴技术服务团队原创开发,现在归属于JS 基金会。

流程化编程模式

流程化编程模式最初是由J. Paul Morrison在20世纪70年代发明的,它将程序的行为表示为一个由黑箱组成的网络,也就是我们在Node-RED中所说的“节点”。每个节点都有其明确的功能目标,为此,我们要向它提供数据,由它对数据进行处理,并将结果发送出去。而网络则负责控制数据在节点间的流动。

如果把它以视觉化模型的形式表示,那么就能被更大范围的用户所接受和理解。只要我们能将问题分解为多个单独的步骤,那么就可以将其表示为流程化模型。这样,即便对各个节点内部的代码不了解,也能对问题的处理过程有个直观的把握。

运行时/编辑器

Node-RED由基于Node.js的运行时环境组成,当你将Web浏览器指向它时,就可以访问到流程编辑器。在浏览器中,我们以拖拽和连线的方式创建应用程序,也就是将所需的节点从面板拖拽到工作区中,然后用连线将它们连接到一起。然后通过一键部署方式,我们又将开发好的应用部署到运行时中,在那里它被运行起来。

利用社区开发的新类型节点,可以很容易地对节点面板进行扩展,同时,用户所创建的流程也很容易以JSON文件形式分享。

历史

Node-RED诞生于2013年,其开发者为IBM新兴技术服务组的Nick O’Leary和Dave Conway-Jones,当初仅仅是两个人的副业项目。

最初的开发目的是为了从概念上验证MQTT主题间映射的视觉化表示和处理方式,但很快地,就变成了一个非常通用的开发工具,而且很容易地扩展到了其他应用领域。

2013年9月起,Node-RED就成为开源项目,并且一直以开放的方式进行开发,最终在2016年10月,成为了JS基金会资助的项目。

更多细节参见:

  • 关于转入JS基金会的博客文章。

  • Nick在Monki Gras 2016上的演讲:

安装

安装node.js

我们建议使用6.x LTS或6.x版的Node.js,因为Node-RED不再支持0.10.x或0.12.x版本。

注意: 由于Node.js 7.x仍在开发过程中,因此不建议将其作为Node-RED的底层环境。另外,很多第三方Node软件包(特别是那些含有二进制组件的)可能对Node 7.x以上版本支持的也不是很好,如果自己搞不定,请尽量与软件包的原作者联系。

你可以从以下地方获得最新的Node 6.x长效版(LTS):

  • Max OS X 安装工具: Universal

  • Windows 安装工具: 32-bit or 64-bit

  • Linux 二进制包: 32-bit or 64-bit

使用与操作系统匹配的打包版本通常是最便捷的一种做法。

另外,对于某些特定的硬件平台,我们还提供了专门的说明:

  • 树莓派

  • BeagleBone Black

此处还有其他可用的下载资源。

安装Node-RED

安装Node-RED的最简单方式就是,使用Node的软件包管理工具npm。将其作为一个全局模块安装时,执行命令node-red将会被加入到系统路径中:

sudo npm install -g --unsafe-perm node-red

注意: 千万不要用 npm 1.x 安装Node-RED,应该先执行:sudo npm install -g [email protected]将其升级到最新的 npm 2.x版。

注意: sudo是Linux或OS X系统的非root用户在执行命令时需要加入的。如果你的系统是Windows,那么就不需要在命令中加入sudo,但是必须要以系统管理员身份执行这些命令行指令。

注意: 在安装过程中,有可能会出现一些node-gyp错误提示,这些大多是典型的非致命性错误, 一般与一些要求编译的可选依赖项有关。Node-RED的运行一般不需要这些可选的依赖项,但如果你发现一些附加的Node模块需要编译功能的话,你可以参考一下这里的node-gyp安装方法。

下一步

安装完成后,就可以运行Node-RED了。


其他安装方法

下载发行版

可以从这里下载最新的发行版压缩文件, 其中包含一个名为node-red-X.Y.Z的目录,X.Y.Z表示版本号。 将其解压后,进入这个目录并执行以下命令:

npm install --production

从Github获取(用于开发)

对于那些愿意使用开发代码的用户,或者是期望贡献代码的开发者,可以从Github获取代码并执行。

你可以直接复制Github上的源代码库:

git clone https://github.com/node-red/node-red.git

复制好后,必须先安装一些必要的核心模块:

cd node-red
npm install

注意: 当运行从git仓库获取的复制代码时,必须要安装所有的依赖项,而不仅仅是与生产有关的部分,因此不能在命令中使用--production选项。

为了在使用前编译应用,还必须以全局方式安装grunt-cli

sudo npm install -g grunt-cli

然后编译并运行整个应用

grunt build
node red

下一步

安装完成后,就可以运行Node-RED了。

运行

如果Node-RED是以全局npm软件包方式进行安装的,那么就直接执行命令node-red:

$ node-red
​
Welcome to Node-RED
===================
​
25 Feb 22:51:09 - [info] Node-RED version: v0.14.6
25 Feb 22:51:09 - [info] Node.js  version: v4.6.0
25 Feb 22:51:09 - [info] Loading palette nodes
25 Feb 22:51:10 - [warn] ------------------------------------------
25 Feb 22:51:10 - [warn] [rpi-gpio] Info : Ignoring Raspberry Pi specific node
25 Feb 22:51:10 - [warn] ------------------------------------------
25 Feb 22:51:10 - [info] Settings file  : /home/nol/.node-red/settings.js
25 Feb 22:51:10 - [info] User Directory : /home/nol/.node-red
25 Feb 22:51:10 - [info] Server now running at http://127.0.0.1:1880/
25 Feb 22:51:10 - [info] Creating new flows file : flows_noltop.json
25 Feb 22:51:10 - [info] Starting flows
25 Feb 22:51:10 - [info] Started flows

这样,你就可以在http://localhost:1880上看到Node-RED编辑器了。

对于某些特殊的硬件平台,我们还提供了一些专门的说明:

  • 树莓派

  • BeagleBone Black

下一步

现在,你可以来建立你的第一个流程了。


运行本地安装版本 - Linux & Mac OS X

即便Node-RED不是以全局方式安装的,依然想通过node-red指令执行。

如果安装方式为npm,那么启动脚本就是,你执行npm install命令时所在文件夹下的node_modules/node-red/bin/node-red。如果安装方式为zip文件,那么脚本就是解压文件夹中的node-red-X.Y.Z/bin/node-red

首先,要让node-red脚本成为可执行文件:

chmod +x /bin/node-red

然后,你可以利用一下方式启动Node-RED:

/bin/node-red

运行本地安装版本 - Windows

对于Windows,要在执行npm install命令或解压zip文件的目录中,执行:

node node_modules/node-red/red.js

命令行用法

Usage: node-red [-v] [-?] [--settings settings.js] [--userDir DIR] [flows.json]

Options:
  -s, --settings FILE  use specified settings file
  -u, --userDir  DIR   use specified user directory
  -v                   enable verbose output
  -?, --help           show usage

保存用户数据

By default, Node-RED stores your data in the directory默认情况下,Node-RED将用户数据保存在$HOME/.node-red目录中。出于向后兼容的原因,如果Node-RED在安装目录中检测到了用户数据,也将会替代使用。在升级文档中,专门有一个部分是关于如何将数据从Node-RED安装目录中移植出来的。

如果想替代默认使用的目录,可以通过添加命令行参数--userDir实现。

向底层Node.js进程传递参数

在某些场合,我们需要向底层的Node.js进程传递参数。比如当它运行在像树莓派或者BeagleBone Black这类内存受限这样的设备上时,

为了做到这点,你必须以node-red-pi方式启动node-red中的脚本。 注意:这个脚本无法在Windows上使用。

另外,也可以通过node指令来运行Node-RED,但是在指定red.js之前,必须手动设定Node进程以及传递给Node-RED本身的相关参数。

以下给出了这两种方式的命令形式:

node-red-pi --max-old-space-size=128 --userDir /home/user/node-red-data/
node --max-old-space-size=128 red.js --userDir /home/user/node-red-data/

开机时自动启动Node-RED

开机时启动、停止和监控应用的方法有很多,对于树莓派用户,强烈建议按照这些说明进行操作。

后面的内容对于大多数用户都可以直接利用,但对于Windows用户,可能无法将PM2作为服务自动运行,可能更适合采用之后的NSSM选项。

使用PM2

PM2是Node.js的进程管理工具,利用它可以非常容易地实现开机应用自动启动以及必要时自动启动的功能。

Note: PM2的发行许可为GNU-AGPL-3.0,在部署前请查看许可的相关条款。

1. 安装PM2
sudo npm install -g pm2

注意: sudo 仅适用于Linux或OS X中的非root用户,如果运行在Windows上,那么就需要以系统身份管理员来执行,而无需使用sudo命令。

另外在Windows上,你还要保证tail.exe已经在目录中安装好,具体情况请参照此处的说明。

2. 确定node-red命令的具体位置。

如果是以全局方式安装的Node-RED,那么对于Linux或OS X系统,那么node-red命令就有可能在/usr/bin/node-red/usr/local/bin/node-red中,我们可以利用which node-red来确定其确切的位置。

如果是本地安装,那么它就应该是你运行npm install命令的那个目录中的node_modules/node-red/bin/node-red

3. 让PM2运行Node-RED

以下命令可使PM2运行Node_RED,其中假设/usr/bin/node-rednode-red命令的存放地址。

另外,--必须出现在传递给node-red的其他任何参数之前。

pm2 start /usr/bin/node-red -- -v

注意: 如果运行在树莓派或BeagleBone Black这类内存受限设备上,你还必须另外再加入一个参数:

pm2 start /usr/bin/node-red --node-args="--max-old-space-size=128" -- -v

注意: 如果希望以root用户身份运行,就必须利用--userDir选项,指定保存用户数据的位置。

执行上述指令后,Node-RED将会以后台方式启动运行。你还可以利用下面的指令来查看相关进程信息并访问运行日志:

pm2 info node-red
pm2 logs node-red

关于利用PM2管理进行的更多信息请访问这里。

4. 让PM2开机运行

PM2能够自动生成和配置一个与运行平台相适应的启动脚本。

执行以下命令,并按照出现的提示进行操作:

pm2 save
pm2 startup

对于更新版的Linux系统,还可以使用systemd

pm2 startup systemd

注意: 最近在Github上提出了一个 open问题,对于Linux用户必须通过手工编辑所生成/etc/init.d/pm2-init.sh来解决,具体做法是将其中的

export PM2_HOME="/root/.pm2"

替换为正确的目录,比如:

export PM2_HOME="/home/{youruser}/.pm2"
5. 重启

最后,重启系统,并检查所有应用是否按预期方式自动启动。

替代方案

以下为社区成员所提供的替代方案。

  • systemd脚本(预装版树莓派专用) by @NodeRED (linux)

  • systemd脚本 by Belphemur (linux)

  • init.d脚本 by dceejay (linux)

  • init.d脚本 by Belphemur (linux)

  • Launchd脚本 by natcl (OS X)

  • 利用NSSM以Windows服务方式运行 by dceejay

  • 以Windows或OS X服务方式运行 by Ben Hardill

增加节点

Node-RED本身只包含了一些核心的基本节点,但还有大量来自于Node-RED项目和广大社区的其他节点可以使用。

你可以在Node-RED代码库或npm仓库中寻找所需要的节点。

使用编辑器

从0.15版开始,你可以直接通过编辑器安装节点。具体做法是,在右上角的菜单中选择管理节点面板,然后在出现的面板中选择安装标签,这样就可以搜索安装新的节点,并启用或禁用已有节点了。

安装由npm包装的节点

既可以将npm包装的节点安装到保存用户数据的本地目录中(默认为$HOME/.node-red):

cd $HOME/.node-red
npm install 

也可以安装到和Node-RED在一起的全局目录中:

sudo npm install -g 

但是这样你需要重启Node-RED,以便它能够获取到新的节点。

安装单独的节点文件

.js.html文件安装到保存用户数据目录中的nodes子目录,也是安装节点的一个可行方式。如果这些节点中存在一些npm依赖项,那么也必须将其安装到用户数据目录中。但建议只是在开发阶段使用这种方式。

升级

注意: 如果你使用的是Raspian Jessie中的预装版本,请参考升级树莓派的相关说明,使用update-nodejs-and-nodered脚本。

目前,我们建议使用版本为2或3的npm(不建议使用版本4),在升级前,请先运行npm -v检查一下你所安装的版本,如果必要,请运行

sudo npm i -g [email protected]
hash -r

如果你是以全局方式安装的Node-RED,那么可以通过以下指令升级到最新版本:

sudo npm cache clean
sudo npm update -g --unsafe-perm node-red

如果要检查安装到用户目录中的节点是否过期,可以执行:

cd ~/.node-red
npm outdated

执行后,将会列出所有需要升级节点的列表,如需升级,可执行:

npm update              # to update all nodes, or
npm update foo          # to only update a node called foo

升级后,需要暂停并重启Node-RED。

升级NNode.js

如果要升级Node.js,比如从v0.10.x升级到v4.6.x,最好先停用Node-RED,然后按照下面的方式重装:

sudo npm cache clean
sudo npm install -g --unsafe-perm node-red

可能还需要重新编译那些有二进制依赖项的节点,如果你是按建议将它们安装在~/.node-red目录中,那么可以这么做:

cd ~/.node-red
npm rebuild

安装完成后,需要重启Node-RED。


升级Node-RED 0.10.4之前版本

对于0.10.4之前的版本,默认是将用户数据写入Node-RED的安装目录,这使得升级的过程变得非常痛苦。下面我们将带领你,将既有的数据从安装目录中移出。

  1. 首先选择你想用来保存数据的地方,Node-RED 0.10.4的默认存储地址为$HOME/.node-red,你也可以利用--userDir改变这项设置。

  2. 备份整个Node-RED安装目录,以防万一。

  3. 将以下文件从Node-RED安装目录移至你选择的用户数据目录:

    • settings.js - 如果你对它进行了修改

    • 所有以flows_开头的文件

    • .config.json

    • .sessions.json - 如果有这个文件的话

    • 整个lib/目录

    • nodes/下手工安装的所有附加节点

  4. 对于已移动的数据,应确保执行Node-RED的用户对新目录和文件具有相应读写权限。

  5. 删除原有Node-RED安装目录,依照安装说明安装新版本系统。

  6. 如果已经用npm安装了附加节点,或手工复制了其npm依赖项,那么需要重新安装它们。

注意: 之所以要在安装时使用--unsafe-perm选项,是因为当node-gyp尝试重新编译本地代码库时,会以”nobody”身份执行,这就造成在存取某些目录资源时有可能会发生错误,并使得与问题相关的节点无法被正常安装(如serialport)。这一选项可使其在安装期间具有访问特权,确保相关节点在升级过程中能被正确安装。

创建第一个节点

一旦Node-RED运行起来,那么你就可以利用一个本地浏览器,通过http://localhost:1880来访问它。如果你能获得Node-RED实例的ip地址或名称,还可以利用其它机器上的浏览器,通过http://{Node-RED-machine-ip-address}:1880对其进行访问。

1. 加入Inject节点

Inject节点允许你以点击节点按钮(手动)或设置时间间隔(自动)的方式,向流程中注入消息。

从节点面板中向工作区中拖入一个Inject节点。

打开边栏(Ctrl加空格键,或者通过下拉菜单),选择信息标签。

选中新加入的Inject节点,仔细查看其相关功能和属性信息。

2. 加入Debug节点

Debug节点的作用是产生能够显示在调试面板中的消息。默认它只显示消息的载荷部分内容,但也可以通过设定,显示整个消息对象。

3. 连接节点

通过在一个节点的输出端口和另一个节点的输入端口之间拖拽,将Inject和Debug节点连接起来。

4. 部署

此时的节点还只存在于编辑器中,必须将其部署到服务器上。

要做到这点,只需点击一下部署按钮,就可以了。

在选中边栏上调试标签的情况下,点击Inject按钮,应该可以在边栏中看到出现的数字。默认情况下,Inject节点使用自1970年1月1日以来的毫秒数作为消息载荷。接着,我们再增加一下有用的功能。

5. 加入Function节点

Function节点允许你将接受到的消息传递给JavaScript函数。

如果要在Inject和Debug节点之间,连入Function节点,需要先删除已有的连线(选取连线,然后点击键盘上的删除键)。

在Function节点上双击后,将会弹出一个编辑器窗口,将以下代码复制到其中的函数输入区域:

// Create a Date object from the payload
var date = new Date(msg.payload);
// Change the payload to be a formatted Date string
msg.payload = date.toString();
// Return the message so it can be sent on
return msg;

点击确定关闭编辑器窗口,然后再点击部署按钮。

此时,当你点击Inject按钮时,出现在边栏中消息的可读性将明显变好。


源码

本例中创建的流程采用以下json形式表示,我们可以把它们粘贴到导入窗口中,这样就可以直接将流程导入到编辑器中。

[{"id":"58ffae9d.a7005","type":"debug","name":"","active":true,"complete":false,"x":640,"y":200,"wires":[]},{"id":"17626462.e89d9c","type":"inject","name":"","topic":"","payload":"","repeat":"","once":false,"x":240,"y":200,"wires":[["2921667d.d6de9a"]]},{"id":"2921667d.d6de9a","type":"function","name":"Format timestamp","func":"// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = date.toString();\n// Return the message so it can be sent on\nreturn msg;","outputs":1,"x":440,"y":200,"wires":[["58ffae9d.a7005"]]}]

创建第二个流程

这个例子要稍微复杂一些,它将带入来自于外部资源的数据,并实现一些有用的本地化功能。

  • 访问外部Web网站

  • 从中抓取一些信息

  • 读取信息并将其转换为有用形式

  • 以两种格式将信息输出,其一为JSON对象,可供进一步的使用,其二为逻辑值,用于开启和关闭事物。

1. 加入Inject节点

在上一个例子中,我们通过点击Inject按钮来触发整个流程。而对于本例,我们将Inject节点设置为,按固定间隔触发流程。

首先将面板上的Inject节点拖拽到工作区中。

然后双击该节点,在弹出的编辑器窗口中,将重复执行间隔设置为每 5 分钟

点击确定关闭窗口。

2. 加入HttpRequest节点

HttpRequest节点可用于在触发时获取Web页面。

拖入工作区后,将其网址属性设置为:

http://realtimeweb-prod.nationalgrid.com/SystemData.aspx

还可以为其设置一个容易识别的名称。

3. 加入Function节点

加入一个Function节点,并在其中添加以下代码:

// does a simple text extract parse of the http output to provide an
// object containing the uk power demand, frequency and time

if (~msg.payload.indexOf('")[1].split("<")[0]);
    msg.payload.frequency = parseFloat(fre.split(">")[1].split("<")[0]);

    msg2 = {};
    msg2.payload = (msg.payload.frequency >= 50) ? true : false;

    return [msg,msg2];
}
return null;

设Function节点的输出端口数为2

4. 加入Debug节点

添加两个Debug节点。

5. 连接所有节点

  • 把Inject节点的输出端口和HttpRequest节点的输入端口连起来。

  • 把HttpRequest节点的输出端口和Function节点的输入端口连起来。

  • 把Function节点的各输出端口连接到不同Debug节点的输入端口上。

6. 部署

至此,所有节点还都在编辑器里,需要把它们部署到服务器上。

点击部署按钮。

选中调试边栏标签后(Ctrl加空格键,或通过下拉菜单,并点击调试标签),点击Inject按钮,应该可以看到类似下面形式的内容出现:

(Object) { "demand": 34819, "frequency": 50.04 }

而在另一个调试面板中可以看到:

(boolean) true

7. 小结

你现在拥有了一个可以访问互联网信息的流程,能够从中获得英国用电总量的动态数据,并且将其转化为包含demand(单位为兆瓦)和frequency(单位为赫兹)两条属性及数据的JavaScript对象形式

该对象经Function节点的第一个输出端口发出。

频率是一个用于表示总体压力的指标,比如当频率低于50赫兹时,表明整个国家电网有可能处于处于超负荷状态。状态标志信息是通过Function节点的第二个输出端口发出的。如果其载荷值为true,那么就表示电网容量满足要求。


源码

本例所创建的流程将以以下json格式表示。如果把它们粘贴到导入窗口(Ctrl加I键,或通过下拉菜单)中,就可以将流程直接导入到编辑器中。

[{"id":"11b032a3.ee4fcd","type":"inject","name":"Tick","topic":"","payload":"","repeat":"","crontab":"*/5 * * * *","once":false,"x":161,"y":828,"z":"6480e14.f9b7f2","wires":[["a2b3542e.5d4ca8"]]},{"id":"a2b3542e.5d4ca8","type":"http request","name":"UK Power","method":"GET","url":"http://realtimeweb-prod.nationalgrid.com/SystemData.aspx","x":301,"y":828,"z":"6480e14.f9b7f2","wires":[["2631e2da.d9ce1e"]]},{"id":"2631e2da.d9ce1e","type":"function","name":"UK Power Demand","func":"// does a simple text extract parse of the http output to provide an\n// object containing the uk power demand, frequency and time\n\nif (~msg.payload.indexOf('\")[1].split(\"<\")[0]);\n    msg.payload.frequency = parseFloat(fre.split(\">\")[1].split(\"<\")[0]);\n    \n    msg2 = {};\n    msg2.payload = (msg.payload.frequency >= 50) ? true : false;\n\n    return [msg,msg2];\n}\n\nreturn null;","outputs":"2","valid":true,"x":478,"y":828,"z":"6480e14.f9b7f2","wires":[["8e56f4d3.71a908"],["cd84371b.327bc8"]]},{"id":"8e56f4d3.71a908","type":"debug","name":"","active":true,"complete":false,"x":678,"y":798,"z":"6480e14.f9b7f2","wires":[]},{"id":"cd84371b.327bc8","type":"debug","name":"","active":true,"complete":false,"x":679,"y":869,"z":"6480e14.f9b7f2","wires":[]}]

Running under Docker

There are many ways you could choose to run Node-RED under Docker. This guide describe some of the ways you can do it.

It assumes you have some basic familiarity with Docker and the Docker Command Line.

Container versions

We publish three tagged versions of the container to DockerHub:

  • latest - uses official Node.JS v4 base image.

  • slim - uses Alpine Linux base image.

  • rpi - uses RPi-compatible base image.

Using Alpine Linux reduces the built image size (~100MB vs ~700MB) but removes standard dependencies that are required for native module compilation. If you want to add modules with native dependencies, use the standard image or extend the slim image with the missing packages.

Quick start

To run the latest container:

docker run -it -p 1880:1880 --name mynodered nodered/node-red-docker

This command will download the nodered/node-red-docker container from DockerHub and run an instance of it with the name of mynodered and with port 1880 exposed. In the terminal window you will see Node-RED start. Once started you can then browse to http://{host-ip}:1880 to access the editor.

Hit Ctrl-p Ctrl-q to detach from the container. This leaves it running in the background.

To reattach to the container:

docker attach mynodered

To stop the container:

docker stop mynodered

To start the container:

docker start mynodered

Note: your flows will be stored in the file called flows.json within the container. This can be customised by setting the FLOWS environment parameter:

docker run -it -p 1880:1880 -e FLOWS=my_flows.json nodered/node-red-docker

Node.js runtime arguments can be passed to the container using an environment parameter (NODE_OPTIONS). For example, to fix the heap size used by the Node.js garbage collector you would use the following command:

docker run -it -p 1880:1880 -e NODE_OPTIONS="--max_old_space_size=128" nodered/node-red-docker

Customising

The container uses the directory /data as the user configuration directory. To add additional nodes you can open shell into the container and run the appropriate npm install commands:

# Open a shell in the container
docker exec -it mynodered /bin/bash

# Once inside the container, npm install the nodes in /data
cd /data
npm install node-red-node-smooth
exit

# Restart the container to load the new nodes
docker stop mynodered
docker start mynodered

Storing data outside of the container

It is possible to mount the /data path on an external volume:

docker run -it -p 1880:1880 -v ~/node-red-data:/data --name mynodered nodered/node-red-docker

This command mounts the host’s ~/node-red-data directory as the user configuration directory inside the container.

Adding extra nodes to the container can then be accomplished by running npm install on the host machine:

cd ~/node-red-data
npm install node-red-node-smooth
docker stop mynodered
docker start mynodered

Note: Modules with a native dependencies will be compiled on the host machine's architecture. These modules will not work inside the Node-RED container unless the architecture matches the container's base image. For native modules, it is recommended to install using a local shell or update the package.json and re-build.

Building the container from source

The Dockerfiles for these containers are maintained here, each under its own branch.

To build your own version:

git clone https://github.com/node-red/node-red-docker.git
cd node-red-docker

# Build it with the desired tag
docker build -f /Dockerfile -t mynodered: .

Building a custom image

Creating a new Docker image, using the public Node-RED images as the base image, allows you to install extra nodes during the build process.

  1. Create a file called Dockerfile with the content:

     FROM nodered/node-red-docker
     RUN npm install node-red-node-wordpos
  2. Run the following command to build the image:

     docker build -t mynodered: .

That will create a Node-RED image that includes the wordpos nodes.

Updating

Updating the base container image is as simple as

docker pull nodered/node-red-docker
docker stop mynodered
docker start mynodered

Linking Containers

You can link containers “internally” within the Docker runtime by using the --link option.

For example, if you have a container that provides an MQTT broker container called mybroker, you can run the Node-RED container with the link parameter to join the two:

docker run -it -p 1880:1880 --name mynodered --link mybroker:broker nodered/node-red-docker

This will make broker a known hostname within the Node-RED container that can be used to access the service within a flow, without having to expose it outside of the Docker host.

[{"id":"190c0df7.e6f3f2","type":"mqtt-broker","broker":"broker","port":"1883","clientid":""},{"id":"37963300.c869cc","type":"mqtt in","name":"","topic":"test","broker":"190c0df7.e6f3f2","x":226,"y":244,"z":"f34f9922.0cb068","wires":[["802d92f9.7fd27"]]},{"id":"edad4162.1252c","type":"mqtt out","name":"","topic":"test","qos":"","retain":"","broker":"190c0df7.e6f3f2","x":453,"y":135,"z":"f34f9922.0cb068","wires":[]},{"id":"13d1cf31.ec2e31","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":226,"y":157,"z":"f34f9922.0cb068","wires":[["edad4162.1252c"]]},{"id":"802d92f9.7fd27","type":"debug","name":"","active":true,"console":"false","complete":"false","x":441,"y":261,"z":"f34f9922.0cb068","wires":[]}]

用户指南

我们还刚刚起步,会有更多的内容补充进来。

  • 设置Node-RED

  • 安全

  • 日志

  • 命令行管理

  • 使用函数节点

  • 嵌入其他应用

其他帮助渠道

如有问题、建议或者仅仅是想打个招呼,那么可以通过以下方式实现:

  • 订阅邮件列表 以及博客

  • 加入我们的Slack

  • 在推特上关注@nodered

配置

可利用以下属性对Node-RED进行配置。

当作为一个独立程序运行时,这些属性可以从settings.js文件中获得,该文件的存放位置可能为:

  • 通过命令行参数--settings|-s设置

  • 由命令行参数--userDir|-u指定的用户目录

  • 默认用户目录: $HOME/.node-red/settings.js

  • Node-RED安装目录

Node-RED中包含一个默认的settings.js文件,当用户没有提供配置文件,就会使用这个文件。另外,它也可作为你创建自有配置文件的起点,在这里可以找到它的源码。

而当以嵌入式方式运行时,则须通过调用RED.init()传入配置参数。这种方式有可能会使其中的某些属性被忽略,但可以通过所嵌入的程序替代实现。

运行时配置

  • flowFile

    存储流程代码的文件。默认值: flows_.json

  • userDir

    保存用户数据的目录,比如流程、凭证文件以及所有代码库数据等。默认值: $HOME/.node-red

  • nodesDir

    用于寻找已安装附加节点的目录。Node-RED一般会默认搜寻userDir目录下的nodes子目录。该属性允许指定一个额外的目录,这样就可以将节点安装在Node-RED系统之外了。默认值: $HOME/.node-red/nodes

  • uiHost

    用于侦听网络连接的接口设置。默认值: 0.0.0.0 - 所有IPv4接口仅适用于独立运行方式.

  • uiPort

    用于提供编辑器服务的端口。默认值: 1880.仅适用于独立运行方式.

  • httpAdminRoot

    编辑器界面的根网址。如果设置为false, 则所有管理员服务端点将被禁用,包括API端点和编辑器界面。如果想只禁用编辑器界面,请查看后面的disableEditor属性,默认值: /

  • httpAdminAuth

    弃用: 请查看adminAuth。在编辑器界面上启用HTTP基本身份认证:httpAdminAuth: {user:"nol", pass:"5f4dcc3b5aa765d61d8327deb882cf99"} ``pass属性为实际密码的md5哈希值,以下命令可用于产生该数值:node -e "console.log(require('crypto').createHash('md5').update('YOUR PASSWORD HERE','utf8').digest('hex'))"仅适用于独立运行方式.

  • httpNodeRoot

    所有提供提供HTTP服务节点的根网址。如果设置为false,则所有基于节点的HTTP服务端点被禁用。默认值: /

  • httpNodeAuth

    启用HTTP基本身份认证,相关格式参看httpAdminAuth

  • httpRoot

    为管理员和节点服务端口设置共同的根网址,它将覆盖由httpAdminRoothttpNodeRoot所设置的值。

  • https

    启用https,需要指定专门的参数对象,请参看其定义.仅适用于独立运行方式.

  • disableEditor

    如果设为true,将会阻止运行时显示编辑器界面,但管理员应用接口将保持可用。默认值: false.

  • httpStatic

    用于提供静态Web内容服务的本地目录,其中的内容可通过顶级网址/访问。当使用该属性时,必须同时使用httpAdminRoot属性,将编辑器界面指向/以外的其他路径。仅适用于独立运行方式.

  • httpStaticAuth

    对于静态内容启用HTTP基本身份认证,相关格式参看httpAdminAuth

  • httpNodeCors

    enables cross-origin resource sharing for the nodes that provide HTTP endpoints, as defined here

  • httpNodeMiddleware

    an HTTP middleware function that is added to all HTTP In nodes. This allows whatever custom processing, such as authentication, is needed for the nodes. The format of the middleware function is documented here.httpNodeMiddleware: function(req,res,next) { // Perform any processing on the request. // Be sure to call next() if the request should be passed // to the relevant HTTP In node. }

  • logging

    currently only console logging is supported. Various levels of logging can be specified. Options are:

  • fatal - only those errors which make the application unusable should be recorded

  • error - record errors which are deemed fatal for a particular request + fatal errors

  • warn - record problems which are non fatal + errors + fatal errors

  • info - record information about the general running of the application + warn + error + fatal errors

  • debug - record information which is more verbose than info + info + warn + error + fatal errors

  • trace - record very detailed logging + debug + info + warn + error + fatal errors

The default level is info. For embedded devices with limited flash storage you may wish to set this to fatal to minimise writes to “disk”.

Editor Configuration

  • adminAuth

    enables user-level security in the editor and admin API. See security for more information.

  • paletteCategories

    defines the order of categories in the palette. If a node’s category is not in the list, the category will get added to the end of the palette. If not set, the following default order is used:['subflows', 'input', 'output', 'function', 'social', 'storage', 'analysis', 'advanced'],Note: Until the user creates a subflow the subflow category will be empty and will not be visible in the palette.

Editor Themes

The theme of the editor can be changed by using the following settings object. All parts are optional.

editorTheme: {
    page: {
        title: "Node-RED",
        favicon: "/absolute/path/to/theme/icon",
        css: "/absolute/path/to/custom/css/file"
    },
    header: {
        title: "Node-RED",
        image: "/absolute/path/to/header/image", // or null to remove image
        url: "http://nodered.org" // optional url to make the header text/image a link to this url
    },
    deployButton: {
        type:"simple",
        label:"Save",
        icon: "/absolute/path/to/deploy/button/image" // or null to remove image
    },
    menu: { // Hide unwanted menu items by id. see editor/js/main.js:loadEditor for complete list
        "menu-item-import-library": false,
        "menu-item-export-library": false,
        "menu-item-keyboard-shortcuts": false,
        "menu-item-help": {
            label: "Alternative Help Link Text",
            url: "http://example.com"
        }
    },
    userMenu: false, // Hide the user-menu even if adminAuth is enabled
    login: {
        image: "/absolute/path/to/login/page/big/image" // a 256x256 image
    }
},

Dashboard

  • ui

    The home path for the Node-RED-Dashboard add-on nodes can specified. This is relative to any already defined httpNodeRootui : { path: “mydashboard” },

Node Configuration

Any node type can define its own settings to be provided in the file.

  • functionGlobalContext

    Function Nodes - a collection of objects to attach to the global function context. For example,functionGlobalContext: { osModule:require('os') }can be accessed in a function node as:var myos = global.get('osModule');

Note: Prior to Node-RED v0.13, the documented way to use global context was to access it as a sub-property of context:

context.global.foo = "bar";
 var osModule = context.global.osModule;

This method is still supported, but deprecated in favour of the global.get/global.set functions. This is in anticipation of being able to persist the context data in a future release.

  • debugMaxLength

    Debug Nodes - the maximum length, in characters, of any message sent to the debug sidebar tab. Default: 1000

  • mqttReconnectTime

    MQTT Nodes - if the connection is lost, how long to wait, in milliseconds, before attempting to reconnect. Default: 5000

  • serialReconnectTime

    Serial Nodes - how long to wait, in milliseconds, before attempting to reopen a serial port. Default: 5000

  • socketReconnectTime

    TCP Nodes - how long to wait, in milliseconds, before attempting to reconnect. Default: 10000

  • socketTimeout

    TCP Nodes - how long to wait, in milliseconds, before timing out a socket. Default: 120000

安全

默认时,并没有对Node-RED编辑器进行任何保护,也就是说,任何人都可以通过访问其IP地址和端口,使用编辑器功能并改变和部署流程,因此,仅适用于在可信网络中运行的情况。

本章主要讲述如何对Node-RED进行保护,共分两个部分:

  • 编辑器和管理API

  • HTTP节点和静态内容.

编辑器和管理API安全

为在编辑器和管理API部分启用用户身份验证功能,请在你的settings.js文件中加入以下内容:

adminAuth: {
    type: "credentials",
    users: [{
        username: "admin",
        password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
        permissions: "*"
    }]
}

users属性为一个用户对象列表,允许你设定多个用户,并且为其设定不同的权限。

上例设置了一个名为admin的用户,其密码为password,在编辑器中具有全部权限,注意密码是经过加密的。

注意: 在以前发布的Node-RED中,可以通过设置httpAdminAuth启用HTTP基本用户身份验证功能,目前这个选项已被弃用,不应再使用了。

生成密码加密字串

可以利用node-red-admin命令行工具,生成适用的密码加密字串:

node-red-admin hash-pw

这个工具会提示你输入希望使用的密码,然后将生成的字串显示在屏幕上,你将其复制到设置文件中。

另外,你还可以通过在Node-RED安装目录中执行以下命令,实现同样的功能:

node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here

设置默认用户

前面给出的设置会禁止所有未登录的用户访问编辑器。

而在某些情况下,可能需要向未登录的用户开放某些访问权限。比如最典型的,只读访问编辑器的权利等。要做到这点,可以在adminAuth设置项中,针对默认用户加入default属性:

adminAuth: {
    type: "credentials",
    users: [ /* list of users */ ],
    default: {
        permissions: "read"
    }
}

用户权限

对Node-RED 0.14之前的版本,用户只能具有以下两类权限的一项:

  • * - 完全访问

  • read - 只读访问

从Node-RED 0.14开始,可以对权限做细微调整,并且在以前支持的单字串属性基础上,加入对多权限数组的支持。

管理API中的每种方法都定义了不同级别的访问权限,其权限模型是基于资源设计的。比如,为了获取当前流程的设置,用户需要有flows.read权限,但如果想修改流程,则需要有flows.write权限。

令牌期限

默认情况下,访问令牌会在被创建七天后过期,目前我们还不能支持令牌更新和延期功能。

可以通过adminAuth设置项中的sessionExpiryTime属性自行设定过期时间,也就是在多长时间内,令牌是有效的,单位为秒。例如,将令牌设为一天内有效:

adminAuth: {
    sessionExpiryTime: 86400,
    ...
}

访问管理API

管理API文档中讲述了如何通过adminAuth属性来访问API。

自定义用户身份验证功能

除了在设置文件中对用户信息进行硬编码,也可以通过插入代码的方式验证用户身份,这就使得与其它用户认证方式整合成为可能。

以下实例显示了,如何利用一个外部模块,来提供个性化身份验证功能。

  • 将以下代码保存为/user-authentication.js文件

var when = require("when");
module.exports = {
   type: "credentials",
   users: function(username) {
       return when.promise(function(resolve) {
           // Do whatever work is needed to check username is a valid
           // user.
           if (valid) {
               // Resolve with the user object. It must contain
               // properties 'username' and 'permissions'
               var user = { username: "admin", permissions: "*" };
               resolve(user);
           } else {
               // Resolve with null to indicate this user does not exist
               resolve(null);
           }
       });
   },
   authenticate: function(username,password) {
       return when.promise(function(resolve) {
           // Do whatever work is needed to validate the username/password
           // combination.
           if (valid) {
               // Resolve with the user object. Equivalent to having
               // called users(username);
               var user = { username: "admin", permissions: "*" };
               resolve(user);
           } else {
               // Resolve with null to indicate the username/password pair
               // were not valid.
               resolve(null);
           }
       });
   },
   default: function() {
       return when.promise(function(resolve) {
           // Resolve with the user object for the default user.
           // If no default user exists, resolve with null.
           resolve({anonymous: true, permissions:"read"});
       });
   }
}
  • 在settings.js的adminAuth属性中加载该模块:

adminAuth: require("./user-authentication");

HTTP节点安全

HTTP In节点对外提供的访问路径可以通过基本身份验证的方式加以保护。

settings.js文件的httpNodeAuth属性中,可以单独设定访问该路径的用户名和密码。

httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},

pass属性所使用的格式与adminAuth相同,详情见生成密码加密字串。

对于httpStatic属性中设定的静态内容的安全防护,可以通过httpStaticAuth属性实现,其格式也基本相同。

注意: 在以前版本的Node-RED中,pass属性采用了MD5加密方式, 因为它不够安全,所以采用了adminAuth所使用的加密方式来替代它。但为了保持兼容,MD5仍被支持,只是不建议再使用。

Logging

By default, Node-RED uses a logger that writes its output to the console. It also supports the use of custom logger modules to allow the output to be sent elsewhere.

Console logger

The console logger can be configured under the logging property in settings.js.

// Configure the logging output
logging: {
    // Console logging
    console: {
        level: "info",
        metrics: false,
        audit: false
    }
}

There are 3 properties used to configure the logger’s behaviour:

level

Level of logging to be recorded. Options are:

  • fatal - only those errors which make the application unusable should be recorded

  • error - record errors which are deemed fatal for a particular request

  • warn - record problems which are non fatal

  • info - record information about the general running of the application

  • debug - record information which is more verbose than info

  • trace - record very detailed logging

  • off - no log messages at all

Other than off, each level includes messages at higher levels - for example, warn level will include error and fatal level messages.

metrics

When set to true, the Node-RED runtime outputs flow execution and memory usage information.

Received and sent events in each node are output into the log. For example, the following logs are output from the flow which has inject and debug nodes.

9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"8bd04b10.813f58","event":"node.inject.receive","msgid":"86c8212c.4ef45","timestamp":1489067873391}
9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"8bd04b10.813f58","event":"node.inject.send","msgid":"86c8212c.4ef45","timestamp":1489067873392}
9 Mar 13:57:53 - [metric] {"level":99,"nodeid":"4146d01.5707f3","event":"node.debug.receive","msgid":"86c8212c.4ef45","timestamp":1489067873393}

Memory usage is logged every 15 seconds.

9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.rss","value":97517568,"timestamp":1489067784815}
9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.heapTotal","value":81846272,"timestamp":1489067784817}
9 Mar 13:56:24 - [metric] {"level":99,"event":"runtime.memory.heapUsed","value":59267432,"timestamp":1489067784817}

audit

When set to true, the Admin HTTP API access events are logged. The event includes additional information such as the end point being accessed, IP address and time stamp.

If adminAuth is enabled, the events include information about the requesting user.

9 Mar 13:49:42 - [audit] {"event":"library.get.all","type":"flow","level":98,"path":"/library/flows","ip":"127.0.0.1","timestamp":1489067382686}
9 Mar 14:34:22 - [audit] {"event":"flows.set","type":"full","version":"v2","level":98,"user":{"username":"admin","permissions":"write"},"path":"/flows","ip":"127.0.0.1","timestamp":1489070062519}

Custom logging module

A custom logging module can also be used. For example, the metrics output may get sent to a separate system for monitoring the performance of the system.

To use a custom logger, edit settings.js to add a new block in the logging section.

// Configure the logging output
logging: {
    // Console logging
    console: {
        level: "info",
        metrics: false,
        audit: false
    },
    // Custom logger
    myCustomLogger: {
        level: 'debug',
        metrics: true,
        handler: function(settings) {
            return function(msg) {
                console.log(msg.timestamp, msg.event);
            }
        }
    }
}


The `level`, `metrics` and `audit` properties are the same as console logging.

The `handler` property defines the custom logging handler. It is a function that
is called once at start-up, passing in the logger's configuration. It must
return a function that will get called with log messages.

Multiple custom loggers can be configured - the only reserved name is `console`.

#### Example logger

The following example adds a custom logger that sends metrics events to a logstash
instance over a TCP connection.

It is a very quick and simple example - with no error handling or reconnect logic.

~~~~~js
logging: {
    console: {
        level: "info",
        metrics: false,
        audit: false
    },
    logstash: {
        level:'off',
        metrics:true,
        handler: function(conf) {
            var net = require('net');
            var logHost = '192.168.99.100',logPort = 9563;
            var conn = new net.Socket();
            conn.connect(logPort,logHost)
                .on('connect',function() {
                    console.log("Logger connected")
                })
                .on('error', function(err) {
                    // Should attempt to reconnect in a real env
                    // This example just exits...
                    process.exit(1);
                });
            // Return the function that will do the actual logging
            return function(msg) {
                var message = {
                    '@tags': ['node-red', 'test'],
                    '@fields': msg,
                    '@timestamp': (new Date(msg.timestamp)).toISOString()
                }
                try {
                    conn.write(JSON.stringify(message)+"\n");
                }catch(err) { console.log(err);}
            }
        }
    }
}

命令行管理

通过node-red-admin命令行工具,可以实现对node-red实例进行远程管理的功能。

安装

以全局方式安装node-red-admin,可以在任意路径中调用工具指令:

npm install -g node-red-admin

注意: sudo仅针对Linux/OS X中的非root用户,如果运行系统为Windows,则需要以系统管理员身份执行命令行指令,而无需使用sudo命令。

目标和登录

首先,必须将工具指向欲访问的Node-RED实例,默认为http://localhost:1880,可通过target命令改变该默认值:

node-red-admin target http://node-red.example.com/admin

如果启启用了用户身份验证功能,那么还必须执行login:

node-red-admin login

这些指令会创建一个名为~/.node-red/cli-config.json的文件,其中保存了访问目标和令牌的相关信息。

其他指令

该工具提供了以下指令:

  • list - 列出所有已安装节点

  • info - 显示模块或节点信息

  • enable - 启用指定模块或节点

  • disable - 禁用指定模块或节点

  • search - 搜索NPM中Node-RED模块

  • install - 从NPM中安装模块

  • remove - 移除NPM模块

  • hash-pw - 创建adminAuthhttpNodeAuth中使用的密码加密字串

编写函数

函数节点可以让我们使用JavaScript对传入的消息进行处理,然后返回多条消息,以使流程继续执行。

传入的消息一般以对象形式表示,其名称为msg,通常都会包含一个msg.payload属性,用来保存消息的主体内容。

其它类型的节点可能会在消息中附加其他专有属性,并且会在文档中加以详细说明。

  • 编写函数

  • 多输出端口

  • 多条消息

  • 异步消息

  • 记录事件

  • 处理错误

  • 存储环境数据

    • 流程环境

    • 全局环境

  • 增加状态

  • 其他模块及函数

编写函数

输入函数节点的代码实际是JavaScript函数的主体部分,最简单的功能就是直接将收到的消息返回:

return msg;

如果函数返回null,那么就意味着没有消息传出,流程将被终止。

返回的消息对象不必于传入的对象保持一致,函数可以构建一个完全不同的新返回对象,比如:

var newMsg = { payload: msg.payload.length };
return newMsg;

注意: 构造一个全新的消息对象,有可能会丢失所接收消息的所有属性,并且造成某些流程中断。比如对于使用HTTP In/Response的流程而言,要求msg.reqmsg.res在端到端的传输过程中一致保留。通常情况下,函数节点应该返回它们所接收到的完整消息对象,只改变其中的某些特性。

多输出端口

函数编辑器允许对输出端口数量进行修改。如果需要多个输出,那么可以通过返回一个消息数组,实现多端口传输功能。

这使得根据特定条件向不同端口发送消息成为可能。比如,以下函数中,将会把主题为banana的消息发往第二个端口:

if (msg.topic === "banana") {
   return [ null, msg ];
} else {
   return [ msg, null ];
}

以下例子则会将原始消息发往第一个端口,而把包含载荷长度的消息发往第二个端口:

var newMsg = { payload: msg.payload.length };
return [msg, newMsg];

多条消息

函数可以在结果数组中,以消息数组的方式输出多条消息。当多条消息被发往一个输出端口时,后续的节点将按照消息的排列顺序依次进行接收。

下例中的msg1msg2msg3将发向第一个端口,msg4则发往第二个输出端口。

var msg1 = { payload:"first out of output 1" };
var msg2 = { payload:"second out of output 1" };
var msg3 = { payload:"third out of output 1" };
var msg4 = { payload:"only message from output 2" };
return [ [ msg1, msg2, msg3 ], msg4 ];

以下的代码将接收到的载荷分解为词,然后按词逐条发送。

var outputMsgs = [];
var words = msg.payload.split(" ");
for (var w in words) {
    outputMsgs.push({payload:words[w]});
}
return [ outputMsgs ];

异步消息

如果函数需要在发出消息前执行一个异步动作,那么就无法在其结束的部分立即返回消息。

解决的办法是,利用node.send()函数,将传入的消息发送出去。比如:

doSomeAsyncWork(msg, function(result) {
    node.send({payload:result});
});
return;

如果在函数中使用了异步的回调代码,那么当流程重新部署时,可能需要对一些未处理的请求进行清理,或者,关闭所有的连接,这些都可以通过加入一个close事件处理器来实现。

node.on('close', function() {
    // 此处为清理异步事件、关闭连接等的代码
});

日志事件

如果需要将节点的有关信息以日志方式输出到控制台,那么可以通过以下函数实现:

node.log("Something happened");
node.warn("Something happened you should know about");
node.error("Oh no, something bad happened");

warnerror等信息也会被发往流程编辑器中的调试面板。

处理错误

函数执行过程中,如果遇到有可能造成流程停止的错误时,将不会返回任何结果。为了能够触发同一个标签面板中的Catch节点,函数应该调用node.error,并且将原始消息作为其第二个参数:

node.error("hit an error", msg);

保存数据

msg对象外,函数还可以将数据保存在context对象中。

以下实例实现了函数执行次数的保存功能:

// 如果计数器不存在则将其初始化为0
var count = context.get('count')||0;
count += 1;
// 保存数据
context.set('count',count);
// 将其作为输出消息的一部分
msg.count = count;

默认情况下,当Node-RED重启时,环境数据并不能被持久保存。

注意: 在Node-RED v0.13以前版本的文档中,是直接通过context访问环境数据的:

var count = context.count;

虽然这种方法目前仍被支持,但不赞成继续使用。为保证在今后的版本中,数据持久化相关功能仍然有效,建议使用context.get/context.set函数。

流程环境

在Node-RED 0.13以上版本中,只有context对象是作用于节点本地范围的,另有一个流程级别的环境对象可以实现同面板所有节点间数据分享,而不是只对Function节点,它是通过flow对象来访问的:

var count = flow.get('count')||0;
全局环境

There is also a global context available that is shared by, and accessible to all nodes. For example to make the variable foo available globally across the canvas: 还有一个全局环境对象,可以被所有节点访问。比如下面的变量foo能被全局访问到:

global.set("foo","bar");  // this is now available to other nodes

并且通过.get读取其保存的数值。

var myfoo = global.get("foo");  // this should now be "bar"

也可以在Node-RED启动时,用对象对全局环境进行预填充,这项功能是通过主settings.js文件中的functionGlobalContext项来设置的。

比如,为使所有函数都能访问预置的os模块:

functionGlobalContext: {
    osModule:require('os')
}

此时,该模块就能以global.get('osModule')方式被引用了。

如果需要引用外部模块,必须首先利用npm将其手动安装到用户目录中。

cd ~/.node-red
npm i name_of_3rd_party_module_to_be_required

注意: 在Node-RED v0.13以前版本文档中,是通过context的子对象属性来访问全局环境的:

context.global.foo = "bar";
var osModule = context.global.osModule;

虽然该方法仍然适用,但建议用global.get/global.set替代它们,因为以这种方式所保存的数据会在未来版本中一直可用。

增加状态

函数节点也可以像其他节点那样,为自身提供状态装饰功能。如果要设置状态,需调用node.status函数。例如

node.status({fill:"red",shape:"ring",text:"disconnected"});
node.status({fill:"green",shape:"dot",text:"connected"});
node.status({text:"Just text status"});
node.status({});   // to clear the status

详细参数说明参见节点状态文档

任何状态变化都能被Status节点(需Node-RED v0.12以上版本)所捕获。

其他模块及函数

Function节点还能使用以下模块及函数:

  • Buffer - Node.js的Buffer模块

  • console - Node.js的console模块(node.log是首选的日志方法)

  • util - Node.js的util模块

  • setTimeout/clearTimeout - JavaScript的timeout函数

  • setInterval/clearInterval - JavaScript的interval函数

注意: 无论何时,当流程停止或重新部署时,函数节点都会自动清除未完成的超时或间隔计时对象。

嵌入现有应用

将Node-RED嵌入一个大型的应用程序,技术上是可行的。典型的场景是,你利用Node-RED来生成数据流,并将其呈现到Web面板上,你希望所有这些功能都出自一个程序。

首先要在应用的package.json中,像加入其它独立模块那样,加入node-red依赖项。

以下为在Express应用中嵌入运行时的最小示例。

var http = require('http');
var express = require("express");
var RED = require("node-red");

// Create an Express app
var app = express();

// Add a simple route for static content served from 'public'
app.use("/",express.static("public"));

// Create a server
var server = http.createServer(app);

// Create the settings object - see default settings.js file for other options
var settings = {
    httpAdminRoot:"/red",
    httpNodeRoot: "/api",
    userDir:"/home/nol/.nodered/",
    functionGlobalContext: { }    // enables global context
};

// Initialise the runtime with a server and settings
RED.init(server,settings);

// Serve the editor UI from /red
app.use(settings.httpAdminRoot,RED.httpAdmin);

// Serve the http nodes UI from /api
app.use(settings.httpNodeRoot,RED.httpNode);

server.listen(8000);

// Start the runtime
RED.start();

当使用这种方式时,Node-RED中的settings.js文件将不再起作用。取而代之的是,像上面的代码那样,将配置信息通过调用RED.init传入。

更进一步,以下配置项也将被忽略,因为它们都可以通过Express实例配置实现:

  • uiHost

  • uiPort

  • httpAdminAuth

  • httpNodeAuth

  • httpStatic

  • httpStaticAuth

  • https

你可能感兴趣的:(node.js,arm,网关,red,redis)