init commit

This commit is contained in:
zhaowei.huang
2026-06-14 11:19:15 +08:00
parent e79a3815a5
commit c8e540d272
174 changed files with 60830 additions and 39 deletions
@@ -0,0 +1,587 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace StandardScene.Charge
{
/// <summary>
/// 通讯报文数据服务(单例模式)
/// </summary>
public class CommunicationMessageService
{
private static CommunicationMessageService _instance;
private static readonly object _lock = new object();
private readonly object _dataLock = new object();
private readonly AlarmConfigDataService dataService;
private readonly LinkedList<CommunicationMessage> _messages;
private const int MaxMessages = 100; // 最多保留100条
/// <summary>
/// 报文添加事件
/// </summary>
public event EventHandler<CommunicationMessage> MessageAdded;
/// <summary>
/// 获取单例实例
/// </summary>
public static CommunicationMessageService Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new CommunicationMessageService();
}
}
}
return _instance;
}
}
private CommunicationMessageService()
{
_messages = new LinkedList<CommunicationMessage>();
dataService = AlarmConfigDataService.Instance;
}
/// <summary>
/// 添加报文
/// </summary>
public void AddMessage(CommunicationMessage message)
{
if (message == null)
return;
lock (_dataLock)
{
// 添加到链表头部(最新的在前面)
_messages.AddFirst(message);
// 如果超过最大数量,移除最旧的
while (_messages.Count > MaxMessages)
{
_messages.RemoveLast();
}
}
// 触发事件
MessageAdded?.Invoke(this, message);
}
/// <summary>
/// 添加发送报文
/// </summary>
public void AddSendMessage(string ipAddress, int port, string rawData, string type, string stationId = null)
{
var message = new CommunicationMessage
{
Direction = MessageDirection.Send,
IpAddress = ipAddress,
Port = port,
RawData = rawData,
Length = rawData.Split(' ')?.Length ?? 0, // 假设是十六进制字符串
StationId = stationId,
Type = type
};
AddMessage(message);
// 发送报文后,解析并更新充电桩数据(发送方向)
ParseSendDataAndUpdateStation(ipAddress, port, rawData, type);
}
/// <summary>
/// 添加接收报文
/// </summary>
public void AddReceiveMessage(string ipAddress, int port, string rawData, string type, string stationId = null)
{
var message = new CommunicationMessage
{
Direction = MessageDirection.Receive,
IpAddress = ipAddress,
Port = port,
RawData = rawData,
Length = rawData.Split(' ')?.Length ?? 0,
StationId = stationId,
Type = type
};
AddMessage(message);
// 接收到报文后,解析并更新充电桩数据(接收方向)
ParseReceiveDataAndUpdateStation(ipAddress, port, rawData, type);
}
/// <summary>
/// 解析发送报文并更新充电桩数据
/// </summary>
private void ParseSendDataAndUpdateStation(string ipAddress, int port, string rawData, string type)
{
try
{
var dataService = ChargeStationDataService.Instance;
// 根据IP地址查找充电桩
var station = dataService.GetStationByIp(ipAddress, port);
if (station == null)
{
return; // 未找到对应充电桩,不处理
}
// 解析发送报文数据
var parsedData = ParseSendRawData(rawData, type);
if (parsedData == null)
{
return; // 解析失败,不处理
}
// 更新充电桩数据(发送方向)
UpdateStationFromSendData(station, parsedData);
// 更新到数据服务
dataService.UpdateStation(station, out string errorMessage);
}
catch
{
// 静默处理异常,不影响报文记录
}
}
/// <summary>
/// 解析接收报文并更新充电桩数据
/// </summary>
public void ParseReceiveDataAndUpdateStation(string ipAddress, int port, string rawData, string type)
{
try
{
var dataService = ChargeStationDataService.Instance;
// 根据IP地址查找充电桩
var station = dataService.GetStationByIp(ipAddress);
if (station == null)
{
return; // 未找到对应充电桩,不处理
}
// 解析接收报文数据
var parsedData = ParseReceiveRawData(rawData, type);
if (parsedData == null)
{
return; // 解析失败,不处理
}
// 更新充电桩数据(接收方向)
UpdateStationFromReceiveData(station, parsedData);
// 合并发送和接收数据,更新到数据服务
dataService.UpdateStation(station, out string errorMessage);
}
catch
{
// 静默处理异常,不影响报文记录
}
}
/// <summary>
/// 解析发送报文数据
/// </summary>
public ParsedSendData ParseSendRawData(string rawData, string type)
{
try
{
// 将逗号分隔的字符串转换为字节数组
var parts = rawData.Split(' ');
if (parts.Length < 10) // 发送报文至少10字节
{
return null;
}
var bytes = new byte[parts.Length];
for (int i = 0; i < parts.Length; i++)
{
if (!byte.TryParse(parts[i], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out bytes[i]))
{
return null;
}
}
byte chargeCommand = 0;
double setVoltage = 0;
double setCurrent = 0;
short carId = 0;
int carSoc = 0;
double carVoltage = 0;
double carCurrent = 0;
if (type == "FRLDShort")
{
chargeCommand = bytes[2];
setCurrent = BitConverter.ToInt32(new byte[] { bytes[6], bytes[5], bytes[4], bytes[3] }, 0) / 10f;
setVoltage = BitConverter.ToInt32(new byte[] { bytes[10], bytes[9], bytes[8], bytes[7] }, 0) / 10f;
carId = BitConverter.ToInt16(new byte[] { bytes[14], bytes[13] }, 0);
carSoc = bytes[15];
carVoltage = BitConverter.ToInt32(new byte[] { bytes[19], bytes[18], bytes[17], bytes[16] }, 0);
carCurrent = BitConverter.ToInt32(new byte[] { bytes[23], bytes[22], bytes[21], bytes[20] }, 0);
}
else if (type == "FRLDTall")
{
chargeCommand = bytes[1];
setCurrent = BitConverter.ToSingle(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2] }, 0);
setVoltage = BitConverter.ToSingle(new byte[] { bytes[9], bytes[8], bytes[7], bytes[6] }, 0);
carId = BitConverter.ToInt16(new byte[] { bytes[13], bytes[12] }, 0);
carSoc = BitConverter.ToInt16(new byte[] { bytes[15], bytes[14] }, 0);
carVoltage = BitConverter.ToSingle(new byte[] { bytes[19], bytes[18], bytes[17], bytes[16] }, 0);
carCurrent = BitConverter.ToSingle(new byte[] { bytes[23], bytes[22], bytes[21], bytes[20] }, 0);
}
// 解析发送报文(根据实际协议)
var parsed = new ParsedSendData
{
ChargeCommand = chargeCommand,
SetVoltage = setVoltage,
SetCurrent = setCurrent,
CurrentVehicleId = carId,
BatteryLevel = carSoc,
CarVoltage = carVoltage,
CarCurrent = carCurrent,
// 发送时间
SendTime = DateTime.Now
};
return parsed;
}
catch
{
return null;
}
}
/// <summary>
/// 解析接收报文数据
/// </summary>
public ParsedReceiveData ParseReceiveRawData(string rawData, string type)
{
try
{
// 将逗号分隔的字符串转换为字节数组
var parts = rawData.Split(' ');
if (parts.Length < 30) // 假设报文至少30字节
{
return null;
}
var bytes = new byte[parts.Length];
for (int i = 0; i < parts.Length; i++)
{
if (!byte.TryParse(parts[i], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out bytes[i]))
{
return null;
}
}
double realTimeVoltage = 0;
double realTimeCurrent = 0;
byte chargeStationStatus = 0;
byte chargeId = 0;
short batteryAH = 0;
byte mechanismStatus = 0;
byte alarmValue = 0;
if (type == "FRLDShort")
{
realTimeCurrent = BitConverter.ToInt32(new byte[] { bytes[5], bytes[4], bytes[3], bytes[2] }, 0) / 10f;
realTimeVoltage = BitConverter.ToInt32(new byte[] { bytes[9], bytes[8], bytes[7], bytes[6] }, 0) / 10f;
chargeStationStatus = bytes[14];
chargeId = bytes[15];
batteryAH = BitConverter.ToInt16(new byte[] { bytes[17], bytes[16] }, 0);
mechanismStatus = bytes[28];
}
else if (type == "FRLDTall")
{
chargeStationStatus = bytes[14];
mechanismStatus = bytes[28];
alarmValue = bytes[15];
}
// 根据实际协议解析接收数据
var parsed = new ParsedReceiveData
{
RealTimeCurrent = realTimeCurrent,
RealTimeVoltage = realTimeVoltage,
Status = type == "FRLDTall" ? ParseStationStatusFRLDTall(chargeStationStatus) : ParseStationStatus(chargeStationStatus),
ChargeID = chargeId,
BatteryAH = batteryAH,
MechanismStatus = type == "FRLDTall" ? ParseMechanismStatusFRLDTall(mechanismStatus) : ParseMechanismStatus(mechanismStatus),
HasAlarm = chargeStationStatus == 2,
AlarmCode = alarmValue,
// AlarmLevel = ParseAlarmLevel(bytes[20])
ReceiveTime = DateTime.Now
};
return parsed;
}
catch
{
return null;
}
}
/// <summary>
/// 从发送报文更新充电桩数据
/// </summary>
private void UpdateStationFromSendData(ChargeStation station, ParsedSendData parsedData)
{
// 更新发送的设定值
//station.SetVoltage = parsedData.SetVoltage;
//station.SetElectricCurrent = parsedData.SetCurrent;
// 更新最后发送时间
station.LastSendTime = parsedData.SendTime;
// 根据发送的充电指令更新状态
if (parsedData.ChargeCommand == 1)
{
// 发送了启动充电指令
station.ChargeCommandStatus = ChargeCommandStatus.Started;
}
else if (parsedData.ChargeCommand == 0)
{
// 发送了停止充电指令
station.ChargeCommandStatus = ChargeCommandStatus.Stopped;
}
station.BatteryLevel = parsedData.BatteryLevel;
station.CurrentVehicle = parsedData.CurrentVehicleId.ToString();
}
/// <summary>
/// 从接收报文更新充电桩数据
/// </summary>
private void UpdateStationFromReceiveData(ChargeStation station, ParsedReceiveData parsedData)
{
station.LastReceiveTime = parsedData.ReceiveTime;
station.MechanismStatus = parsedData.MechanismStatus;
station.RealTimeVoltage = parsedData.RealTimeVoltage;
station.RealTimeCurrent = parsedData.RealTimeCurrent;
station.Status = parsedData.Status;
station.HasAlarm = parsedData.HasAlarm;
station.AlarmLevel = parsedData.AlarmLevel;
if (parsedData.HasAlarm)
{
var alarmInfo = dataService.GetAlarmConfigAlarmCode(parsedData.AlarmCode);
if (alarmInfo != null)
{
station.AlarmMessage = $"报警级别: {GetAlarmLevelText(alarmInfo.Level)}:{alarmInfo.AlarmContent}";
}
}
else
{
station.AlarmMessage = string.Empty;
}
}
/// <summary>
/// 解析机构状态
/// </summary>
private MechanismStatus ParseMechanismStatus(byte statusByte)
{
switch (statusByte)
{
case 1: return MechanismStatus.Retracted;
case 2: return MechanismStatus.Extended;
default: return MechanismStatus.Extending;
}
}
/// <summary>
/// 解析机构状态
/// </summary>
private MechanismStatus ParseMechanismStatusFRLDTall(byte statusByte)
{
switch (statusByte)
{
case 1: return MechanismStatus.Extended;
case 2: return MechanismStatus.Retracted;
default: return MechanismStatus.Extending;
}
}
/// <summary>
/// 解析报警级别
/// </summary>
private AlarmLevel ParseAlarmLevel(byte alarmByte)
{
if (alarmByte == 0) return AlarmLevel.None;
if (alarmByte <= 2) return AlarmLevel.Low;
if (alarmByte <= 5) return AlarmLevel.Medium;
if (alarmByte <= 8) return AlarmLevel.High;
return AlarmLevel.Critical;
}
/// <summary>
/// 解析充电桩状态
/// </summary>
private ChargeStationStatus ParseStationStatus(byte statusByte)
{
switch (statusByte)
{
case 0: return ChargeStationStatus.Idle;
case 1: return ChargeStationStatus.Charging;
case 2: return ChargeStationStatus.Fault;
case 3: return ChargeStationStatus.Battery;
default: return ChargeStationStatus.Idle;
}
}
private ChargeStationStatus ParseStationStatusFRLDTall(byte statusByte)
{
switch (statusByte)
{
case 0: return ChargeStationStatus.Idle;
case 2: return ChargeStationStatus.Idle;
case 3: return ChargeStationStatus.Charging;
case 4: return ChargeStationStatus.Fault;
default: return ChargeStationStatus.Idle;
}
}
/// <summary>
/// 获取报警级别文本
/// </summary>
private string GetAlarmLevelText(AlarmLevel level)
{
switch (level)
{
case AlarmLevel.None: return "无";
case AlarmLevel.Low: return "低";
case AlarmLevel.Medium: return "中";
case AlarmLevel.High: return "高";
case AlarmLevel.Critical: return "严重";
default: return "未知";
}
}
/// <summary>
/// 解析后的发送报文数据(内部类)
/// </summary>
public class ParsedSendData
{
public byte ChargeCommand { get; set; }
public double SetVoltage { get; set; }
public double SetCurrent { get; set; }
public double BatteryLevel { get; set; }
public int CurrentVehicleId { get; set; }
public double CarVoltage { get; set; }
public double CarCurrent { get; set; }
public DateTime SendTime { get; set; }
}
/// <summary>
/// 解析后的接收报文数据(内部类)
/// </summary>
public class ParsedReceiveData
{
public CommunicationStatus CommStatus { get; set; }
public ChargeCommandStatus ChargeCommandStatus { get; set; }
public MechanismStatus MechanismStatus { get; set; }
public double RealTimeVoltage { get; set; }
public double RealTimeCurrent { get; set; }
public int ChargeID { get; set; }
public float BatteryAH { get; set; }
public bool HasAlarm { get; set; }
public AlarmLevel AlarmLevel { get; set; }
public int AlarmCode { get; set; }
public ChargeStationStatus Status { get; set; }
public DateTime ReceiveTime { get; set; }
}
/// <summary>
/// 获取所有报文
/// </summary>
public List<CommunicationMessage> GetAllMessages()
{
lock (_dataLock)
{
return _messages.ToList();
}
}
/// <summary>
/// 根据IP筛选报文
/// </summary>
public List<CommunicationMessage> GetMessagesByIp(string ipAddress)
{
if (string.IsNullOrWhiteSpace(ipAddress))
return GetAllMessages();
lock (_dataLock)
{
return _messages.Where(m => m.IpAddress == ipAddress).ToList();
}
}
/// <summary>
/// 根据充电桩ID筛选报文
/// </summary>
public List<CommunicationMessage> GetMessagesByStationId(string stationId)
{
if (string.IsNullOrWhiteSpace(stationId))
return GetAllMessages();
lock (_dataLock)
{
return _messages.Where(m => m.StationId == stationId).ToList();
}
}
/// <summary>
/// 清空所有报文
/// </summary>
public void Clear()
{
lock (_dataLock)
{
_messages.Clear();
}
}
/// <summary>
/// 获取所有唯一IP地址列表
/// </summary>
public List<string> GetUniqueIpAddresses()
{
lock (_dataLock)
{
return _messages
.Select(m => m.IpAddress)
.Distinct()
.OrderBy(ip => ip)
.ToList();
}
}
}
}