using System.Collections.Concurrent;
using Aging.Infrastructure.Contracts;
using log4net;
namespace Aging.Infrastructure.Core
{
///
/// 设备管理实现。
/// 提供设备驱动的注册、连接管理和状态查询功能。
/// 使用 ConcurrentDictionary 管理驱动实例和缓存状态。
///
public sealed class DeviceManager : IDeviceManager
{
private static readonly ILog Log = LogManager.GetLogger(typeof(DeviceManager));
///
/// 设备驱动字典(key = deviceId)
///
private readonly ConcurrentDictionary _drivers = new();
///
/// 设备状态缓存字典(key = deviceId)
///
private readonly ConcurrentDictionary _statusCache = new();
///
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}");
}
///
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}");
}
}
///
public IDeviceDriver? GetDriver(string deviceId)
{
if (string.IsNullOrWhiteSpace(deviceId))
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
_drivers.TryGetValue(deviceId, out var driver);
return driver;
}
///
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 = "设备未注册或状态未初始化"
};
}
///
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;
}
}
///
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;
}
}
///
public IReadOnlyList GetRegisteredDevices()
{
return _drivers.Keys.ToList().AsReadOnly();
}
///
public bool IsDeviceRegistered(string deviceId)
{
if (string.IsNullOrWhiteSpace(deviceId))
return false;
return _drivers.ContainsKey(deviceId);
}
///
/// 处理设备连接状态变化事件
///
/// 事件发送者
/// 事件参数
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}"));
}
}
}
}