using System.Collections.Concurrent;
|
using Aging.Infrastructure.Contracts;
|
using log4net;
|
|
namespace Aging.Infrastructure.Core
|
{
|
/// <summary>
|
/// 设备管理实现。
|
/// 提供设备驱动的注册、连接管理和状态查询功能。
|
/// 使用 ConcurrentDictionary 管理驱动实例和缓存状态。
|
/// </summary>
|
public sealed class DeviceManager : IDeviceManager
|
{
|
private static readonly ILog Log = LogManager.GetLogger(typeof(DeviceManager));
|
|
/// <summary>
|
/// 设备驱动字典(key = deviceId)
|
/// </summary>
|
private readonly ConcurrentDictionary<string, IDeviceDriver> _drivers = new();
|
|
/// <summary>
|
/// 设备状态缓存字典(key = deviceId)
|
/// </summary>
|
private readonly ConcurrentDictionary<string, DeviceDriverStatus> _statusCache = new();
|
|
/// <inheritdoc/>
|
public void RegisterDriver(string deviceId, IDeviceDriver driver)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
if (driver == null) throw new ArgumentNullException(nameof(driver));
|
|
if (_drivers.ContainsKey(deviceId))
|
{
|
Log.Warn($"[DeviceManager] 设备 {deviceId} 已注册,将覆盖现有驱动");
|
UnregisterDriver(deviceId);
|
}
|
|
_drivers[deviceId] = driver;
|
|
// 初始化状态缓存
|
var initialStatus = driver.GetStatus();
|
_statusCache[deviceId] = initialStatus;
|
|
// 订阅连接状态变化事件
|
driver.ConnectionChanged += OnConnectionChanged;
|
|
Log.Info($"[DeviceManager] 设备 {deviceId} 驱动注册成功,当前连接状态: {initialStatus.IsConnected}");
|
}
|
|
/// <inheritdoc/>
|
public void UnregisterDriver(string deviceId)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
|
if (_drivers.TryRemove(deviceId, out var driver))
|
{
|
// 取消事件订阅
|
driver.ConnectionChanged -= OnConnectionChanged;
|
|
// 清理状态缓存
|
_statusCache.TryRemove(deviceId, out _);
|
|
Log.Info($"[DeviceManager] 设备 {deviceId} 驱动已注销");
|
}
|
else
|
{
|
Log.Warn($"[DeviceManager] 尝试注销不存在的设备: {deviceId}");
|
}
|
}
|
|
/// <inheritdoc/>
|
public IDeviceDriver? GetDriver(string deviceId)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
|
_drivers.TryGetValue(deviceId, out var driver);
|
return driver;
|
}
|
|
/// <inheritdoc/>
|
public DeviceDriverStatus GetStatus(string deviceId)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
|
if (_statusCache.TryGetValue(deviceId, out var status))
|
{
|
return status;
|
}
|
|
// 如果缓存中没有,返回默认状态
|
Log.Warn($"[DeviceManager] 设备 {deviceId} 状态缓存不存在,返回默认状态");
|
return new DeviceDriverStatus
|
{
|
IsConnected = false,
|
IsHealthy = false,
|
LastError = "设备未注册或状态未初始化"
|
};
|
}
|
|
/// <inheritdoc/>
|
public async Task ConnectAsync(string deviceId, CancellationToken ct)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
|
if (!_drivers.TryGetValue(deviceId, out var driver))
|
{
|
throw new InvalidOperationException($"设备 {deviceId} 未注册驱动");
|
}
|
|
try
|
{
|
Log.Info($"[DeviceManager] 正在连接设备: {deviceId}");
|
await driver.ConnectAsync(ct).ConfigureAwait(false);
|
|
// 更新状态缓存
|
_statusCache[deviceId] = driver.GetStatus();
|
|
Log.Info($"[DeviceManager] 设备 {deviceId} 连接成功");
|
}
|
catch (Exception ex)
|
{
|
// 更新错误状态
|
if (_statusCache.TryGetValue(deviceId, out var status))
|
{
|
status.IsConnected = false;
|
status.IsHealthy = false;
|
status.LastError = ex.Message;
|
status.LastErrorTime = DateTime.UtcNow;
|
_statusCache[deviceId] = status;
|
}
|
|
Log.Error($"[DeviceManager] 设备 {deviceId} 连接失败: {ex.Message}", ex);
|
throw;
|
}
|
}
|
|
/// <inheritdoc/>
|
public async Task DisconnectAsync(string deviceId)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
|
|
if (!_drivers.TryGetValue(deviceId, out var driver))
|
{
|
Log.Warn($"[DeviceManager] 尝试断开未注册的设备: {deviceId}");
|
return;
|
}
|
|
try
|
{
|
Log.Info($"[DeviceManager] 正在断开设备: {deviceId}");
|
await driver.DisconnectAsync().ConfigureAwait(false);
|
|
// 更新状态缓存
|
_statusCache[deviceId] = driver.GetStatus();
|
|
Log.Info($"[DeviceManager] 设备 {deviceId} 已断开连接");
|
}
|
catch (Exception ex)
|
{
|
Log.Error($"[DeviceManager] 设备 {deviceId} 断开连接失败: {ex.Message}", ex);
|
throw;
|
}
|
}
|
|
/// <inheritdoc/>
|
public IReadOnlyList<string> GetRegisteredDevices()
|
{
|
return _drivers.Keys.ToList().AsReadOnly();
|
}
|
|
/// <inheritdoc/>
|
public bool IsDeviceRegistered(string deviceId)
|
{
|
if (string.IsNullOrWhiteSpace(deviceId))
|
return false;
|
|
return _drivers.ContainsKey(deviceId);
|
}
|
|
/// <summary>
|
/// 处理设备连接状态变化事件
|
/// </summary>
|
/// <param name="sender">事件发送者</param>
|
/// <param name="e">事件参数</param>
|
private void OnConnectionChanged(object? sender, DeviceConnectionEventArgs e)
|
{
|
var deviceId = e.DeviceId;
|
|
if (string.IsNullOrWhiteSpace(deviceId))
|
{
|
Log.Warn("[DeviceManager] 收到连接变化事件但 DeviceId 为空");
|
return;
|
}
|
|
if (_statusCache.TryGetValue(deviceId, out var status))
|
{
|
status.IsConnected = e.IsConnected;
|
if (!e.IsConnected)
|
{
|
status.IsHealthy = false;
|
if (!string.IsNullOrEmpty(e.Reason))
|
{
|
status.LastError = e.Reason;
|
status.LastErrorTime = DateTime.UtcNow;
|
}
|
}
|
else
|
{
|
status.IsHealthy = true;
|
status.LastError = "";
|
}
|
|
_statusCache[deviceId] = status;
|
|
Log.Info($"[DeviceManager] 设备 {deviceId} 连接状态变化: {(e.IsConnected ? "已连接" : "已断开")}" +
|
(string.IsNullOrEmpty(e.Reason) ? "" : $", 原因: {e.Reason}"));
|
}
|
}
|
}
|
}
|