3. SCADA实时数据采集与数据库接入
SCADA 系统的数据采集层,本质上是把现场设备中不断变化的物理量,转换成数据库能够长期存储、查询和分析的结构化记录。这个过程涉及三个关键决策:用什么协议把数据取回来、以多快的频率取、取回来之后分别写进哪一类数据库。三者互相牵制——协议决定单次采集的时延与可寻址范围,采集频率决定数据量与实时库压力,而实时库与关系库的边界划分则决定后续查询、报表与历史追溯的成本。
一、三类主流协议的解析差异
OPC UA、Modbus、IEC 60870-5-104 在数据模型、寻址方式和传输语义上差异明显,直接决定了采集程序的写法。
OPC UA 是面向对象的地址空间模型。每个变量由 NodeId 唯一标识,例如 ns=2;s=Boiler1.Temp,其中 ns=2 是命名空间索引,s= 表示字符串型标识符。客户端通过订阅(Subscription)机制注册感兴趣的点位,并设置 PublishingInterval(发布周期)和 SamplingInterval(采样周期)。服务端只在数据变化超过 Deadband(死区)时才推送,因此 OPC UA 天然适合“变化上报”型采集,而不是盲目轮询。读取时返回的 StatusCode 必须判断,Good 才写入数据库,Bad 或 Uncertain 应记录质量戳而非直接丢弃。
Modbus 是典型的寄存器寻址模型,没有语义,只有地址。常见四类区域:线圈(0x)、离散输入(1x)、输入寄存器(3x)、保持寄存器(4x)。例如读取保持寄存器 40001 起始的 10 个寄存器,功能码 03,从站地址 1,报文为 01 03 00 00 00 0A C5 CD。Modbus 是主从轮询,必须由采集端主动发起,因此采集频率直接等于轮询周期。浮点数需要两个寄存器拼接,且存在大小端(ABCD/CDAB/BADC/DCBA)问题,配置错误会得到完全错误的数值,这是现场最常见的接入故障之一。
IEC 104 用于电力调度,采用 ASDU(应用服务数据单元)结构,通过类型标识区分遥测(M_ME_NC_1,短浮点)、遥信(M_SP_NA_1,单点)、遥控等。它支持总召唤(C_IC_NA_1)和变化上送(COS),并带有传送原因(COT)字段,如 3 表示突发、20 表示响应总召唤。IEC 104 的时标是 CP56Time2a 七字节格式,接入时必须正确解析,否则历史曲线时间轴会整体偏移。
二、采集频率设计
采集频率不是越高越好。频率由三个因素共同决定:工艺变化速度、控制/报警响应要求、以及数据库写入能力。经验上,温度、液位等慢变量 1~5 秒一次即可;电流、功率等电气量 200 ms~1 s;开关量变位需要毫秒级捕获,但应采用“变化上送”而非高频轮询。
以 1000 个模拟量点位为例,若每点每秒采集一次,实时库写入速率为 1000 点/秒,一天约 8640 万条记录。若改为 5 秒一次并启用死区过滤(如温度死区 0.2℃),实际写入量通常可下降 60%~80%。关系库则不应接收这个量级,而应通过定时任务把实时库数据按分钟聚合后写入,例如每分钟计算平均值、最大值、最小值,一天仅 1440 条/点。
三、实时库与关系库的边界划分
边界划分的核心判断标准是“访问模式”,而不是“数据新旧”。实时库面向高频写入、按时间点快速读取、保留期短;关系库面向结构化查询、聚合统计、长期归档。具体可遵循以下分工:
- 实时库:当前值快照、秒级原始历史、报警状态、画面刷新数据源。保留 7~30 天,超期自动降采样或删除。
- 关系库:点位台账(点位 ID、名称、单位、量程、所属设备)、分钟/小时/日聚合值、报警事件记录、操作日志、报表配置。长期保留。
一个常见错误是把所有原始秒级数据直接写入关系库。以 PostgreSQL 为例,单表日增千万行后,即使有索引,按时间范围查询也会明显变慢,且磁盘增长迅速。正确做法是实时库承担高频写入,关系库只接收聚合结果和业务数据。
四、数据接入实战示例
假设需要接入一台锅炉的 3 个点位:炉温(Modbus 保持寄存器 40001,浮点 ABCD)、压力(OPC UA NodeId ns=2;s=Boiler1.Press)、运行状态(IEC 104 遥信,信息体地址 0x4001)。采集周期统一设为 1 秒,死区:温度 0.2℃,压力 0.01 MPa。
Modbus 读取报文构造:从站 1,功能码 03,起始地址 0,数量 2,得到 4 字节后按 ABCD 解析为 float。OPC UA 建立 Subscription,PublishingInterval=1000ms,SamplingInterval=500ms,MonitoredItem 设置 Deadband=0.01。IEC 104 启动后先发总召唤,收到 COT=20 的响应后进入变化上送模式。
采集服务把三个点位统一为如下结构写入实时库:
{
"point_id": "BOILER1_TEMP",
"value": 186.4,
"quality": "Good",
"ts_source": "2025-03-11T08:15:22.000Z",
"ts_collect": "2025-03-11T08:15:22.180Z"
}
随后由聚合任务每分钟从实时库读取,计算 avg/max/min 写入关系库表 boiler_1min。判断接入是否成功的依据:实时库中点位值随现场变化而更新、质量戳为 Good、关系库分钟表在整分钟后出现对应记录、时间戳无整体偏移。若发现数值明显异常(如温度 1.8e38),优先检查 Modbus 字节序;若时间戳偏移 8 小时,检查 IEC 104 时标是否按 UTC 解析。
完成上述配置后,SCADA 的数据链路即形成“协议采集 → 统一模型 → 实时库高频写入 → 聚合任务 → 关系库长期存储”的闭环。后续的画面刷新、报警判断、能耗报表都建立在这条链路之上,因此协议解析的正确性、采集频率的合理性、以及两库边界的清晰度,直接决定整个能源管理系统的稳定性与可维护性。