一、目前国内接入最常见、最有代表性的 4 类光伏设备
二、华为 SUN2000 逆变器通讯报文示例
这是一个标准 Modbus TCP 请求报文:
00 01 00 00 00 06 01 03 75 30 00 06
含义:
Modbus TCP 报文由两部分组成:
MBAP Header(7字节) + PDU(功能码 + 数据)
在光伏逆变器里,这类请求通常用于:
响应
这是一个标准的Modbus TCP 响应报文结构
00 01 00 00 00 0F 01 03 0C 09 C4 00 64 13 88 00 32
MBAP Header(7字节) + PDU(功能码 + 数据)
PDU数据解析
结合光伏业务的数值换算
厂家协议通常定义 倍率(Scale):
最终物模型字段赋值示例
{ “dcVoltage”: 250.0, “dcCurrent”: 10.0, “dcPower”: 5.0, “internalTemp”: 50 }
三、示例代码
报文请求构造 → 响应报文解析 → 寄存器解码 → 光伏设备物模型组织
目标:
- 协议层、解析层、物模型层解耦
- 方便后续做 多品牌 Adapter + 配置化映射
代码结构
1、Modbus TCP 请求报文构造
ModbusRequest.cs- public class ModbusRequest
- {
- public ushort TransactionId { get; set; }
- public byte UnitId { get; set; }
- public byte FunctionCode { get; set; } = 0x03;
- public ushort StartAddress { get; set; }
- public ushort Quantity { get; set; }
- public byte[] ToBytes()
- {
- var buffer = new List<byte>();
- // Transaction ID
- buffer.AddRange(BitConverter.GetBytes(TransactionId).Reverse());
- // Protocol ID (0x0000)
- buffer.Add(0x00);
- buffer.Add(0x00);
- // Length = UnitId + PDU
- ushort length = 1 + 1 + 2 + 2;
- buffer.AddRange(BitConverter.GetBytes(length).Reverse());
- // Unit ID
- buffer.Add(UnitId);
- // PDU
- buffer.Add(FunctionCode);
- buffer.AddRange(BitConverter.GetBytes(StartAddress).Reverse());
- buffer.AddRange(BitConverter.GetBytes(Quantity).Reverse());
- return buffer.ToArray();
- }
- }
复制代码 2. Modbus TCP 响应解析
ModbusResponse.cs- public class ModbusResponse
- {
- public ushort TransactionId { get; set; }
- public byte UnitId { get; set; }
- public byte FunctionCode { get; set; }
- public byte ByteCount { get; set; }
- public byte[] Data { get; set; }
- }
复制代码 ModbusParser.cs
[code]public static class ModbusParser{ public static ModbusResponse ParseResponse(byte[] response) { if (response.Length < 9) throw new Exception("Invalid Modbus response length"); var result = new ModbusResponse(); result.TransactionId = ReadUInt16(response, 0); ushort protocolId = ReadUInt16(response, 2); ushort length = ReadUInt16(response, 4); if (protocolId != 0) throw new Exception("Invalid Protocol ID"); result.UnitId = response[6]; result.FunctionCode = response[7]; result.ByteCount = response[8]; result.Data = response.Skip(9).Take(result.ByteCount).ToArray(); return result; } private static ushort ReadUInt16(byte[] buffer, int index) { return (ushort)((buffer[index] |