设置色彩模式后不重启连接

This commit is contained in:
zqm
2025-10-28 16:43:18 +08:00
parent 2aa69ee0a8
commit bfbe7696f3
2 changed files with 304 additions and 133 deletions

View File

@@ -604,7 +604,6 @@ namespace JoyD.Windows.CS.Toprie
}
}
}
/// <summary>
/// 清理所有资源,确保安全释放
/// </summary>
@@ -2251,6 +2250,16 @@ namespace JoyD.Windows.CS.Toprie
// 即使获取失败,仍尝试设置新值
}
// 将PaletteType枚举转换为int类型
int paletteValue = (int)paletteType;
// 检查新的色彩模式是否与当前值相同,如果相同则不需要设置
if (originalValue == paletteValue)
{
Log($"当前色彩模式已为目标值,无需设置");
return true;
}
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
@@ -2263,9 +2272,7 @@ namespace JoyD.Windows.CS.Toprie
continue;
}
// 将PaletteType枚举转换为int类型并发送命令
// 按照SDK文档中的参数映射白热(0)、黑热(1)、铁红(2)、熔岩(3)、彩虹(4)、铁灰(5)、红热(6)、彩虹2(7)
int paletteValue = (int)paletteType;
// 已在循环外部计算paletteValue避免重复计算
// 直接设置色彩模式,不再在每次尝试中读取原始值
_a8Sdk.Color_plate = paletteValue;
@@ -2276,6 +2283,11 @@ namespace JoyD.Windows.CS.Toprie
// 减少读取验证避免嵌套UDP命令
// 信任SDK的设置操作不再额外验证
Log($"色彩模式设置成功: {paletteType} (值: {paletteValue})");
// 移除图像接收重启逻辑,因为色彩模式不影响图像接收
// 仅保留短暂延迟确保设置生效
Thread.Sleep(200); // 给设备处理时间
return true;
// 注释掉需要再次读取验证的代码避免嵌套UDP命令

View File

