Files
ADP/UIShare/GlobalVariable/CANSignalBroadcaster.cs
2026-07-10 09:56:59 +08:00

115 lines
3.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
}
}
}