3. 数据采集层部署:风机PLC数据采集协议配置、采集网关部署、数据清洗与预处理

好,咱们进入第三章节。数据采集层,说白了就是风场的“耳朵”和“眼睛”。你想想看,如果连风机转没转、发了多少电都拿不到,那远程监控就是个空壳子。这一章,我重点讲三件事:协议怎么配、网关怎么装、数据怎么洗。

核心逻辑:数据采集层是连接物理风机与数字平台的桥梁。协议选不对,数据传不上来;网关部署不好,数据会丢包;清洗做不干净,分析全是垃圾。

数据采集层核心架构 风机1号 风机2号 风机N号 协议适配层 Modbus TCP OPC UA IEC 61400-25 自定义协议 采集网关 数据汇聚 协议转换 边缘计算 数据清洗 去重 补零 滤波 格式统一 → 监控平台

3.1 Modbus TCP 协议配置

Modbus TCP 是风场里最常见的协议之一。很多老风机、国产风机都支持。我个人习惯,先确认风机PLC的IP地址和端口号,默认一般是502端口。

配置时,你需要知道每个寄存器的地址。比如风速、功率、桨距角,它们都对应着特定的寄存器编号。我在项目中遇到过,有些厂家给的寄存器表是错的,或者版本没更新。嗯,这里要注意:一定要现场用Modbus扫描工具读一遍,确认地址和数据类型

小技巧:用 Modbus Poll 或 QModMaster 先离线测试。我曾经在甘肃一个风场,就是因为没提前测试,结果网关上去后读回来的全是乱码——原来是寄存器字节顺序搞反了。

下面是一个典型的 Modbus TCP 读取配置示例:

# 风机PLC Modbus TCP 配置示例
PLC_IP = "192.168.1.100"
PLC_PORT = 502
SLAVE_ID = 1

# 寄存器映射表
REGISTERS = {
    "wind_speed":      {"addr": 0x0000, "type": "float32", "unit": "m/s"},
    "active_power":    {"addr": 0x0002, "type": "float32", "unit": "kW"},
    "rotor_speed":     {"addr": 0x0004, "type": "float32", "unit": "rpm"},
    "pitch_angle":     {"addr": 0x0006, "type": "float32", "unit": "deg"},
    "grid_frequency":  {"addr": 0x0008, "type": "float32", "unit": "Hz"}
}

# 读取函数(伪代码)
def read_modbus_data():
    client = ModbusClient(PLC_IP, PLC_PORT)
    client.connect()
    for tag, cfg in REGISTERS.items():
        raw = client.read_holding_registers(cfg["addr"], 2)
        value = decode_float32(raw)  # 注意字节序
        print(f"{tag}: {value} {cfg['unit']}")
    client.close()

3.2 OPC UA 协议配置

OPC UA 比 Modbus 高级不少。它自带安全机制,支持数据订阅,而且能自动发现节点。现在新风机基本都支持 OPC UA。我建议,如果条件允许,优先用 OPC UA。

配置 OPC UA 时,核心是找到正确的节点ID(NodeId)。每个数据点都有一个唯一的节点路径。比如:

# OPC UA 节点路径示例
ns=2;s=WindTurbine.WTG01.Generator.ActivePower
ns=2;s=WindTurbine.WTG01.Nacelle.WindSpeed
ns=2;s=WindTurbine.WTG01.Rotor.RotorSpeed

为什么会这样?因为 OPC UA 的命名空间(Namespace)和标识符(Identifier)是分层设计的。你想想看,一个风场几十台风机,每台风机几百个数据点,如果没有这种结构化的命名方式,管理起来会非常混乱。

避坑指南:我曾经在山东一个海上风场,OPC UA 服务器配置了安全证书,但网关没导入证书,结果一直连不上。折腾了两天才发现是证书问题。所以,OPC UA 的安全配置一定要提前和风机厂家确认,是采用 Basic256Sha256 还是 Basic128Rsa15,别想当然。

