using DeviceCommand.Base;
using DeviceCommand.Devices;
using Logger;
using Model.Models;
using Prism.Events;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Reflection;
using UIShare.PubEvent;
using UIShare.UIViewModel;
using ZLGUSBCANFD;

namespace UIShare.GlobalVariable
{
    /// <summary>
    /// 设备管理器：根据 <see cref="SystemConfig.DeviceList"/> 反射实例化所有启用的设备，
    /// 通过 <see cref="IBaseInterface"/> 多态统一管理，避免为每种设备单独硬编码字段。
    /// </summary>
    public class DeviceManager:IDisposable
    {
        private object _lockObj = new object();
        public SystemConfig _systemConfig { get; set; }
        private readonly GlobalInfo _globalInfo;
        private readonly string _scopeName;
        private readonly IEventAggregator _eventAggregator;

        /// <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 ZLGCANFD CANFD { get; set; }
        public IOBoardGroup IOGroup { get; set; }

        public DeviceManager(SystemConfig systemConfig, GlobalInfo globalInfo, IEventAggregator eventAggregator)
        {
            _systemConfig = systemConfig;
            _globalInfo = globalInfo;
            _eventAggregator = eventAggregator;
            // 用 SystemConfig.Title 作为作用域唯一标识，无需反查 ConfigDic
            _scopeName =  _systemConfig.Title;
            InitDevices();
        }

        /// <summary>
        /// 根据设备配置提取唯一的硬件指纹字符串。
        /// <para>Tcp → "Tcp:IP:Port"；Serial → "Serial:PortName"；无法识别则返回空字符串。</para>
        /// </summary>
        public static string ExtractHardwareFingerprint(DeviceInfoVM config)
        {
            if (string.Equals(config.ConnectionType, "Tcp", StringComparison.OrdinalIgnoreCase)
                && config.TcpConfig != null)
            {
                return $"Tcp:{config.TcpConfig.IPAddress}:{config.TcpConfig.Port}";
            }

            if (string.Equals(config.ConnectionType, "Serial", StringComparison.OrdinalIgnoreCase)
                && config.SerialPortConfig != null)
            {
                return $"Serial:{config.SerialPortConfig.PortName}";
            }

            if (string.Equals(config.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase)
                && config.CANConfig != null)
            {
                return $"CAN:{config.CANConfig.DeviceIndex}";
            }

            return string.Empty;
        }

        /// <summary>
        /// 获取当前作用域配置的 CAN 设备硬件指纹（与 GlobalInfo.CanPool 的 Key 一致）。
        /// 如 "CAN:0"，其中 0 是 CANConfig.DeviceIndex。
        /// </summary>
        public string GetCanDeviceFingerprint()
        {
            if (_systemConfig?.DeviceList == null) return string.Empty;
            var canConfig = _systemConfig.DeviceList.FirstOrDefault(d =>
                d != null && d.IsEnabled &&
                string.Equals(d.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase));
            return canConfig != null ? ExtractHardwareFingerprint(canConfig) : string.Empty;
        }

        private void InitDevices()
        {
            DeviceMap = new Dictionary<string, IBaseInterface>(StringComparer.OrdinalIgnoreCase);

            if (_systemConfig?.DeviceList == null) return;

            foreach (var config in _systemConfig.DeviceList)
            {
                if (config == null || !config.IsEnabled) continue;

                // CAN 设备：ZLGCANFD 不实现 IBaseInterface，通过 SystemConfig.CANFD 单独管理，
                // 按指纹从全局 CanPool 创建/复用实例，并注册作用域引用计数。
                if (string.Equals(config.ConnectionType, "CAN", StringComparison.OrdinalIgnoreCase))
                {
                    var fingerprint = ExtractHardwareFingerprint(config);
                    if (string.IsNullOrEmpty(fingerprint))
                    {
                        LoggerHelper.Warn($"设备 [{config.DeviceName}] 无法提取硬件指纹（连接方式={config.ConnectionType}），已跳过。");
                        continue;
                    }

                    if (config.CANConfig == null)
                    {
                        LoggerHelper.Warn($"设备 [{config.DeviceName}] 缺少 CAN 连接参数，已跳过。");
                        continue;
                    }

                    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,
                                config.CANConfig.ABitBaud, config.CANConfig.DBitBaud, config.CANConfig.EnableTerminalResistance)));

                        _systemConfig.CANFD = canLazy.Value;
                        CANFD = canLazy.Value;

