1、前言
在设备联网建设中,一般通过边缘网关采集设备或SCADA系统数据,然后上传到服务端进行处理。数据如何上传是承上启下的重要一环。
早期的数据传输,一般每个报文的长度有限,内容采用二进制编码。目前在工厂内部,IT条件都比较好,更多的是从通用性、易用性和可维护性等方面进行考虑,这时报文一般采用JSON格式。如何设计上传的JSON,本文给出笔者的个人建议。
2、来自OPC软件的参考
工控行业有些大名鼎鼎的设备连接软件,如KepServer,支持非常多的设备通讯协议,它采用工程、通道、设备和数据项的模式对连接的设备进行管理。
简单配置的KepServerEx6工程
使用Opc Client客户端查询数据
从上面的示例可以看出,一个工程下面,可以建立多个通道,每个通道是同一通信连接设备的集合。通道下面可以建立具体的设备,可以有多个。设备下面配置具体的设备数据点。KepServerEx为每个通道建立了部分内部数据点。
3、设备采集网关设计
设备采集网关设计,在参考KepServerEx的基础上,适当简化:即每个网关支持对多个设备的连接,省去通道这层,采用网关-设备-数据项3级结构。网关与设备为1:N关系,设备下面连接的数据点由设备本身决定,几个到几万个都有可能。
同一个工厂里可以根据设备布局、网络规划、服务器负载等实际情况的不同,部署多个网关。网关与设备之间其实是弱绑定关系,一个设备可以挂到A网关,也可以挂到B网关。设备与数据项之间是强绑定关系,每个设备的数据项的固定的。
从监控需要出发,网关与设备设备下可挂部分虚拟的检测点,如网关与服务器连接次数,网关与服务器通信建立时间、网关与服务器连接尝试次数、设备连接状态、设备重连次数、设备采集数据次数等,方便进行全链路的数据监控与排查。
对于基于TCP连接的设备,也可以根据需要部署冷备或热备模式。服务由任务调度平台调度管理。冷备时,备用网关服务启动但不工作,直到主网关失效后再启动设备连接和数据上传。热备模式下,备用网关保持对设备的连接但不上传数据,直到收到调度指令才上传。冷网关模式下切换时间稍长。需要注意的是,很多支持TCP的设备,本身对连接数量是有限制的,需要根据情况制定相应的策略。
4、上传报文设计
上传报文使用JSON格式,每次可以上传一条或多条数据记录。参考示例:
{
"factoryId" : "fc01",
"edgeId" : "edge01",
"startTimeStamp" : 1652500178755,
"seq" : 1,
"dataTimeStamp" : 1652500205000,
"dataType" : "data",
"data" : [ {
"devId" : "dev1",
"tag" : "tag_01",
"ts" : "1652500205000",
"vt" : "int",
"v" : 1234,
"vq" : 0,
"seq" : 1
}, {
"devId" : "dev1",
"tag" : "tag_02",
"ts" : "1652500205000",
"vt" : "float",
"v" :12.34,
"vq" : 0,
"seq" : 1
}, {
"devId" : "dev2",
"tag" : "tag_01",
"ts" : "1652500409535",
"vt" : "int",
"v" : 1234,
"vq" : 0,
"seq" : 1
}, {
"devId" : "dev2",
"tag" : "tag_02",
"ts" : "1652500409535",
"vt" : "float",
"v" :43.21,
"vq" : 0,
"seq" : 1
} ]
}
主要数据项说明如下:
序号 | 数据项 | 说明 |
1 | factoryId | 工厂编号 |
2 | edgeId | 网关编号 |
3 | startTimeStamp | 网关启动时间 |
4 | seq | 数据上报数据序列号 |
5 | dataTimeStamp | 上报数据生成时间(与实际上传时间有差异) |
6 | dataType | 数据类型,对应不同数据处理需求 |
7 | data | 数据值列表 |
数据值数据项目说明:
序号 | 数据项 | 说明 |
1 | devId | 设备编号 |
2 | tag | 数据项名称 |
3 | ts | 数据采集时间 |
4 | vt | 数据项值类型,比如int/float/bool/string等 |
5 | v | 数据值(对于Java Object类型) |
6 | vq | 数据质量,不同协议质量代码不同。OPC数据可以取OPC质量代码 |
7 | seq | 数据上传序列号(订阅变化数据非周期更新) |
seq主要用于数据追踪。
数据上传,可以采用简单的FIFO先进先出,所有数据先进队列,数据队列根据内存、数量大小进行缓存,避免短时间的网络或服务器异常造成的数据丢失。根据上传接入对于协议要求进行封装,上传可以采用MQTT,纯内网环境也可以直接入Kafka。Kafka推荐使用网关Id做为Key,确保同一个网关的数据在使用时可以先进先出。
5、其他
数据根据需要可以进行压缩,比如zip,JAVA和.NET都有成熟的库可以直接调用。压缩可以仅压缩data域部分,也可以全部压缩。压缩能节省网络流量和存储,但会增加解析时间和CPU耗用。