321 lines
13 KiB
Markdown
321 lines
13 KiB
Markdown
# 充电桩报文分离解析使用示例
|
||||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
系统现在支持**发送报文**和**接收报文**分开解析,然后自动合并更新到充电桩管理界面。
|
|||
|
|
|
|||
|
|
## 数据流向图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 应用程序 │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│ 发送充电指令
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────────────────────┐
|
|||
|
|
│ CommunicationMessageService │
|
|||
|
|
│ ┌─────────────────────────────────────┐ │
|
|||
|
|
│ │ AddSendMessage() │ │
|
|||
|
|
│ │ ├─ 记录发送报文 │ │
|
|||
|
|
│ │ └─ ParseSendDataAndUpdateStation() │ │
|
|||
|
|
│ │ ├─ 解析设定电压 │ │
|
|||
|
|
│ │ ├─ 解析设定电流 │ │
|
|||
|
|
│ │ └─ 更新充电桩设定值 │ │
|
|||
|
|
│ └─────────────────────────────────────┘ │
|
|||
|
|
└─────────────────┬───────────────────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌────────────────┐
|
|||
|
|
│ ChargeStation │ ◄─── 设定值已更新
|
|||
|
|
│ SetVoltage │
|
|||
|
|
│ SetCurrent │
|
|||
|
|
└────────┬───────┘
|
|||
|
|
│
|
|||
|
|
│ 同时...
|
|||
|
|
│
|
|||
|
|
┌─────────────────▼───────────────────────────┐
|
|||
|
|
│ ChargeUdpService (监听端口40001) │
|
|||
|
|
│ ├─ 接收充电桩返回的UDP报文 │
|
|||
|
|
│ └─ 调用 AddReceiveMessage() │
|
|||
|
|
└─────────────────┬───────────────────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────────────────────┐
|
|||
|
|
│ CommunicationMessageService │
|
|||
|
|
│ ┌─────────────────────────────────────┐ │
|
|||
|
|
│ │ AddReceiveMessage() │ │
|
|||
|
|
│ │ ├─ 记录接收报文 │ │
|
|||
|
|
│ │ └─ ParseReceiveDataAndUpdateStation()│ │
|
|||
|
|
│ │ ├─ 解析实时电压 │ │
|
|||
|
|
│ │ ├─ 解析实时电流 │ │
|
|||
|
|
│ │ ├─ 解析充电状态 │ │
|
|||
|
|
│ │ ├─ 解析机构状态 │ │
|
|||
|
|
│ │ └─ 更新充电桩实时数据 │ │
|
|||
|
|
│ └─────────────────────────────────────┘ │
|
|||
|
|
└─────────────────┬───────────────────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌────────────────┐
|
|||
|
|
│ ChargeStation │ ◄─── 实时值已更新
|
|||
|
|
│ RealTimeVoltage│
|
|||
|
|
│ RealTimeCurrent│
|
|||
|
|
│ Status │
|
|||
|
|
│ MechanismStatus│
|
|||
|
|
└────────┬───────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────┐
|
|||
|
|
│ ChargeStationManagementForm │
|
|||
|
|
│ (每2秒自动刷新) │
|
|||
|
|
│ 显示: │
|
|||
|
|
│ - 设定电压 vs 实时电压 │
|
|||
|
|
│ - 设定电流 vs 实时电流 │
|
|||
|
|
│ - 充电状态 │
|
|||
|
|
│ - 机构状态 │
|
|||
|
|
└─────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 代码示例
|
|||
|
|
|
|||
|
|
### 1. 发送充电指令(自动解析发送报文)
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 在充电桩类中发送充电指令
|
|||
|
|
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. 接收充电桩反馈(自动解析接收报文)
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 在 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. 在充电桩管理界面查看合并后的数据
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 在 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. 查看报文记录
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
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. 对比设定值与实时值
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
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` 使用单例模式,内部已做线程同步
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
通过分离解析发送和接收报文,系统可以:
|
|||
|
|
- 准确记录每次发送的指令参数
|
|||
|
|
- 准确获取充电桩的实时反馈
|
|||
|
|
- 自动合并两种数据到充电桩管理界面
|
|||
|
|
- 便于对比分析和故障诊断
|
|||
|
|
|
|||
|
|
这种设计使得充电桩管理更加精确和可靠!
|
|||
|
|
|
|||
|
|
|
|||
|
|
|