Files
2026-06-14 11:19:15 +08:00

13 KiB
Raw Permalink Blame History

充电桩报文分离解析使用示例

概述

系统现在支持发送报文接收报文分开解析,然后自动合并更新到充电桩管理界面。

数据流向图

┌─────────────────┐
│   应用程序      │
└────────┬────────┘
         │ 发送充电指令
         ▼
┌─────────────────────────────────────────────┐
│  CommunicationMessageService                │
│  ┌─────────────────────────────────────┐   │
│  │ AddSendMessage()                    │   │
│  │  ├─ 记录发送报文                    │   │
│  │  └─ ParseSendDataAndUpdateStation() │   │
│  │      ├─ 解析设定电压                │   │
│  │      ├─ 解析设定电流                │   │
│  │      └─ 更新充电桩设定值            │   │
│  └─────────────────────────────────────┘   │
└─────────────────┬───────────────────────────┘
                  │
                  ▼
         ┌────────────────┐
         │ ChargeStation  │ ◄─── 设定值已更新
         │   SetVoltage   │
         │   SetCurrent   │
         └────────┬───────┘
                  │
                  │ 同时...
                  │
┌─────────────────▼───────────────────────────┐
│  ChargeUdpService (监听端口40001)           │
│  ├─ 接收充电桩返回的UDP报文                 │
│  └─ 调用 AddReceiveMessage()                │
└─────────────────┬───────────────────────────┘
                  │
                  ▼
┌─────────────────────────────────────────────┐
│  CommunicationMessageService                │
│  ┌─────────────────────────────────────┐   │
│  │ AddReceiveMessage()                 │   │
│  │  ├─ 记录接收报文                    │   │
│  │  └─ ParseReceiveDataAndUpdateStation()│ │
│  │      ├─ 解析实时电压                │   │
│  │      ├─ 解析实时电流                │   │
│  │      ├─ 解析充电状态                │   │
│  │      ├─ 解析机构状态                │   │
│  │      └─ 更新充电桩实时数据          │   │
│  └─────────────────────────────────────┘   │
└─────────────────┬───────────────────────────┘
                  │
                  ▼
         ┌────────────────┐
         │ ChargeStation  │ ◄─── 实时值已更新
         │ RealTimeVoltage│
         │ RealTimeCurrent│
         │ Status         │
         │ MechanismStatus│
         └────────┬───────┘
                  │
                  ▼
    ┌─────────────────────────────┐
    │ ChargeStationManagementForm │
    │  (每2秒自动刷新)             │
    │  显示:                      │
    │  - 设定电压 vs 实时电压      │
    │  - 设定电流 vs 实时电流      │
    │  - 充电状态                  │
    │  - 机构状态                  │
    └─────────────────────────────┘

代码示例

1. 发送充电指令(自动解析发送报文)

// 在充电桩类中发送充电指令
public void StartCharging(double voltage, double current)
{
    // 构造发送报文
    byte[] sendData = new byte[10];
    sendData[5] = 1; // 充电指令:启动
    sendData[6] = (byte)((int)(voltage * 10) >> 8); // 设定电压高字节
    sendData[7] = (byte)((int)(voltage * 10) & 0xFF); // 设定电压低字节
    sendData[8] = (byte)((int)(current * 10) >> 8); // 设定电流高字节
    sendData[9] = (byte)((int)(current * 10) & 0xFF); // 设定电流低字节
    
    // 发送UDP报文
    udpClient.Send(sendData, sendData.Length, endPoint);
    
    // 记录发送报文(自动解析并更新设定值)
    var messageService = CommunicationMessageService.Instance;
    messageService.AddSendMessage(
        ipAddress: endPoint.Address.ToString(),
        port: endPoint.Port,
        rawData: string.Join(",", sendData),
        stationId: this.StationId
    );
    
    // ✅ 此时充电桩的 SetVoltage 和 SetCurrent 已自动更新
}

2. 接收充电桩反馈(自动解析接收报文)

// 在 ChargeUdpService 中接收报文
private static async void ListenerProcess()
{
    var messageService = CommunicationMessageService.Instance;
    using (UdpClient udpListener = new UdpClient(40001))
    {
        while (true)
        {
            var result = await udpListener.ReceiveAsync();
            var remoteEndPoint = result.RemoteEndPoint;
            var message = result.Buffer;
            
            // 记录接收报文(自动解析并更新实时数据)
            messageService.AddReceiveMessage(
                ipAddress: remoteEndPoint.Address.ToString(),
                port: 40001,
                rawData: string.Join(",", message)
            );
            
            // ✅ 此时充电桩的实时数据已自动更新:
            //    - RealTimeVoltage(实时电压)
            //    - RealTimeCurrent(实时电流)
            //    - Status(充电状态)
            //    - MechanismStatus(机构状态)
            //    - BatteryLevel(电量百分比)
            //    - 等等...
        }
    }
}

3. 在充电桩管理界面查看合并后的数据

// 在 ChargeStationManagementForm 中显示数据
private void LoadStations()
{
    var stations = ChargeStationDataService.Instance.GetAllStations();
    
    foreach (var station in stations)
    {
        // 显示设定值(来自发送报文解析)
        Console.WriteLine($"设定电压: {station.SetVoltage}V");
        Console.WriteLine($"设定电流: {station.SetElectricCurrent}A");
        
        // 显示实时值(来自接收报文解析)
        Console.WriteLine($"实时电压: {station.RealTimeVoltage}V");
        Console.WriteLine($"实时电流: {station.RealTimeCurrent}A");
        Console.WriteLine($"充电状态: {GetStatusText(station.Status)}");
        Console.WriteLine($"机构状态: {GetMechanismStatusText(station.MechanismStatus)}");
        Console.WriteLine($"电量: {station.BatteryLevel}%");
        
        // 显示通讯时间
        Console.WriteLine($"最后发送: {station.LastSendTime}");
        Console.WriteLine($"最后接收: {station.LastReceiveTime}");
    }
}

