node-red - 节点实战总结

本文围绕Node-RED展开,介绍了其多种功能,包括循环(for/while)的三种实现方式;网络方面有mqtt、http相关节点;存储涉及文件、MySQL、redis、TDEngine的存/取;还介绍了modbus、opcua等协议,以及时间格式化、定时器输入和缓冲区解析等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1

二、功能

2.1 循环(for\while)

1
  安装节点node-red-contrib-loop-processing,该节点支持三种方式的循环:

  • array-loop:数组循环,功能类似于数组的forEach或for循环,但此节点无法处理关联的数组,使用示例如下
    1
  • counter-loop:使用计数器循环。相当于for(int i=s;i<length;i+n)循环,支持设置指定下标、指定递增值、指定循环结束点。
    2
  • while-loop:使用条件循环。相当于while循环。
    3
    回到目录

三、网络

3.1 mqtt in\out

1
  安装节点node-red ,将提供与mqtt互联的节点mqtt in 和 ,mqtt out详细使用参考链接:

回到目录

3.2 httpin/http response/http request

  安装节点node-red ,将提供用于Web服务交互的HTTP端点操作。包含http in、http response、http request,详细使用参考链接:

回到目录

六、存储

6.1 write/read/watch file

1
  安装节点node-red ,将提供用于文件的读\写\删除\增加操作。详细使用参考链接:
file控件介绍

回到目录

6.2 MySQL存/取

1
  安装节点node-red-contrib-stackhero-mysql ,用于读取和写入MySQL或MariaDB数据库。
它使用TLS(SSL)加密,并且与“缓存SHA2密码”身份验证方法兼容(MySQL> = 8)。
  使用时,先创建或选择一个数据库实例,并设置名称。
1
创建数据库实例操作如下:
1
  通过function中的topic和payload对数据库进行增\删\改\查操作,详细如下实例:

  • select:查询操作
    1
  • insert:插入操作
  1. 单条插入:
    (1)不使用payload传入,直接使用topic中sql表示语句
    1
    (2)使用payload传入,在使用topic的sql语句中创建变量,注意变量与payload的object的key要保持一致。
    1
  2. 批量插入:
    1

6.3 redis存/取

1
  安装节点node-red-contrib-redis ,用于与redis数据库的交互。使用参考链接:
Node-RED 读写操作redis

回到目录

6.4 TDEngine存/取

1
  安装节点node-red-contrib-tdengine ,用于与TDEngine数据库的交互。

  1. 数据查询
    1
  2. 多表插入语句
    2
  3. 删除语句
    3

七、协议

7.1 modbus

1
  安装节点node-red-contrib-modbus ,用于向ModbusTCP设备写数据或读取ModbusTCP设备数据。使用参考链接:
Node-RED采集modbus数据

  • 注意:node-red通过modbus协议采集时,端口不能在0-100以内,node-red会出问题

回到目录

7.2 opcua - (abplc)

1
  安装节点node-red-contrib-opcua ,基于OPC UA与西门子PLC进行通讯。比如对于AB协议的PLC,node-red暂时不支持直接进行通讯,需要先通过OPC UA服务器与客户端进行通信,然后node-red与OPC UA的进行通讯,从而达到数据管理的目的。使用参考链接:
Node-RED opc-ua节点操作

回到目录

7.3 s7

1
  安装节点node-red-contrib-s7 ,基于 Node-red S7 通信,实现 SIMATIC IOT2040 读写 Siemens S7-300/400/1200/1500 或 S7-200 Smart PLC 中的数据。S7 节点是一个允许使用西门子 S7 以太网协议 RFC1006 与 S7-300/400/1200/1500 PLC通信的库。同时,它也适用于 S7-200 Smart PLC。
2

使用参考链接:

回到目录

7.4 amqp

1
  安装节点@meowwolf/node-red-contrib-amqp@2.4.1 ,基于AMQP协议,实现客户端与消息中间件数据的传递。
  AMQP,即 Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
  一般搭配RabitMQ进行使用,RabbitMQ是一个开源的,在AMQP基础上完整的,可复用的企业消息系统。
  节点使用参考链接:node-red:使用node-red-contrib-amqp节点,实现与RabbitMQ服务器(AMQP)的消息传递

八、formats