                        // 注册作用域引用计数
                        if (!string.IsNullOrEmpty(_scopeName))
                        {
                            var scopeList = _globalInfo.DeviceAndScopeDic.GetOrAdd(fingerprint,
                                _ => new Lazy<List<string>>(() => new List<string>())).Value;
                            lock (scopeList)
                            {
                                if (!scopeList.Contains(_scopeName))
                                    scopeList.Add(_scopeName);
                            }
                        }

                        LoggerHelper.Info($"已加载 CAN 设备 [{config.DeviceName}] 指纹={fingerprint}（通过 SystemConfig.CANFD 管理）");
                    }
                    catch (Exception ex)
                    {
                        LoggerHelper.ErrorWithNotify(_scopeName, $"CAN 设备 [{config.DeviceName}] 实例化失败：{ex.Message}");
                    }
                    continue;
                }

                if (string.IsNullOrWhiteSpace(config.DeviceType) ||
                    !_deviceTypeMap.TryGetValue(config.DeviceType, out var deviceType))
                {
                    LoggerHelper.Warn($"未识别的设备类型 [{config.DeviceType}]，已跳过 [{config.DeviceName}]。");
                    continue;
                }

                try
                {
                    // 第一步：提取硬件指纹，为空则跳过
                    var fingerprint = ExtractHardwareFingerprint(config);
                    if (string.IsNullOrEmpty(fingerprint))
                    {
                        LoggerHelper.Warn($"设备 [{config.DeviceName}] 无法提取硬件指纹（连接方式={config.ConnectionType}），已跳过。");
                        continue;
                    }

                    // 第二步：原子化获取或添加 Lazy 包装盒，确保同一指纹全局只创建一个实例
                    var lazy = _globalInfo.HardwarePool.GetOrAdd(fingerprint, key => new Lazy<IBaseInterface>(() =>
                    {
                        return config.ConnectionType switch
                        {
                            "Tcp" => CreateTcpDevice(deviceType, config.TcpConfig)!,
                            "Serial" => CreateSerialDevice(deviceType, config.SerialPortConfig)!,
                            _ => null!
                        };
                    }));

                    // 第三步：安全拆盒，Lazy 内部线程锁保证只实例化一次
                    var instance = lazy.Value;

                    if (instance == null)
                    {
                        LoggerHelper.Warn($"设备 [{config.DeviceName}] 连接方式 [{config.ConnectionType}] 不支持，已跳过。");
                        continue;
                    }

                    // 第四步：绑定逻辑名 → 同一物理设备可被多个台架名称映射
                    if (!string.IsNullOrWhiteSpace(config.DeviceName))
                    {
                        DeviceMap[config.DeviceName] = instance;
                    }

                    // 第五步：将当前作用域注册到指纹的作用域列表，用于引用计数与安全销毁
                    if (!string.IsNullOrEmpty(_scopeName))
                    {
                        var scopeList = _globalInfo.DeviceAndScopeDic.GetOrAdd(fingerprint,
                            _ => new Lazy<List<string>>(() => new List<string>())).Value;
                        lock (scopeList)
                        {
                            if (!scopeList.Contains(_scopeName))
                                scopeList.Add(_scopeName);
                        }
                    }

                    LoggerHelper.Info($"已加载设备 [{config.DeviceName} / {config.DeviceType} / {config.ConnectionType}] 指纹={fingerprint}");
                }
                catch (Exception ex)
                {
                    var inner = ex.InnerException?.Message ?? ex.Message;
                    LoggerHelper.ErrorWithNotify(_scopeName, $"设备 [{config.DeviceName}] 实例化失败：{inner}");
                }
            }

            // IOGroup 初始化：从已实例化的设备中取出前两个 IOBoard 实例组建 IOBoardGroup
            try
            {
                var ioBoards = DeviceMap.Values.OfType<IOBoard>().Take(2).ToList();
                if (ioBoards.Count == 2)
                {
                    IOGroup = new IOBoardGroup(ioBoards[0], ioBoards[1]);
                    LoggerHelper.Info($"IOBoardGroup 已初始化，Board1={ioBoards[0].GetType().Name}, Board2={ioBoards[1].GetType().Name}。");
                }
                else
                {
                    LoggerHelper.Warn($"IOBoardGroup 初始化跳过：需要 2 个 IOBoard 实例，当前仅找到 {ioBoards.Count} 个。");
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.ErrorWithNotify(_scopeName, $"IOBoardGroup 初始化失败：{ex.Message}");
            }
        }

        public async Task ConnectAllDevices(CancellationToken ct = default)
        {
            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;

                // 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));
            }

            await Task.WhenAll(tasks);
        }


        public async Task ConnectSpecifiedDevice(string deviceName, CancellationToken ct = default)
        {
            if (string.IsNullOrWhiteSpace(deviceName))
            {
                LoggerHelper.Warn("ConnectSpecifiedDevice：设备名为空。");
                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;
            }

            await ConnectInternalAsync(info, device, ct);
        }

        /// <summary>
        /// 异步关闭指定设备，释放底层连接并更新 UI 状态
        /// </summary>
        public async Task CloseDeviceAsync(string deviceName)
        {
            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;

            lock (_lockObj)
            {
                if (!DeviceMap.TryGetValue(deviceName, out device)) return;
            }

            await CloseInternalAsync(info, device);
        }

        /// <summary>
        /// 异步关闭所有设备
        /// </summary>
        public async Task CloseAllDevicesAsync()
        {
            List<Task> tasks = new List<Task>();

            lock (_lockObj)
            {
                if (DeviceMap.Count == 0 && (CANFD == null)) return;

                foreach (var kvp in DeviceMap)
                {
                    string deviceName = kvp.Key;
                    var device = kvp.Value;
                    var info = _systemConfig?.DeviceList?
                        .FirstOrDefault(d => d != null && string.Equals(d.DeviceName, deviceName, StringComparison.OrdinalIgnoreCase));

                    tasks.Add(CloseInternalAsync(info, device));
                }
            }

            // 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("所有设备已执行关闭操作。");
        }

        #region 辅助方法
        private async Task CloseInternalAsync(DeviceInfoVM? info, IBaseInterface device)
        {
            string name = info?.DeviceName ?? device.GetType().Name;
            string conn = info?.ConnectionType ?? "?";

            try
            {
                // 如果设备本身已经是断开状态，直接更新 UI 并返回
                if (!device.IsConnected)
                {
                    if (info != null) info.IsConnected = false;
                    LoggerHelper.Info($"设备 [{name}] 本就处于断开状态。");
                    return;
                }
                await Task.Run(() => device.Close());

                LoggerHelper.Info($"设备 [{name}/{conn}] 已成功关闭连接。");
            }
            catch (Exception ex)
            {
                var inner = ex.InnerException?.Message ?? ex.Message;
                LoggerHelper.Error($"设备 [{name}/{conn}] 关闭连接时出现异常: {inner}");
            }
            finally
            {
                // 无论关闭时是否抛出异常，均强制同步 UI 状态为未连接
                if (info != null)
                {
                    info.IsConnected = false;
                }
            }
        }
        private async Task ConnectInternalAsync(DeviceInfoVM? info, IBaseInterface device, CancellationToken ct)
        {
            string name = info?.DeviceName ?? device.GetType().Name;
            string conn = info?.ConnectionType ?? "?";

            try
            {
                if (device.IsConnected)
                {
                    if (info != null) info.IsConnected = true;
                    LoggerHelper.Info($"设备 [{name}] 已连接，跳过。");
                    return;
                }

                bool ok = conn switch
                {
                    "Tcp" => await ConnectTcpAsync(name, device, ct),
                    "Serial" => await ConnectSerialAsync(name, device, ct),
                    _ => false
                };

                if (info != null) info.IsConnected = ok;

                if (ok)
                    LoggerHelper.Info($"设备 [{name}/{conn}] 连接成功。");
                else
                    LoggerHelper.Warn($"设备 [{name}/{conn}] 连接失败。");
            }
            catch (OperationCanceledException)
            {
                if (info != null) info.IsConnected = false;
                LoggerHelper.Warn($"设备 [{name}/{conn}] 连接已取消。");
            }
            catch (Exception ex)
            {
                if (info != null) info.IsConnected = false;
                var inner = ex.InnerException?.Message ?? ex.Message;
                LoggerHelper.ErrorWithNotify(_scopeName, $"设备 [{name}/{conn}] 连接异常：{inner}");
            }
        }

        private static async Task<bool> ConnectTcpAsync(string name, IBaseInterface device, CancellationToken ct)
        {
            if (device is  ITcp tcp)
            {
                return await tcp.ConnectAsync(ct);
            }
            if (device is IModbusDevice modbusTCP)
            {
                return await modbusTCP.ConnectAsync(ct);
            }
            LoggerHelper.Warn($"设备 [{name}] 配置为 Tcp 但未实现 ITcp，实际类型为 {device.GetType().Name}。");
            return false;
        }

        private static async Task<bool> ConnectSerialAsync(string name, IBaseInterface device, CancellationToken ct)
        {
            if (device is not ISerialPort sp)
            {
                LoggerHelper.Warn($"设备 [{name}] 配置为 Serial 但未实现 ISerialPort，实际类型为 {device.GetType().Name}。");
                return false;
            }
            return await sp.ConnectAsync(ct);
        }

        /// <summary>
        /// 打开 CAN 卡：打开设备 + 初始化并启动所有通道 + 自动加载 DBC + 启动信号广播
        /// </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;
                    // 自动加载 DBC 文件
                    if (_systemConfig?.DBCAutoLoadList != null)
                    {
                        foreach (var item in _systemConfig.DBCAutoLoadList)
                        {
                            if (item.DBCChannel < 0 || item.DBCChannel >= 4) continue;
                            if (string.IsNullOrWhiteSpace(item.DBCFilePath)) continue;

                            if (!File.Exists(item.DBCFilePath))
                            {
                                // 发布 DBC 卸载事件，通知监控系统清除对应信号
                                _eventAggregator.GetEvent<DBCUnloadedEvent>().Publish(new DBCUnloadedArgs
                                {
                                    Channel = (uint)item.DBCChannel,
                                    Scope = _scopeName
                                });
                                LoggerHelper.Warn($"CAN 通道 {item.DBCChannel} 自动加载 DBC 失败：文件不存在 [{item.DBCFilePath}]");
                                continue;
                            }
                            CANFD.初始化并启动通道((uint)item.DBCChannel);
                            bool loadOk = CANFD.加载通道DBC文件((uint)item.DBCChannel, item.DBCFilePath);
                            if (loadOk)
                            {
                                LoggerHelper.Info($"CAN 通道 {item.DBCChannel} 已自动加载 DBC：{item.DBCFilePath}");
                                // 发布 DBC 加载完成事件，通知监控系统刷新信号列表
                                _eventAggregator.GetEvent<DBCLoadedEvent>().Publish(new DBCLoadedArgs
                                {
                                    Channel = (uint)item.DBCChannel,
                                    Scope = _scopeName
                                });
                            }
                            else
                            {
                                LoggerHelper.Warn($"CAN 通道 {item.DBCChannel} 自动加载 DBC 失败：{item.DBCFilePath}");
                                _eventAggregator.GetEvent<DBCUnloadedEvent>().Publish(new DBCUnloadedArgs
                                {
                                    Channel = (uint)item.DBCChannel,
                                    Scope = _scopeName
                                });
                            }
                        }
                    }

                    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
            {
                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 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;
        }
        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;
        }

        public void Dispose()
        {
            if (string.IsNullOrEmpty(_scopeName)) return;

            // 遍历当前作用域用到的所有指纹，逐一移除本作用域的引用
            var fingerprintsToRemove = new List<string>();

            foreach (var kvp in _globalInfo.DeviceAndScopeDic)
            {
                string fingerprint = kvp.Key;
                var scopeList = kvp.Value.IsValueCreated ? kvp.Value.Value : null;
                if (scopeList == null) continue;

                lock (scopeList)
                {
                    scopeList.Remove(_scopeName);

                    // 引用归零 → 标记为待清理
                    if (scopeList.Count == 0)
                        fingerprintsToRemove.Add(fingerprint);
                }
            }

            // 对引用归零的指纹：销毁设备实例 + 从全局池中移除
            foreach (var fingerprint in fingerprintsToRemove)
            {
                // 尝试从 HardwarePool 取出并销毁
                if (_globalInfo.HardwarePool.TryRemove(fingerprint, out var lazy))
                {
                    if (lazy.IsValueCreated && lazy.Value is IBaseInterface device)
                    {
                        try { device.Close(); }
                        catch { /* 销毁时忽略异常 */ }
                        LoggerHelper.Info($"指纹 [{fingerprint}] 无作用域引用，已销毁设备实例。");
                    }
                }

                // 尝试从 CanPool 取出并销毁
                if (_globalInfo.CanPool.TryRemove(fingerprint, out var canLazy))
                {
                    if (canLazy.IsValueCreated)
                    {
                        try { canLazy.Value.Dispose(); }
                        catch { /* 销毁时忽略异常 */ }
                        LoggerHelper.Info($"指纹 [{fingerprint}] 无作用域引用，已销毁 CAN 设备实例。");
                    }
                }

                // 同步清除 DeviceAndScopeDic 中的空条目
                _globalInfo.DeviceAndScopeDic.TryRemove(fingerprint, out _);
            }

            DeviceMap.Clear();
        }
        #endregion
    }
}
