4、数据源配置:OPC DA/UA配置、Modbus TCP配置、数据库连接配置

各位工程师朋友,咱们今天聊聊数据源配置。说实话,这是整个历史趋势分析里最基础、也最容易踩坑的环节。我见过太多项目,趋势图出不来,最后发现是数据源配置出了问题。嗯,咱们一个一个来拆解。

核心观点:数据源配置就像水管工接管道。接对了,数据哗哗流;接错了,要么没水,要么漏水,要么水压不稳。我个人习惯是先画一张数据流向图,再动手配置。

数据源配置知识体系 SCADA 历史趋势系统 OPC 协议族 Modbus TCP 数据库连接 OPC DA (Windows) OPC UA (跨平台) PLC 直连 RTU 采集 SQL Server MySQL / PostgreSQL

4.1 OPC DA 与 OPC UA 配置

OPC 协议,说白了就是工业界的「通用翻译器」。不同厂家的 PLC、DCS 都讲自己的方言,OPC 负责把它们翻译成 SCADA 能听懂的话。

OPC DA(Data Access) 是老前辈了。它基于 COM/DCOM 技术,只能在 Windows 上跑。我记得十年前做一个水厂项目,OPC DA 配置折腾了我整整两天。为什么?DCOM 的权限设置太坑了。你想想看,两台工控机之间要互相访问,防火墙、用户权限、网络策略,一个不对就报错。

我的经验:OPC DA 配置时,先把两台机器的防火墙都关掉测试。通了再慢慢开端口。DCOM 配置里,把「启动权限」和「访问权限」都设为「允许所有人」。虽然不安全,但调试阶段先跑通再说。

OPC UA(Unified Architecture) 是升级版。它不再依赖 COM/DCOM,跨平台、更安全。我个人现在新项目一律用 UA。配置起来也简单很多:

// OPC UA 客户端连接示例(C#)
var config = new ApplicationConfiguration {
    ApplicationName = "MyTrendApp",
    ApplicationUri = "urn:MyCompany:MyTrendApp",
    SecurityConfiguration = new SecurityConfiguration {
        AutoAcceptUntrustedCertificates = true  // 开发环境用,生产环境要关掉
    }
};

var client = new SessionClient(config);
await client.ConnectAsync("opc.tcp://192.168.1.100:4840");
var value = await client.ReadValueAsync("ns=2;s=Tag1");

注意:OPC UA 的安全证书是个大坑。我曾经在生产环境忘了关 AutoAcceptUntrustedCertificates,结果被安全审计抓了个正着。生产环境一定要配置好证书信任链。

4.2 Modbus TCP 配置

Modbus TCP 是工业现场最常用的协议之一。它简单、可靠、占用资源少。说白了,就是主站问、从站答的问答模式。

配置 Modbus TCP 时,有几个关键参数:

参数 说明 常见值
IP 地址 从站设备的 IP 192.168.1.10
端口号 默认 502 502
从站 ID 设备地址(1-247) 1
寄存器类型 线圈、离散输入、保持寄存器、输入寄存器 保持寄存器(03功能码)
数据格式 16位、32位、浮点数、字符串 Float32(AB CD)

嗯,这里要注意数据格式。Modbus 本身不定义数据类型,全靠你约定。我遇到过最坑的一次,甲方说温度数据是浮点数,结果读出来全是乱码。查了半天,原来是字节顺序搞反了。Modbus 默认是大端模式,但有些国产设备用小端。

// Modbus TCP 读取示例(Python)
from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient('192.168.1.10', port=502)
client.connect()

# 读取保持寄存器,从地址0开始,读2个寄存器(32位浮点数)
result = client.read_holding_registers(0, 2, slave=1)
if not result.isError():
    # 大端模式解析
    import struct
    bytes_data = struct.pack('>HH', result.registers[0], result.registers[1])
    value = struct.unpack('>f', bytes_data)[0]
    print(f"温度值: {value}")

client.close()

避坑指南:我曾经在调试一个水处理项目时,Modbus 通信总是超时。后来发现是轮询频率太高,PLC 处理不过来。建议轮询间隔至少设 100ms,如果设备老旧,500ms 更稳妥。

4.3 数据库连接配置

历史趋势数据最终要存到数据库里。常用的有 SQL Server、MySQL、PostgreSQL,还有工业专用的时序数据库如 InfluxDB。

数据库连接配置,核心就三件事:连接字符串、连接池、超时设置

连接字符串 是数据库的「门牌号」。写错一个字符就连不上。我习惯把连接字符串放在配置文件里,不要硬编码。

// SQL Server 连接字符串示例
"Server=192.168.1.200;Database=SCADA_History;User Id=sa;Password=****;TrustServerCertificate=True;"

// MySQL 连接字符串
"Server=192.168.1.201;Database=SCADA_History;User=root;Password=****;SslMode=none;"

// PostgreSQL 连接字符串
"Host=192.168.1.202;Database=SCADA_History;Username=postgres;Password=****;"

连接池 是个好东西。每次读写都创建新连接,性能太差。连接池复用已有的连接,能大幅提升效率。我个人习惯设置最小连接数 5,最大连接数 50。

超时设置 容易被忽略。网络抖动时,连接超时设得太短会频繁报错,设得太长又卡死。我一般设 15 秒连接超时,30 秒命令超时。

重要提醒:数据库写频繁时,一定要用批量插入,不要一条一条 insert。我曾经见过一个项目,每秒写 1000 条数据,一条一条插,数据库直接崩了。改成批量 500 条一次提交,CPU 占用从 90% 降到 20%。

// 批量插入示例(C#)
using (var bulkCopy = new SqlBulkCopy(connectionString))
{
    bulkCopy.DestinationTableName = "HistoryData";
    bulkCopy.BatchSize = 500;
    
    DataTable dt = new DataTable();
    dt.Columns.Add("Timestamp", typeof(DateTime));
    dt.Columns.Add("TagName", typeof(string));
    dt.Columns.Add("Value", typeof(float));
    
    // 填充数据...
    bulkCopy.WriteToServer(dt);
}

好了,数据源配置这块就聊到这儿。三种方式各有适用场景:OPC UA 适合新系统、跨平台需求;Modbus TCP 适合现场设备直连;数据库连接适合已有数据平台。实际项目中,往往是三种混用。嗯,记住一点:先通再优,先把数据读上来,再慢慢优化性能。

总结一句话:数据源配置没有银弹。理解每种协议的脾气,结合现场情况灵活选择,才是工程师该有的态度。

专注资料整理