请求编写Node-RED函数节点JS脚本:仅上传PLC变更数据至IoT Hub
Node-RED函数节点实现PLC数据增量上报到IoT Hub
需求说明
通过部署在IoT边缘设备的Node-RED,从西门子S7 PLC每秒接收固定属性集合的JSON对象,其中部分属性每秒更新、部分每5分钟更新、部分数小时不变。需要在发送至IoT Hub前处理数据:对比当前与上一次的JSON对象,仅发送包含变化属性的新对象。
正确JavaScript实现代码
在Node-RED的函数节点中使用以下代码:
// 从flow上下文获取上一次的状态 let prevState = flow.get('plc_prev_state') || {}; const currentState = msg.payload; const diff = {}; // 遍历当前状态的所有属性,对比是否变化 for (const key in currentState) { // 处理数值类型的精度问题,比如浮点数可添加容差判断 if (typeof currentState[key] === 'number' && typeof prevState[key] === 'number') { // 可根据实际需求调整容差值,示例为0.001 if (Math.abs(currentState[key] - prevState[key]) > 0.001) { diff[key] = currentState[key]; } } else { // 非数值类型直接做全等对比 if (currentState[key] !== prevState[key]) { diff[key] = currentState[key]; } } } // 首次上报无历史状态,直接发送全量数据 if (Object.keys(prevState).length === 0) { msg.payload = currentState; } else { // 无属性变化则不发送消息;有变化则发送增量对象 if (Object.keys(diff).length === 0) { return null; } msg.payload = diff; } // 更新flow上下文的状态为当前最新状态 flow.set('plc_prev_state', currentState); return msg;
代码说明
- 状态持久化:通过
flow.get()和flow.set()操作flow上下文,确保上一次的状态不会在函数每次执行时被重置。 - 数值精度兼容:针对PLC传来的浮点数(如示例中的
Wire_tension),添加容差判断避免因微小精度差异误判为属性变化。 - 首次上报处理:第一次运行时无历史状态,直接发送全量数据,保证云端能获取完整初始值。
- 无效请求过滤:如果没有属性变化,返回
null阻止消息发送,减少不必要的IoT Hub通信开销。
内容的提问来源于stack exchange,提问作者Arseniy Sleptsov
相关产品推荐
相关产品推荐

