diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 635c09b..42cd53c 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -1041,28 +1041,28 @@ namespace JoyD.Windows.CS.Toprie // 更新视频模式菜单项的选中状态 try { - int currentMode = _deviceManager.GetCurrentVideoMode(); + var currentMode = _deviceManager.CurrentVideoMode; switch (currentMode) { - case 0: + case VideoMode.Infrared: thermalModeToolStripMenuItem.Checked = true; break; - case 1: + case VideoMode.VisibleLight: visibleModeToolStripMenuItem.Checked = true; break; - case 2: + case VideoMode.Fusion1: fusionMode1ToolStripMenuItem.Checked = true; break; - case 3: + case VideoMode.Fusion2: fusionMode2ToolStripMenuItem.Checked = true; break; - case 4: + case VideoMode.Fusion3: fusionMode3ToolStripMenuItem.Checked = true; break; - case 5: + case VideoMode.Fusion4: fusionMode4ToolStripMenuItem.Checked = true; break; - case 6: + case VideoMode.Fusion5: fusionMode5ToolStripMenuItem.Checked = true; break; } @@ -1247,7 +1247,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到红外模式"); - _deviceManager.SetVideoMode(0); + _deviceManager.SetVideoMode(VideoMode.Infrared); } } catch (Exception ex) @@ -1267,7 +1267,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到自然模式"); - _deviceManager.SetVideoMode(1); + _deviceManager.SetVideoMode(VideoMode.VisibleLight); } } catch (Exception ex) @@ -1287,7 +1287,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到融合模式1"); - _deviceManager.SetVideoMode(2); + _deviceManager.SetVideoMode(VideoMode.Fusion1); } } catch (Exception ex) @@ -1307,7 +1307,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到融合模式2"); - _deviceManager.SetVideoMode(3); + _deviceManager.SetVideoMode(VideoMode.Fusion2); } } catch (Exception ex) @@ -1327,7 +1327,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到融合模式3"); - _deviceManager.SetVideoMode(4); + _deviceManager.SetVideoMode(VideoMode.Fusion3); } } catch (Exception ex) @@ -1347,7 +1347,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到融合模式4"); - _deviceManager.SetVideoMode(5); + _deviceManager.SetVideoMode(VideoMode.Fusion4); } } catch (Exception ex) @@ -1367,7 +1367,7 @@ namespace JoyD.Windows.CS.Toprie if (_deviceManager != null) { Console.WriteLine("切换到融合模式5"); - _deviceManager.SetVideoMode(6); + _deviceManager.SetVideoMode(VideoMode.Fusion5); } } catch (Exception ex) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs index fb40335..8cd3403 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/DeviceManager.cs @@ -52,6 +52,21 @@ namespace JoyD.Windows.CS.Toprie RedHot, // 红热,对应SDK参数6 Rainbow2 // 彩虹2,对应SDK参数7 } + + /// + /// 视频模式枚举 + /// 对应SDK文档中的7种视频模式:红外、可见光、融合1~5 + /// + public enum VideoMode + { + Infrared, // 红外,对应SDK参数0 + VisibleLight, // 可见光,对应SDK参数1 + Fusion1, // 融合1,对应SDK参数2 + Fusion2, // 融合2,对应SDK参数3 + Fusion3, // 融合3,对应SDK参数4 + Fusion4, // 融合4,对应SDK参数5 + Fusion5 // 融合5,对应SDK参数6 + } /// /// 连接状态改变事件参数 @@ -163,6 +178,8 @@ namespace JoyD.Windows.CS.Toprie private ImageMode _currentImageMode = ImageMode.Thermal; // 当前色彩模式 private PaletteType _currentPaletteType = PaletteType.WhiteHot; + // 当前视频模式 + private VideoMode _currentVideoMode = VideoMode.Infrared; // 默认红外模式 // 自动重连是否启用 private bool _autoReconnectEnabled = true; // 自动重连定时器 @@ -2232,15 +2249,9 @@ namespace JoyD.Windows.CS.Toprie /// /// 设置视频模式 /// - /// 视频模式(0:红外,1:自然,2-6:融合模式1-5) - public void SetVideoMode(int videoMode) + /// 视频模式枚举 + public void SetVideoMode(VideoMode videoMode) { - // 验证参数范围 - if (videoMode < 0 || videoMode > 6) - { - throw new ArgumentOutOfRangeException("videoMode", "视频模式必须在0-6范围内"); - } - // 调用SDK设置视频模式 SendVideoModeCommand(videoMode); } @@ -2248,8 +2259,8 @@ namespace JoyD.Windows.CS.Toprie /// /// 获取当前视频模式 /// - /// 当前视频模式值(0-6) - public int GetCurrentVideoMode() + /// 当前视频模式枚举 + public VideoMode GetCurrentVideoMode() { lock (_sdkOperationLock) { @@ -2259,16 +2270,19 @@ namespace JoyD.Windows.CS.Toprie throw new InvalidOperationException("设备未连接"); } - // 调用SDK获取视频模式 - return _a8Sdk.GetVideoMode(); + // 从设备同步视频模式到内部状态 + SyncVideoModeFromDevice(); + + // 返回内部状态中的视频模式值 + return _currentVideoMode; } } /// /// 发送视频模式变更命令到设备 /// - /// 视频模式值 - private void SendVideoModeCommand(int videoMode) + /// 视频模式枚举值 + private void SendVideoModeCommand(VideoMode videoMode) { lock (_sdkOperationLock) { @@ -2287,22 +2301,32 @@ namespace JoyD.Windows.CS.Toprie continue; } - // 调用SDK设置视频模式 - _a8Sdk.SetVideoMode(videoMode); + // 调用SDK设置视频模式(转换为int) + _a8Sdk.SetVideoMode((int)videoMode); // 短暂延迟,确保设置生效 Thread.Sleep(50); // 简单验证:尝试读取视频模式确认设置成功 - int currentMode = _a8Sdk.GetVideoMode(); - if (currentMode == videoMode) + int currentModeInt = _a8Sdk.GetVideoMode(); + if (Enum.IsDefined(typeof(VideoMode), currentModeInt)) { - Log($"视频模式切换成功,当前模式: {videoMode}"); - return; + VideoMode currentMode = (VideoMode)currentModeInt; + if (currentMode == videoMode) + { + // 更新内部状态 + _currentVideoMode = videoMode; + Log($"视频模式切换成功,当前模式: {videoMode}"); + return; + } + else + { + Log($"视频模式验证失败,期望: {videoMode},实际: {currentMode}"); + } } else { - Log($"视频模式验证失败,期望: {videoMode},实际: {currentMode}"); + Log($"视频模式验证失败,获取到无效的视频模式值: {currentModeInt}"); } } catch (Exception ex) @@ -2337,7 +2361,54 @@ namespace JoyD.Windows.CS.Toprie get { return _currentPaletteType; } set { _currentPaletteType = value; } } + + /// + /// 获取或设置当前视频模式 + /// + public VideoMode CurrentVideoMode + { + get { return _currentVideoMode; } + set { _currentVideoMode = value; } + } + /// + /// 从设备同步视频模式到内部状态 + /// + public void SyncVideoModeFromDevice() + { + try + { + // 确保设备已连接且SDK实例有效 + if (_connectionStatus == ConnectionStatus.Connected && _a8Sdk != null) + { + // 获取当前设备的视频模式值 + int currentValue = _a8Sdk.GetVideoMode(); + Log($"从设备读取的视频模式值: {currentValue}"); + + // 验证视频模式值是否在有效范围内并转换为枚举 + if (Enum.IsDefined(typeof(VideoMode), currentValue)) + { + VideoMode actualMode = (VideoMode)currentValue; + _currentVideoMode = actualMode; + Log($"已更新内部状态为设备实际值: {actualMode} (值: {currentValue})"); + } + else + { + Log($"警告:设备返回的视频模式值 {currentValue} 不在有效范围内(0-6),使用默认值"); + } + } + else + { + Log($"同步视频模式失败:设备未连接或SDK未初始化"); + } + } + catch (Exception ex) + { + Log($"同步视频模式时发生异常: {ex.Message}"); + throw; // 重新抛出异常,让调用方知道发生了错误 + } + } + /// /// 从设备同步色彩模式到内部状态 /// @@ -2458,11 +2529,11 @@ namespace JoyD.Windows.CS.Toprie setSuccess = (currentValue == paletteValue); // 如果设置成功,更新内部状态 - if (setSuccess) - { - _currentPaletteType = paletteType; - Log($"内部状态_currentPaletteType已更新为: {paletteType}"); - } + if (setSuccess) + { + _currentPaletteType = paletteType; + Log($"内部状态_currentPaletteType已更新为: {paletteType}"); + } } catch (Exception ex) { @@ -3181,7 +3252,7 @@ namespace JoyD.Windows.CS.Toprie UpdateConnectionStatus(ConnectionStatus.Connected, "设备连接成功"); - // 连接成功后同步色彩模式 + // 连接成功后同步色彩模式和视频模式 try { SyncPaletteTypeFromDevice(); @@ -3190,6 +3261,16 @@ namespace JoyD.Windows.CS.Toprie { Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 同步色彩模式失败: {ex.Message}"); }; + + // 同步视频模式 + try + { + SyncVideoModeFromDevice(); + } + catch (Exception ex) + { + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 同步视频模式失败: {ex.Message}"); + }; } else if (!token.IsCancellationRequested) { @@ -3703,7 +3784,7 @@ namespace JoyD.Windows.CS.Toprie UpdateConnectionStatus(ConnectionStatus.Connected, $"设备 {deviceIp} 连接成功"); - // 重连成功后同步色彩模式 + // 重连成功后同步色彩模式和视频模式 try { SyncPaletteTypeFromDevice(); @@ -3712,6 +3793,16 @@ namespace JoyD.Windows.CS.Toprie { Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 重连后同步色彩模式失败: {ex.Message}"); }; + + // 同步视频模式 + try + { + SyncVideoModeFromDevice(); + } + catch (Exception ex) + { + Log($"[{DateTime.Now:HH:mm:ss.fff}] [线程:{Thread.CurrentThread.ManagedThreadId}] 重连后同步视频模式失败: {ex.Message}"); + }; StartConnectionCheck(); connectionSuccessful = true; } diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs index 3d9a0e3..3d50950 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/V8.cs @@ -767,49 +767,208 @@ namespace JoyD.Windows.CS.Toprie } } - public int Video_mode + private int _lastKnownVideoMode = 0; // 保存最后已知的视频模式值 + private readonly object _videoModeLock = new object(); // 线程锁,确保线程安全 + + /// + /// 获取当前视频模式值(内部方法) + /// + /// 视频模式值,如果获取失败则返回上次已知值 + private int GetVideoModeInternal() { - get + lock (_videoModeLock) { try { - // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$ - string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$"; + const int maxRetries = 3; + int retryCount = 0; + bool success = false; + int resultValue = _lastKnownVideoMode; - if (SendCommand(command, out string response)) + while (retryCount < maxRetries && !success) { - return ParseResponseValue(response); + retryCount++; + // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$ + string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$"; + + Log($"[视频模式读取] 开始获取视频模式值{(retryCount > 1 ? " (重试 " + retryCount + "/" + maxRetries + ")" : "")},发送命令: {command}"); + + if (SendCommand(command, out string response)) + { + Log($"[视频模式读取] 收到响应: {response}"); + try + { + int parsedValue = ParseResponseValue(response); + + if (response != null && parsedValue != -1) // 确保响应有效且解析成功 + { + Log($"[视频模式读取] 解析成功,当前值: {parsedValue},上一次值: {_lastKnownVideoMode}"); + _lastKnownVideoMode = parsedValue; + resultValue = parsedValue; + success = true; + } + else if (retryCount < maxRetries) + { + Log($"[视频模式读取] 解析失败或响应无效,将重试..."); + System.Threading.Thread.Sleep(200); // 短暂延迟后重试 + } + else + { + Log($"[视频模式读取] 解析失败或响应无效,返回-1表示获取失败"); + resultValue = -1; // 失败时返回-1而不是上次已知值 + } + } + catch (Exception ex) + { + if (retryCount < maxRetries) + { + Log($"[视频模式读取] 解析异常: {ex.Message},将重试..."); + System.Threading.Thread.Sleep(200); // 短暂延迟后重试 + } + else + { + Log($"[视频模式读取] 解析异常: {ex.Message},重试次数已达上限"); + resultValue = -1; + } + } + } + else if (retryCount < maxRetries) + { + Log($"[视频模式读取] 发送命令失败,将重试..."); + System.Threading.Thread.Sleep(200); // 短暂延迟后重试 + } + else + { + Log($"[视频模式读取] 发送命令失败,重试次数已达上限"); + resultValue = -1; + } } - return 0; // 默认模式 + + return resultValue; } catch (Exception ex) { - Console.WriteLine($"获取视频模式失败: {ex.Message}"); - return 0; + Log($"[视频模式读取] 发生异常: {ex.Message}"); + return -1; } } - set + } + + /// + /// 设置视频模式值(内部方法) + /// + /// 要设置的视频模式值 + /// 设置是否成功 + private bool SetVideoModeInternal(int value) + { + lock (_videoModeLock) { try { + // 首先尝试获取当前值 + int currentValue = GetVideoModeWithoutLock(); + Log($"[视频模式设置] 开始设置视频模式值为: {value},尝试获取当前值: {currentValue}"); + + // 只有在成功获取到当前值(currentValue != -1)且与目标值相同时才跳过设置 + // 如果获取失败(currentValue == -1),仍然执行设置操作,避免因获取失败而跳过设置 + if (currentValue != -1 && currentValue == value) + { + Log($"[视频模式设置] 当前视频模式已为目标值,无需设置"); + return true; + } + // 如果获取失败,记录日志说明将继续执行设置 + else if (currentValue == -1) + { + Log($"[视频模式设置] 获取当前值失败,将执行设置操作"); + } + // 使用SDK格式设置视频模式: +CMD:param_mode,param_value$ string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_VIDEO_MODE},{value}$"; - if (SendCommand(command, out string response)) + Log($"[视频模式设置] 发送命令: {command}"); + + bool success = SendCommand(command, out string response); + if (success && response != null) { - // 验证响应 - if (response != null) + Log($"[视频模式设置] 收到响应: {response}"); + + // 验证响应是否包含成功标记 + bool responseValid = response.Contains("+RET:") && + (!response.Contains("error") && !response.Contains("失败")); + + if (responseValid) { - Console.WriteLine("设置视频模式成功"); + Log($"[视频模式设置成功] 从 {_lastKnownVideoMode} 变更为 {value}"); + _lastKnownVideoMode = value; // 更新最后已知值 + + // 验证设置是否生效 + Log($"[视频模式设置] 验证设置是否生效..."); + int validatedValue = GetVideoModeWithoutLock(); + if (validatedValue == value) + { + Log($"[视频模式设置] 验证成功,当前值确认为: {validatedValue}"); + return true; + } + else + { + Log($"[视频模式设置] 验证失败,当前值: {validatedValue},目标值: {value}"); + return false; + } } + else + { + Log($"[视频模式设置] 响应无效或失败: {response}"); + return false; + } + } + else + { + Log($"[视频模式设置] 发送命令失败或未收到响应"); + return false; } } catch (Exception ex) { - Console.WriteLine($"设置视频模式失败: {ex.Message}"); + Log($"[视频模式设置] 发生异常: {ex.Message}"); + return false; } } } + + /// + /// 不带锁获取视频模式,避免在设置后验证时出现死锁 + /// + private int GetVideoModeWithoutLock() + { + try + { + // 使用SDK格式获取视频模式: +CMD:param_mode,param_value$ + string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.VIDEO_MODE}$"; + if (SendCommand(command, out string response)) + { + int result = ParseResponseValue(response); + // 如果解析结果不是特殊值-1,表示解析成功 + if (result != -1) + { + return result; + } + } + } + catch (Exception ex) + { + Log($"[GetVideoModeWithoutLock异常] {ex.Message}"); + } + // 返回特殊值-1表示获取失败,而不是返回_lastKnownVideoMode + // 这样SetVideoModeInternal方法可以明确判断是否获取到了真实值 + return -1; + } + + // 保留原属性以保持向后兼容性 + public int Video_mode + { + get => GetVideoModeInternal(); + set => SetVideoModeInternal(value); + } public void Set_area_pos(int index, SharedStructures.AreaPos area_data) { @@ -2251,28 +2410,13 @@ namespace JoyD.Windows.CS.Toprie // 获取视频模式 public int GetVideoMode() { - try - { - return Video_mode; - } - catch (Exception ex) - { - Console.WriteLine($"获取视频模式失败: {ex.Message}"); - return 0; - } + return GetVideoModeInternal(); } // 设置视频模式 public void SetVideoMode(int mode) { - try - { - Video_mode = mode; - } - catch (Exception ex) - { - Console.WriteLine($"设置视频模式失败: {ex.Message}"); - } + SetVideoModeInternal(mode); } // 新增方法:获取图像数据