using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; using System.Net.Http; using System.Net.Sockets; using System.Text; using System.Threading; using MesServerWork; using System.Threading.Tasks; namespace MesServerFunctions { partial class FunctionMES { private readonly object _lockObject = new object(); private volatile bool _isTestOk = false; private string _opName; private const int DEFAULT_TIMEOUT = 7000; // 默认超时时间(毫秒) private const int MAX_RETRY_COUNT = 10; // 最大重试次数 private const int RESULT_LENGTH = 113; // 预期结果长度 /// /// 电阻测试 /// private void ReqTestResistor(object e) { try { DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; _opName = Convert.ToString(msgEvent.OpName); int tagValue = Convert.ToInt32(msgEvent.TagValue); if (tagValue == 1) { TestResistor().GetAwaiter().GetResult(); } else { ResetPLCValues(); } } catch (Exception err) { MyLog4Net.MyLogHelper.Error("电阻测试", $"测试过程发生错误: {err.Message}"); ErrPLCValues(); } } /// /// 执行电阻测试 /// private async Task TestResistor() { TcpClient tcpClient = null; try { string IP = ConfigurationManager.AppSettings["ResistorDeviceIP_" + _opName]; string Port = ConfigurationManager.AppSettings["ResistorDevicePort"]; using (tcpClient = new TcpClient()) { var connectTask = tcpClient.ConnectAsync(IP, Convert.ToInt32(Port)); if (await Task.WhenAny(connectTask, Task.Delay(DEFAULT_TIMEOUT)) != connectTask) { throw new TimeoutException("连接电阻仪超时"); } if (tcpClient.Connected) { MyLog4Net.MyLogHelper.Info("电阻测试", "电阻仪链接成功!"); await SendCommand(tcpClient, "01 09 64 00 05 00 00 00 00 00 73"); await Task.Delay(DEFAULT_TIMEOUT); var readTask = Task.Run(() => Read(tcpClient)); int count = 0; while (!_isTestOk && count < MAX_RETRY_COUNT) { await Task.Delay(1000); await SendCommand(tcpClient, "03 01 04"); count++; } if (count >= MAX_RETRY_COUNT && !_isTestOk) { MyLog4Net.MyLogHelper.Error("电阻测试", "测试超时,未收到有效结果"); ErrPLCValues(); } } } } catch (Exception ex) { MyLog4Net.MyLogHelper.Error("电阻测试", $"测试过程发生错误: {ex.Message}"); ErrPLCValues(); } finally { if (tcpClient != null) { tcpClient.Close(); MyLog4Net.MyLogHelper.Info("电阻测试", "电阻仪链接关闭"); } } } private void ResetPLCValues() { lock (_lockObject) { MIS_BASE.WritePLC(202, _opName, 0); MIS_BASE.WritePLC(203, _opName, 0); MIS_BASE.WritePLC(204, _opName, 0); MIS_BASE.WritePLC(34, _opName, false); } } private void ErrPLCValues() { lock (_lockObject) { MIS_BASE.WritePLC(202, _opName, 0); MIS_BASE.WritePLC(203, _opName, 0); MIS_BASE.WritePLC(204, _opName, 0); MIS_BASE.WritePLC(34, _opName, true); } } /// /// 发送命令到电阻仪 /// private async Task SendCommand(TcpClient tcpClient, string command) { try { // 将空格分隔的HEX字符串转换为字节数组 string[] hexValues = command.Split(' '); byte[] commandbyte = new byte[hexValues.Length]; for (int i = 0; i < hexValues.Length; i++) { commandbyte[i] = Convert.ToByte(hexValues[i], 16); } // 发送HEX格式的数据 await tcpClient.Client.SendAsync(new ArraySegment(commandbyte), SocketFlags.None); // 记录发送的命令 MyLog4Net.MyLogHelper.Info("电阻测试Send", $"发送命令: {command}"); } catch (Exception err) { MyLog4Net.MyLogHelper.Error("电阻测试Send", $"发送命令失败: {err.Message}"); throw; } } private void Read(TcpClient tcpClient) { try { while (!_isTestOk) { if (tcpClient != null && tcpClient.Connected) { byte[] byteCommand = new byte[1024]; int icommand = tcpClient.Client.Receive(byteCommand); string hexString = BitConverter.ToString(byteCommand, 0, icommand).Replace("-", " "); if (hexString.Length == RESULT_LENGTH) { DataAnalysis(hexString); } } } } catch (Exception err) { MyLog4Net.MyLogHelper.Error("电阻测试Read", err.Message); } } private void DataAnalysis(string hexString) { try { var byteArray = HexStringToByteArray(hexString.Replace(" ", "")); var start = 2; var 状态 = BitConverter.ToInt32(byteArray.Skip(start + 0).Take(4).ToArray(), 0); if (状态 != 2) return; var 电压V = BitConverter.ToDouble(byteArray.Skip(start + 4).Take(8).ToArray(), 0); var 电流A = BitConverter.ToDouble(byteArray.Skip(start + 12).Take(8).ToArray(), 0); var 电阻uΩ = BitConverter.ToDouble(byteArray.Skip(start + 20).Take(8).ToArray(), 0) * 1000000; var yyyy = BitConverter.ToUInt16(byteArray.Skip(start + 28).Take(2).ToArray(), 0); var MM = byteArray[start + 30]; var dd = byteArray[start + 31]; var HH = byteArray[start + 32]; var mm = byteArray[start + 33]; var ss = byteArray[start + 34]; var datetime = $"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}"; lock (_lockObject) { MIS_BASE.WritePLC(202, _opName, 电压V); MIS_BASE.WritePLC(203, _opName, 电流A); MIS_BASE.WritePLC(204, _opName, 电阻uΩ); MIS_BASE.WritePLC(34, _opName, true); _isTestOk = true; } MyLog4Net.MyLogHelper.Info("电阻测试", $"电阻结果写入完毕 【电压】{电压V}【电流】{电流A}【电阻】{电阻uΩ}"); } catch (Exception ex) { MyLog4Net.MyLogHelper.Error("电阻测试DataAnalysis", $"数据分析错误: {ex.Message}"); } } public static byte[] HexStringToByteArray(string hex) { if (hex.Length % 2 != 0) { throw new ArgumentException("十六进制字符串长度必须是偶数"); } byte[] bytes = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length; i += 2) { bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return bytes; } } }