消息负载处理
消息负载处理
本节介绍如何操作 Node-RED 消息中的 payload 数据。学习完成后,您将能够:
- 理解 payload 对象的结构
- 使用 Function 节点修改 payload
- 使用 Change 节点简化常见操作
- 处理不同类型的数据格式转换
Understanding Payload
Section titled “Understanding Payload”Payload 是 Node-RED 消息中的核心数据字段:
完整消息对象:{ _msgid: "abc123", topic: "sensor/temperature", payload: 25.3, ← 核心数据 data: {...}, ← 自定义属性 ...}Payload 的常见数据类型
Section titled “Payload 的常见数据类型”| 类型 | 示例 | IoT 场景 |
|---|---|---|
| String | "25.3" | MQTT 原始数据 |
| Number | 25.3 | 传感器数值 |
| Boolean | true | 开关状态 |
| Array | [25.3, 68.2, 42] | 批量数据 |
| Object | {"temp": 25.3} | 结构化数据 |
| JSON | '{"temp":25.3}' | API 响应 |
Using Change Node
Section titled “Using Change Node”Change 节点无需编程即可修改消息属性:
[Inject] → [Change Node] → [Debug]
Change 节点操作:├─ Set (设置值)├─ Change (替换值)├─ Delete (删除属性)└─ Move (移动属性)Change 节点配置示例
Section titled “Change 节点配置示例”示例 1: 设置固定值
{ "action": "set", "property": "payload", "to": "Hello IoT"}示例 2: 类型转换
{ "action": "change", "property": "payload", "from": "temperature", "to": "temp"}示例 3: 删除属性
{ "action": "delete", "property": "data.timestamp"}Using Function Node
Section titled “Using Function Node”1. 修改简单值
Section titled “1. 修改简单值”// 输入: msg.payload = 25.3
// 数学运算msg.payload = Math.round(msg.payload * 10) / 10; // 25.3msg.payload = msg.payload.toFixed(2); // "25.30"
// 类型转换msg.payload = Number(msg.payload); // 字符串 → 数字msg.payload = String(msg.payload); // 数字 → 字符串msg.payload = Boolean(msg.payload); // 其他 → 布尔
return msg;2. 处理对象
Section titled “2. 处理对象”// 输入: msg.payload = {temp: 25.3, hum: 68.2, device: "SENSOR-01"}
// 提取特定属性msg.payload = msg.payload.temp;
// 合并新属性msg.payload.timestamp = Date.now();msg.payload.status = "online";
// 结构转换var newPayload = { device_id: msg.payload.device, measurement: "temperature", value: msg.payload.temp, unit: "celsius"};msg.payload = newPayload;
return msg;3. 处理数组
Section titled “3. 处理数组”// 输入: msg.payload = [25.3, 68.2, 1013]
// 计算数组统计var sum = msg.payload.reduce((a, b) => a + b, 0);var avg = sum / msg.payload.length;var max = Math.max(...msg.payload);var min = Math.min(...msg.payload);
msg.payload = { average: avg.toFixed(2), max: max, min: min, count: msg.payload.length};
return msg;4. 解析和构建 JSON
Section titled “4. 解析和构建 JSON”// 解析 JSON 字符串 (如从 HTTP API 接收)try { var parsed = JSON.parse(msg.payload); msg.payload = { id: parsed.id || "unknown", value: parsed.value, timestamp: parsed.ts || Date.now() };} catch (e) { node.error("Invalid JSON: " + e.message); return null;}
return msg;Using Switch Node
Section titled “Using Switch Node”Switch 节点根据 payload 值进行条件路由:
[SWITCH Node]条件:├─ payload > 30 ──→ [Email Alert]├─ payload < 10 ──→ [Heating Control]└─ else ──→ [InfluxDB Storage]Switch 配置示例
Section titled “Switch 配置示例”{ "property": "payload.temperature", "rules": [ {"t": "gt", "v": "30", "output": 1}, {"t": "lt", "v": "10", "output": 2} ], "checkall": "true", "repair": false}Data Transformation Patterns
Section titled “Data Transformation Patterns”Pattern 1: ESP32 到 InfluxDB 格式
Section titled “Pattern 1: ESP32 到 InfluxDB 格式”// ESP32 发送: topic: "sensor/SENSOR-01/temperature"// payload: "25.3"
// Node-RED Function: 转换为 InfluxDB 格式var deviceId = msg.topic.split('/')[1]; // "SENSOR-01"
msg.payload = { measurement: "temperature", tags: { device: deviceId }, fields: { value: Number(msg.payload) }, timestamp: Date.now() * 1000000 // 纳秒时间戳};
return msg;Pattern 2: 数据清洗
Section titled “Pattern 2: 数据清洗”// 输入: 可能包含异常值// 过滤和清洗数据
var value = Number(msg.payload);
// 过滤异常值if (isNaN(value) || value < -50 || value > 150) { node.warn("Invalid value filtered: " + msg.payload); return null; // 丢弃异常数据}
// 范围映射if (value < 0) value = 0;if (value > 100) value = 100;
msg.payload = Math.round(value * 100) / 100;return msg;Pattern 3: 单位转换
Section titled “Pattern 3: 单位转换”// 温度: 摄氏度 ↔ 华氏度var celsius = Number(msg.payload);var fahrenheit = celsius * 9 / 5 + 32;
msg.payload = { celsius: celsius.toFixed(1), fahrenheit: fahrenheit.toFixed(1)};
return msg;Using Template Node
Section titled “Using Template Node”Template 节点用于格式化字符串输出:
// 模板: "At {{payload.time}}, temperature is {{payload.value}}{{payload.unit}}"
// 输出: "At 10:30, temperature is 25.3°C"
// JSONata 表达式:payload.time & " - " & payload.value & payload.unit✅ 推荐做法:
- 简单修改用 Change 节点(无需编程)
- 复杂逻辑用 Function 节点
- 数据过滤要在入库前完成
- 类型转换要使用安全的方法
- 异常数据及时丢弃或标记
❌ 避免做法:
- 在多个节点重复修改同个 payload
- 忽略错误处理
- 不验证数据来源
- 丢失原始数据导致难以排错
- 在 Function 中做过多格式化工作
Summary
Section titled “Summary”- Payload 是 Node-RED 消息的核心数据载体
- Change 节点适合简单的属性修改
- Function 节点处理复杂的数据操作
- Switch 节点根据条件路由消息
- 数据格式转换是 IoT 场景的常见需求