2453 lines
96 KiB
C#
2453 lines
96 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using System.Net.Sockets;
|
||
using System.Net;
|
||
using System.Threading;
|
||
using System.IO;
|
||
using System.Runtime.InteropServices;
|
||
// 导入UDP通信管理器
|
||
using JoyD.Windows.CS.Toprie;
|
||
|
||
namespace JoyD.Windows.CS.Toprie
|
||
{
|
||
public class V8
|
||
{
|
||
// 结构体引用已移至SharedStructures类
|
||
|
||
// 常量定义
|
||
private const int SDK_PORT = 8080;
|
||
private const int BUFFER_SIZE = 4096;
|
||
private const int TIMEOUT = 3000;
|
||
private const string CMD_HEAD = "+CMD";
|
||
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
|
||
{
|
||
SHUTTER_CORRECTION = 0,
|
||
// 根据设备实际通信协议调整枚举值,避免冲突
|
||
SET_COLOR_PLATE = 2, // 修正为2,与设备实际接受的命令格式匹配
|
||
SET_AUTO_SHUTTER = 1, // 保持为1,不要与其他命令冲突
|
||
SET_MIRROR_VIDEO = 3,
|
||
SET_VIDEO_MODE = 4,
|
||
GET_VIDEO_MODE = 28,
|
||
SET_AREA_POS = 5,
|
||
SET_SPOT_POS = 6,
|
||
SET_LINE_POS = 7,
|
||
SET_TEMP_RANGE = 8,
|
||
SET_ISP_X_OFFSET = 9,
|
||
SET_ISP_Y_OFFSET = 10,
|
||
SET_ISP_X_SCALE = 11,
|
||
SET_ISP_Y_SCALE = 12,
|
||
SET_LED = 13,
|
||
SET_EMAIL_SERVER = 14,
|
||
SET_TFTP_SERVER = 15,
|
||
SET_NETWORK_ETH = 16,
|
||
GET_PARAMETER = 20, // 修改为20,与a8_sdk保持一致
|
||
SET_FUSION_DISTANCE = 18,
|
||
SET_ENVIR_PARAM = 19,
|
||
SET_ALARM_PARAM = 20,
|
||
POWER_REBOOT = 21,
|
||
PARAM_RECOVER = 22,
|
||
UPDATER = 23,
|
||
HEARTBEAT = 24,
|
||
SET_UART_PORT = 25,
|
||
UART_COMMAND = 26,
|
||
AUTOFOCUS = 27,
|
||
SET_DEVICE_NAME = 28,
|
||
SET_TEMP_FRAME = 29,
|
||
SET_ALARM_OUT = 30,
|
||
SET_ALARM = 31,
|
||
GET_ALARM = 32,
|
||
GET_COMP_TEMP = 33,
|
||
SET_TIME = 34,
|
||
SET_IMAGE_MODE = 35,
|
||
GET_IMAGE_DATA = 36,
|
||
GET_ALL_TEMP = 37,
|
||
UPDATE = 38,
|
||
SET_UART = 39,
|
||
SEND_UART_COMMAND = 40,
|
||
GET_DETECT_NUMBER = 41,
|
||
GET_TEMP_FRAME = 42,
|
||
GET_GLOBAL_ALARM_PARAM = 43,
|
||
GET_LINE_ALARM_PARAM = 44,
|
||
GET_AREA_TEMP = 45,
|
||
GET_SPOT_TEMP = 46,
|
||
GET_LINE_TEMP = 47,
|
||
GET_GLOBAL_TEMP = 48,
|
||
GET_AREA_ENVIR_PARAM = 49,
|
||
GET_SPOT_ENVIR_PARAM = 50,
|
||
GET_LINE_ENVIR_PARAM = 51,
|
||
GET_GLOBAL_ENVIR_PARAM = 52,
|
||
GET_AREA_ALARM_PARAM = 53,
|
||
GET_SPOT_ALARM_PARAM = 54,
|
||
GET_AREA_POS = 55,
|
||
GET_SPOT_POS = 56,
|
||
GET_LINE_POS = 57,
|
||
GET_ALL_POS = 58
|
||
}
|
||
|
||
// 参数类型枚举
|
||
private enum PARAM_TYPE
|
||
{
|
||
AUTO_SHUTTER_TIME = 0,
|
||
COLOR_PLATE = 1,
|
||
MIRROR_MODE = 2,
|
||
VIDEO_MODE = 3,
|
||
AREA_POS = 4,
|
||
SPOT_POS = 5,
|
||
LINE_POS = 6,
|
||
TEMP_RANGE = 7,
|
||
ISP_X_OFFSET = 8,
|
||
ISP_Y_OFFSET = 9,
|
||
ISP_X_SCALE = 10,
|
||
ISP_Y_SCALE = 11,
|
||
LED_PARAM = 12,
|
||
EMAIL_SERVER = 13,
|
||
TFTP_SERVER = 14,
|
||
NETWORK_ETH = 15,
|
||
FUSION_DISTANCE = 16,
|
||
ENVIR_PARAM = 17,
|
||
ALARM_PARAM = 18,
|
||
TEMP_DATA = 19,
|
||
ALL_POS = 20,
|
||
DEVICE_NA = 21,
|
||
DETECT_NO = 22,
|
||
TEMP_FRAME = 23,
|
||
ALARM_IN = 24,
|
||
COMP_TEMP = 25,
|
||
LED_STATUS = 26,
|
||
EMAIL_SERVER_CONFIG = 27,
|
||
TFTP_SERVER_CONFIG = 28,
|
||
NETWORK_ETH_CONFIG = 29
|
||
}
|
||
|
||
// 私有字段
|
||
private readonly string deviceIp;
|
||
private Socket socket = null;
|
||
private static bool isSdkInitialized = false;
|
||
private static readonly Dictionary<string, V8> deviceInstances = new Dictionary<string, V8>();
|
||
|
||
public V8(string ip)
|
||
{
|
||
deviceIp = ip;
|
||
}
|
||
|
||
~V8()
|
||
{
|
||
Disconnect();
|
||
}
|
||
|
||
|
||
|
||
// 断开连接(UDP模式下)
|
||
private void Disconnect()
|
||
{
|
||
try
|
||
{
|
||
// 注意:在UDP模式下,不需要关闭socket连接
|
||
// 只需重置连接状态标志
|
||
// 仍然清理socket资源以防万一
|
||
if (socket != null)
|
||
{
|
||
socket.Close();
|
||
socket = null;
|
||
}
|
||
Console.WriteLine("UDP通信状态已重置");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"重置UDP通信状态失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// 发送命令并接收响应(字节数组版本)
|
||
private bool SendCommand(byte[] command, out byte[] response, int responseLength = 0)
|
||
{
|
||
response = null;
|
||
|
||
try
|
||
{
|
||
// 使用UDP通信管理器发送请求
|
||
response = UdpCommunicationManager.Instance.SendRequest(deviceIp, command, 18890, 200);
|
||
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine($"UDP命令已发送到 {deviceIp}:18890");
|
||
Console.WriteLine($"收到UDP命令响应,长度: {response.Length}");
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"UDP命令发送后未收到响应或超时");
|
||
return false;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"UDP发送命令失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 发送命令并接收响应(字符串版本)
|
||
private bool SendCommand(string cmd, out string response)
|
||
{
|
||
response = null;
|
||
|
||
try
|
||
{
|
||
// 使用UDP通信管理器发送请求,获取详细的请求结果
|
||
var result = UdpCommunicationManager.Instance.SendRequest(deviceIp,
|
||
Encoding.ASCII.GetBytes(cmd), out byte[] responseBytes, 18890, 500);
|
||
|
||
if (result == UdpCommunicationManager.RequestResult.Success && responseBytes != null)
|
||
{
|
||
response = Encoding.ASCII.GetString(responseBytes);
|
||
Console.WriteLine($"UDP命令已发送: {cmd}");
|
||
Console.WriteLine($"目标IP: {deviceIp}:18890");
|
||
Console.WriteLine($"收到UDP命令响应: {response}");
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
// 根据不同的结果类型提供更详细的信息
|
||
switch (result)
|
||
{
|
||
case UdpCommunicationManager.RequestResult.Timeout:
|
||
Console.WriteLine($"UDP命令 '{cmd}' 发送后超时");
|
||
break;
|
||
case UdpCommunicationManager.RequestResult.NetworkError:
|
||
Console.WriteLine($"UDP命令 '{cmd}' 网络错误");
|
||
break;
|
||
case UdpCommunicationManager.RequestResult.InvalidResponse:
|
||
Console.WriteLine($"UDP命令 '{cmd}' 收到无效响应");
|
||
break;
|
||
case UdpCommunicationManager.RequestResult.ProcessingError:
|
||
Console.WriteLine($"UDP命令 '{cmd}' 处理错误");
|
||
break;
|
||
default:
|
||
Console.WriteLine($"UDP命令 '{cmd}' 发送后未收到有效响应");
|
||
break;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"UDP发送命令失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 解析响应数据
|
||
private int ParseResponseValue(string response)
|
||
{
|
||
if (string.IsNullOrEmpty(response))
|
||
return -1; // 返回-1表示解析失败
|
||
|
||
// 支持两种响应格式: +RET: 和 +RSP:
|
||
int startIndex = -1;
|
||
if (response.StartsWith("+RET:"))
|
||
startIndex = 5;
|
||
else if (response.StartsWith("+RSP:"))
|
||
startIndex = 5;
|
||
|
||
if (startIndex == -1)
|
||
return -1;
|
||
|
||
try
|
||
{
|
||
// 从第5个字符开始解析数值,与热像仪SDK保持一致
|
||
string valueStr = response.Substring(startIndex);
|
||
// 移除结尾可能存在的$符号
|
||
if (valueStr.EndsWith("$"))
|
||
valueStr = valueStr.Substring(0, valueStr.Length - 1);
|
||
return int.Parse(valueStr);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"解析响应失败: {ex.Message}");
|
||
}
|
||
return -1; // 返回-1表示解析失败
|
||
}
|
||
|
||
// SDK核心功能实现 - 不使用DllImport
|
||
public static int SDK_initialize()
|
||
{
|
||
try
|
||
{
|
||
if (isSdkInitialized)
|
||
return 0; // 已初始化
|
||
|
||
// 初始化SDK资源
|
||
deviceInstances.Clear();
|
||
isSdkInitialized = true;
|
||
Console.WriteLine("SDK初始化成功");
|
||
return 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"SDK初始化失败: {ex.Message}");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
public static int SDK_destroy()
|
||
{
|
||
try
|
||
{
|
||
if (!isSdkInitialized)
|
||
return 0; // 未初始化
|
||
|
||
// 清理所有设备连接
|
||
foreach (var instance in deviceInstances.Values)
|
||
{
|
||
instance.Disconnect();
|
||
}
|
||
deviceInstances.Clear();
|
||
isSdkInitialized = false;
|
||
Console.WriteLine("SDK销毁成功");
|
||
return 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"SDK销毁失败: {ex.Message}");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
public static string SDK_serch_device(int list_len)
|
||
{
|
||
try
|
||
{
|
||
if (!isSdkInitialized)
|
||
{
|
||
Console.WriteLine("SDK未初始化");
|
||
return string.Empty;
|
||
}
|
||
|
||
const int DISCOVERY_UDP_PORT = 18889;
|
||
const int SEARCH_DEVICE_MAX_NUM = 99;
|
||
const int TIMEOUT_MS = 200; // 200毫秒超时
|
||
const string DISCOVERY_CMD = "CMD_DISCOVER";
|
||
|
||
StringBuilder deviceList = new StringBuilder();
|
||
List<string> discoveredDevices = new List<string>();
|
||
|
||
// 创建UDP socket
|
||
using (Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
||
{
|
||
// 设置为广播模式
|
||
udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
|
||
|
||
// 设置接收超时
|
||
udpSocket.ReceiveTimeout = TIMEOUT_MS;
|
||
|
||
// 发送广播命令
|
||
byte[] sendData = Encoding.ASCII.GetBytes(DISCOVERY_CMD);
|
||
IPEndPoint broadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, DISCOVERY_UDP_PORT);
|
||
udpSocket.SendTo(sendData, broadcastEndPoint);
|
||
|
||
Console.WriteLine("发送设备发现广播命令: CMD_DISCOVER");
|
||
|
||
// 接收设备回复,最多接收99个设备
|
||
int loopCount = SEARCH_DEVICE_MAX_NUM;
|
||
byte[] receiveBuffer = new byte[1024];
|
||
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||
|
||
try
|
||
{
|
||
while (loopCount > 0)
|
||
{
|
||
int receiveLength = udpSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint);
|
||
if (receiveLength > 0)
|
||
{
|
||
string deviceIp = ((IPEndPoint)remoteEndPoint).Address.ToString();
|
||
if (!discoveredDevices.Contains(deviceIp))
|
||
{
|
||
discoveredDevices.Add(deviceIp);
|
||
Console.WriteLine($"发现设备: {deviceIp}");
|
||
}
|
||
}
|
||
loopCount--;
|
||
}
|
||
}
|
||
catch (SocketException ex)
|
||
{
|
||
// 超时异常是正常的,继续处理已发现的设备
|
||
if (ex.SocketErrorCode != SocketError.TimedOut)
|
||
{
|
||
Console.WriteLine($"接收设备回复异常: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
// 将发现的设备IP用分号连接
|
||
for (int i = 0; i < discoveredDevices.Count; i++)
|
||
{
|
||
deviceList.Append(discoveredDevices[i]);
|
||
if (i < discoveredDevices.Count - 1)
|
||
{
|
||
deviceList.Append(';');
|
||
}
|
||
}
|
||
|
||
return deviceList.ToString();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"搜索设备失败: {ex.Message}");
|
||
return string.Empty;
|
||
}
|
||
}
|
||
|
||
public void Shutter_correction()
|
||
{
|
||
try
|
||
{
|
||
// 根据SDK格式构建快门校正命令: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SHUTTER_CORRECTION},0$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
Console.WriteLine($"快门校正命令已发送,响应: {response}");
|
||
}
|
||
else
|
||
{
|
||
throw new Exception("快门校正失败");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"快门校正失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public int Shutter_times
|
||
{
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取快门校正时间: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.AUTO_SHUTTER_TIME}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 根据SDK响应格式解析
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 60; // 默认值
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取快门时间失败: {ex.Message}");
|
||
return 60; // 默认值
|
||
}
|
||
}
|
||
set
|
||
{;
|
||
try
|
||
{
|
||
// 使用SDK格式设置快门校正时间: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_AUTO_SHUTTER},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置快门时间成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置快门时间失败: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
private int _lastKnownColorPlate = 0; // 保存最后已知的色板值
|
||
private readonly object _colorPlateLock = new object(); // 线程锁,确保日志记录的线程安全
|
||
|
||
/// <summary>
|
||
/// 静态日志写入方法
|
||
/// </summary>
|
||
/// <param name="message">日志消息</param>
|
||
public static void Log(string message)
|
||
{
|
||
try
|
||
{
|
||
// 同时输出到控制台
|
||
Console.WriteLine(message);
|
||
|
||
// 仅在DeviceManager.LogToFile为true时写入日志文件
|
||
if (DeviceManager.LogToFile)
|
||
{
|
||
// 确保日志目录存在
|
||
string logDirectory = Path.GetDirectoryName(LogFilePath);
|
||
if (!Directory.Exists(logDirectory))
|
||
{
|
||
Directory.CreateDirectory(logDirectory);
|
||
}
|
||
|
||
// 写入日志,不添加额外时间戳(因为原始消息已包含时间戳)
|
||
File.AppendAllText(LogFilePath, message + Environment.NewLine);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 如果日志写入失败,至少输出到控制台
|
||
Console.WriteLine($"[日志写入失败] {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前色彩模式值
|
||
/// </summary>
|
||
/// <returns>色彩模式值,如果获取失败则返回上次已知值</returns>
|
||
public int GetColorPlate()
|
||
{
|
||
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 = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.COLOR_PLATE}$";
|
||
|
||
Log($"[色彩模式读取] 开始获取色彩模式值{(retryCount > 1 ? " (重试 " + retryCount + "/" + maxRetries + ")" : "")},发送命令: {command}");
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
Log($"[色彩模式读取] 收到响应: {response}");
|
||
try
|
||
{
|
||
int parsedValue = ParseResponseValue(response);
|
||
|
||
if (response != null && parsedValue != -1) // 确保响应有效且解析成功(现在parsedValue为-1表示解析失败)
|
||
{
|
||
Log($"[色彩模式读取] 解析成功,当前值: {parsedValue},上一次值: {_lastKnownColorPlate}");
|
||
_lastKnownColorPlate = 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},返回-1表示获取失败");
|
||
resultValue = -1; // 失败时返回-1而不是上次已知值
|
||
}
|
||
}
|
||
}
|
||
else if (retryCount < maxRetries)
|
||
{
|
||
Log($"[色彩模式读取] 命令发送失败或超时,将重试...");
|
||
System.Threading.Thread.Sleep(200); // 短暂延迟后重试
|
||
}
|
||
else
|
||
{
|
||
Log($"[色彩模式读取] 命令发送失败或超时,返回-1表示获取失败");
|
||
resultValue = -1; // 失败时返回-1而不是上次已知值
|
||
}
|
||
}
|
||
// 根据是否成功获取来记录不同的日志
|
||
if (resultValue != -1)
|
||
{
|
||
Log($"成功读取当前色彩模式值: {resultValue}");
|
||
}
|
||
else
|
||
{
|
||
Log($"获取色彩模式值失败");
|
||
}
|
||
|
||
return resultValue;
|
||
}
|
||
catch (Exception ex)
|
||
{ Log($"[色彩模式读取异常] {ex.Message},返回-1表示获取失败");
|
||
return -1; // 异常时返回-1而不是上次已知值
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置色彩模式值
|
||
/// </summary>
|
||
/// <param name="value">要设置的色彩模式值</param>
|
||
/// <returns>设置是否成功</returns>
|
||
public bool SetColorPlate(int value)
|
||
{
|
||
lock (_colorPlateLock)
|
||
{
|
||
try
|
||
{
|
||
// 首先尝试获取当前值
|
||
int currentValue = GetColor_plateWithoutLock();
|
||
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_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("失败"));
|
||
|
||
if (responseValid)
|
||
{
|
||
Log($"[色彩模式设置成功] 从 {_lastKnownColorPlate} 变更为 {value}");
|
||
_lastKnownColorPlate = value; // 更新最后已知值
|
||
|
||
// 验证设置是否生效
|
||
Log($"[色彩模式设置] 验证设置是否生效...");
|
||
int validatedValue = GetColor_plateWithoutLock();
|
||
if (validatedValue == value)
|
||
{
|
||
Log($"[色彩模式设置] 验证成功,当前值确认为: {validatedValue}");
|
||
|
||
// 移除图像接收重启逻辑,因为色彩模式不影响图像接收
|
||
// 仅保留短暂延迟确保设置生效
|
||
Log($"[色彩模式设置] 设置成功,不需要重启图像接收");
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
Log($"[色彩模式设置] 验证失败,实际值: {validatedValue},期望值: {value}");
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Log($"[色彩模式设置失败] 响应验证失败: {response}");
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Log($"[色彩模式设置失败] 命令发送失败或超时,响应为null: {success}");
|
||
return false;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log($"[色彩模式设置异常] {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 保留原属性以保持向后兼容性
|
||
public int Color_plate
|
||
{
|
||
get => GetColorPlate();
|
||
set => SetColorPlate(value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不带锁获取色彩模式,避免在设置后验证时出现死锁
|
||
/// </summary>
|
||
private int GetColor_plateWithoutLock()
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取色彩模式: +CMD:param_mode,param_value$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.COLOR_PLATE}$";
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
int result = ParseResponseValue(response);
|
||
// 如果解析结果不是特殊值-1,表示解析成功
|
||
if (result != -1)
|
||
{
|
||
return result;
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log($"[GetColor_plateWithoutLock异常] {ex.Message}");
|
||
}
|
||
// 返回特殊值-1表示获取失败,而不是返回_lastKnownColorPlate
|
||
// 这样SetColorPlate方法可以明确判断是否获取到了真实值
|
||
return -1;
|
||
}
|
||
|
||
|
||
|
||
public int Mirror_mode
|
||
{
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取镜像模式: +CMD:param_mode,param_value$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.MIRROR_MODE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 0; // 默认不镜像
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取镜像模式失败: {ex.Message}");
|
||
return 0;
|
||
}
|
||
}
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置镜像模式: +CMD:param_mode,param_value$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_MIRROR_VIDEO},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置镜像模式成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置镜像模式失败: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
private int _lastKnownVideoMode = 0; // 保存最后已知的视频模式值
|
||
private readonly object _videoModeLock = new object(); // 线程锁,确保线程安全
|
||
|
||
/// <summary>
|
||
/// 获取当前视频模式值(内部方法)
|
||
/// </summary>
|
||
/// <returns>视频模式值,如果获取失败则返回上次已知值</returns>
|
||
private int GetVideoModeInternal()
|
||
{
|
||
lock (_videoModeLock)
|
||
{
|
||
try
|
||
{
|
||
const int maxRetries = 3;
|
||
int retryCount = 0;
|
||
bool success = false;
|
||
int resultValue = _lastKnownVideoMode;
|
||
|
||
while (retryCount < maxRetries && !success)
|
||
{
|
||
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 resultValue;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log($"[视频模式读取] 发生异常: {ex.Message}");
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置视频模式值(内部方法)
|
||
/// </summary>
|
||
/// <param name="value">要设置的视频模式值</param>
|
||
/// <returns>设置是否成功</returns>
|
||
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}$";
|
||
|
||
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("失败"));
|
||
|
||
if (responseValid)
|
||
{
|
||
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)
|
||
{
|
||
Log($"[视频模式设置] 发生异常: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 不带锁获取视频模式,避免在设置后验证时出现死锁
|
||
/// </summary>
|
||
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)
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置区域位置: ip:param_mode,index,enable,x,y,width$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_AREA_POS},{index},{area_data.enable},{area_data.x},{area_data.y},{area_data.width}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置区域位置失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AreaPos Get_area_pos(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取区域位置: ip:param_mode,index$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_AREA_POS},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应数据
|
||
SharedStructures.AreaPos area_data = new SharedStructures.AreaPos();
|
||
|
||
if (!string.IsNullOrEmpty(response))
|
||
{
|
||
// 移除结束符$并按逗号分割数据
|
||
string[] values = response.TrimEnd('$').Split(',');
|
||
if (values.Length >= 5)
|
||
{
|
||
area_data.enable = int.Parse(values[1]);
|
||
area_data.x = int.Parse(values[2]);
|
||
area_data.y = int.Parse(values[3]);
|
||
area_data.width = int.Parse(values[4]);
|
||
}
|
||
}
|
||
return area_data;
|
||
}
|
||
return new SharedStructures.AreaPos();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取区域位置失败: {ex.Message}");
|
||
return new SharedStructures.AreaPos();
|
||
}
|
||
}
|
||
|
||
public void Set_spot_pos(int index, SharedStructures.SpotPos spot_data)
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置点位置: ip:param_mode,index,enable,x,y$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_SPOT_POS},{index},{spot_data.enable},{spot_data.x},{spot_data.y}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置点位置失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public SharedStructures.SpotPos Get_spot_pos(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取点位置: ip:param_mode,index$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_SPOT_POS},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
SharedStructures.SpotPos spot_data = new SharedStructures.SpotPos();
|
||
|
||
if (!string.IsNullOrEmpty(response))
|
||
{
|
||
// 移除结束符$并按逗号分割数据
|
||
string[] values = response.TrimEnd('$').Split(',');
|
||
if (values.Length >= 4)
|
||
{
|
||
spot_data.enable = int.Parse(values[1]);
|
||
spot_data.x = int.Parse(values[2]);
|
||
spot_data.y = int.Parse(values[3]);
|
||
}
|
||
}
|
||
return spot_data;
|
||
}
|
||
return new SharedStructures.SpotPos();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取点位置失败: {ex.Message}");
|
||
return new SharedStructures.SpotPos();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.LinePos Line_pos
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置线位置: +CMD:param_mode,enable,sta_x,sta_y,end_x,end_y$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_LINE_POS},{value.enable},{value.sta_x},{value.sta_y},{value.end_x},{value.end_y}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置线位置失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取线位置: +CMD:param_mode,0$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_LINE_POS},0$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
SharedStructures.LinePos line_data = new SharedStructures.LinePos();
|
||
|
||
if (!string.IsNullOrEmpty(response))
|
||
{
|
||
// 移除结束符$并按逗号分割数据
|
||
string[] values = response.TrimEnd('$').Split(',');
|
||
if (values.Length >= 6)
|
||
{
|
||
line_data.enable = int.Parse(values[1]);
|
||
line_data.sta_x = int.Parse(values[2]);
|
||
line_data.sta_y = int.Parse(values[3]);
|
||
line_data.end_x = int.Parse(values[4]);
|
||
line_data.end_y = int.Parse(values[5]);
|
||
}
|
||
}
|
||
return line_data;
|
||
}
|
||
return new SharedStructures.LinePos();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取线位置失败: {ex.Message}");
|
||
return new SharedStructures.LinePos();
|
||
}
|
||
}
|
||
}
|
||
|
||
public SharedStructures.ImagePos All_pos
|
||
{
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取所有位置: ip:param_mode,0$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_ALL_POS},0$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 创建默认的ImagePos对象
|
||
SharedStructures.ImagePos data = new SharedStructures.ImagePos() {
|
||
area = new SharedStructures.AreaPos[6],
|
||
spot = new SharedStructures.SpotPos[6]
|
||
};
|
||
|
||
// 这里应该解析完整的响应数据
|
||
// 简化实现,返回默认值
|
||
return data;
|
||
}
|
||
return new SharedStructures.ImagePos();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取所有位置失败: {ex.Message}");
|
||
return new SharedStructures.ImagePos();
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Temp_range
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置温度范围: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_TEMP_RANGE},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置温度范围成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置温度范围失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取温度范围: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.TEMP_RANGE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 0; // 默认范围
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取温度范围失败: {ex.Message}");
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Video_isp_x_offset
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置X偏移: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_ISP_X_OFFSET},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置X偏移成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置X偏移失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取X偏移: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.ISP_X_OFFSET}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取X偏移失败: {ex.Message}");
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Video_isp_y_offset
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置Y偏移: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_ISP_Y_OFFSET},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置Y偏移成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置Y偏移失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取Y偏移: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.ISP_Y_OFFSET}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取Y偏移失败: {ex.Message}");
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Video_isp_x_scale
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置X缩放: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_ISP_X_SCALE},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置X缩放成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置X缩放失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取X缩放: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.ISP_X_SCALE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 100; // 默认100%
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取X缩放失败: {ex.Message}");
|
||
return 100;
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Video_isp_y_scale
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置Y缩放: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_ISP_Y_SCALE},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置Y缩放成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置Y缩放失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取Y缩放: ip:param_mode,param_value$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.ISP_Y_SCALE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 100; // 默认100%
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取Y缩放失败: {ex.Message}");
|
||
return 100;
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Set_led
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置LED状态: +CMD:param_mode,param_value$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_LED},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置LED状态成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置LED失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取LED状态: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.LED_STATUS}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 0; // 默认关闭
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取LED状态失败: {ex.Message}");
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public SharedStructures.EmailServer Email_server
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置邮件服务器配置: ip:param_mode,param_value$
|
||
// 构建参数字符串,包含enable标志
|
||
string paramsStr = $"{value.enable}";
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_EMAIL_SERVER},{paramsStr}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置邮件服务器成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置邮件服务器失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取邮件服务器配置: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.EMAIL_SERVER_CONFIG}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建EmailServer对象
|
||
SharedStructures.EmailServer emailServer = new SharedStructures.EmailServer();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return emailServer;
|
||
}
|
||
return new SharedStructures.EmailServer();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取邮件服务器失败: {ex.Message}");
|
||
return new SharedStructures.EmailServer();
|
||
}
|
||
}
|
||
}
|
||
|
||
public SharedStructures.TftpServer Tftp_server
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置TFTP服务器配置: ip:param_mode,param_value$
|
||
string paramsStr = $"{value.enable}";
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_TFTP_SERVER},{paramsStr}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置TFTP服务器成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置TFTP服务器失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式获取TFTP服务器配置: ip:param_mode,param_value$
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.TFTP_SERVER_CONFIG}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建TftpServer对象
|
||
SharedStructures.TftpServer tftpServer = new SharedStructures.TftpServer();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return tftpServer;
|
||
}
|
||
return new SharedStructures.TftpServer();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取TFTP服务器失败: {ex.Message}");
|
||
return new SharedStructures.TftpServer();
|
||
}
|
||
}
|
||
}
|
||
|
||
public SharedStructures.NetworkEth Network_eth
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SDK格式设置网络参数: +CMD:param_mode,param_value$
|
||
string paramsStr = $"{value.enable}";
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_NETWORK_ETH},{paramsStr}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置网络参数成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置网络参数失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_PARAMETER命令获取网络参数
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.NETWORK_ETH_CONFIG}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建NetworkEth对象
|
||
SharedStructures.NetworkEth networkEth = new SharedStructures.NetworkEth();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return networkEth;
|
||
}
|
||
return new SharedStructures.NetworkEth();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取网络参数失败: {ex.Message}");
|
||
return new SharedStructures.NetworkEth();
|
||
}
|
||
}
|
||
}
|
||
|
||
public int Fusion_distance
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_FUSION_DISTANCE命令设置融合距离 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_FUSION_DISTANCE},{value}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置融合距离成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置融合距离失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_PARAMETER命令获取融合距离 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.FUSION_DISTANCE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
return ParseResponseValue(response);
|
||
}
|
||
return 1000; // 默认1米
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取融合距离失败: {ex.Message}");
|
||
return 1000;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Set_envir_param(SharedStructures.EnvirParam data)
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_ENVIR_PARAM命令设置环境参数 - SDK格式
|
||
// 构建参数字符串,包含所有环境参数
|
||
string paramsStr = $"{data.method},{data.num},{data.emissivity},{data.airTemp},{data.targetTemp},{data.atmosTrans},{data.distance},{data.infraredTemp},{data.infraredRadia}";
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_ENVIR_PARAM},{paramsStr}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设置环境参数成功");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置环境参数失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public SharedStructures.EnvirParam Get_area_envir_param(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_AREA_ENVIR_PARAM命令获取区域环境参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_AREA_ENVIR_PARAM},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建EnvirParam对象
|
||
SharedStructures.EnvirParam envirParam = new SharedStructures.EnvirParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return envirParam;
|
||
}
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取区域环境参数失败: {ex.Message}");
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.EnvirParam Get_spot_envir_param(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_SPOT_ENVIR_PARAM命令获取点环境参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_SPOT_ENVIR_PARAM},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建EnvirParam对象
|
||
SharedStructures.EnvirParam envirParam = new SharedStructures.EnvirParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return envirParam;
|
||
}
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取点环境参数失败: {ex.Message}");
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.EnvirParam Get_line_envir_param()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_LINE_ENVIR_PARAM命令获取线环境参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_LINE_ENVIR_PARAM}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建EnvirParam对象
|
||
SharedStructures.EnvirParam envirParam = new SharedStructures.EnvirParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return envirParam;
|
||
}
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取线环境参数失败: {ex.Message}");
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.EnvirParam Get_globa_envir_param()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_GLOBAL_ENVIR_PARAM命令获取全局环境参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_GLOBAL_ENVIR_PARAM}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建EnvirParam对象
|
||
SharedStructures.EnvirParam envirParam = new SharedStructures.EnvirParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return envirParam;
|
||
}
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取全局环境参数失败: {ex.Message}");
|
||
return new SharedStructures.EnvirParam();
|
||
}
|
||
}
|
||
|
||
public void Set_alarm_param(SharedStructures.AlarmParam data)
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_ALARM_PARAM命令设置报警参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_ALARM_PARAM},{data.method},{data.num},{data.active},{data.condition},{data.captrue},{data.disableCalib},{data.email},{data.digital},{data.ftp},{data.threshold},{data.hysteresis},{data.thresholeTime}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
// 命令执行成功
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置报警参数失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AlarmParam Get_area_alarm_param(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_AREA_ALARM_PARAM命令获取区域报警参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_AREA_ALARM_PARAM},{index}$";
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建AlarmParam对象
|
||
SharedStructures.AlarmParam alarmParam = new SharedStructures.AlarmParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return alarmParam;
|
||
}
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取区域报警参数失败: {ex.Message}");
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AlarmParam Get_spot_alarm_param(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_SPOT_ALARM_PARAM命令获取点报警参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_SPOT_ALARM_PARAM},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建AlarmParam对象
|
||
SharedStructures.AlarmParam alarmParam = new SharedStructures.AlarmParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return alarmParam;
|
||
}
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取点报警参数失败: {ex.Message}");
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AlarmParam Get_globa_alarm_param()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_GLOBAL_ALARM_PARAM命令获取全局报警参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_GLOBAL_ALARM_PARAM}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建AlarmParam对象
|
||
SharedStructures.AlarmParam alarmParam = new SharedStructures.AlarmParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return alarmParam;
|
||
}
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取全局报警参数失败: {ex.Message}");
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AlarmParam Get_line_alarm_param()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_LINE_ALARM_PARAM命令获取线报警参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_LINE_ALARM_PARAM}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建AlarmParam对象
|
||
SharedStructures.AlarmParam alarmParam = new SharedStructures.AlarmParam();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return alarmParam;
|
||
}
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取线报警参数失败: {ex.Message}");
|
||
return new SharedStructures.AlarmParam();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.AreaTemp Get_area_temp(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_AREA_TEMP命令获取区域温度 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_AREA_TEMP},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建AreaTemp对象
|
||
SharedStructures.AreaTemp areaTemp = new SharedStructures.AreaTemp();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return areaTemp;
|
||
}
|
||
return new SharedStructures.AreaTemp();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取区域温度失败: {ex.Message}");
|
||
return new SharedStructures.AreaTemp();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.SpotTemp Get_spot_temp(int index)
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_SPOT_TEMP命令获取点温度 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_SPOT_TEMP},{index}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建SpotTemp对象
|
||
SharedStructures.SpotTemp spotTemp = new SharedStructures.SpotTemp();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return spotTemp;
|
||
}
|
||
return new SharedStructures.SpotTemp();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取点温度失败: {ex.Message}");
|
||
return new SharedStructures.SpotTemp();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.LineTemp Get_line_temp()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_LINE_TEMP命令获取线温度 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_LINE_TEMP}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建LineTemp对象
|
||
SharedStructures.LineTemp lineTemp = new SharedStructures.LineTemp();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return lineTemp;
|
||
}
|
||
return new SharedStructures.LineTemp();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取线温度失败: {ex.Message}");
|
||
return new SharedStructures.LineTemp();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.GlobaTemp Get_globa_temp()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_GLOBAL_TEMP命令获取全局温度 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_GLOBAL_TEMP}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建GlobaTemp对象
|
||
SharedStructures.GlobaTemp globaTemp = new SharedStructures.GlobaTemp();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return globaTemp;
|
||
}
|
||
return new SharedStructures.GlobaTemp();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取全局温度失败: {ex.Message}");
|
||
return new SharedStructures.GlobaTemp();
|
||
}
|
||
}
|
||
|
||
public SharedStructures.ImageTemp Get_all_temp()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_ALL_TEMP命令获取所有温度数据 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_ALL_TEMP}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应并创建ImageTemp对象
|
||
SharedStructures.ImageTemp imageTemp = new SharedStructures.ImageTemp();
|
||
// 这里可以根据实际响应格式进行解析
|
||
// 目前返回默认对象
|
||
return imageTemp;
|
||
}
|
||
return new SharedStructures.ImageTemp();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取所有温度数据失败: {ex.Message}");
|
||
return new SharedStructures.ImageTemp();
|
||
}
|
||
}
|
||
|
||
public void Power_reboot()
|
||
{
|
||
try
|
||
{
|
||
// 使用POWER_REBOOT命令重启设备 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.POWER_REBOOT}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设备重启命令已发送");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设备重启失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void Param_recover()
|
||
{
|
||
try
|
||
{
|
||
// 使用PARAM_RECOVER命令恢复参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.PARAM_RECOVER}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("参数恢复命令已发送");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"参数恢复失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
try
|
||
{
|
||
// 使用UPDATE命令更新设备 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.UPDATE}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
Console.WriteLine("设备更新命令已发送");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设备更新失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// 使用SendCommand方法发送心跳命令,与SDK保持一致
|
||
public int Heartbeat()
|
||
{
|
||
try
|
||
{
|
||
// 根据SDK实际实现,心跳命令格式是 +CMD:24$
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.HEARTBEAT}$";
|
||
|
||
// SDK实现中会尝试3次心跳,这里也采用相同的策略
|
||
for (int retry = 0; retry < 3; retry++)
|
||
{
|
||
Console.WriteLine($"心跳检测...(尝试 {retry + 1}/3)");
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// SDK要求响应中必须包含 ":ok" 字符串才算成功
|
||
if (!string.IsNullOrEmpty(response) && response.Contains(":ok"))
|
||
{
|
||
Console.WriteLine("心跳成功: 响应包含':ok'");
|
||
return 1; // 返回1表示成功,与DeviceManager中的heartbeatResult > 0判断一致
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"心跳响应不包含':ok',验证失败。收到的响应: '{response}'");
|
||
}
|
||
}
|
||
|
||
// 如果不是最后一次尝试,短暂延迟后重试
|
||
if (retry < 2)
|
||
{
|
||
Thread.Sleep(100);
|
||
}
|
||
}
|
||
|
||
// 所有重试都失败了
|
||
Console.WriteLine("三次心跳检测均失败,连接未建立");
|
||
return -1;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"心跳检测异常: {ex.Message}");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
public void Set_uart(int nSpeed, int nBits, char nEvent, int nStop)
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_UART命令设置串口参数 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_UART},{nSpeed},{nBits},{(int)nEvent},{nStop}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
// 命令执行成功
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置串口失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void Send_uart_command(byte[] cmd)
|
||
{
|
||
try
|
||
{
|
||
// 将byte数组转换为十六进制字符串格式
|
||
string hexData = BitConverter.ToString(cmd).Replace("-", "");
|
||
// 使用SEND_UART_COMMAND命令发送串口命令 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SEND_UART_COMMAND},{hexData}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"发送串口命令失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void Autofocus(SharedStructures.FocusParam data)
|
||
{
|
||
try
|
||
{
|
||
// 使用AUTOFOCUS命令设置自动对焦参数 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.AUTOFOCUS},{data.method},{data.x},{data.y},{data.width},{data.height}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
// 命令执行成功
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"自动对焦失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void Set_device_name(string data)
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_DEVICE_NAME命令设置设备名称 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_DEVICE_NAME},{data}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
// 命令执行成功
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置设备名称失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public string Get_device_name()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_PARAMETER命令获取设备名称 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.DEVICE_NA}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应中的设备名称
|
||
// 格式: +RET:1:设备名称$ 或 +RET:设备名称$
|
||
if (response != null && (response.StartsWith("+RET:") || response.StartsWith("+RSP:")))
|
||
{
|
||
int paramTypeEndPos = response.IndexOf(':', 5);
|
||
int nameStartPos = (paramTypeEndPos > 0) ? paramTypeEndPos + 1 : 5;
|
||
int endPos = response.IndexOf('$', nameStartPos);
|
||
|
||
if (endPos > nameStartPos)
|
||
{
|
||
return response.Substring(nameStartPos, endPos - nameStartPos);
|
||
}
|
||
}
|
||
}
|
||
return string.Empty;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取设备名称失败: {ex.Message}");
|
||
return string.Empty;
|
||
}
|
||
}
|
||
|
||
public byte[] Get_detect_number()
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_DETECT_NUMBER命令获取检测编号 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_DETECT_NUMBER}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应,返回检测编号数据
|
||
// 响应格式: +RET:0:数据内容$ 或 +RET:数据内容$
|
||
if (response != null && (response.StartsWith("+RET:") || response.StartsWith("+RSP:")))
|
||
{
|
||
// 解析响应中的数据部分
|
||
int startPos = response.IndexOf(':', 5) + 1;
|
||
int endPos = response.IndexOf('$', startPos);
|
||
|
||
if (endPos > startPos)
|
||
{
|
||
string dataStr = response.Substring(startPos, endPos - startPos);
|
||
// 将十六进制字符串转换为字节数组
|
||
// 注意:这里需要根据实际响应格式进行适当的转换
|
||
return Encoding.ASCII.GetBytes(dataStr);
|
||
}
|
||
}
|
||
}
|
||
return new byte[0];
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取检测编号失败: {ex.Message}");
|
||
return new byte[0];
|
||
}
|
||
}
|
||
|
||
public char Temp_frame
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_TEMP_FRAME命令设置温度帧 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_TEMP_FRAME},{(byte)value}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置温度帧失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_TEMP_FRAME命令获取温度帧 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_TEMP_FRAME}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应中的温度帧值
|
||
if (response != null && (response.StartsWith("+RET:") || response.StartsWith("+RSP:")))
|
||
{
|
||
int valueStartPos = response.IndexOf(':', 5) + 1;
|
||
int endPos = response.IndexOf('$', valueStartPos);
|
||
|
||
if (endPos > valueStartPos)
|
||
{
|
||
string valueStr = response.Substring(valueStartPos, endPos - valueStartPos);
|
||
if (byte.TryParse(valueStr, out byte result))
|
||
{
|
||
return (char)result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return (char)0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取温度帧失败: {ex.Message}");
|
||
return (char)0;
|
||
}
|
||
}
|
||
}
|
||
|
||
public char Alarm
|
||
{
|
||
set
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_ALARM命令设置报警输出 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.SET_ALARM},{(byte)value}$";
|
||
|
||
SendCommand(command, out _);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置报警输出失败: {ex.Message}");
|
||
}
|
||
}
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 使用GET_ALARM命令获取报警输出状态 - SDK格式
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_ALARM}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应中的报警状态值
|
||
if (response != null && response.StartsWith("+RET:"))
|
||
{
|
||
int valueStartPos = response.IndexOf(':', 5) + 1;
|
||
int endPos = response.IndexOf('$', valueStartPos);
|
||
|
||
if (endPos > valueStartPos)
|
||
{
|
||
string valueStr = response.Substring(valueStartPos, endPos - valueStartPos);
|
||
if (byte.TryParse(valueStr, out byte result))
|
||
{
|
||
return (char)result;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return (char)0;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取报警输入失败: {ex.Message}");
|
||
return (char)0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 私有字段,用于存储最后一次成功获取的温补值
|
||
private int _lastSuccessfulCompTemp = 0;
|
||
|
||
public int Comp_temp
|
||
{
|
||
get
|
||
{
|
||
try
|
||
{
|
||
// 与C++ SDK保持一致,使用GET_PARAMETER命令并指定COMP_TEMP参数类型
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.GET_PARAMETER},{(int)PARAM_TYPE.COMP_TEMP}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 解析响应中的补偿温度值 - 支持+RET:和+RSP:两种格式
|
||
if (response != null && (response.StartsWith("+RET:") || response.StartsWith("+RSP:")))
|
||
{
|
||
// 与C++ SDK一致,从缓冲区+5位置解析值
|
||
string valueStr = response.Substring(5);
|
||
// 移除末尾的$符号
|
||
if (valueStr.EndsWith("$"))
|
||
{
|
||
valueStr = valueStr.Substring(0, valueStr.Length - 1);
|
||
}
|
||
if (int.TryParse(valueStr, out int result))
|
||
{
|
||
// 查询成功,更新并返回温补值
|
||
_lastSuccessfulCompTemp = result;
|
||
return result;
|
||
}
|
||
}
|
||
}
|
||
// 查询失败但有上一次成功的值,则返回上一次的值
|
||
Console.WriteLine("温补查询失败,使用上一次成功的温补值");
|
||
return _lastSuccessfulCompTemp;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取补偿温度失败: {ex.Message},使用上一次成功的温补值");
|
||
// 异常情况下也返回上一次成功的值
|
||
return _lastSuccessfulCompTemp;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Set_time(SharedStructures.TimeParam data)
|
||
{
|
||
try
|
||
{
|
||
// 使用SET_TIME命令设置系统时间 - SDK格式
|
||
string command = $"{CMD_HEAD}:{(int)CMD_TYPE.SET_TIME},{data.year},{data.month},{data.day},{data.hour},{data.minute},{data.second}$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 验证响应是否成功
|
||
if (response != null)
|
||
{
|
||
// 命令执行成功
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"设置系统时间失败: {ex.Message}");
|
||
}
|
||
}
|
||
// 获取视频模式
|
||
public int GetVideoMode()
|
||
{
|
||
return GetVideoModeInternal();
|
||
}
|
||
|
||
// 设置视频模式
|
||
public void SetVideoMode(int mode)
|
||
{
|
||
SetVideoModeInternal(mode);
|
||
}
|
||
|
||
// 新增方法:获取图像数据
|
||
public byte[] GetImageData()
|
||
{
|
||
try
|
||
{
|
||
// 根据SDK实现,使用正确的命令格式获取图像数据
|
||
// 格式为:"ip:param_mode,param_value$"
|
||
string command = $"{deviceIp}:{(int)CMD_TYPE.GET_IMAGE_DATA},0$";
|
||
|
||
if (SendCommand(command, out string response))
|
||
{
|
||
// 处理图像数据响应
|
||
// 注意:由于图像数据可能较大且为二进制,这里需要根据实际响应格式进行解析
|
||
if (response != null)
|
||
{
|
||
// 查找响应中的数据部分
|
||
int endPos = response.IndexOf('$');
|
||
|
||
if (endPos > 0)
|
||
{
|
||
string dataStr = response.Substring(0, endPos);
|
||
// 假设图像数据是base64编码的,需要解码
|
||
try
|
||
{
|
||
return Convert.FromBase64String(dataStr);
|
||
}
|
||
catch
|
||
{
|
||
// 如果不是base64编码,返回空数组
|
||
return new byte[0];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return new byte[0];
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"获取图像数据失败: {ex.Message}");
|
||
return new byte[0];
|
||
}
|
||
}
|
||
}
|
||
}
|