using System; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace StandardScene.Charge { /// /// 通讯报文数据服务(单例模式) /// 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 _messages; private const int MaxMessages = 100; // 最多保留100条 /// /// 报文添加事件 /// public event EventHandler MessageAdded; /// /// 获取单例实例 /// public static CommunicationMessageService Instance { get { if (_instance == null) { lock (_lock) { if (_instance == null) { _instance = new CommunicationMessageService(); } } } return _instance; } } private CommunicationMessageService() { _messages = new LinkedList(); dataService = AlarmConfigDataService.Instance; } /// /// 添加报文 /// public void AddMessage(CommunicationMessage message) { if (message == null) return; lock (_dataLock) { // 添加到链表头部(最新的在前面) _messages.AddFirst(message); // 如果超过最大数量,移除最旧的 while (_messages.Count > MaxMessages) { _messages.RemoveLast(); } } // 触发事件 MessageAdded?.Invoke(this, message); } /// /// 添加发送报文 /// 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); } /// /// 添加接收报文 /// 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); } /// /// 解析发送报文并更新充电桩数据 /// 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 { // 静默处理异常,不影响报文记录 } } /// /// 解析接收报文并更新充电桩数据 /// 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 { // 静默处理异常,不影响报文记录 } } /// /// 解析发送报文数据 /// 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; } } /// /// 解析接收报文数据 /// 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; } } /// /// 从发送报文更新充电桩数据 /// 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(); } /// /// 从接收报文更新充电桩数据 /// 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; } } /// /// 解析机构状态 /// private MechanismStatus ParseMechanismStatus(byte statusByte) { switch (statusByte) { case 1: return MechanismStatus.Retracted; case 2: return MechanismStatus.Extended; default: return MechanismStatus.Extending; } } /// /// 解析机构状态 /// private MechanismStatus ParseMechanismStatusFRLDTall(byte statusByte) { switch (statusByte) { case 1: return MechanismStatus.Extended; case 2: return MechanismStatus.Retracted; default: return MechanismStatus.Extending; } } /// /// 解析报警级别 /// 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; } /// /// 解析充电桩状态 /// 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; } } /// /// 获取报警级别文本 /// 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 "未知"; } } /// /// 解析后的发送报文数据(内部类) /// 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; } } /// /// 解析后的接收报文数据(内部类) /// 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; } } /// /// 获取所有报文 /// public List GetAllMessages() { lock (_dataLock) { return _messages.ToList(); } } /// /// 根据IP筛选报文 /// public List GetMessagesByIp(string ipAddress) { if (string.IsNullOrWhiteSpace(ipAddress)) return GetAllMessages(); lock (_dataLock) { return _messages.Where(m => m.IpAddress == ipAddress).ToList(); } } /// /// 根据充电桩ID筛选报文 /// public List GetMessagesByStationId(string stationId) { if (string.IsNullOrWhiteSpace(stationId)) return GetAllMessages(); lock (_dataLock) { return _messages.Where(m => m.StationId == stationId).ToList(); } } /// /// 清空所有报文 /// public void Clear() { lock (_dataLock) { _messages.Clear(); } } /// /// 获取所有唯一IP地址列表 /// public List GetUniqueIpAddresses() { lock (_dataLock) { return _messages .Select(m => m.IpAddress) .Distinct() .OrderBy(ip => ip) .ToList(); } } } }