跳转到内容

消息负载处理

消息负载处理

本节介绍如何操作 Node-RED 消息中的 payload 数据。学习完成后,您将能够:

  • 理解 payload 对象的结构
  • 使用 Function 节点修改 payload
  • 使用 Change 节点简化常见操作
  • 处理不同类型的数据格式转换

Payload 是 Node-RED 消息中的核心数据字段:

完整消息对象:
{
_msgid: "abc123",
topic: "sensor/temperature",
payload: 25.3, ← 核心数据
data: {...}, ← 自定义属性
...
}
类型示例IoT 场景
String"25.3"MQTT 原始数据
Number25.3传感器数值
Booleantrue开关状态
Array[25.3, 68.2, 42]批量数据
Object{"temp": 25.3}结构化数据
JSON'{"temp":25.3}'API 响应

Change 节点无需编程即可修改消息属性:

[Inject] → [Change Node] → [Debug]
Change 节点操作:
├─ Set (设置值)
├─ Change (替换值)
├─ Delete (删除属性)
└─ Move (移动属性)

示例 1: 设置固定值

{
"action": "set",
"property": "payload",
"to": "Hello IoT"
}

示例 2: 类型转换

{
"action": "change",
"property": "payload",
"from": "temperature",
"to": "temp"
}

示例 3: 删除属性

{
"action": "delete",
"property": "data.timestamp"
}
// 输入: msg.payload = 25.3
// 数学运算
msg.payload = Math.round(msg.payload * 10) / 10; // 25.3
msg.payload = msg.payload.toFixed(2); // "25.30"
// 类型转换
msg.payload = Number(msg.payload); // 字符串 → 数字
msg.payload = String(msg.payload); // 数字 → 字符串
msg.payload = Boolean(msg.payload); // 其他 → 布尔
return msg;
// 输入: 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;
// 输入: 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;
// 解析 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;

Switch 节点根据 payload 值进行条件路由:

[SWITCH Node]
条件:
├─ payload > 30 ──→ [Email Alert]
├─ payload < 10 ──→ [Heating Control]
└─ else ──→ [InfluxDB Storage]
{
"property": "payload.temperature",
"rules": [
{"t": "gt", "v": "30", "output": 1},
{"t": "lt", "v": "10", "output": 2}
],
"checkall": "true",
"repair": false
}
// 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;
// 输入: 可能包含异常值
// 过滤和清洗数据
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;
// 温度: 摄氏度 ↔ 华氏度
var celsius = Number(msg.payload);
var fahrenheit = celsius * 9 / 5 + 32;
msg.payload = {
celsius: celsius.toFixed(1),
fahrenheit: fahrenheit.toFixed(1)
};
return msg;

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 中做过多格式化工作
  1. Payload 是 Node-RED 消息的核心数据载体
  2. Change 节点适合简单的属性修改
  3. Function 节点处理复杂的数据操作
  4. Switch 节点根据条件路由消息
  5. 数据格式转换是 IoT 场景的常见需求