From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点
---
Aging.Infrastructure/Core/DeviceManager.cs | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 226 insertions(+), 0 deletions(-)
diff --git a/Aging.Infrastructure/Core/DeviceManager.cs b/Aging.Infrastructure/Core/DeviceManager.cs
new file mode 100644
index 0000000..7622a94
--- /dev/null
+++ b/Aging.Infrastructure/Core/DeviceManager.cs
@@ -0,0 +1,226 @@
+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>
+ /// 璁惧椹卞姩瀛楀吀锛坘ey = 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] 姝e湪杩炴帴璁惧: {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] 姝e湪鏂紑璁惧: {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}"));
+ }
+ }
+ }
+}
--
Gitblit v1.9.1