diff --git a/MisDataFunction/Function1053/MesServerFunction/Function1053.cs b/MisDataFunction/Function1053/MesServerFunction/Function1053.cs new file mode 100644 index 0000000..76c232b --- /dev/null +++ b/MisDataFunction/Function1053/MesServerFunction/Function1053.cs @@ -0,0 +1,358 @@ +using MesServerWork; +using System.Collections.Generic; +using System.Threading; +using MisDataFunDll; +using System.Configuration; + + +namespace MesServerFunctions +{ + public partial class FunctionMES + { + object lockFunWork; + //public void FunWork(DeviceDriver_BasicData.CustomeEvetnArgs e) + public void FunWork(string recData) + { + + + lockFunWork = new object(); + lock (lockFunWork) + { + List dataArray = MisDataFun.GetCmdStringList(recData); + //string[] dataArray = recData.Split('|'); + //if (dataArray.Count != 4) + //return; + //消息来源 + string m_Source = dataArray[0].ToString(); + //消息类型 Barcode + string m_Command = dataArray[1].ToString(); + //工位号 + string m_OpName = dataArray[2].ToString(); + //消息参数 + string m_Value = dataArray[3].ToString(); + + DeviceDriver_BasicData.CustomeEvetnArgs e = new DeviceDriver_BasicData.CustomeEvetnArgs();// = Newtonsoft.Json.JsonConvert.DeserializeObject(m_Value); + string tagValue; + switch (m_Source) + { + case "BarCode": + e.OpName = m_OpName; + e.TagValue = m_Value; + fun_Barcode(e); + + break; + case "WEB": + e.OpName = m_OpName; + e.TagValue = m_Command + "|" + m_Value; + fun_WebSubmit(e); + break; + case "PLC": + e = Newtonsoft.Json.JsonConvert.DeserializeObject(m_Value); + string TagID = e.TagID.ToString(); + switch (e.TagValue.ToString().ToLower()) + { + case "false": + tagValue = "0"; + break; + case "true": + tagValue = "1"; + break; + default: + tagValue = e.TagValue.ToString(); + break; + } + e.TagValue = tagValue; + switch (e.TagTypeCodeID.ToString()) + { + //PLC 工件到位 + case "2": + fun_WorkStart(e); + break; + //PLC 允许保存质量数据 + case "19": + fun_MesRead(e); + break; + //MES 保存数据完成 + case "20": + fun_MesReadOver(e); + break; + //PLC 申请上线 + case "43": + PartLoad(e); + break; + //PLC 传递机型 + case "44": + fun_EngineTypeGetOverPLC(e); + break; + //MES 合格放行 + case "51": + fun_ConfirmOkGo(e); + break; + //MES 不合格放行 + case "8": + fun_FalseGo(e); + break; + // PLC 系统健康心跳 + case "14": + fun_HeartBeatMIS(e); + break; + //物料扫码完成(弃用!) + case "49": + fun_MaterislaScanOver(e); + break; + //物料扫码完成 + case "65": + fun_MaterialsVerify(e); + break; + // 写入托盘号后通知MES + case "48": + string write_Pallet_res; + MIS_BASE.Read_TagTypeID(48, m_OpName, out write_Pallet_res); + if (write_Pallet_res.ToLower() == "true" || write_Pallet_res.ToLower() == "1") + { + SendMessageFun.SendInfomation("writePallet", "1", m_OpName); + } + MIS_BASE.WritePLC(70, m_OpName, false); + break; + case "63": + fun_ReqEarlyFeeding(e); + break; + case "64": + fun_ReqTestResistor(e); + break; + } + if (ConfigurationManager.AppSettings["WebapiPostHeader_Systemcode"].ToString() == "MES_ZHDQ_126ZZ") + { + switch (e.TagTypeCodeID.ToString()) + { + case "58": // 请求AGV进站(上线) + if (tagValue == "1") fun_LGAgvDispatch(e, "BASE_TO_OP10", "CALL_IN", "上线点", "请求AGV进站"); + else MIS_BASE.WritePLC(28, m_OpName, false); + break; + case "59": // 请求前往总装点(上线) + if (tagValue == "1") fun_LGAgvDispatch(e, "BASE_TO_OP10", "TO_ASSEMBLY", "总装点", "请求前往总装点"); + else MIS_BASE.WritePLC(29, m_OpName, false); + break; + case "76": // 请求AGV离开(上线) + if (tagValue == "1") fun_LGAgvDispatch(e, "OP10_TO_OP20", "LEAVE_TO_NEXT", "总装点", "请求AGV离开"); + else MIS_BASE.WritePLC(30, m_OpName, false); + break; + case "61": // 请求AGV退出(自动) + if (tagValue == "1") MIS_BASE.WritePLC(31, m_OpName, true); + else MIS_BASE.WritePLC(31, m_OpName, false); + break; + case "62": // 请求AGV进入(自动) + if (tagValue == "1") MIS_BASE.WritePLC(32, m_OpName, true); + else MIS_BASE.WritePLC(32, m_OpName, false); + break; + case "63": // 请求AGV托盘举升 + if (tagValue == "1") MIS_BASE.WritePLC(33, m_OpName, true); + else MIS_BASE.WritePLC(33, m_OpName, false); + break; + case "64": // 请求AGV托盘下降 + if (tagValue == "1") MIS_BASE.WritePLC(34, m_OpName, true); + else MIS_BASE.WritePLC(34, m_OpName, false); + break; + case "65": // 请求AGV离站(自动) + if (tagValue == "1") MIS_BASE.WritePLC(35, m_OpName, true); + else MIS_BASE.WritePLC(35, m_OpName, false); + break; + default: + break; + } + } + break; + } + } + } + //public void FunWork(DeviceDriver_BasicData.CustomeEvetnArgs e) + //{ + // //lock1 = new object(); + // //lock (lock1) + // { + // switch (e.TagTypeCodeID.ToString()) + // { + // //PLC 工件到位 + // case "2": + // fun_WorkStart(e); + // break; + // //PLC 允许保存质量数据 + // case "19": + // fun_MesRead(e); + // break; + // //MES 保存数据完成 + // case "20": + // fun_MesReadOver(e); + // break; + // //PLC 传递机型 + // case "44": + // fun_EngineTypeGetOverPLC(e); + // break; + // //MES 合格放行 + // case "51": + // fun_ConfirmOkGo(e); + // break; + // //MES 不合格放行 + // case "8": + // fun_FalseGo(e); + // break; + // //MES 扫描条码 + // case "Barcode": + // fun_Barcode(e); + // break; + // //WEB 处理页面传递过来的数据 + // case "WebSubmit": + // fun_WebSubmit(e); + // break; + // } + // } + + //} + //1.工件到位后,PLC给MES传递机型(DBX0.4)(44), + //2.MES判断是否扫描完成 + //3.若扫描完成,则MES给出合格放行(DBX2.5)(51) + /// + /// 扫描条码 + /// + /// + /// + public void fun_Barcode(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(Barcode, e); + } + + + /// + /// 传递机型 + /// + /// + /// + public void fun_EngineTypeGetOverPLC(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(EngineTypeGetOver_PLC, e); + } + + /// + /// 合格放行 + /// + /// + /// + public void fun_ConfirmOkGo(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + //// ThreadPool.QueueUserWorkItem(ConfirmOkGo, e); + } + + + /// + /// 提前上料 + /// + /// + /// + public void fun_ReqEarlyFeeding(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(ReqEarlyFeeding, e); + } + + /// + /// 请求测试电阻 调用电阻仪 + /// + /// + /// + public void fun_ReqTestResistor(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem( ReqTestResistor, e); + } + + /// + /// 不合格放行 + /// + /// + /// + public void fun_FalseGo(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + // ThreadPool.QueueUserWorkItem(FalseGO, e); + } + + + /// + /// 保存完成 20 + /// + /// + /// + public void fun_MesReadOver(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + // ThreadPool.QueueUserWorkItem(MesReadOver, e); + } + + /// + /// 物料扫码完成 + /// + public void fun_MaterislaScanOver(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(MaterialsScanOver, e); + } + + /// + /// 物料扫码完成 + /// + public void fun_MaterialsVerify(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(MaterialsVerify, e); + } + + /// + /// 保存完成 19 + /// + /// + /// + public void fun_MesRead(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(MesRead, e); + } + + /// + /// 工件到位离开(清空所有的MES信号) + /// + /// + /// + public void fun_WorkStart(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(WorkStart, e); + } + + /// + /// 处理WEB页面发送过来的请求(m_Command + "|" + m_Value;) + /// + /// + /// + public void fun_WebSubmit(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + ThreadPool.QueueUserWorkItem(WebSubmit, e); + } + + public int fun_SubLineLoadPartCountMatch() + { + return SubLineLoadPartCountMatch; + } + + + /// + /// MES系统健康心跳监测 + /// + /// + /// + public void fun_HeartBeatMIS(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + // ThreadPool.QueueUserWorkItem(HeartBeatMES, e); + } + /// + /// PLC系统健康心跳监测 + /// + /// + /// + public void fun_HeartBeatPLC(DeviceDriver_BasicData.CustomeEvetnArgs e) + { + //ThreadPool.QueueUserWorkItem(HeartBeatPLC, e); + } + } +} diff --git a/MisDataFunction/Function1053/Methods/LGAgvDispatch.cs b/MisDataFunction/Function1053/Methods/LGAgvDispatch.cs new file mode 100644 index 0000000..cb7e035 --- /dev/null +++ b/MisDataFunction/Function1053/Methods/LGAgvDispatch.cs @@ -0,0 +1,158 @@ +using System; +using System.Threading; +using MesServerWork; +using MisDataSaveDate; + +namespace MesServerFunctions +{ + partial class FunctionMES + { + private const string LGAgvWorkStation = "AC1101"; + + private class LGAgvDispatchContext + { + public DeviceDriver_BasicData.CustomeEvetnArgs EventArgs { get; set; } + public string RouteCode { get; set; } + public string ActionCode { get; set; } + public string ProcessPointType { get; set; } + public string Description { get; set; } + } + + private class LGAgvProductInfo + { + public int EngineTypeID { get; set; } + public string EngineType { get; set; } + public string EngineID { get; set; } + public string OrderForm { get; set; } + public int PartPalletCode { get; set; } + } + + private void fun_LGAgvDispatch(DeviceDriver_BasicData.CustomeEvetnArgs e, string routeCode, string actionCode, string processPointType, string description) + { + ThreadPool.QueueUserWorkItem(LGAgvDispatch, new LGAgvDispatchContext + { + EventArgs = e, + RouteCode = routeCode, + ActionCode = actionCode, + ProcessPointType = processPointType, + Description = description + }); + } + + private void LGAgvDispatch(object state) + { + string opName = LGAgvWorkStation; + try + { + LGAgvDispatchContext context = (LGAgvDispatchContext)state; + if (context == null || context.EventArgs == null) + { + throw new Exception("AGV调度参数为空"); + } + + string eventOpName = Convert.ToString(context.EventArgs.OpName); + opName = string.IsNullOrWhiteSpace(eventOpName) ? LGAgvWorkStation : eventOpName; + LGAgvProductInfo productInfo = ReadLGAgvProductInfo(opName); + + LGWEB_DispatchResult result = LGWEB_BusinessLogic.DispatchAGV(new LGWEB_DispatchRequest + { + routeCode = context.RouteCode, + productModelCode = productInfo.EngineTypeID.ToString(), + productModel = productInfo.EngineType, + actionCode = context.ActionCode, + processPointType = context.ProcessPointType, + workStation = LGAgvWorkStation, + productCode = productInfo.EngineID, + containerNo = productInfo.PartPalletCode > 0 ? productInfo.PartPalletCode.ToString() : "", + orderNo = productInfo.OrderForm, + operatorCode = "PLC", + operatorName = "PLC自动", + remark = context.Description + }, "PLC_AUTO", true); + + if (!result.Success) + { + throw new Exception(result.Message); + } + + string logText = $"临工AGV任务已下发:动作={context.ActionCode},起点={result.StartPosition},终点={result.EndPosition},任务ID={result.RequestTaskId}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(opName, logText, MisDataSaveDate.Helper.MesLogType.INFO); + SendMessage.AsyncSendMessage_Notice(opName, logText); + } + catch (Exception ex) + { + string logText = $"临工AGV调度失败:{ex.Message}"; + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(opName, logText, MisDataSaveDate.Helper.MesLogType.ERROR); + SendMessage.AsyncSendMessage_Notice(opName, logText); + MyLog4Net.MyLogHelper.Error("Function1053_LGAgvDispatch", $"{logText}{Environment.NewLine}{ex}"); + } + } + + private LGAgvProductInfo ReadLGAgvProductInfo(string opName) + { + LGAgvProductInfo productInfo = ReadLGAgvProductInfoFromMes(opName); + if (productInfo.EngineTypeID <= 0 || string.IsNullOrWhiteSpace(productInfo.EngineType)) + { + productInfo = ReadLGAgvProductInfoFromPlc(opName); + } + + if (productInfo.EngineTypeID <= 0 || string.IsNullOrWhiteSpace(productInfo.EngineType)) + { + throw new Exception("未读取到产品型号,无法解析AGV产品点位配置"); + } + + return productInfo; + } + + private LGAgvProductInfo ReadLGAgvProductInfoFromMes(string opName) + { + int engineTypeID = 0; + string engineType = ""; + string engineID = ""; + string orderForm = ""; + + try + { + MIS_BASE.GetEngineTypeFromPLC_MES(opName, out engineTypeID, out engineType, out engineID, out orderForm); + } + catch + { + } + + return new LGAgvProductInfo + { + EngineTypeID = engineTypeID, + EngineType = engineType ?? "", + EngineID = engineID ?? "", + OrderForm = orderForm ?? "", + PartPalletCode = 0 + }; + } + + private LGAgvProductInfo ReadLGAgvProductInfoFromPlc(string opName) + { + int engineTypeID = 0; + int partPalletCode = 0; + string engineType = ""; + string engineID = ""; + string orderForm = ""; + + try + { + MIS_BASE.GetEngineTypeFromPLC(opName, out engineTypeID, out engineType, out engineID, out partPalletCode, out orderForm); + } + catch + { + } + + return new LGAgvProductInfo + { + EngineTypeID = engineTypeID, + EngineType = engineType ?? "", + EngineID = engineID ?? "", + OrderForm = orderForm ?? "", + PartPalletCode = partPalletCode + }; + } + } +} diff --git a/MisDataFunction/Function1053/OpcServer/MaterialsScanOver.cs b/MisDataFunction/Function1053/OpcServer/MaterialsScanOver.cs new file mode 100644 index 0000000..665afe9 --- /dev/null +++ b/MisDataFunction/Function1053/OpcServer/MaterialsScanOver.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading; +//using SystemFramework; +using MesServerWork; +using MisDataFunDll; + +namespace MesServerFunctions +{ + partial class FunctionMES + { + /// + /// 物料扫码完成 + /// + /// + /// + private void MaterialsScanOver(object e) + { + try + { + DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; + string OpName = Convert.ToString(msgEvent.OpName); + int tagValue = Convert.ToInt32(msgEvent.TagValue); + + + if (tagValue == 1) + { + MIS_BASE.GetEngineTypeFromPLC(OpName, out int EngineTypeID, out string EngineType, out string EngineID, out int PartPallet_Code, out string OrderForm); + string materialsCode = MIS_BASE.ReadPLC(40, OpName).ToString(); + var dt = MisDataFun.Get_MaterialsScanOverRes(OpName, OrderForm, EngineID, materialsCode); + int result = Convert.ToInt32(dt.Rows[0]["result"]); + if (result == 1) + { + MIS_BASE.WritePLC(95, OpName, 1); + } + else if (result == 2) + { + MIS_BASE.WritePLC(95, OpName, 2); + } + } + else + { + MIS_BASE.WritePLC(96, OpName, 0); // 提前上料位置 + MIS_BASE.WritePLC(33, OpName, false); // 允许提前上料 + MIS_BASE.Write_EngineID_MES(OpName, ""); + } + } + catch (Exception err) + { + ////ApplicationLog.WriteLog(err, "Function08:MesReadOver"); + } + } + } +} diff --git a/MisDataFunction/Function1053/OpcServer/MesReadOver.cs b/MisDataFunction/Function1053/OpcServer/MesReadOver.cs new file mode 100644 index 0000000..1b7206b --- /dev/null +++ b/MisDataFunction/Function1053/OpcServer/MesReadOver.cs @@ -0,0 +1,36 @@ +using System; +//using SystemFramework; +using MesServerWork; + +namespace MesServerFunctions +{ + partial class FunctionMES + { + /// + /// 保存完成(针对半自动和手动压装工位) + /// + /// + /// + private void MesReadOver(object e) + { + try + { + //DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; + //string OpName = Convert.ToString(msgEvent.OpName); + //int tagValue = Convert.ToInt32(msgEvent.TagValue); + + //if (tagValue == 1) + //{ + + // BaseDataSystemMES.Material_Insert(OpName, tagValue); + + // MIS_BASE.Write_ConfirmOkGo(OpName, true); + //} + } + catch (Exception err) + { + ////ApplicationLog.WriteLog(err, "Function08:MesReadOver"); + } + } + } +} diff --git a/MisDataFunction/Function1053/OpcServer/ReqEarlyFeeding.cs b/MisDataFunction/Function1053/OpcServer/ReqEarlyFeeding.cs new file mode 100644 index 0000000..3b24ea4 --- /dev/null +++ b/MisDataFunction/Function1053/OpcServer/ReqEarlyFeeding.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading; +using MesServerWork; +using MisDataFunDll; + +namespace MesServerFunctions +{ + partial class FunctionMES + { + /// + /// 申请提前上料 + /// + /// + /// + private void ReqEarlyFeeding(object e) + { + try + { + DeviceDriver_BasicData.CustomeEvetnArgs msgEvent = (DeviceDriver_BasicData.CustomeEvetnArgs)e; + string OpName = Convert.ToString(msgEvent.OpName); + int tagValue = Convert.ToInt32(msgEvent.TagValue); + + + if (tagValue == 1) + { + var dt = MisDataFun.Get_ReqEarlyFeedingData(OpName); + int result = Convert.ToInt32(dt.Rows[0]["result"]); + string msg = dt.Rows[0]["msg"].ToString(); + int EngineTypeID = Convert.ToInt32(dt.Rows[0]["产品型号代码"]); + if (result == 1) + { + MIS_BASE.WritePLC(96, OpName, EngineTypeID); // 产品型号 + MIS_BASE.Write_EngineID_MES(OpName, dt.Rows[0]["工件编号"].ToString()); + int ReadEngineID = Convert.ToInt32(MIS_BASE.ReadPLC(96, OpName)); + if (EngineTypeID != ReadEngineID) + { + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "ReqEarlyFeeding " + $"写入提前上料机型{EngineTypeID.ToString()} 与 读取到的{ReadEngineID.ToString()}不一致", MisDataSaveDate.Helper.MesLogType.ERROR); + return; + } + if (EngineTypeID == 0 || ReadEngineID == 0) + { + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "ReqEarlyFeeding " + $"写入提前上料机型{EngineTypeID.ToString()} 与 读取到的{ReadEngineID.ToString()} 其中存在空值", MisDataSaveDate.Helper.MesLogType.ERROR); + return; + } + MIS_BASE.WritePLC(33, OpName, true); // 允许提前上料 + + } + else if (result == 2) + { + MIS_BASE.WritePLC(33, OpName, false); + string msg2 = "【" + OpName + "】" + msg; + SendMessage.AsyncSendMessage_Notice(OpName, msg); + MisDataSaveDate.Helper.ApiLogHelper.SaveMesLog(OpName, "ReqEarlyFeeding " + msg2, MisDataSaveDate.Helper.MesLogType.ERROR); + + return; + } + } + else + { + MIS_BASE.WritePLC(96, OpName, 0); // 提前上料位置 + MIS_BASE.WritePLC(33, OpName, false); // 允许提前上料 + //MIS_BASE.Write_EngineID_MES(OpName, ""); + } + } + catch (Exception err) + { + ////ApplicationLog.WriteLog(err, "Function08:MesReadOver"); + } + } + } +} diff --git a/MisDataFunction/Function1053/OpcServer/ReqTestResistor.cs b/MisDataFunction/Function1053/OpcServer/ReqTestResistor.cs new file mode 100644 index 0000000..7418852 --- /dev/null +++ b/MisDataFunction/Function1053/OpcServer/ReqTestResistor.cs @@ -0,0 +1,238 @@ +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(_opName+"连接电阻仪超时"); + } + + if (tcpClient.Connected) + { + MyLog4Net.MyLogHelper.Info(_opName + "电阻测试", "电阻仪链接成功!"); + 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(_opName + "电阻测试", "测试超时,未收到有效结果"); + ErrPLCValues(); + } + } + } + } + catch (Exception ex) + { + MyLog4Net.MyLogHelper.Error(_opName + "电阻测试", $"测试过程发生错误: {ex.Message}"); + ErrPLCValues(); + } + finally + { + if (tcpClient != null) + { + tcpClient.Close(); + MyLog4Net.MyLogHelper.Info(_opName + "电阻测试", "电阻仪链接关闭"); + } + } + } + + 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(_opName + "电阻测试Send", $"发送命令: {command}"); + } + catch (Exception err) + { + MyLog4Net.MyLogHelper.Error(_opName + "电阻测试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(_opName + "电阻测试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(_opName + "电阻测试", $"电阻结果写入完毕 【电压】{电压V}【电流】{电流A}【电阻】{电阻uΩ}"); + } + catch (Exception ex) + { + MyLog4Net.MyLogHelper.Error(_opName + "电阻测试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; + } + } +} \ No newline at end of file