107 lines
3.9 KiB
C#
107 lines
3.9 KiB
C#
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<string, TLIBCANFD> RealTimeMessages { get; set; } = new();
|
|
public ConcurrentDictionary<string, double> 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<byte>.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<byte>.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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止监测:从广播器注销并清理实时数据。
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
IsStopped = true;
|
|
if (IsRegistered)
|
|
{
|
|
CANSignalBroadcaster.UnregisterService(this);
|
|
IsRegistered = false;
|
|
}
|
|
RealTimeSignals.Clear();
|
|
RealTimeMessages.Clear();
|
|
}
|
|
}
|
|
}
|