做光伏运维时经常遇到这类情况:电站里有一批 8-10 年前的老旧逆变器,原厂家可能已经合并或不再提供支持,文档找不到,技术支持也联系不上。但这些设备仍在发电,运维负责人和 EPC 工程师需要把它们的数据接入新系统。
这种情况下,协议逆向工程是绕不开的工作。下面把我们在多个电站改造项目中沉淀的方法论整理出来,给数采工程师和协议运行时开发者参考。
一、先盘点现场能拿到什么
动手抓包前,先做一次现场盘点:
- 设备品牌、型号、固件版本,优先看铭牌和上位机关于页;
- 通讯接口物理形态,确认是 RS485、RS232、以太网,还是混合接口;
- 已有文档,哪怕是中文残页、销售 PPT、安装手册或调试记录;
- 现场是否还有可用的原厂监控软件,很多老设备配过 Windows 客户端,仍能产生可对照的报文和数值。
这一步决定后续是「从零开始」还是「已有部分线索」。有原厂监控软件可对照时,效率通常能提升数倍,因为原始报文和业务数值可以互相印证。
二、抓包工具与抓包方式
目标是拿到「主站 -> 设备」和「设备 -> 主站」的完整双向报文样本,并尽量记录方向、时间戳和触发场景。
RS485 抓包
- 使用支持监听 / 旁路的 RS485 转 USB 适配器,关键是不启用本地发送,只接收总线数据;
- 串口抓包可使用 Termite、Serial Port Monitor 等工具,或自己写日志脚本;
- 让已知可用的主站(原厂监控软件或调试软件)正常通讯,抓包工具同时记录。
RS485 是半双工总线,简单旁路通常可以同时看到两侧数据。若需要严格区分收发方向,建议用两路适配器分别监听 A/B 差分线和发送使能 / 方向线,或用逻辑分析仪辅助判断。
以太网抓包
- Wireshark + 交换机端口镜像(SPAN / port mirror);
- 条件允许时使用网络分路器(TAP)或独立镜像口,减少对原链路的影响。
三、识别协议家族
抓包后先按帧特征做初筛:
| 报文特征 | 初步判断 | 备注 |
|---|---|---|
每帧以 0x68 起始 | 可能是 DL/T 645 或 IEC 60870-5-104 类 | 结合串口 / TCP、地址和校验进一步确认 |
每帧以 0x7E 起始 | HDLC / PPP 类帧格式 | 多见于串行链路 |
出现 ASCII : 开头 | Modbus ASCII | 帧内为十六进制 ASCII 字符 |
| 二进制,典型 8 字节请求 + N 字节应答 + CRC16 | Modbus RTU | 光伏逆变器最常见 |
含 0x01 SOH、0x03 ETX 等控制字符 | 厂商私有协议 | 需要按私有协议逆向 |
帧特征只是初筛,不能只凭起始字节下结论。应结合从站地址、功能码、长度字段和校验算法一起确认。
四、Modbus RTU 逆向
如果识别为 Modbus RTU:
- 确定从站地址:请求帧第 1 字节通常是从站地址,常见 1-10;
- 确定功能码:第 2 字节,常见
03(读保持寄存器)和04(读输入寄存器); - 确定寄存器范围:第 3-4 字节为起始地址,第 5-6 字节为寄存器数量;
- 逐个匹配寄存器:让设备在已知工况下运行,例如先稳定输出 5 kW,再切换到 10 kW,观察哪些寄存器同步变化;
- 确定缩放因子:用两次已知工况的数值比例推断线性缩放;对频率、功率因数等非线性量要谨慎,最好用原厂监控、面板读数或多个测点交叉锚定;
- 确定字节序:32-bit 值通常由两个 16-bit 寄存器拼接,按
ABCD、CDAB、BADC、DCBA四种组合逐一试验,部分厂家还会混用字节序和字序。
安全提示:逆向过程中先做只读扫描,避免在未确认语义前写寄存器。误写控制寄存器可能导致设备停机、参数异常甚至损坏设备。
完成这一步,通常能映射出大部分常用测点:有功功率、电压、电流、温度、运行状态和故障码。
五、私有协议逆向
如果是厂商私有协议,工程量会明显增加:
- 找帧分隔符:是固定起始 / 结束字节,还是长度字段引导;
- 找校验机制:CRC16、CRC32、Checksum、XOR,还是无校验;
- 找命令码:哪一字节表示命令,如何区分请求和应答;
- 找数据布局:应答数据按固定长度还是 TLV 组织;
- 找加密 / 混淆:是否存在简单 XOR 混淆、滚动码或时间相关扰动。
经验上,单人单台老设备从零逆向通常 1-2 周起步,遇到加密或混淆可能更长;同品牌多台设备可并行找规律,显著加速。
六、点表声明的工程化
逆向出来的协议,最终产物应是一份声明式点表,而不是散落在脚本里的硬编码。
device: legacy-vendor-x-50kw
protocol: modbus-rtu
transport: rs485
slave_id: 1
baud_rate: 9600
parity: none
stop_bits: 1
registers:
- name: active_power_kw
address: 0x0010
count: 2
type: float32
byte_order: ABCD
scale: 0.1
unit: kW
- name: dc_voltage_v
address: 0x0020
count: 1
type: uint16
scale: 0.1
unit: V
- name: device_state
address: 0x0050
count: 1
type: enum
enum:
0: stopped
1: starting
2: running
3: fault
点表作为协议运行时的输入,做到声明与解析器分离:点表描述「数据在哪里、如何解释」,运行时负责「如何采集、如何校验、如何暴露」。后续遇到同型号设备,直接复用点表即可。
七、验证与回归
点表必须在多种工况下回归:
- 正常发电;
- 雨天或低功率;
- 故障状态;
- 启停过程;
- 通讯抖动、超时或异常帧。
每种工况下,把逆向解出的值与原厂监控、逆变器面板或电能表读数对比;不一致就修正点表。原始抓包、固件版本、设备序列号和测试环境应留档,便于复现和仲裁。
八、沉淀到协议运行时
单个老设备的逆向做完一次就过去了,价值有限;真正降低重复工作量的是把它沉淀为可复用能力:
- 逆向后的点表进入协议包库;
- 该型号设备的 quirks(字节序、单位、枚举映射、异常处理)做成增量包;
- 后续遇到同型号设备直接加载,不再重新逆向。
这是我们在已有厂商 API 之外,通过协议包和 quirks 覆盖多种老旧协议的方式:新现场遇到老型号,优先复用已有点表,必要时再做增量补丁。
TL;DR
老旧逆变器协议逆向 = 现场盘点 + 抓包识别 + 协议家族判断 + Modbus / 私有协议拆解 + 声明式点表 + 多工况验证。单台 1-2 周起步;先只读、不盲写;原始抓包留档;把单台成果沉淀为可复用的协议包,是降低重复工作量的关键。


被折叠的 条评论
为什么被折叠?



