115 lines
3.5 KiB
C#
115 lines
3.5 KiB
C#
using Model.Models;
|
||
using Prism.Events;
|
||
using System;
|
||
using System.Text;
|
||
using UIShare.PubEvent;
|
||
using ZLGUSBCANFD;
|
||
|
||
namespace UIShare.GlobalVariable
|
||
{
|
||
/// <summary>
|
||
/// CAN 信号广播器:订阅 ZLGCANFD.OnDbcMessageDecoded 事件,
|
||
/// 将解码后的 DBC 信号值通过 HardwareDataReportedEvent 广播给监控系统。
|
||
/// 由 DeviceManager 创建和管理,生命周期与 CAN 设备绑定。
|
||
/// </summary>
|
||
public class CANSignalBroadcaster : IDisposable
|
||
{
|
||
private readonly IEventAggregator _eventAggregator;
|
||
private readonly string _scopeName;
|
||
private ZLGCANFD? _canfd;
|
||
private bool _disposed;
|
||
|
||
public CANSignalBroadcaster(IEventAggregator eventAggregator, string scopeName)
|
||
{
|
||
_eventAggregator = eventAggregator;
|
||
_scopeName = scopeName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定 CANFD 实例并订阅解码事件。
|
||
/// </summary>
|
||
public void Bind(ZLGCANFD canfd)
|
||
{
|
||
Unbind();
|
||
_canfd = canfd;
|
||
_canfd.OnDbcMessageDecoded += OnDbcMessageDecoded;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消订阅。
|
||
/// </summary>
|
||
public void Unbind()
|
||
{
|
||
if (_canfd != null)
|
||
{
|
||
_canfd.OnDbcMessageDecoded -= OnDbcMessageDecoded;
|
||
_canfd = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// DBC 解码回调:提取所有信号并广播。
|
||
/// </summary>
|
||
private void OnDbcMessageDecoded(uint channel, ZDBC.DBCMessage msg)
|
||
{
|
||
if (_disposed) return;
|
||
|
||
string fingerprint = $"CAN:{channel}";
|
||
var now = DateTime.Now;
|
||
|
||
for (int i = 0; i < msg.nSignalCount; i++)
|
||
{
|
||
var signal = msg.vSignals[i];
|
||
string signalName = Encoding.Default.GetString(signal.strName).TrimEnd('\0');
|
||
if (string.IsNullOrEmpty(signalName)) continue;
|
||
|
||
// 计算物理值:physical = raw * factor + offset
|
||
double physicalValue = signal.nRawvalue * signal.nFactor + signal.nOffset;
|
||
|
||
// MethodName 格式:"{MessageId:X}.{SignalName}"
|
||
string methodName = $"{msg.nID:X}.{signalName}";
|
||
|
||
_eventAggregator.GetEvent<HardwareDataReportedEvent>().Publish(new HardwareReportArgs
|
||
{
|
||
Scope = _scopeName,
|
||
HardwareFingerprint = fingerprint,
|
||
MethodName = methodName,
|
||
Value = physicalValue,
|
||
Time = now
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成 CAN 信号的 DisplayName 格式:"{MessageName}.{SignalName}"
|
||
/// </summary>
|
||
public static string BuildDisplayName(string messageName, string signalName)
|
||
{
|
||
return $"{messageName}.{signalName}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成 CAN 信号的 MethodName 格式:"{MessageId:X}.{SignalName}"
|
||
/// </summary>
|
||
public static string BuildMethodName(uint messageId, string signalName)
|
||
{
|
||
return $"{messageId:X}.{signalName}";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成 CAN 信号的 Fingerprint 格式:"CAN:{Channel}"
|
||
/// </summary>
|
||
public static string BuildFingerprint(uint channel)
|
||
{
|
||
return $"CAN:{channel}";
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
if (_disposed) return;
|
||
_disposed = true;
|
||
Unbind();
|
||
}
|
||
}
|
||
}
|