3.3 采集网关部署

采集网关是数据采集层的“大脑”。它负责把各种协议的数据收上来,再统一转发到监控平台。网关的选型,我一般看三点:

  • 协议支持能力:是否同时支持 Modbus TCP、OPC UA、IEC 61400-25 等
  • 边缘计算能力:能否在本地做简单的数据聚合和过滤
  • 环境适应性:工业级温度范围、防护等级、电磁兼容性

部署时,网关一般放在风机塔基的电气柜里,或者升压站的机柜中。我个人习惯,每台风机配一个网关,或者每 3-5 台风机共用一个网关,看距离和网络条件。

部署方式 优点 缺点 适用场景
一对一(每台风机一个网关) 故障隔离好,调试方便 成本高,维护量大 大型风场、关键风机
多对一(多台风机共享网关) 成本低,部署简单 单点故障风险,网络带宽要求高 小型风场、分布式风电
环网+集中网关 可靠性高,冗余好 配置复杂,调试周期长 海上风场、大型基地

部署小贴士:网关的电源一定要稳定。我见过太多因为电源波动导致网关反复重启的案例。建议用工业级 DC-DC 电源模块,输入范围 9-36V,输出 24V。另外,网线要用屏蔽双绞线,接地要做好,不然雷雨天气容易烧端口。

3.4 数据清洗与预处理

数据采集上来,不能直接用。为什么?因为现场环境太复杂了。传感器可能漂移、通信可能丢包、PLC 可能死机。数据清洗,说白了就是把这些“脏数据”处理掉。

我总结了一套清洗流程,供你参考:

  1. 去重:同一时间戳的数据只保留一条。有时候网关会重复发送,导致数据冗余。
  2. 补零/插值:对于短暂缺失的数据,用线性插值或前值填充。比如风速缺失 1-2 秒,可以用前后值平均一下。
  3. 限幅滤波:超出物理范围的数据直接丢弃。比如风速不可能超过 50m/s,功率不可能为负值。
  4. 格式统一:把所有数据转换成统一的时间格式、单位、精度。比如时间统一为 UTC,功率统一为 kW。

核心原则:清洗的目的是“去伪存真”,不是“篡改数据”。不要为了好看而过度平滑数据,那样会丢失真实的风机运行特征。

下面是一个简单的数据清洗代码示例:

# 数据清洗预处理示例
import pandas as pd
import numpy as np

def clean_wind_data(df):
    # 1. 去重:按时间戳去重
    df = df.drop_duplicates(subset='timestamp')
    
    # 2. 限幅滤波:风速 0-50 m/s,功率 0-5000 kW
    df = df[(df['wind_speed'] >= 0) & (df['wind_speed'] <= 50)]
    df = df[(df['active_power'] >= 0) & (df['active_power'] <= 5000)]
    
    # 3. 线性插值:缺失值不超过 5 秒的进行插值
    df = df.set_index('timestamp').resample('1S').asfreq()
    df = df.interpolate(method='linear', limit=5)
    
    # 4. 格式统一:保留两位小数
    df = df.round(2)
    
    return df.reset_index()

嗯,这里要注意:清洗参数要根据实际风机的特性来调整。比如有的老旧风机,功率波动本来就大,限幅阈值就要放宽一些。我在内蒙古一个风场就吃过这个亏,限幅设得太死,结果把正常的数据都滤掉了,导致后续分析完全失真。

避坑指南:数据清洗一定要保留原始数据备份。我曾经见过有人直接覆盖原始数据,结果清洗逻辑有 bug,所有数据都变成了 NaN,想恢复都恢复不了。所以,永远保留一份 raw data,清洗后的数据另存一份。

好了,数据采集层的内容就这些。协议配置、网关部署、数据清洗,这三步走扎实了,后面的监控和分析才有意义。记住,数据质量决定监控系统的上限。

公众号:蓝海资料掘金营,微信deep3321