解析流程详解

发送报文解析流程

AddSendMessage()
    ↓
ParseSendDataAndUpdateStation()
    ↓
ParseSendRawData()  ← 解析发送报文
    ├─ ChargeCommand (字节5)
    ├─ SetVoltage (字节6-7)
    └─ SetCurrent (字节8-9)
    ↓
UpdateStationFromSendData()  ← 更新设定值
    ├─ station.SetVoltage = parsedData.SetVoltage
    ├─ station.SetElectricCurrent = parsedData.SetCurrent
    ├─ station.LastSendTime = parsedData.SendTime
    └─ station.ChargeCommandStatus = ...

接收报文解析流程

AddReceiveMessage()
    ↓
ParseReceiveDataAndUpdateStation()
    ↓
ParseReceiveRawData()  ← 解析接收报文
    ├─ CommStatus (字节28)
    ├─ ChargeCommandStatus (字节10)
    ├─ MechanismStatus (字节11)
    ├─ RealTimeVoltage (字节12-13)
    ├─ RealTimeCurrent (字节14-15)
    ├─ BatteryLevel (字节16)
    ├─ HasAlarm (字节20)
    ├─ Status (字节25)
    └─ CurrentVehicleId (字节26-29)
    ↓
UpdateStationFromReceiveData()  ← 更新实时值
    ├─ station.RealTimeVoltage = parsedData.RealTimeVoltage
    ├─ station.RealTimeCurrent = parsedData.RealTimeCurrent
    ├─ station.Status = parsedData.Status
    ├─ station.MechanismStatus = parsedData.MechanismStatus
    ├─ station.BatteryLevel = parsedData.BatteryLevel
    ├─ station.LastReceiveTime = parsedData.ReceiveTime
    └─ ...

数据对比示例

数据项 来源 更新时机 用途
SetVoltage 发送报文 发送充电指令时 显示设定的目标电压
RealTimeVoltage 接收报文 接收充电桩反馈时 显示当前实际电压
SetElectricCurrent 发送报文 发送充电指令时 显示设定的目标电流
RealTimeCurrent 接收报文 接收充电桩反馈时 显示当前实际电流
ChargeCommandStatus 发送+接收 发送指令时更新,接收反馈时确认 显示充电指令执行状态
Status 接收报文 接收充电桩反馈时 显示充电桩当前状态
MechanismStatus 接收报文 接收充电桩反馈时 显示机构伸缩状态
BatteryLevel 接收报文 接收充电桩反馈时 显示电池电量百分比
LastSendTime 发送报文 发送充电指令时 显示最后发送时间
LastReceiveTime 接收报文 接收充电桩反馈时 显示最后接收时间

优势

数据分离:发送和接收数据各自独立,不会互相覆盖
完整记录:同时保留设定值和实时值,便于对比分析
自动合并:系统自动将两种数据合并到同一个充电桩对象
实时更新:界面每2秒自动刷新,显示最新数据
易于调试:可以清楚看到发送的指令和接收的反馈

调试技巧

1. 查看报文记录

var messageService = CommunicationMessageService.Instance;

// 查看所有报文
var allMessages = messageService.GetAllMessages();

// 查看某个IP的报文
var ipMessages = messageService.GetMessagesByIp("192.168.1.101");

// 查看某个充电桩的报文
var stationMessages = messageService.GetMessagesByStationId("1");

foreach (var msg in allMessages)
{
    Console.WriteLine($"[{msg.Direction}] {msg.IpAddress}:{msg.Port}");
    Console.WriteLine($"时间: {msg.Timestamp}");
    Console.WriteLine($"数据: {msg.RawData}");
    Console.WriteLine("---");
}

2. 对比设定值与实时值

var station = ChargeStationDataService.Instance.GetStationByIp("192.168.1.101");

if (station != null)
{
    // 电压对比
    double voltageDiff = Math.Abs(station.SetVoltage - station.RealTimeVoltage);
    Console.WriteLine($"电压偏差: {voltageDiff}V");
    
    // 电流对比
    double currentDiff = Math.Abs(station.SetElectricCurrent - station.RealTimeCurrent);
    Console.WriteLine($"电流偏差: {currentDiff}A");
    
    // 通讯延迟
    if (station.LastSendTime != null && station.LastReceiveTime != null)
    {
        var delay = station.LastReceiveTime.Value - station.LastSendTime.Value;
        Console.WriteLine($"通讯延迟: {delay.TotalMilliseconds}ms");
    }
}

3. 监控解析错误

如果数据没有更新,检查以下几点:

  1. IP地址是否匹配:确保充电桩的IP地址在管理列表中
  2. 报文长度是否足够:发送报文至少10字节,接收报文至少30字节
  3. 字节位置是否正确:根据实际协议调整字节位置
  4. 数据类型是否正确:检查高低字节顺序、单位换算等

注意事项

⚠️ 字节位置:示例中的字节位置仅供参考,请根据实际通讯协议调整
⚠️ 报文格式:确保发送和接收的报文格式与解析规则一致
⚠️ 异常处理:解析失败不会影响报文记录,但数据不会更新
⚠️ 线程安全CommunicationMessageService 使用单例模式,内部已做线程同步

总结

通过分离解析发送和接收报文,系统可以:

  • 准确记录每次发送的指令参数
  • 准确获取充电桩的实时反馈
  • 自动合并两种数据到充电桩管理界面
  • 便于对比分析和故障诊断

这种设计使得充电桩管理更加精确和可靠!