8.1 时间格式化与时区转换

【node-red-contrib-moment 中文文档教程】
【node-red时区问题解决方案对比】
  安装节点node-red-contrib-moment,使用 Moment.JS 生成格式良好的日期/时间字符串和进行时区/DST/区域设置。
8

  1. 对时间字符串进行格式化输出
     选用Date/Time Formatter节点,配置输入、输出、时区及格式:
  • Input(输入):时间(Date)格式的数据
  • Format(格式):支持两种格式输入:
    (1)如果format为ISO8601,则输出采用 ISO 8601格式,等同于date.toISOString(),例如“2015-01-28T16:24:48.123Z”。请注意,ISO8601 格式的输出始终采用 UTC(“Z”,祖鲁时间),而不是本地时间,无论您指定哪个输出时区。
    1
    (2)手动指定格式字符串,如YYYY-MM-DD HH:mm:ss
    1

更多示例

  1. “DD.MM.YYYY HH:mm”给出20.09.2020 08:30
  2. “dddd, MMMM Do YYYY, h:mm:ss a”给出Sunday, February 14th 2010, 3:25:50 pm
  3. “[Today is] dddd”给出 Today is Sunday
  4. “[Date: ]YYYY-MM-DD [Time:]HH:mm:ss”给出 < em>日期:2020-09-20 时间:08:31:45

8.2 输入(定时器)

1
  安装节点node-red-contrib-cron-plus,一个灵活的定时器/调度器(cron、solar events、simple dates)节点,具有完全的动态控制和时区支持。
2
详细使用参考官网案例:https://flows.nodered.org/node/node-red-contrib-cron-plus
3

九、解析

9.1 buffer-parser

  安装节点node-red-contrib-buffer-parser,用于在缓冲区/数组之间转换值。支持大/小端序、BCD、字节交换等。
1

  • 一、将十六进制数组字节流转换为十进制数字:
    s
  • 更多示例:
    2
    源码:
[
    {
        "id": "1523dd03.6332f3",
        "type": "buffer-parser",
        "z": "ba42f58dd77dba8a",
        "name": "",
        "data": "payload",
        "dataType": "msg",
        "specification": "{\"options\":{\"byteSwap\":[\"swap16\"],\"resultType\":\"object\",\"singleResult\":true,\"msgProperty\":\"data\"},\"items\":[{\"name\":\"alphabet\",\"type\":\"string\",\"offset\":0,\"length\":26},{\"name\":\"single byte pos 4\",\"type\":\"int\",\"offset\":4},{\"name\":\"bcd equiv\",\"type\":\"bcd\",\"offset\":4,\"length\":5},{\"name\":\"Array[6] of int16le\",\"type\":\"int16le\",\"offset\":26,\"length\":6},{\"name\":\"Array[6] of int16be\",\"type\":\"int16be\",\"offset\":26,\"length\":6},{\"name\":\"32 bools\",\"type\":\"bool\",\"offset\":0,\"length\":32},{\"name\":\"Array[4] of 16bits\",\"type\":\"16bit\",\"offset\":0,\"length\":4}]}",
        "specificationType": "ui",
        "items": [
            {
                "type": "string",
                "name": "alphabet",
                "offset": 0,
                "length": 26,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int8",
                "name": "single byte pos 4",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bcd",
                "name": "bcd equiv",
                "offset": 4,
                "length": 5,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16le",
                "name": "Array[6] of int16le",
                "offset": 26,
                "length": 6,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "Array[6] of int16be",
                "offset": 26,
                "length": 6,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "32 bools",
                "offset": 0,
                "length": 32,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "16bitbe",
                "name": "Array[4] of 16bits",
                "offset": 0,
                "length": 4,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "swap16",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "data",
        "msgPropertyType": "",
        "resultType": "object",
        "resultTypeType": "",
        "multipleResult": false,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 410,
        "y": 300,
        "wires": [
            [
                "a3051c67.b82ad"
            ]
        ]
    },
    {
        "id": "a3051c67.b82ad",
        "type": "debug",
        "z": "ba42f58dd77dba8a",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "data",
        "targetType": "msg",
        "x": 640,
        "y": 300,
        "wires": []
    },
    {
        "id": "9b72f1f5.1aacc",
        "type": "inject",
        "z": "ba42f58dd77dba8a",
        "name": "Fake PLC data 16bit Array",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "[25185,25699,26213,26727,27241,27755,28013,28783,29297,29811,30325,30839,31353,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3597]",
        "payloadType": "json",
        "x": 190,
        "y": 300,
        "wires": [
            [
                "1523dd03.6332f3",
                "41581ab6f61cec9a"
            ]
        ]
    },
    {
        "id": "a9a2dd4c.118f9",
        "type": "comment",
        "z": "ba42f58dd77dba8a",
        "name": "取一个16位值的数组,进行字节反转,拆分出几个值,并在msg.data中传输一个包含命名对象的消息",
        "info": "",
        "x": 400,
        "y": 260,
        "wires": []
    },
    {
        "id": "1194a28a.49d0ad",
        "type": "buffer-parser",
        "z": "ba42f58dd77dba8a",
        "name": "",
        "data": "payload",
        "dataType": "msg",
        "specification": "{\"options\":{\"byteSwap\":[\"swap16\"],\"resultType\":\"value\",\"singleResult\":false,\"msgProperty\":\"payload\"},\"items\":[{\"name\":\"plc1/production/alphabet\",\"type\":\"string\",\"offset\":0,\"length\":26},{\"name\":\"plc1/production/status/count\",\"type\":\"int\",\"offset\":25},{\"name\":\"plc1/production/status/sequence\",\"type\":\"bcd\",\"offset\":4},{\"name\":\"plc1/machine/status/runner/temperature\",\"type\":\"int16le\",\"offset\":26},{\"name\":\"plc1/machine/status/runner/speed\",\"type\":\"int16be\",\"offset\":26},{\"name\":\"plc1/machine/status/running\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":0},{\"name\":\"plc1/machine/status/warning\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":1},{\"name\":\"plc1/machine/status/fault\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":2}]}",
        "specificationType": "ui",
        "items": [
            {
                "type": "string",
                "name": "plc1/production/alphabet",
                "offset": 0,
                "length": 26,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int8",
                "name": "plc1/production/status/count",
                "offset": 25,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bcd",
                "name": "plc1/production/status/sequence",
                "offset": 4,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16le",
                "name": "plc1/machine/status/runner/temperature",
                "offset": 26,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "int16be",
                "name": "plc1/machine/status/runner/speed",
                "offset": 26,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "plc1/machine/status/running",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "plc1/machine/status/warning",
                "offset": 0,
                "length": 1,
                "offsetbit": 1,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "plc1/machine/status/fault",
                "offset": 0,
                "length": 1,
                "offsetbit": 2,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "swap16",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "",
        "resultType": "value",
        "resultTypeType": "",
        "multipleResult": true,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 410,
        "y": 460,
        "wires": [
            [
                "858b1ecf.77b58"
            ]
        ]
    },
    {
        "id": "858b1ecf.77b58",
        "type": "debug",
        "z": "ba42f58dd77dba8a",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 650,
        "y": 460,
        "wires": []
    },
    {
        "id": "c22cd2e8.52649",
        "type": "inject",
        "z": "ba42f58dd77dba8a",
        "name": "Fake PLC data 16bit Array",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "[25185,25699,26213,26727,27241,27755,28013,28783,29297,29811,30325,30839,31353,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3597]",
        "payloadType": "json",
        "x": 190,
        "y": 460,
        "wires": [
            [
                "1194a28a.49d0ad",
                "b55c0bab245908d7"
            ]
        ]
    },
    {
        "id": "970db39d.106a6",
        "type": "comment",
        "z": "ba42f58dd77dba8a",
        "name": "取一个16位值的数组,进行字节反转,拆分出几个值,并使用主题+有效载荷传输单个消息",
        "info": "",
        "x": 370,
        "y": 420,
        "wires": []
    },
    {
        "id": "41581ab6f61cec9a",
        "type": "debug",
        "z": "ba42f58dd77dba8a",
        "name": "debug 26",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 400,
        "y": 360,
        "wires": []
    },
    {
        "id": "b55c0bab245908d7",
        "type": "debug",
        "z": "ba42f58dd77dba8a",
        "name": "debug 27",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 400,
        "y": 520,
        "wires": []
    }
]

回到目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值