Node-Red自定义节点(Node)

在使用Node-Red的过程中,总有一些节点是无法满足需求,或者通用方法复用率高的想直接转化为节点的,这时就会用到自定义节点这个功能。
Node-Red是一个基于Node开发的框架工具,所以为她开发的节点都要遵从于Node开发的模式。比如说,我们需要npm init生成package.json,需要npm publishnpm install 等,但是又跟纯的Node Package又有些许不同,因为是给Node-Red开发的package,所以在package.json中需要加上Node-Red的标识。自定义Node-Red的Node大致可以分为三部分,1.创建package.json、2.创建js、3.创建html
我这里的自定节点方法是:根据对象的属性名称以及属性值获取对象,所以首先创建文件夹node-red-get-value-by-prop

mkdir node-red-get-value-by-prop && cd node-red-get-value-by-prop

执行初始化

npm init

执行操作之后就得到了package.json文件了

step 1 修改package.json

{
  "name": "node-red-get-value-by-prop",
  "version": "1.0.0",
  "description": "node red tool get value by prop",
  "main": "get-value-by-prop.js",
  "node-red": {
    "nodes": {
      "get-value-by-prop": "get-value-by-prop.js"
    }
  },
  "scripts": {
   
  },
  "author": "jonathan",
  "license": "ISC"
}

看到这里可以发现不同点,就是添加了node-red标识,以及节点名称和节点路径值等。

step 2 创建js

在同路径下创建package.jsonnodes对象的js文件,我们这里命名为get-value-by-prop.js并且填写以下内容:

module.exports = function (RED) {
    function _getValByProp(data, prop, propVal, r) {
        r = r ? r : { status: false };
        if (data && data.hasOwnProperty(prop) && data[prop] == propVal) {
            r.status = true;
            r.result = data;
            return r;
        }
        for (var i in data) {
            if (data && typeof data[i] == "object" && null !== data[i]) {
                var r = _getValByProp(data[i], prop, propVal, r);
                if (r.status) return r;
            }
        }
        return r;
    }
    function getValByProp(config) {
        RED.nodes.createNode(this, config);
        var node = this;
        this.prop = config.prop;
        this.propVal = config.propVal;
        node.on("input", function (msg) {
            var data = msg.payload || {};
            msg.payload = _getValByProp(data,this.prop,this.propVal);
            node.send(msg);
        });
    }
    RED.nodes.registerType("get-value-by-prop", getValByProp);
}

看到这里,首先Node由构造函数定义,可用于创建Node的新实例。 该函数在运行时注册,因此可以在Flow中部署相应类型的Node时调用它。
该函数被传递一个包含在Flow编辑器中设置的属性的对象。
它必须做的第一件事是调用 RED.nodes.createNode 函数来初始化所有Node共享的特征。 之后,自定义Node的代码就创建好了。
当然这里如果想让写法更高级一点可以改成es6的class,这样写类构造函数会更加优雅,比如你可以把代码修改成这样:

module.exports = function (RED) {
    function _getValByProp(data, prop, propVal, r) {
        r = r ? r : { status: false };
        if (data && data.hasOwnProperty(prop) && data[prop] == propVal) {
            r.status = true;
            r.result = data;
            return r;
        }
        for (var i in data) {
            if (data && typeof data[i] == "object" && null !== data[i]) {
                var r = _getValByProp(data[i], prop, propVal, r);
                if (r.status) return r;
            }
        }
        return r;
    }
    class getValByProp {
        constructor(config) {
            RED.nodes.createNode(this, config);
            var node = this;
            this.prop = config.prop;
            this.propVal = config.propVal;
            node.on("input", function (msg) {
                var data = msg.payload || {};
                msg.payload = _getValByProp(data, this.prop, this.propVal);
                node.send(msg);
            });
        }
    }
    RED.nodes.registerType("get-value-by-prop", getValByProp);
}

接收消息

Node在输入事件上注册一个侦听器,以接收来自流中上游Node的消息。

this.on('输入', function(msg) {
     // 用 'msg' 做点什么
});

发送消息

Node可以使用 send 函数将消息发送到流中的下游Node:

var msg = { payload:“hi”}
this.send(msg);

如果 msg 为空,则不发送任何消息。

step 3 创建html

自定义Node .html文件定义了节点在编辑器中的显示方式。 它包含三个不同的部分,每个部分都包含在自己的

这里需要注意,inputidlabel for 前缀固定为node-input,后缀为defaults对象中的值。data-template-namedata-help-name,以及RED.nodes.registerType注册的方法名都要统一为上面js注册的名称。

step 4 install Node

经过上述的操作我就基本完成了Node-Red的自定义节点。接下来就是安装自定义的节点。

  • 找到自定义节点的路径,以我本地的为例,执行pwd,得到路径为
$ pwd
/Users/dev/Documents/workspace/node-red-package/node-red-get-value-by-prop
  • 找到安装Node-Red的路径下执行
$ cnpm install ~/Documents/workspace/node-red-package/node-red-get-value-by-prop --no-save

执行成功后会得到以下输出

$ cnpm install ~/Documents/workspace/node-red-package/node-red-get-value-by-prop --no-save
✔ Installed 1 packages
✔ Linked 1 latest versions
✔ Run 0 scripts
✔ All packages installed (1 packages installed from local file, used 202ms(network 201ms), speed 0B/s, json 0(0B), tarball 0B, manifests cache hit 0, etag hit 0 / miss 0)

这时我们重启服务,在Node-Red的编辑界面就可以看到对应的自定义节点了。


自定义节点

step 5 测试自定义节点

  • 见自定义模板拖到编辑中,编辑内添加测试数据


    编辑自定义节点
  • 添加inject节点和debug节点


    测试节点
  • 在inject节点添加数据


    测试数据
  • 部署控制台输出


    测试数据输出

总结

这样一个完整的自定义节点例子就完成了,总结一下其实还是挺容易的,至少保持思路明确,主要步骤就是这些。当然这个例子很简单,如果要实现复杂的程序的话还是有难度的。

你可能感兴趣的:(Node-Red自定义节点(Node))