数采仪数据补传不生效?按 HJ 212 报文四层排查

“数采仪屏幕上显示连接成功,平台那边实时数据也在跳,可一到月底导报表,历史数据里一段一段是空的。”这是华东一家印染厂的运维工程师在电话里说的原话。远程连上去看,设备本地存的数据是齐的,补传记录也在跑,平台上那段就是补不上。

结论先给:数采仪数据补传不生效,十有八九是补传报文里的时间戳和平台侧的入库规则对不上,而不是设备存不下、也不是网络断过。设备把数据重新发了一遍,平台也收到了,但按自己的规则判成超窗口、重复或者无效数据,直接丢掉,你在界面上自然看不到。定位这类问题,按网络—协议—设备—平台四层顺序走,比一上来就换卡、重启、刷固件有效得多。

一、补传这件事,设备端到底做了什么

按 HJ 212 的报文规范,数据上行是分段的:1000–1999 是上位机(平台)下发的命令,2000–2999 是现场机(数采仪)上传的应答。补传走的是历史数据命令——平台下发 1014 提取分钟历史数据,现场机用 2014 应答上传;1015 / 2015 对应小时数据;3020 用来上传数采仪与监控设备(仪表)的连接状态。设备自己主动补传时,用的也是 20xx 这一段的命令码。

一条报文的骨架是固定的:以 ## 开头,接 4 位十进制的数据段长度,然后是 QN 请求编号、ST 系统编码、CN 命令编码、PW 密码、MN 设备唯一标识、Flag 标志位,再接 CP=&&…&& 包起来的数据区,最后是 4 位十六进制的 CRC 校验,尾部 CRLF。CRC 用的是 CRC16,生成多项式 X16+X12+X5+1。

数据区里常见的字段有污染物编码(比如 w01018 化学需氧量、w21003 氨氮)、Cou 浓度、Avg 平均值、以及一个很容易被忽略的 Flag 数据标记:N 正常、F 故障、M 维护、D 无数据、C 校准。补传的时候,这个标记是跟着数据一起走的。

想清楚这一点,后面的排查就有抓手了——补传失败,等于这条链条上某一环没有把“这条数据是什么时候的、是否有效”表达清楚。

二、四层原因拆开看

网络层:先看心跳,不看信号格

  • 心跳掉了但界面还显示在线。心跳是 9011 / 9012 一收一回,很多数采仪的“在线”图标只代表 TCP 连上了,不代表心跳通。
  • NAT 会话老化。现场走 4G 或经过防火墙时,会话超时时间可能比设备心跳间隔短,链路看着在,实际早就单向不通。
  • 双卡或 APN 切换。信号强度满格不代表数据出得去,拨号成功和能连平台是两回事。

协议层:报文发出去了,对方有没有认

  • CRC 错或数据段长度算错。4 位长度必须和 ## 之后到 CRC 之前的字节数严格对应,改字段忘了改长度,平台直接丢弃。
  • 应答超时与重发次数设置不合理。重发次数过多,同一批数据被反复推,反而容易触发平台去重。
  • QN 请求编号重复。有些平台按 QN 做幂等去重,设备重发时 QN 不变,第二批就被当成重复包扔掉。
  • Flag 里的应答要求位没置对。需要平台回执的包没要求回执,设备就当发成功了,其实没入库。

设备层:数据在,不等于补得出去

  • 本地存储循环覆盖。存储分区存满后覆盖老数据,断线时间一长,最早那段已经被盖掉了。
  • 设备时钟漂移。没做 NTP 同步的设备,跑几个月差几分钟到几小时都常见,补传出去的时间戳整体错位。
  • 数据标记被写成 F 或 D。仪表检修、校准期间的数据被打上故障或无效标记,补传时原样带出去。
  • 补传开关只开了小时没开分钟。分钟数据没打开,平台上分钟曲线就是断的。

