基于.NET和C#构建光伏IoT物模型方案
一、目前国内接入最常见、最有代表性的 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
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] << 8) | buffer[index + 1]);
}
}
3. 寄存器解码(倍率 + 字节序)
RegisterDecoder.cs
public static class RegisterDecoder
{
public static ushort ReadUInt16(byte[] data, int registerIndex)
{
int offset = registerIndex * 2;
return (ushort)((data[offset] << 8) | data[offset + 1]);
}
public static double ReadScaledValue(
byte[] data,
int registerIndex,
double scale)
{
return ReadUInt16(data, registerIndex) / scale;
}
}
4、光伏设备物模型定义
PvThingModel.cs
public class PvThingModel
{
public double DcVoltage { get; set; }
public double DcCurrent { get; set; }
public double DcPower { get; set; }
public double InternalTemperature { get; set; }
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
5. 从响应到物模型的映射
public static class PvThingModelBuilder
{
public static PvThingModel FromModbus(ModbusResponse response)
{
var data = response.Data;
return new PvThingModel
{
DcVoltage = RegisterDecoder.ReadScaledValue(data, 0, 10), // 30000
DcCurrent = RegisterDecoder.ReadScaledValue(data, 1, 10), // 30001
DcPower = RegisterDecoder.ReadScaledValue(data, 2, 1000), // 30002
InternalTemperature = RegisterDecoder.ReadUInt16(data, 3) // 30003
};
}
}
6. 完整示例调用(Demo)
public class Demo
{
public static void Run()
{
// 1. 构造请求
var request = new ModbusRequest
{
TransactionId = 1,
UnitId = 1,
StartAddress = 30000,
Quantity = 6
};
byte[] requestBytes = request.ToBytes();
// === 这里通常通过 TCP Socket 发送 requestBytes ===
// 2. 模拟接收到的响应报文
byte[] responseBytes =
{
0x00,0x01,0x00,0x00,0x00,0x0F,0x01,0x03,0x0C,
0x09,0xC4,0x00,0x64,0x13,0x88,0x00,0x32
};
// 3. 解析响应
var response = ModbusParser.ParseResponse(responseBytes);
// 4. 构建物模型
PvThingModel model = PvThingModelBuilder.FromModbus(response);
Console.WriteLine($"DC Voltage: {model.DcVoltage} V");
Console.WriteLine($"DC Current: {model.DcCurrent} A");
Console.WriteLine($"DC Power: {model.DcPower} kW");
Console.WriteLine($"Temperature: {model.InternalTemperature} ℃");
}
}
浙公网安备 33010602011771号