@@ -23,6 +23,9 @@ namespace JoyD.Windows.CS.Toprie
private const int DISCOVERY_UDP_PORT = 18889;
private const int SEARCH_DEVICE_MAX_NUM = 99;
// 日志文件路径
private static readonly string LogFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log.txt");
// 命令类型枚举
private enum CMD_TYPE
{
@@ -460,7 +463,7 @@ namespace JoyD.Windows.CS.Toprie
}
}
set
{
{;
try
{
// 使用SDK格式设置快门校正时间: ip:param_mode,param_value$
@@ -483,69 +486,225 @@ namespace JoyD.Windows.CS.Toprie
}
private int _lastKnownColorPlate = 0; // 保存最后已知的色板值
private readonly object _colorPlateLock = new object(); // 线程锁,确保日志记录的线程安全
/// <summary>
/// 静态日志写入方法
/// </summary>
/// <param name="message">日志消息</param>
public static void Log(string message)
{
try
{
// 确保日志目录存在
string logDirectory = Path.GetDirectoryName(LogFilePath);
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
// 写入日志,不添加额外时间戳(因为原始消息已包含时间戳)
File.AppendAllText(LogFilePath, message + Environment.NewLine);
// 同时输出到控制台
Console.WriteLine(message);
}
catch (Exception ex)
{
// 如果日志写入失败,至少输出到控制台
Console.WriteLine($"[日志写入失败] {ex.Message}");
}
}
public int Color_plate
{
get
{
lock (_colorPlateLock)
{
try
{
const int maxRetries = 3;
int retryCount = 0;
bool success = false;
int resultValue = _lastKnownColorPlate;
while (retryCount < maxRetries && !success)
{
retryCount++;
// 使用SDK格式获取色板: ip:param_mode,param_value$
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.COLOR_PLATE}$";
Log($"[色彩模式读取] 开始获取色彩模式值{(retryCount > 1 ? " ( " + retryCount + "/" + maxRetries + ")" : "")},发送命令: {command}");
if (SendCommand(command, out string response))
{
int parsedValue = ParseResponseValue(response);
if (parsedValue != 0 || response != null) // 确保至少解析成功或有响应
Log($"[色彩模式读取] 收到响应: {response}");
try
{
int parsedValue = ParseResponseValue(response);
if (response != null && parsedValue != -1) // 确保响应有效且解析成功
{
Log($"[色彩模式读取] 解析成功,当前值: {parsedValue},上一次值: {_lastKnownColorPlate}");
_lastKnownColorPlate = parsedValue;
return parsedValue;
resultValue = parsedValue;
success = true;
}
else if (retryCount < maxRetries)
{
Log($"[色彩模式读取] 解析失败或响应无效,将重试...");
System.Threading.Thread.Sleep(200); // 短暂延迟后重试
}
else
{
Log($"[色彩模式读取] 解析失败或响应无效,返回上次已知值: {_lastKnownColorPlate}");
}
Console.WriteLine("获取色板失败,返回上次已知值");
return _lastKnownColorPlate; // 返回上次已知值
}
catch (Exception ex)
{
Console.WriteLine($"获取色板异常: {ex.Message},返回上次已知值");
if (retryCount < maxRetries)
{
Log($"[色彩模式读取] 解析异常: {ex.Message},将重试...");
System.Threading.Thread.Sleep(200); // 短暂延迟后重试
}
else
{
Log($"[色彩模式读取] 解析异常: {ex.Message},返回上次已知值: {_lastKnownColorPlate}");
}
}
}
else if (retryCount < maxRetries)
{
Log($"[色彩模式读取] 命令发送失败或超时,将重试...");
System.Threading.Thread.Sleep(200); // 短暂延迟后重试
}
else
{
Log($"[色彩模式读取] 命令发送失败或超时,返回上次已知值: {_lastKnownColorPlate}");
}
}
Log($"成功读取当前色彩模式值: {resultValue}"); // 添加一致的成功日志
return resultValue;
}
catch (Exception ex)
{
Log($"[色彩模式读取异常] {ex.Message},返回上次已知值: {_lastKnownColorPlate}");
return _lastKnownColorPlate;
}
}
}
set
{
lock (_colorPlateLock)
{
try
{
int currentValue = GetColor_plateWithoutLock();
Log($"[色彩模式设置] 开始设置色彩模式值为: {value},当前值: {currentValue}");
// 如果值相同,不需要设置
if (currentValue == value)
{
Log($"[色彩模式设置] 当前色彩模式已为目标值,无需设置");
return;
}
// 使用SDK格式设置色板: ip:param_mode,param_value$
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_COLOR_PLATE},{value}$";
Log($"[色彩模式设置] 发送命令: {command}");
bool success = SendCommand(command, out string response);
if (success && response != null)
{
Log($"[色彩模式设置] 收到响应: {response}");
// 验证响应是否包含成功标记
bool responseValid = response.Contains("+RET:") &&
(!response.Contains("error") || !response.Contains("失败"));
(!response.Contains("error") && !response.Contains("失败"));
if (responseValid)
{
Console.WriteLine($"设置色板成功: {value}");
Log($"[色彩模式设置成功] 从 {_lastKnownColorPlate} 变更为 {value}");
_lastKnownColorPlate = value; // 更新最后已知值
// 验证设置是否生效
Log($"[色彩模式设置] 验证设置是否生效...");
int validatedValue = GetColor_plateWithoutLock();
if (validatedValue == value)
{
Log($"[色彩模式设置] 验证成功,当前值确认为: {validatedValue}");
// 设置成功后重启图像接收以避免卡顿
Log($"[色彩模式设置] 设置成功后重启图像接收以避免卡顿");
SafeRestartImageReceiving();
}
else
{
Console.WriteLine($"设置色板响应验证失败: {response}");
Log($"[色彩模式设置] 验证失败,实际值: {validatedValue},期望值: {value}");
}
}
else
{
Console.WriteLine($"设置色板失败: 命令发送失败或超时");
Log($"[色彩模式设置失败] 响应验证失败: {response}");
}
}
else
{
Log($"[色彩模式设置失败] 命令发送失败或超时响应为null: {success}");
}
}
catch (Exception ex)
{
Console.WriteLine($"设置色板异常: {ex.Message}");
Log($"[色彩模式设置异常] {ex.Message}");
}
}
}
}
/// <summary>
/// 不带锁获取色彩模式,避免在设置后验证时出现死锁
/// </summary>
private int GetColor_plateWithoutLock()
{
try
{
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.COLOR_PLATE}$";
if (SendCommand(command, out string response))
{
return ParseResponseValue(response);
}
}
catch (Exception ex)
{
Log($"[GetColor_plateWithoutLock异常] {ex.Message}");
}
return _lastKnownColorPlate;
}
/// <summary>
/// 安全地重启图像接收,避免重复停止和启动
/// </summary>
private void SafeRestartImageReceiving()
{
try
{
// 注意V8类不直接管理图像接收和连接检查
// 这个方法被Color_plate属性调用主要是为了在设置色彩模式后提供稳定的过渡时间
Log("执行色彩模式变更后的稳定处理");
// 添加短暂延迟以确保设备有时间处理色彩模式变更
System.Threading.Thread.Sleep(300);
Log("色彩模式变更后的稳定处理完成");
}
catch (Exception ex)
{
Log($"色彩模式变更后稳定处理过程中发生异常: {ex.Message}");
}
}
public int Mirror_mode
{