平台层:最容易被甩锅,也最容易出问题

  • 接收时间窗口。不少平台只接受一定时限内的历史数据,超出窗口的报文回执正常但直接不入库。
  • 按接收时间而不是数据时间入库。补传上来的旧数据被记成“今天”,看着补了,其实落到别的日期。
  • 污染物编码未注册。数据区里的因子编码平台侧没登记,整包过滤。
  • 标记过滤规则。平台默认丢弃 F、D 标记的数据,补传再多也不显示。

三、为什么先查心跳、最后查平台

这个顺序本身就是知识,不是随便排的。心跳是零成本、非侵入的判断,看一眼平台在线状态和最近心跳时间就能排除一大半;抓报文要停点或者做端口镜像,会短暂影响生产;翻设备存储要远程登录或到现场;平台侧规则往往要协调对方技术人员,周期最长。按“成本从低到高、影响从小到大”推,能少走很多弯路。

反过来,如果先怀疑平台规则,可能折腾一圈才发现是设备时钟错了三小时,白等两轮沟通。

四、每一步的判断标准和处置动作

层次现象判断动作
网络层平台在线状态频繁闪烁,9011 发出后无 9012 回执链路通但会话已老化对比心跳周期与防火墙会话超时,缩短心跳间隔
协议层平台日志有报文但校验失败CRC 或数据段长度计算有误抓包核对 ## 后 4 位长度与 CP 区实际字节数
协议层报文正常,平台无入库记录QN 重复被去重,或 Flag 应答位缺失换新 QN 单发一条,观察平台是否落库
设备层本地存储有数据,补传记录为 0补传未触发,或断线判定阈值过长检查补传策略、断线判定时间与补传开关
设备层补传记录有,时间戳与平台相差数小时设备时钟漂移用 1011 提取现场机时间,与标准时间比对后校时
平台层报文里 Flag 为 F 或 D被平台按无效数据过滤核实故障/维护时段,确认是否需要修正标记后补传
平台层补传时段早于平台接收窗口超出平台可接受的历史范围确认窗口时长,改为短周期补传而非攒长段

五、三个最容易踩的坑

坑一:平台按接收时间入库,你以为没补上。数据其实到了,只是落在补传当天的时间点上,报表按数据时间一筛就是空的。这时候去查设备的补传记录,会看到“已补传成功”,别急着说设备有问题,先让平台把两种时间维度的入库记录都调出来。

坑二:设备时钟被校错,数据被判为未来数据。有的现场为了和省平台对齐,手工改过设备时间,或者校时服务器不可达导致时间跑偏,补传出去的时间戳落在未来几小时。多数平台对“未来时间”的数据是直接拒收的,报文回执正常,数据没了。

坑三:重发不换 QN,被平台当重复包扔掉。补传程序为了稳妥会多次重发,如果 QN 一直是同一个,平台去重后只留第一条。表现就是补传日志显示“发送成功 N 条”,平台只多了一条。

六、FAQ

问:我这个情况到底要不要开补传?
看你的联网稳定性和管理要求。链路每天都断一两次、每次十几分钟的,不开补传报表肯定缺段;常年稳定的,开个短周期补传做兜底也不亏,但别把补传周期设得太长。

问:补传上去的数据,平台要不要标出来是补的?
数据本身的标记位跟着原始数据走就行,不要在补传时人工改成 N。如果原来就是维护或校准期间的数据,标记保留 M 或 C,比事后被查出来强。

问:4G 断过两小时,补传只补回来一半是什么原因?
先看本地存储的覆盖策略和时间范围,再看补传是按条数分批还是按时间段分批,分批的话中间有失败的批次会停在那。还有一种可能是平台窗口只接受一定时限内的数据,超出部分被静默丢弃。

问:换新数采仪以后,老设备里没补完的数据还能补上吗?
理论上把老设备的存储导出来,按相同 MN 和数据时间重新组包发出去是可以的,但要确认平台侧对同一 MN 的历史数据没有锁定期。换设备前先把存量数据补完,比事后补要省事得多。

补传这件事,说到底是一个“时间对得上、标记说得清、回执拿得到”的问题。设备端能做的都做了,剩下的往往在另外一头。