规则链中如何实现Aggregate Stream节点结果间的键运算?
解决Node-RED中异步聚合结果的计算问题
方法一:使用Join节点(推荐)
这是最简洁的方案,专门用来合并异步到达的消息:
- 给两个
Aggregate Stream节点的输出消息添加标识:比如第一个节点输出时设置msg.topic = "encendido",第二个设置msg.topic = "apagado";或者直接让两个聚合节点分别输出tiempo_encendido_ms和tiempo_apagado_ms字段。 - 添加一个Join节点,配置为「Manual」模式:
- 设置合并规则为「合并到单个消息的属性」,指定需要合并的两个字段(
tiempo_encendido_ms和tiempo_apagado_ms); - 或者选择「按Topic分组」,设置等待2条消息后合并。
- 设置合并规则为「合并到单个消息的属性」,指定需要合并的两个字段(
- 将Join节点的输出接入你的Script节点,此时
msg会同时包含两个聚合后的数值,原代码就能正常运行:
var newMsg = {}; newMsg.ratio_on_off = parseFloat(msg.tiempo_encendido_ms / (msg.tiempo_encendido_ms + msg.tiempo_apagado_ms)); return {msg: newMsg};
方法二:使用Context存储临时数据
如果需要更灵活的控制,可以用Node-RED的上下文存储来暂存数据,等两个值都到位后再计算:
- 给第一个
Aggregate Stream节点接一个Script节点,代码如下:
// 把第一个聚合结果存入流程上下文 context.set('tiempo_encendido_ms', msg.tiempo_encendido_ms); // 检查第二个值是否已存在 var offTime = context.get('tiempo_apagado_ms'); if (offTime !== undefined) { var newMsg = {}; newMsg.ratio_on_off = parseFloat(msg.tiempo_encendido_ms / (msg.tiempo_encendido_ms + offTime)); // 计算完成后清空上下文,避免重复触发 context.set('tiempo_encendido_ms', undefined); context.set('tiempo_apagado_ms', undefined); return {msg: newMsg}; } // 第二个值未到,不输出消息 return;
- 给第二个
Aggregate Stream节点接另一个Script节点,代码如下:
// 把第二个聚合结果存入流程上下文 context.set('tiempo_apagado_ms', msg.tiempo_apagado_ms); // 检查第一个值是否已存在 var onTime = context.get('tiempo_encendido_ms'); if (onTime !== undefined) { var newMsg = {}; newMsg.ratio_on_off = parseFloat(onTime / (onTime + msg.tiempo_apagado_ms)); // 计算完成后清空上下文 context.set('tiempo_encendido_ms', undefined); context.set('tiempo_apagado_ms', undefined); return {msg: newMsg}; } // 第一个值未到,不输出消息 return;
注意:如果是多设备或多实例场景,建议给上下文键添加唯一标识(比如设备ID),避免不同数据源的数据互相干扰。
内容的提问来源于stack exchange,提问作者tomasnav
相关产品推荐
相关产品推荐

