CAN功能移植兼容
This commit is contained in:
@@ -96,8 +96,10 @@ namespace UIShare.GlobalVariable
|
||||
try
|
||||
{
|
||||
// 按指纹全局唯一创建 ZLGCANFD 实例(maxChannels 默认 4,对应 USBCANFD-400U)
|
||||
// 波特率与终端电阻从 CANConfigVM 传入,初始化并启动通道 时直接使用
|
||||
var canLazy = _globalInfo.CanPool.GetOrAdd(fingerprint, key => new Lazy<ZLGCANFD>(() =>
|
||||
new ZLGCANFD(config.CANConfig.DeviceType, config.CANConfig.DeviceIndex, 4)));
|
||||
new ZLGCANFD(config.CANConfig.DeviceType, config.CANConfig.DeviceIndex, 4,
|
||||
config.CANConfig.ABitBaud, config.CANConfig.DBitBaud, config.CANConfig.EnableTerminalResistance)));
|
||||
|
||||
_systemConfig.CANFD = canLazy.Value;
|
||||
CANFD = canLazy.Value;
|
||||
@@ -190,15 +192,22 @@ namespace UIShare.GlobalVariable
|
||||
|
||||
public async Task ConnectAllDevices(CancellationToken ct = default)
|
||||
{
|
||||
if (_systemConfig?.DeviceList == null || DeviceMap.Count == 0) return;
|
||||
if (_systemConfig?.DeviceList == null) return;
|
||||
|
||||
var tasks = new List<Task>();
|
||||
foreach (var info in _systemConfig.DeviceList)
|
||||
{
|
||||
if (info == null || !info.IsEnabled) continue;
|
||||
if (string.IsNullOrWhiteSpace(info.DeviceName)) continue;
|
||||
if (!DeviceMap.TryGetValue(info.DeviceName, out var device)) continue;
|
||||
|
||||
// CAN 设备:直接打开 CAN 卡
|
||||
if (string.Equals(info.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tasks.Add(ConnectCanAsync(info));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DeviceMap.TryGetValue(info.DeviceName, out var device)) continue;
|
||||
tasks.Add(ConnectInternalAsync(info, device, ct));
|
||||
}
|
||||
|
||||
@@ -214,15 +223,28 @@ namespace UIShare.GlobalVariable
|
||||
return;
|
||||
}
|
||||
|
||||
var info = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
LoggerHelper.Warn($"ConnectSpecifiedDevice:未找到设备配置 [{deviceName}]。");
|
||||
return;
|
||||
}
|
||||
|
||||
// CAN 设备:直接打开 CAN 卡
|
||||
if (string.Equals(info.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await ConnectCanAsync(info);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DeviceMap.TryGetValue(deviceName, out var device))
|
||||
{
|
||||
LoggerHelper.Warn($"ConnectSpecifiedDevice:未找到设备 [{deviceName}]。");
|
||||
return;
|
||||
}
|
||||
|
||||
var info = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
await ConnectInternalAsync(info, device, ct);
|
||||
}
|
||||
|
||||
@@ -233,15 +255,21 @@ namespace UIShare.GlobalVariable
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(deviceName)) return;
|
||||
|
||||
var info = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// CAN 设备:直接关闭 CAN 卡
|
||||
if (info != null && string.Equals(info.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await CloseCanAsync(info);
|
||||
return;
|
||||
}
|
||||
|
||||
IBaseInterface? device;
|
||||
DeviceInfoVM? info;
|
||||
|
||||
lock (_lockObj)
|
||||
{
|
||||
if (!DeviceMap.TryGetValue(deviceName, out device)) return;
|
||||
|
||||
info = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
await CloseInternalAsync(info, device);
|
||||
@@ -256,7 +284,7 @@ namespace UIShare.GlobalVariable
|
||||
|
||||
lock (_lockObj)
|
||||
{
|
||||
if (DeviceMap.Count == 0) return;
|
||||
if (DeviceMap.Count == 0 && (CANFD == null)) return;
|
||||
|
||||
foreach (var kvp in DeviceMap)
|
||||
{
|
||||
@@ -269,6 +297,17 @@ namespace UIShare.GlobalVariable
|
||||
}
|
||||
}
|
||||
|
||||
// CAN 设备:直接关闭 CAN 卡
|
||||
if (CANFD != null)
|
||||
{
|
||||
var canInfo = _systemConfig?.DeviceList?
|
||||
.FirstOrDefault(d => d != null && string.Equals(d.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase));
|
||||
if (canInfo != null)
|
||||
{
|
||||
tasks.Add(CloseCanAsync(canInfo));
|
||||
}
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
LoggerHelper.Info("所有设备已执行关闭操作。");
|
||||
}
|
||||
@@ -366,6 +405,88 @@ namespace UIShare.GlobalVariable
|
||||
}
|
||||
return await sp.ConnectAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开 CAN 卡:打开设备 + 初始化并启动所有通道
|
||||
/// </summary>
|
||||
private async Task<bool> ConnectCanAsync(DeviceInfoVM info)
|
||||
{
|
||||
string name = info.DeviceName ?? "CAN";
|
||||
|
||||
try
|
||||
{
|
||||
if (CANFD == null)
|
||||
{
|
||||
LoggerHelper.Warn($"CAN 设备 [{name}] 尚未实例化,无法连接。");
|
||||
info.IsConnected = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.IsConnected)
|
||||
{
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 已连接,跳过。");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ok = await Task.Run(() =>
|
||||
{
|
||||
if (!CANFD.打开设备()) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
info.IsConnected = ok;
|
||||
|
||||
if (ok)
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 连接成功,已初始化 {CANFD.DBCParser.MaxChannels} 个通道。");
|
||||
else
|
||||
LoggerHelper.Warn($"CAN 设备 [{name}] 连接失败。");
|
||||
|
||||
return ok;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
info.IsConnected = false;
|
||||
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||
LoggerHelper.ErrorWithNotify(_scopeName, $"CAN 设备 [{name}] 连接异常:{inner}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭 CAN 卡
|
||||
/// </summary>
|
||||
private async Task CloseCanAsync(DeviceInfoVM info)
|
||||
{
|
||||
string name = info.DeviceName ?? "CAN";
|
||||
|
||||
try
|
||||
{
|
||||
if (CANFD == null)
|
||||
{
|
||||
info.IsConnected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info.IsConnected)
|
||||
{
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 本就处于断开状态。");
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Run(() => CANFD.关闭CAN卡设备());
|
||||
LoggerHelper.Info($"CAN 设备 [{name}] 已成功关闭连接。");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||
LoggerHelper.Error($"CAN 设备 [{name}] 关闭连接时出现异常: {inner}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
info.IsConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, Type> BuildDeviceTypeMap()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace UIShare.GlobalVariable
|
||||
public string DefaultDBCFilePath { get; set; } = "";
|
||||
public ObservableCollection<DeviceInfoVM> DeviceList = new();
|
||||
public ObservableCollection<SharedParameter> SharedParameterList = new();
|
||||
public ObservableCollection<CANSignalConfig> ConfigurationList = new();
|
||||
public ObservableCollection<AutoDBCLoadItem> dbcAutoLoadList = new();
|
||||
public ZLGCANFD CANFD = new();
|
||||
[JsonIgnore]
|
||||
public ObservableCollection<ParameterVM> ParameterList = new()
|
||||
|
||||
33
UIShare/UIViewModel/AutoDBCLoadItemVM.cs
Normal file
33
UIShare/UIViewModel/AutoDBCLoadItemVM.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace UIShare.UIViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// CAN 通道枚举(对应 ZLGCANFD 通道选择)
|
||||
/// </summary>
|
||||
public enum APP_CHANNEL
|
||||
{
|
||||
CH0 = 0,
|
||||
CH1 = 1,
|
||||
CH2 = 2,
|
||||
CH3 = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DBC 自动加载配置项
|
||||
/// </summary>
|
||||
public class AutoDBCLoadItem : BindableBase
|
||||
{
|
||||
private int _dbcChannel;
|
||||
public int DBCChannel
|
||||
{
|
||||
get => _dbcChannel;
|
||||
set => SetProperty(ref _dbcChannel, value);
|
||||
}
|
||||
|
||||
private string _dbcFilePath;
|
||||
public string DBCFilePath
|
||||
{
|
||||
get => _dbcFilePath;
|
||||
set => SetProperty(ref _dbcFilePath, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
UIShare/UIViewModel/CANSignalConfigVM.cs
Normal file
14
UIShare/UIViewModel/CANSignalConfigVM.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace UIShare.UIViewModel
|
||||
{
|
||||
public class CANSignalConfig
|
||||
{
|
||||
public int Channel { get; set; }
|
||||
public int MessageID { get; set; }
|
||||
public string MessageName { get; set; }
|
||||
public string SignalName { get; set; }
|
||||
public int CollectionInterval { get; set; }
|
||||
public Guid CollectionID { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,9 @@
|
||||
// 字段声明
|
||||
private byte _通道;
|
||||
private int _报文ID;
|
||||
private ulong _时间戳;
|
||||
private double _时间戳;
|
||||
private byte _长度;
|
||||
private bool _fd;
|
||||
private bool _isTx;
|
||||
private byte[] _bytes = new byte[64];
|
||||
private string _报文;
|
||||
|
||||
|
||||
// 通道属性
|
||||
public byte 通道
|
||||
@@ -27,7 +24,7 @@
|
||||
}
|
||||
|
||||
// 时间戳属性
|
||||
public ulong 时间戳
|
||||
public double 时间戳
|
||||
{
|
||||
get { return _时间戳; }
|
||||
set { SetProperty(ref _时间戳, value); }
|
||||
@@ -40,32 +37,6 @@
|
||||
set { SetProperty(ref _长度, value); }
|
||||
}
|
||||
|
||||
// FD属性
|
||||
public bool FD
|
||||
{
|
||||
get { return _fd; }
|
||||
set { SetProperty(ref _fd, value); }
|
||||
}
|
||||
|
||||
// IsTx属性
|
||||
public bool IsTx
|
||||
{
|
||||
get { return _isTx; }
|
||||
set { SetProperty(ref _isTx, value); }
|
||||
}
|
||||
|
||||
// Bytes属性
|
||||
public byte[] Bytes
|
||||
{
|
||||
get { return _bytes; }
|
||||
set { SetProperty(ref _bytes, value); }
|
||||
}
|
||||
|
||||
// 报文属性
|
||||
public string 报文
|
||||
{
|
||||
get { return _报文; }
|
||||
set { SetProperty(ref _报文, value); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Prism.Dialogs;
|
||||
|
||||
namespace UIShare.ViewModelBase
|
||||
{
|
||||
@@ -11,12 +12,41 @@ namespace UIShare.ViewModelBase
|
||||
{
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
public IEventAggregator _eventAggregator;
|
||||
public IDialogService _dialogService;
|
||||
private INotificationManager _notificationManager;
|
||||
public DialogViewModelBase(IContainerProvider containerProvider)
|
||||
{
|
||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||
_dialogService = containerProvider.Resolve<IDialogService>();
|
||||
_notificationManager = containerProvider.Resolve<INotificationManager>();
|
||||
}
|
||||
|
||||
protected void ShowInfoMessageBox(string Message, Action callback)
|
||||
{
|
||||
var dialogParams = new DialogParameters();
|
||||
dialogParams.Add("Title", "提示");
|
||||
dialogParams.Add("Message", Message);
|
||||
dialogParams.Add("Icon", "info");
|
||||
dialogParams.Add("ShowOk", true);
|
||||
_dialogService.ShowDialog("MessageBoxView", dialogParams, result =>
|
||||
{
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
protected void ShowErrorMessageBox(string Message, Action callback)
|
||||
{
|
||||
var dialogParams = new DialogParameters();
|
||||
dialogParams.Add("Title", "错误");
|
||||
dialogParams.Add("Message", Message);
|
||||
dialogParams.Add("Icon", "info");
|
||||
dialogParams.Add("ShowOk", true);
|
||||
_dialogService.ShowDialog("MessageBoxView", dialogParams, result =>
|
||||
{
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
#region Dialog
|
||||
|
||||
public virtual bool CanCloseDialog() => true;
|
||||
|
||||
Reference in New Issue
Block a user