接入一台工业设备,演示版本通常很快:建立连接、读取寄存器、打印数值。
真正进入平台以后,链路会变成:
物理设备
-> 协议驱动
-> 数据解析
-> 设备身份映射
-> 标准模型
-> 本地缓存或时序库
-> MQTT/HTTP 转发
-> 告警与应用
任何一层语义不一致,问题都可能在最远的下游才出现。这篇按完整链路总结工业设备接入时需要处理的核心问题。
一、连接层:连接成功不等于可以通信
常见接入方式包括串口、TCP、Modbus、厂商私有协议、HTTP、SOAP 和 MQTT。连接层需要统一管理:
- 建连与认证;
- 读取、写入超时;
- 心跳;
- 断线重连;
- 连接状态;
- 优雅关闭。
重连要使用退避策略,避免设备断电后所有客户端同时高频重试:
1s -> 2s -> 4s -> 8s -> 30s
成功通信后再重置退避时间。连接对象还要有明确所有者,不能由多个 goroutine 在没有协调的情况下同时重连和关闭。
二、解析层:不要让原始协议泄漏到业务层
协议返回的是字节、寄存器或厂商字段,业务需要的是温度、压力、运行状态和告警。
解析层应完成:
- 字节序处理;
- 数据类型转换;
- 缩放系数;
- 单位标准化;
- 位域解析;
- CRC 或校验和;
- 异常值识别。
例如一个寄存器值 253,可能表示 25.3℃。下游不应该再次猜测缩放规则,标准模型里应直接保存数值、单位和质量信息。
三、身份层:先回答“这是谁”
设备可能同时拥有配置编号、IP、序列号、厂商编号、数据库 ID 和 GUID。IP 会变,名称会重,数据库自增 ID 只在局部有意义。
稳定身份应该由平台统一下发或维护,并贯穿:
配置 -> 采集 -> 存储 -> 转发 -> 告警 -> 页面
共享设备还需要把“设备身份”和“连接关系”分开。一个一次设备可以同时被两台 PLC 观测,不能因为树结构方便,就把设备复制成两个身份。
四、时间层:数据是什么时候发生的
工业数据里至少有三个时间:
- 设备产生时间;
- 网关采集时间;
- 平台接收时间。
只保存 created_at 会丢失重要信息。网络中断后补传的数据,如果使用接收时间,就会看起来像刚刚发生。
标准事件可以包含:
{
"deviceTime": "...",
"collectTime": "...",
"receiveTime": "..."
}
还要明确设备时钟是否可信、时区如何处理、时间解析失败时使用哪个备用值。
五、质量层:数值之外还要有可信度
采集值不只有“有”和“没有”。
GOOD 正常采集
STALE 超过预期周期未更新
BAD_FORMAT 协议解析失败
OUT_OF_RANGE 超出物理范围
DISCONNECTED 设备连接中断
SUBSTITUTED 使用补偿值
如果下游只收到一个 0,它无法判断设备真实测得零,还是采集失败后填了默认值。质量码能避免错误数据被当成真实业务事实。
六、模型层:统一共性,保留差异
完全按厂商定义模型,下游会面对几十套字段;强行把所有设备压进同一张表,又会产生大量无意义字段。
更实用的方式是分两层:
通用信封
device_guid
metric_code
value
unit
quality
collect_time
source
设备专属属性
通过模型配置描述指标名称、类型、地址、倍率和业务含义。
这样传输、存储和告警可以复用通用能力,协议驱动仍能保留设备差异。
七、转发层:离线时数据怎么办
现场网关到中心平台的网络并不稳定。转发模块要明确:
- 断网是否缓存;
- 缓存容量上限;
- 恢复后按什么顺序补传;
- 重复消息如何去重;
- 实时数据与补传数据谁优先;
- 磁盘写满如何降级。
不能无限缓存。更合理的是按业务价值区分:告警和事件优先保留,高频实时值可以按时间窗口压缩或丢弃。
八、告警层:规则依赖统一语义
告警规则需要明确输入数据、窗口、阈值、恢复条件和去重键。
alarm_key = device_guid + metric_code + rule_id
触发和恢复必须使用同一设备身份。否则规则引擎已产生告警,页面却无法把告警映射到对应设备。
九、运维层:接入完成以后才开始长期运行
一套可维护的设备接入应提供:
- 当前连接状态;
- 最近成功采集时间;
- 连续失败次数;
- 最近一次原始报文;
- 配置版本;
- 驱动版本;
- 数据吞吐与错误率;
- 远程诊断能力。
没有这些信息,现场问题只能依靠临时加日志和反复重启。
十、接入验收清单
- [ ] 断开网线后能自动恢复;
- [ ] 设备重启后不会产生重复身份;
- [ ] 非法报文不会导致进程退出;
- [ ] 时间、单位、倍率已经标准化;
- [ ] 缺失值与真实零可以区分;
- [ ] 上游离线时有明确缓存策略;
- [ ] 同一消息重复到达不会重复产生告警;
- [ ] 日志可以关联设备 GUID;
- [ ] 配置错误能在启动阶段发现;
- [ ] 服务停止时连接和 goroutine 能正常退出。
工业设备接入不是把协议翻译成 JSON。它是在不稳定的物理环境与相对稳定的软件平台之间,建立一份长期可维护的数据契约。