一、Node-Red是什么?
(一)Node-Red是IBM公司开发的一个可视化的编程工具。它允许程序员通过组合各部件来编写应用程序。这些部件可以是硬件设备(如:Arduino板子)、Web API(如:WebSocket in和WebSocket out)、功能函数(如:range)或者在线服务(如:twitter)。
(二)Node-Red提供基于网页的编程环境。通过拖拽已定义node到工作区并用线连接node创建数据流来实现编程。程序员通过点击‘Deploy’按钮实现一键保存并执行。程序以JSON字符串的格式保存,方便用户分享、修改。
(三)Node-Red基于Node.js,它的执行模型和Node.js一样,也是事件驱动非阻塞的。理论上,Node.js的所有模块都可以被封装成Node-Red的一个或几个node。
二、Node-Red的结构框架
(一)Node-Red由两部分组成。一部分是用户可见的数据流的编辑界面,另一部分是数据流的执行。
(二)数据流的编辑界面由四部分组成。最左边是已定义的各种node的列表;中间是一个工作区,用户可以拖放node到工作区来创建node的实例,Node-Red为每个node实例赋予了唯一的ID,通过双击node实例来编辑单个实例,通过连接node的in和out口创建数据流,node实例会记录out口连线的信息,每条线会记录目标node实例的信息;最右边是debug node的输出区及node的帮助信息显示区。右上角有‘Deploy’按钮,用来把编写的程序保存到本地并执行。
(三)数据流的执行。通过读取用户编辑的数据流信息,可以知道node的类型及可编辑部分的值,据此来创建node的可执行实例;通过读取编辑时连线的信息,可以得到可执行实例间的数据关系,实例间的数据发送和接受是利用Node.js的event模块实现的。
三、如何执行Node-Red?
(一)在Node-Red的根目录下,执行‘node red.js’。
(二)打开浏览器访问http://localhost:1880,就可以看到Node-Red的编辑界面。
(三)Node-Red编辑完成的数据流默认保存在flows_
四、Node-Red可配置的选项
(一)编辑界面的选项:数据流保存的文件名字,浏览器访问Node-Red的端口等,一般情况下这些配置都不需要修改。
(二)Node的选项:functionGlobalContext (在函数间可见的变量集合,是全局变量,主要用于保存函数的执行状态)等。
五、如何创建一个Node-Red的node?
(一)为了保证所创建的Node能够提供一致的用户体验,Node-Red官网上列出了一些创建Node的原则。有一条需要格外注意,它要求创建的Node要对各种类型的输入数据进行必要的处理,即使某些类型并不是这个Node所需要的。
(二)一个Node-Red的node节点包括两个文件:一个.html模板文件,一个.js可执行文件。由于Node-Red在识别和处理node的时候使用了大量的字符串匹配操作,所以在node的定义中有一些名字的字符串是必须保持一致的,否则Node-Red在解析的时候就会出错。
(三)文件的命名采用‘数字-名字.html’和‘数字-名字.js’的规则,例如:16-range.html和16-range.js。 两个文件名字除了后缀不一样,其他的必须一样。
(四).html文件分为3部分:node的定义,node的编辑模板和node的帮助信息。Node的定义主要用于:确定node的类型,可编辑的属性,在浏览器中显示的样式,是一段可执行的js代码,RED.nodes.registerType;编辑模板主要是生成用户编辑该node的实例时的界面(由data-template-name包括的一段HTML代码),用户的输入最终会保存在node的定义中;
(五)在.html文件中,data-template-name、node-input-xx、data-help-name都是Node-Red系统保留字。data-template-name、data-help-name的值必须和文件名字的name部分一致。RED.nodes.registerType的第一个参数也必须和文件名字的name部分一致。
(六)每个Node的可编辑的域在defaults中声明,data-template-name所包含的node-input-xx负责生成输入框。defaults的每个域的名字必须和node-input-xx中的名字保持一致。在.js文件中使用可编辑域的值的时候,直接访问defaults的域就可以,不必添加defaults前缀。
(七)label是node在编辑工作区显示的名字。
(八)inputs表示node可以接收的输入的个数,目前仅支持<=1
(九)outputs表示node提供的输出的个数,>=0
(十)
(十一)在.js文件中,RED.nodes.registerType用来注册一个node实例的生成函数,它的第一个参数必须和文件名字的name部分一致。传给生成函数的参数是node可编辑域的值(已编辑完成)及node共享域的值。
(十二)input的callback是node输入的处理函数。需要注意的是,Node-Red节点间数据传输使用的是名字为payload的域,这个也是Node-Red系统保留的。
(十三)
六、一个数据流的实例。
(一)[{"type":"tab","id":"2626a1cb.d9d95e","label":"Sheet 1"},{"id":"afc91f2.f5036e","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":110,"y":110,"z":"2626a1cb.d9d95e","wires":[["181f5786.e7e0a8"]]},{"id":"181f5786.e7e0a8","type":"debug","name":"","active":true,"console":"false","complete":"false","x":346,"y":107,"z":"2626a1cb.d9d95e","wires":[]}]
(二)这个数据流包含一个inject节点和一个debug节点。id是由系统生成的实例的唯一标示。每个实例包含所有的可编辑域的值。x和y表示节点实例在编辑区的位置坐标,z表示制表。wires是节点间的数据流,值为节点输出的目标节点。
七、在Smart_Mug上使用node-red示例,一个文本输入node,一个显示node,一个摄像头node。
(一)116-mugTextInput.html,接受一个输入inputFile,节点监控文件inputFile,当文件改变的时候,把文件内容作为payload输出,并清空文件等待新的输入;
(二)
(三)117-mugDisplay.html,接受一个输入color,表示在smart_mug上显示文字的颜色,默认为red;当收到从其他节点(mugTextInput)输入的文本后,立刻显示在杯子上。目前的实现虽然用户可以输入颜色选项,但是实际并没有实现颜色变化,只能显示红色的字。这个比较容易实现,可以让新手来练习。
(四)
(五)把上述flow部署到Smart_mug上后,改变文件/home/root/node-red/input的内容,文本内容就会显示在Smart_mug上。
(六)测试
1.杯子上滚动显示”intel labs china”;
2.
3.改变/home/root/node-red/input的内容为”node-red on mug”,保存退出vi,杯子上立即显示新的文本;
4.
(七)118-mugCamera.html。Action选项,选择是输出视频文件还是图片文件。如果是视频文件,输入文件绝对路径、名字及时长(秒),还可以继续增加其他选项,如:分辨率等;如果是图片文件,需要输入文件的绝对路径及名字,同样也可以增加其他选项,如:分辨率,亮度,对比度,饱和度,间隔几秒抓一张图片。该节点不输入,有一个输出。当文件生成结束后,会把文件名字输出给其他节点,供其他节点读取文件做处理。
(八)118-mugCamera.js。后台使用的是32-bit的uvccapture和streamer来抓取图片和视频。在使用前要先配置好uvccapture和streamer在edison上的运行环境,主要是一些库文件要拷贝到edison上,包括libcrypto.so,libdv.so.4,libexplain.so.30,libexplain.so.30.20.0,libssl.so,libv4l2.so.0,libv4lconvert.so.0。
(九)
八、下面是Node-Red的代码分析,对想深入理解及利用Node-Red做点其他东西的同学比较有用。MCF是一个基于Node-Red的多设备间互连互通互操作的平台,源代码https://github.com/ilc-opensource/mcf.git。
九、
十、public目录:编辑node并创建flow
(一)public/index.html, node、flow和subflow的编辑界面
1.工作区左边的palette,
2.public/red/ui/palette.js,动态生成一级分类标签core,MCF利用这里插入device和flow标签;
3.MCF采用更严格的部署前检查。如果发现问题,不允许用户进行部署;
4.增加devList.js和flowList.js,分别用来管理编辑界面的device和flow两个一级分类标签。
(二)public/red/devList.js, add by MCF
1.Connect to local WebSocket server to get found device info, {id:, name:}
(三)public/red/flowList.js, add by MCF
1.Called by node editor to create and delete flows of MCF. When user edits flow attribute of a instance of node, undo add or delete action of a node instance, and import a flow, flow must be updated immediately.
(四)public/red/history.js
1.处理node编辑中的undo操作,更新flowList信息
(五)public/red/main.js
1.当点击Deploy按钮的时候调用save(),把相关的node和target device的信息发送给local WebSocket server,ajax ”POST flows”。
2.由于要把一个flow分解成多个subflow,然后把subflow部署到不同的设备上。相对于原来只能把整个flow部署到本地,要对部署进行一些限制以防止用户误操作,例如:1) Can’t deploy one flow to two or more different devices; 2) Save the deploy info to flows_
(六)public/red/nodes.js
1.Add “flow” attribute to each node instance, update its shown label, add onflowupdate to update flowList when changing a node
2.Only push node of the selected flow to the local WebSocket server, then to the target device. For security, only the deploy device owns the whole flow, other devices only own their sub part of the whole flow.
十一、red目录:启动后台服务和部署执行
(一)启动后台服务的流程,red/server.js start() red/nodes/index.js load()red/nodes/registry.js load() load all palette nodes through scanning some directories
(二)red/nodes/registry.js load()
1.getNodeFiles,返回包含目录下所有.js文件名字的一个数组
2.所有palette nodes的js文件传进的参数是red/red.js中的RED,会分别执行一下各个js文件中的函数。
(三)red/comms.js,用于node-red本身及debug node,没有其他用处.
(四)MCF增加的分布式部署的支持
1.deviceServer.js,remote device的统一接口。
2.activeConnections保存所有active的设备间连接,用于向所有已连接设备广播查找某个node的消息。
3.pendingMsg是所有没有发送出去的消息。之所以没有发送是因为没有找到目标node所在的设备。
4.nodeIdToConnection用于向包含指定node的设备发送消息。
5.devToConnection用于发送要部署的subflow。
6.send,当本地设备上没有目标node的时候,调用该send尝试查找node并发送信息到node所在的设备,然后有设备分发给node。
7.oneToOne,已经找到目标node所在的设备,直接向该设备发送消息。
8.broadcast,向所有已连接设备发送消息来查找哪个设备上有指定的node。
9.ownNode,向请求节点发送消息告知它该设备有它要查找的node,请求节点更新nodeIdToConnection。
10.deploy,收到要部署的本地的subflow。
11.channel,告知本地该channel对应的是哪个远端设备。
12.protocol,各个具体协议的device server,目前仅实现了WebSocket协议,计划中的有BT和MQTT。
13.WebSocket server除了作为远端设备连接到本地外,还负责为浏览器更新device list。
14.discovery.js,生成本地device的信息,各种device discovery交换的设备信息均来自这个device object,它必须是一个可以转换为JSON字符串的object。
15.当发现新设备时,就尝试调用protocol下的各个协议的connection函数,建立连接。目前都是直接连接,将来将支持类似路由的间接连接。连接建立成功后,首先发送当前设备的ID给远端,以便建立devToConnection。
16.localDev.js,生成本地设备唯一的ID。
17.device object数据结构:
(1)id: 一个全网唯一的一个字符串;
(2)name: 一个用户可读的字符串,当前使用os.hostname,
(3)ip[]: IPV4。如果设备拥有多个不是127.0.0.1的IP,要把所有的IP都包含进来。
(4)BT和MQTT的支持。
十二、red/api/index.js,flow的编辑和执行的传输接口
(一)用到最多的是adminApp.post("/nodes",nodes.post);,它把编辑完成的flow发送给后台保存并执行。
十三、nodes: 所有Node-Red自带的node的定义
关于:中科研拓
深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,通过IT技术实现创造客户和社会的价值,成为优秀的软件公司,通过客户需求导向、开放式创新、卓越运营管理等战略的实施,全面打造公司的核心竞争力。很好软件开发公司,联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com