using Model.Models; using Prism.Events; using System; using System.Text; using UIShare.PubEvent; using ZLGUSBCANFD; namespace UIShare.GlobalVariable { /// /// CAN 信号广播器:订阅 ZLGCANFD.OnDbcMessageDecoded 事件, /// 将解码后的 DBC 信号值通过 HardwareDataReportedEvent 广播给监控系统。 /// 由 DeviceManager 创建和管理,生命周期与 CAN 设备绑定。 /// 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; } /// /// 绑定 CANFD 实例并订阅解码事件。 /// public void Bind(ZLGCANFD canfd) { Unbind(); _canfd = canfd; _canfd.OnDbcMessageDecoded += OnDbcMessageDecoded; } /// /// 取消订阅。 /// public void Unbind() { if (_canfd != null) { _canfd.OnDbcMessageDecoded -= OnDbcMessageDecoded; _canfd = null; } } /// /// DBC 解码回调:提取所有信号并广播。 /// 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().Publish(new HardwareReportArgs { Scope = _scopeName, HardwareFingerprint = fingerprint, MethodName = methodName, Value = physicalValue, Time = now }); } } /// /// 生成 CAN 信号的 DisplayName 格式:"{MessageName}.{SignalName}" /// public static string BuildDisplayName(string messageName, string signalName) { return $"{messageName}.{signalName}"; } /// /// 生成 CAN 信号的 MethodName 格式:"{MessageId:X}.{SignalName}" /// public static string BuildMethodName(uint messageId, string signalName) { return $"{messageId:X}.{signalName}"; } /// /// 生成 CAN 信号的 Fingerprint 格式:"CAN:{Channel}" /// public static string BuildFingerprint(uint channel) { return $"CAN:{channel}"; } public void Dispose() { if (_disposed) return; _disposed = true; Unbind(); } } }