using System; using System.Buffers; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TSMasterCAN; using TSMaster; namespace UIShare.GlobalVariable { public class CANMonitoringService { public bool IsStopped { get; set; } = false; public bool IsInitialized { get; set; } = false; public bool IsRegistered { get; set; } = false; private SystemConfig _systemConfig { get; set; } public CANMonitoringService(SystemConfig systemConfig) { _systemConfig = systemConfig; CANSignalBroadcaster.RegisterService(this); IsRegistered = true; } public int Init(CancellationToken ct = default) { int re = 0; if (IsInitialized == false) { re = CAN.Init(_systemConfig.TSMasterName); } if (IsInitialized == false) { re = CAN.RegisterListener(MonitorEvent); if (re == 0) IsInitialized = true; } return re; } public ConcurrentDictionary RealTimeMessages { get; set; } = new(); public ConcurrentDictionary RealTimeSignals { get; set; } = new(); public void MonitorEvent(ref int AObj, ref TLIBCANFD AData) { if (IsStopped) return; byte[] oldbytes = null; //记录至实时报文数据库 var cpAData = AData; cpAData.FData = ArrayPool.Shared.Rent(64); Array.Copy(AData.FData, 0, cpAData.FData, 0, cpAData.FData.Length); var MessageName = $"{AData.FIdxChn}/{AData.FIdentifier}"; if (RealTimeMessages.TryGetValue(MessageName, out var v)) { oldbytes = v.FData; } RealTimeMessages[MessageName] = cpAData; //记录至DBC数据库 var dbcfind = DBCParse.MsgDatabase[AData.FIdxChn].FirstOrDefault(s => s.msg_id == cpAData.FIdentifier); if (dbcfind != null) { Array.Copy(cpAData.FData, 0, dbcfind.ACANFD.FData, 0, cpAData.FData.Length); dbcfind.ACANFD.FTimeUS = cpAData.FTimeUS; dbcfind.ACANFD.FIsFD = cpAData.FIsFD; dbcfind.ACANFD.FIsBRS = cpAData.FIsBRS; dbcfind.ACANFD.FIsESI = cpAData.FIsESI; dbcfind.ACANFD.FIsError = cpAData.FIsError; dbcfind.ACANFD.FIsRemote = cpAData.FIsRemote; dbcfind.ACANFD.FIsExt = cpAData.FIsExt; } if (oldbytes is not null) ArrayPool.Shared.Return(oldbytes); var id = AData.FIdentifier; var ch = AData.FIdxChn; var canSignalList = _systemConfig.ConfigurationList.Where(s => s.MessageID == id && s.Channel == ch).ToArray(); if (canSignalList.Length > 0) { var find = DBCParse.MsgDatabase[ch].First(s => s.msg_id == id); foreach (var item in canSignalList) { double Signalre = double.NaN; var re = CAN.GetSignalValue(ref cpAData, item.MessageName, item.SignalName, ref Signalre); //Debug.Assert(re == 0); var SinalName = $"{AData.FIdxChn}/{item.MessageName}/{item.SignalName}"; RealTimeSignals[SinalName] = Signalre; } } } /// /// 停止监测:从广播器注销并清理实时数据。 /// public void Stop() { IsStopped = true; if (IsRegistered) { CANSignalBroadcaster.UnregisterService(this); IsRegistered = false; } RealTimeSignals.Clear(); RealTimeMessages.Clear(); } } }