本节摘要:数据上行有三条路:OPC UA以信息模型提供语义化访问,MQTT以发布订阅实现轻量广播,数据库直连是老办法但隐患多。本节为青线的产量、报警、配方三类数据分别选路,给出MQTT组包的完整代码与通信健康位的协作设计。
主干道通了,最后一程是往上位系统送数据。这条路上的协议选择比下位更自由,也因此更容易乱——青线立项时收到的需求只有一句"厂长要在办公室看到每小时的产量和报警"。把它翻译成工程方案,是这一节的全部内容。
先把需求翻译。产量数据:每小时一班次汇总,延迟分钟级即可,量大、写入型。报警数据:事件型,发生即推,一条不能丢,还要带时间戳与确认状态。配方参数:双向的,上位能下发、下发前要校验、下发后要生效确认,安全等级最高。三类数据的形状完全不同——批量汇总、事件流、受控双向——一条协议打天下注定别扭,这正是分路选型的起点。
OPC UA是工业上行的正席。它不只是传输协议,更是一套信息模型:服务器把数据组织成带类型、带单位、带层级关系的地址空间,客户端浏览树状结构就能发现"这里有什么、每个节点什么意思"。PLC在组态时勾选哪些变量进服务器接口,上位软件就能自助浏览与订阅——5.1节里Modbus的"寄存器表靠文档对齐"之苦,在OPC UA这里被信息模型根治。
青线的分工:OPC UA服务器跑在CPU上,把配方库、班产量、报警摘要、关键工艺量挂进地址空间;上位的历史库与报表系统订阅这些节点,秒级刷新。PLC程序只需维护一个3.3节说过的"交换数据块"——服务器接口只暴露交换块里的变量,内部数据的读写全部走符号路径在程序内完成,把上位系统与程序内部结构隔离开。
产量与报警要往云平台和厂级系统推,MQTT是顺手的喇叭:设备往主题发布消息,任何订阅者各取所需,服务器中间人(消息代理)不关心谁在听。它比OPC UA轻得多——没有信息模型,消息体自带约定(行业里常用JSON负载),适合"我发我的、你收你的"的松耦合场景。青线的报警推云平台、产量小时报推厂级MES,都走MQTT。
组包代码不长,关键是纪律。看青线边缘网关上的发布逻辑(Python示意,跑在与PLC同网段的边缘盒子里,数据源是OPC UA订阅):
import json, paho.mqtt.client as mqtt client = mqtt.Client(client_id="greenline-gw01") client.connect("broker", 1883, keepalive=60) # 代理地址与心跳 def publish_alarm(alarm): payload = json.dumps({ "ts": alarm.timestamp, # ISO格式时间戳 "line": "greenline-1", "code": alarm.code, # 报警号,与PLC诊断字典一致 "text": alarm.text, "sev": alarm.severity, # 1提示 2警告 3故障 }, ensure_ascii=False) client.publish("factory/greenline/alarm", payload, qos=1) # qos=1:至少一次送达,报警不丢(可能重复,接收端按消息id去重)
三条纪律藏在注释里:时间戳由源头打,转发链路各自补时戳是时序混乱之源;报警号字典两边同源,PLC的诊断字典是唯一权威,网关不做翻译只做搬运;服务质量按数据性质选,报警至少一次,产量可至多一次,配方根本不走MQTT——它的双向与安全要求是OPC UA加校验流程的活。
还有一条老路要说破:让上位软件直接连数据库,甚至让第三方工具直写PLC数据块。直连数据库曾经普遍流行,问题在于绕过了语义层——表结构一改,所有直连方一起崩,而且权限颗粒度只有"能连与不能连"。青线的规矩:数据库只做最终存储,任何系统想拿数据,走OPC UA或MQTT的正规闸口。这为第8章的IT与OT融合预留了同样的原则:跨层数据必须过闸门,闸门上挂语义与权限。
| 数据类别 | 通道 | 方向与频率 | 关键纪律 |
|---|---|---|---|
| 班产量汇总 | OPC UA订阅 | 上行,秒级刷新 | 交换块隔离内部结构 |
| 报警事件 | MQTT q1上行 | 事件驱动 | 源头时戳,字典同源 |
| 配方下发 | OPC UA加校验 | 双向,低频 | 下发前校验,生效要确认 |
| 工艺趋势量 | OPC UA订阅 | 上行,周期采样 | 只暴露交换块白名单 |
| 能耗电表数据 | Modbus转MQTT | 上行,五秒轮询 | 5.1节轮询预算内运行 |
上行数据会不会撒谎?会——网络断了,报表系统看到的还是最后一次缓存。青线的解法是把通信健康做进数据:交换块里放一个心跳计数器,PLC每拍自增;上位订阅时检查它在走,停走即宣告"数据陈旧",报表上打灰条而不是继续展示旧数。这个不到十行的机制,让"数据是活的"变成了可验证的命题——它也是第6章排错实录里定位故障的重要线索,先把机制记在这里。心跳的姐妹机制是序号:每条上行报文带递增序号,接收端发现跳号即知丢包,配合MQTT的 qos 组合使用,数据链路的完整图景就闭环了。
OPC UA订阅有一个常被忽略的参数组:发布间隔、采样间隔与死区。三者配错,要么数据洪水淹了网关,要么数据干涸误了分析。青线的配置法则是按数据用途分档:趋势分析类采样秒级、死区百分之二;报警类事件触发、零死区;配方与参数类按需读取、不订阅。这份"订阅档位表"与控制规格书同版本管理,IT侧的需求变化先改表再改配置——5.3节开头那句"翻译需求",至此有了完整的落点。
同一思路也约束MQTT侧的负载设计:主题层级按"厂区/产线/数据类"三级规划,负载字段定长优先、时间戳统一UTC、版本号进首字段——将来负载结构演进时,接收端按版本号兼容解析。这些细节单看都小,攒起来就是"数据口感能不能被下游接受"的分水岭。
三层网络全部架通,青线正式"联上网"了。联上网的代价是新故障面——第6章排错现场,灯已打开。