设备列表
This commit is contained in:
@@ -1,45 +1,140 @@
|
||||
using DeviceCommand.Base;
|
||||
using DeviceCommand.Device;
|
||||
using Logger;
|
||||
using Prism.Ioc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace UIShare.GlobalVariable
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备管理器:根据 <see cref="SystemConfig.DeviceList"/> 反射实例化所有启用的设备,
|
||||
/// 通过 <see cref="IBaseInterface"/> 多态统一管理,避免为每种设备单独硬编码字段。
|
||||
/// </summary>
|
||||
public class DeviceManager
|
||||
{
|
||||
public SystemConfig _systemConfig { get; set; }
|
||||
public IContainerProvider _containerProvider { get; set; }
|
||||
public IT7800E _iT7800E { get; set; }
|
||||
public N36200 _n36200 { get; set; }
|
||||
public N36600 _n36600 { get; set; }
|
||||
public N69200 _n69200 { get; set; }
|
||||
public SDS2000X_HD _sDS2000X_HD { get; set; }
|
||||
public SPAW7000 _sPAW7000 { get; set; }
|
||||
public IList<IBaseInterface> DeviceList { get; set; }
|
||||
public DeviceManager(IContainerProvider containerProvider,SystemConfig systemConfig)
|
||||
public IList<IBaseInterface> DeviceList { get; private set; } = new List<IBaseInterface>();
|
||||
|
||||
/// <summary>按 DeviceName 索引的设备字典,便于业务层按名取实例。</summary>
|
||||
public IDictionary<string, IBaseInterface> DeviceMap { get; private set; }
|
||||
= new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>类名 → Type 的反射缓存(仅扫描一次)。</summary>
|
||||
private static readonly IReadOnlyDictionary<string, Type> _deviceTypeMap = BuildDeviceTypeMap();
|
||||
|
||||
public DeviceManager(SystemConfig systemConfig)
|
||||
{
|
||||
_containerProvider = containerProvider;
|
||||
_systemConfig = systemConfig;
|
||||
InitDevices();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扫描 <see cref="IBaseInterface"/> 所在程序集中所有可实例化的实现类,
|
||||
/// 以类型名为键建立映射。这样新增设备类无需修改 DeviceManager。
|
||||
/// </summary>
|
||||
private static IReadOnlyDictionary<string, Type> BuildDeviceTypeMap()
|
||||
{
|
||||
try
|
||||
{
|
||||
return typeof(IBaseInterface).Assembly
|
||||
.GetTypes()
|
||||
.Where(t => t.IsClass && !t.IsAbstract && typeof(IBaseInterface).IsAssignableFrom(t))
|
||||
.ToDictionary(t => t.Name, t => t, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
LoggerHelper.Error($"扫描设备类型失败:{ex.Message}");
|
||||
return new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitDevices()
|
||||
{
|
||||
foreach(var Config in _systemConfig.DeviceList)
|
||||
DeviceMap = new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (_systemConfig?.DeviceList == null) return;
|
||||
|
||||
foreach (var config in _systemConfig.DeviceList)
|
||||
{
|
||||
if (Config.ConnectionType == "Tcp")
|
||||
{
|
||||
if (config == null || !config.IsEnabled) continue;
|
||||
|
||||
}
|
||||
else if (Config.ConnectionType == "Serial")
|
||||
if (string.IsNullOrWhiteSpace(config.DeviceType) ||
|
||||
!_deviceTypeMap.TryGetValue(config.DeviceType, out var deviceType))
|
||||
{
|
||||
LoggerHelper.Warn($"未识别的设备类型 [{config.DeviceType}],已跳过 [{config.DeviceName}]。");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
IBaseInterface? instance = config.ConnectionType switch
|
||||
{
|
||||
"Tcp" => CreateTcpDevice(deviceType, config.TcpConfig),
|
||||
"Serial" => CreateSerialDevice(deviceType, config.SerialPortConfig),
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
LoggerHelper.Warn($"设备 [{config.DeviceName}] 连接方式 [{config.ConnectionType}] 不支持,已跳过。");
|
||||
continue;
|
||||
}
|
||||
|
||||
DeviceList.Add(instance);
|
||||
if (!string.IsNullOrWhiteSpace(config.DeviceName))
|
||||
{
|
||||
DeviceMap[config.DeviceName] = instance;
|
||||
}
|
||||
|
||||
LoggerHelper.Info($"已加载设备 [{config.DeviceName} / {config.DeviceType} / {config.ConnectionType}]");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var inner = ex.InnerException?.Message ?? ex.Message;
|
||||
LoggerHelper.ErrorWithNotify($"设备 [{config.DeviceName}] 实例化失败:{inner}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例化 TCP 类设备:将 <see cref="TcpConfigVM"/> 转为 <see cref="TcpConfig"/> POCO,
|
||||
/// 调用设备类的 (TcpConfig) 构造函数。
|
||||
/// </summary>
|
||||
private static IBaseInterface? CreateTcpDevice(Type type, TcpConfigVM? vm)
|
||||
{
|
||||
vm ??= new TcpConfigVM();
|
||||
var cfg = new TcpConfig
|
||||
{
|
||||
IPAddress = vm.IPAddress,
|
||||
Port = vm.Port,
|
||||
SendTimeout = vm.SendTimeout,
|
||||
ReceiveTimeout = vm.ReceiveTimeout
|
||||
};
|
||||
return Activator.CreateInstance(type, cfg) as IBaseInterface;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实例化串口类设备:将 <see cref="SerialPortConfigVM"/> 转为 <see cref="SerialPortConfig"/> POCO,
|
||||
/// StopBits / Parity 从字符串解析为枚举,调用设备类的 (SerialPortConfig) 构造函数。
|
||||
/// </summary>
|
||||
private static IBaseInterface? CreateSerialDevice(Type type, SerialPortConfigVM? vm)
|
||||
{
|
||||
vm ??= new SerialPortConfigVM();
|
||||
var cfg = new SerialPortConfig
|
||||
{
|
||||
PortName = vm.PortName,
|
||||
BaudRate = vm.BaudRate,
|
||||
DataBits = vm.DataBits,
|
||||
StopBits = Enum.TryParse<StopBits>(vm.StopBits, true, out var sb) ? sb : StopBits.One,
|
||||
Parity = Enum.TryParse<Parity>(vm.Parity, true, out var pa) ? pa : Parity.None,
|
||||
ReadTimeout = vm.ReadTimeout,
|
||||
WriteTimeout = vm.WriteTimeout
|
||||
};
|
||||
return Activator.CreateInstance(type, cfg) as IBaseInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user