using System; using System.Collections.Generic; using System.Linq; using System.Web; using QMAPP.FJC.Entity.Basic; using System.Configuration; using OPCPLC; using QMAPP.FJC.Entity; using System.Threading; using OPCAutomation; using OpcServerHost.Common; using QMFrameWork.Common.Serialization; using QMAPP.FJC.DAL.Basic; using QMAPP.FJC.BLL.Process; using EQUIPINTERFACETEST; using QMFrameWork.Data; using QMAPP.FJC.Entity.Operation; using OpcServerHost.WebServiceForOpc; using QMAPP.FJC.Entity.QT; using System.Text; namespace OpcServerHost.Init { public static class ParaInit { //用来存储工控机发起连接服务器建立双通道连接的设备信息 public static List connectMachineList; //用来存储生产设备信息 public static List machineList; //用来存储OPC配置参数与服务端句柄的对应关系 //key:OPC配置参数,样式为 设备号+":"+模具号+":"+数据库字段 //value:服务端句柄 public static Dictionary parameterValueDict = new Dictionary(); public static Dictionary opcItemDict = new Dictionary(); /// /// 用来存储客户端句柄与设备参数对应关系 /// key:客户端句柄值 /// value:OPC配置参数,样式为设备号+":"+模具号+":"+数据库字段 /// public static Dictionary clientHandleDict = new Dictionary(); //OPC配置参数列表静态变量 public static List paraConfigList; //设备模具参数信息静态变量 public static List moldList; //OPC连接字典静态变量 public static OPCPLCAutomation opcplcConnection; public static OPCPLCAutomation MonitorConnection; public static Dictionary opcDict = new Dictionary(); //客户端句柄参数 private static int clientHandleValue = 0; private static OpcServiceClient client; public static List sendOrderList; #region 初始化 /// /// 初始化相关信息 /// public static void InitParameter() { moldList = new List(); machineList = new List(); sendOrderList = new List(); //opcServer服务器IP string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP"); //opcServer服务名称 string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName"); try { #region 获取数据库中所有的生产设备信息 client = new OpcServiceClient(); string maincheStr = client.GetMachineList(); //获取所有的设备信息 machineList = JsonConvertHelper.GetDeserialize>(maincheStr); #endregion #region 获取所有的配置信息和命令信息 string produceLine = ConfigurationManager.AppSettings.Get("PRODUCELINE"); string paraConfigStr = client.GetParaConfigList(); paraConfigList = JsonConvertHelper.GetDeserialize>(paraConfigStr); paraConfigList = paraConfigList .Where(o => o.PROCESSTYPE != EnumGeter.ProcessType.tangsu.GetHashCode().ToString() ) .ToList(); //获取发送命令信息 string sendConfigStr = client.GetSendOrderConfigList(); sendOrderList = JsonConvertHelper.GetDeserialize>(sendConfigStr); #endregion #region 获取设备模块信息 //对加工参数配置信息按照设备及模具信息进行分组 var objlist = from pc in paraConfigList group pc by new { pc.MACHINECODDE, pc.MOLDNUMBER } into g select new ParameterConfig { MACHINECODDE = g.Key.MACHINECODDE, MOLDNUMBER = g.Key.MOLDNUMBER }; //添加到静态变量中 foreach (var ob in objlist) { moldList.Add(new ParameterConfig() { MACHINECODDE = ob.MACHINECODDE, MOLDNUMBER = ob.MOLDNUMBER }); } //按照设备进行排序 moldList = moldList.OrderBy(o => o.MACHINECODDE).ToList(); #endregion #region 建立opc服务连接 opcplcConnection = new OPCPLC.OPCPLCAutomation(); opcplcConnection.GetListOPCServers(opcServerIP); opcplcConnection.ConnectRemoteServer(opcServerName, opcServerIP); MonitorConnection = new OPCPLC.OPCPLCAutomation(); MonitorConnection.GetListOPCServers(opcServerIP); MonitorConnection.ConnectRemoteServer(opcServerName, opcServerIP); MonitorConnection.CreateGroup("Monitor"); MonitorConnection.KepGroups.DefaultGroupIsActive = true;//激活组。 MonitorConnection.KepGroups.DefaultGroupDeadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。 MonitorConnection.KepGroups.DefaultGroupUpdateRate = 50;//默认组群的刷新频率为200ms MonitorConnection.KepGroup.UpdateRate = 50;//刷新频率为1秒。 MonitorConnection.KepGroup.IsSubscribed = true;//使用订阅功能,即可以异步,默认false //绑定监控事件 MonitorConnection.KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange); foreach (var machine in machineList) { //只有需要控制的设备才建立连接 if (moldList.Count(o => o.MACHINECODDE == machine.MACHINECODDE) == 0) { continue; } OPCPLCAutomation dataConnection = new OPCPLC.OPCPLCAutomation(); dataConnection.GetListOPCServers(opcServerIP); dataConnection.ConnectRemoteServer(opcServerName, opcServerIP); opcDict.Add(machine.MACHINECODDE, dataConnection); } #endregion #region 加载模块下的加工参数配置信息 //变量所有的模具信息 foreach (var m in moldList) { if (machineList.Count(o => o.MACHINECODDE == m.MACHINECODDE) == 0) { continue; } MachineInfo machineEntity = machineList.First(o => o.MACHINECODDE == m.MACHINECODDE); #region 获取加工参数组 //获取该模块下所有的加工参数信息 List paraList = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString() ) .ToList(); if (paraList.Count > 0) { //为该模块创建参数组 opcDict[m.MACHINECODDE].CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":GetData"); if (opcDict[m.MACHINECODDE].KepGroups.DefaultGroupUpdateRate == 1000) { opcDict[m.MACHINECODDE].KepGroups.DefaultGroupUpdateRate = 200; } //变该模块下的所有参数信息 foreach (var pc in paraList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE; try { //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; clientHandleValue++; try { clientHandleDict.Add(clientHandleValue, dicKeyStr); //将字典中的与PLC内存地址向绑定 //parameterValueDict[dicKeyStr] = opcDict[m.MACHINECODDE].AddKepItem(itemName, clientHandleValue); opcItemDict[dicKeyStr] = opcDict[m.MACHINECODDE].AddKepOPCItem(itemName, clientHandleValue); parameterValueDict[dicKeyStr] = opcItemDict[dicKeyStr].ServerHandle; } catch (Exception ex) { Console.WriteLine("clientHandleDict重复:" + dicKeyStr); } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(dicKeyStr); continue; } } int i = 1; } #endregion #region 写入组 //包括写人设备可操作标记和获取加工参数完成标记 List writeList = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.OPERATEFLAG.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString() ) ) .ToList(); if (writeList.Count > 0) { opcplcConnection.CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":WriteData"); //变该模块下的所有参数信息 foreach (var pc in writeList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE; try { //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; clientHandleValue++; try { clientHandleDict.Add(clientHandleValue, dicKeyStr); //将字典中的与PLC内存地址向绑定 parameterValueDict[dicKeyStr] = opcplcConnection.AddKepItem(itemName, clientHandleValue); } catch (Exception ex) { Console.WriteLine("重复:" + dicKeyStr); } WriteLog.Write(dicKeyStr + " | " + itemName + " | " + clientHandleValue + " | " + parameterValueDict[dicKeyStr]); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(dicKeyStr); continue; } } } #endregion #region 条码信息 List barcodePara = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.BARCODE.GetHashCode().ToString()) .ToList(); if (barcodePara.Count > 0) { //创建该设备该模块下的条码组 opcplcConnection.CreateGroup(m.MACHINECODDE + ":" + m.MOLDNUMBER + ":BarCodePara"); //变该模块下的所有参数信息 foreach (var pc in barcodePara) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE; try { //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; clientHandleValue++; clientHandleDict.Add(clientHandleValue, dicKeyStr); //将字典中的与PLC内存地址向绑定 //parameterValueDict[dicKeyStr] = opcplcConnection.AddKepItem(itemName, clientHandleValue); opcItemDict[dicKeyStr] = opcplcConnection.AddKepOPCItem(itemName, clientHandleValue); parameterValueDict[dicKeyStr] = opcItemDict[dicKeyStr].ServerHandle; } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(dicKeyStr); continue; } } } #endregion #region 监控组 //获取设备扫描条码完成标记和设备加工完成标记 List monitorList = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.COMPLETEFLAG.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPCOMPLETE.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.MOULDNUMBER.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.EQUIPSCANFLAG.GetHashCode().ToString() ) ) .ToList(); if (monitorList.Count > 0) { //变该模块下的所有参数信息 foreach (var pc in monitorList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + ":" + m.MOLDNUMBER + ":" + pc.COLUMNCODE; Console.WriteLine(dicKeyStr); try { //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; clientHandleValue++; try { clientHandleDict.Add(clientHandleValue, dicKeyStr); //将字典中的与PLC内存地址向绑定 parameterValueDict[dicKeyStr] = MonitorConnection.AddKepItem(itemName, clientHandleValue); } catch (Exception ex) { Console.WriteLine("重复:" + dicKeyStr); } WriteLog.Write(dicKeyStr + " | " + itemName + " | " + clientHandleValue + " | " + parameterValueDict[dicKeyStr]); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(dicKeyStr); continue; } } //MonitorList.Add(mouldConnection); } #endregion } #endregion GC.Collect(); Console.WriteLine("Finish loading basedata!"); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } } #endregion private static void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps) { try { for (int i = 1; i <= NumItems; i++) { try { #region 获取被获取的获取数据类型 //获取写入的值 var itemValue = ItemValues.GetValue(i); //获取客户端句柄 int chvalue = Convert.ToInt32(ClientHandles.GetValue(i)); //获取服务端字典key值 string dicKeyStr = clientHandleDict[chvalue]; //获取设备信息 string machCode = dicKeyStr.Substring(0, dicKeyStr.IndexOf(':')); string moldAndColumn = dicKeyStr.Substring(dicKeyStr.IndexOf(':') + 1); //获取模块信息 string moldNumber = moldAndColumn.Substring(0, moldAndColumn.IndexOf(':')); //获取字段名称 string columnCode = dicKeyStr.Substring(dicKeyStr.LastIndexOf(':') + 1); //获取该标记信息 ParameterConfig currentPC = paraConfigList.First(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNCODE == columnCode); Console.WriteLine(currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":" + currentPC.COLUMNCODE.ToString()); #endregion #region 捕获完成标记 if (currentPC.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.COMPLETEFLAG.GetHashCode().ToString()) { if (itemValue == null) { continue; } //如果完成标记表示更新了加工参数 //获取所有的加工参数 if ((Boolean)itemValue == true) { //设置延迟2秒 //因为plc刷新频率 //个别情况获取不到值可以适当的延长等待时间 Thread.Sleep(2000); Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch Finish Flag " + currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":" + currentPC.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch Finish Flag " + currentPC.COLUMNCODE, currentPC.MACHINECODDE); List resultList = new List(); #region 获取该模块下的加工参数 List getParaList = new List(); //获取加工参数和公用参数 List paraList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPVALUE.GetHashCode().ToString() ) ) .ToList(); //获取所有的加工参数 foreach (var parameter in paraList) { //临时存储值不获取值 if (parameter.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPVALUE.GetHashCode().ToString()) { ParameterConfig paraConfig = GetResultParameterConfig(parameter); paraConfig.PARAVALUE = parameter.PARAVALUE; resultList.Add(paraConfig); Console.WriteLine(paraConfig.MACHINECODDE + ":" + paraConfig.MOLDNUMBER + ":" + paraConfig.COLUMNCODE + " " + ((paraConfig.PARAVALUE == null) ? " " : paraConfig.PARAVALUE.ToString())); WriteLog.Write(paraConfig.COLUMNCODE + " " + ((paraConfig.PARAVALUE == null) ? " " : paraConfig.PARAVALUE.ToString()), paraConfig.MACHINECODDE); continue; } try { #region 获取参数 ParameterConfig paraConfig = GetResultParameterConfig(parameter); var result = new object(); try { string item = parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE; int indexValue = parameterValueDict[item]; OPCPLCAutomation m = opcDict[currentPC.MACHINECODDE]; result = m.ReadtagValue(opcItemDict[item]); } catch (Exception ex) { Console.WriteLine(paraConfig.COLUMNCODE + ":" + ex.Message); WriteLog.Write(paraConfig.COLUMNCODE + ":" + ex.Message, currentPC.MACHINECODDE); } if (result != null) { paraConfig.PARAVALUE = result; Console.WriteLine(paraConfig.MACHINECODDE + ":" + paraConfig.MOLDNUMBER + ":" + paraConfig.COLUMNCODE + " " + ((result == null) ? " " : result.ToString())); WriteLog.Write(paraConfig.COLUMNCODE + " " + ((result == null) ? " " : result.ToString()), paraConfig.MACHINECODDE); } resultList.Add(paraConfig); #endregion } catch (Exception ex) { continue; } } #endregion #region 处理已经读取完加工参数标记 //目前主要针对浇注设备 //浇注设备读取完加工参数后要将加工参数读取完成标记位修改为true if (paraConfigList.Count(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString() ) > 0) { List collectedList = paraConfigList.Where(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString()) .ToList(); opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup(collectedList[0].MACHINECODDE + ":" + collectedList[0].MOLDNUMBER.ToString() + ":WriteData"); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; foreach (var p in collectedList) { //获取对应的OPC操作对象 //获取对应的服务端句柄 //向服务端句柄写入 opcplcConnection.WritetagValue(parameterValueDict[p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE], true); Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Set Collected true" + p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Set Collected true " + p.COLUMNCODE, p.MACHINECODDE); } } #endregion #region 将参数信息传递到web服务中 client.SubmitParameters(JsonConvertHelper.GetSerializes(resultList)); #endregion #region 加工步骤返回工控机信息 Thread.Sleep(2000); //该处需要例外处理一下 //浇注设备浇注完成后记录先输出浇注机的加工参数 //模架浇注完成后再输出模架的加工参数 //浇注的实际参数是浇注加+浇注模架参数的合集 //Q5的浇注模架和浇注机不是同一个厂家,交互起来麻烦 //所以先返回浇注机参数,将参数暂存,再获取浇注模架参数进行合并 //浇注机的浇注完成的参数名称是PouringFinish //定义参数信息 ChatEventArgs e = new ChatEventArgs(); //设备编号 e.MachineCode = machCode; //传输参数的类别 e.MessageType = OpcEnumGeter.MESSAGETYPE.PROCESSFINISH.GetHashCode().ToString(); //传输参数的内容 e.MessageContent = resultList[0].MOLDNUMBER; OpcService opcService = new OpcService(); opcService.ReturnProductCodeToMachine(e); //异步调用服务 #endregion } else { #region 冷刀设备的处理 if (currentPC.MACHINECODDE == "D3599-132") { //获取对应的OPC操作对象 opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup( currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":WriteData" ); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; List paraReadList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.OPERATEFLAG.GetHashCode().ToString() ) ) .ToList(); foreach (var p in paraReadList) { Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Get Finish false, set false " + p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Get Finish false, set false " + p.COLUMNCODE, p.MACHINECODDE); opcplcConnection.WritetagValue(parameterValueDict[p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE], false); } } #endregion } } #endregion #region 捕获条码扫描完成标记 if (currentPC.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.EQUIPSCANFLAG.GetHashCode().ToString()) { #region 提示扫描条码完成 if (itemValue == null) { continue; } //如果完成标记表示更新了加工参数 //获取所有的加工参数 if ((Boolean)itemValue == true) { Thread.Sleep(1000); Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch BarcodeScan Flag :" + currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":" + currentPC.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch BarcodeScan Flag :" + currentPC.COLUMNCODE, currentPC.MACHINECODDE); #region 获取条码信息 bool ishaveBarcode = true; //获取该设备模块下的条码配置信息 List barCodeParaList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.BARCODE.GetHashCode().ToString() ) .OrderBy(o => o.COLUMNCODE) .ToList(); //确定组信息 if (barCodeParaList.Count > 0) { opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup(currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER.ToString() + ":BarCodePara"); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; } //获取的信息集合 List getParaList = new List(); //循环获取条码信息 foreach (var parameter in barCodeParaList) { try { string item = parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE; var result = opcplcConnection.ReadtagValue(opcItemDict[item]); if (result != null) { ASCIIEncoding asciiEncoding = new ASCIIEncoding(); var arraysList = (object[])result; var count = Convert.ToInt32(arraysList[1]) - 1; //var count = 24; var productCode = ""; for (int c = 0; c <= count; c++) { byte[] byteArray = new byte[] { Convert.ToByte(arraysList[c + 2]) }; productCode += asciiEncoding.GetString(byteArray); } parameter.PARAVALUE = productCode; } Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "Get Barcode " + " " + parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE + " " + ((result == null) ? " " : result.ToString()), currentPC.MACHINECODDE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "Get Barcode " + ":" + parameter.PARAVALUE + " " + ((result == null) ? " " : result.ToString()), currentPC.MACHINECODDE); getParaList.Add(parameter); } catch (Exception ex) { Console.WriteLine("获取" + parameter.COLUMNCODE + "值异常"); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ex.Message, currentPC.MACHINECODDE); continue; } } if (ishaveBarcode == false) { Console.WriteLine("Fail to get barcode!"); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "Fail to get barcode!", currentPC.MACHINECODDE); continue; } #endregion #region 在双攻通信的条件下将扫描的条码信息传送到工控机上 try { //定义参数信息 ChatEventArgs e = new ChatEventArgs(); //设备编号 e.MachineCode = machCode; //传输参数的类别 e.MessageType = OpcEnumGeter.MESSAGETYPE.PRODUCTCODE.GetHashCode().ToString(); //传输参数的内容 e.MessageContent = JsonConvertHelper.GetSerializes(getParaList); OpcService opcService = new OpcService(); opcService.ReturnProductCodeToMachine(e); } catch (Exception ex) { Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "Fail to connect to " + currentPC.MACHINECODDE + "!"); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "Fail to connect to " + currentPC.MACHINECODDE + "!", currentPC.MACHINECODDE); } #endregion } #endregion } #endregion #region 中断 if (currentPC.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.INTERRUPT.GetHashCode().ToString()) { //捕获停止事件 if (itemValue == null) { continue; } if ((Boolean)itemValue == true) { Console.WriteLine("Catch " + currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":" + currentPC.COLUMNCODE + " Interrupt"); opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup(currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER.ToString() + ":GetData"); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; List resultList = new List(); List getResultList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString() && o.COLUMNCODE.ToUpper() == "RESULT" ) .ToList(); if (getResultList.Count > 0) { foreach (var r in getResultList) { ParameterConfig paraConfig = GetResultParameterConfig(r); var result = opcplcConnection.ReadtagValue(parameterValueDict[r.MACHINECODDE + ":" + r.MOLDNUMBER + ":" + r.COLUMNCODE]); if (result != null) { paraConfig.PARAVALUE = result; } resultList.Add(paraConfig); } } string machineNo = currentPC.MACHINECODDE; MachineInfoDAL machineDal = new MachineInfoDAL(); MachineInfo machineInfo = machineDal.GetMachineInfo(new MachineInfo() { MACHINECODDE = machineNo }); OperateProcess operateProcess = new OperateProcess(); operateProcess.Interrupt(machineInfo, resultList); //定义参数信息 ChatEventArgs e = new ChatEventArgs(); //设备编号 e.MachineCode = machCode; //传输参数的类别 e.MessageType = OpcEnumGeter.MESSAGETYPE.INTERRUPT.GetHashCode().ToString(); //传输参数的内容 e.MessageContent = ""; OpcService opcService = new OpcService(); opcService.ReturnProductCodeToMachine(e); } } #endregion #region 浇注机浇注完成信号 if (currentPC.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPCOMPLETE.GetHashCode().ToString()) { if (itemValue == null) { continue; } //如果完成标记表示更新了加工参数 //获取所有的加工参数 if ((Boolean)itemValue == true) { //设置延迟2秒 //因为plc刷新频率 //个别情况获取不到值可以适当的延长等待时间 Thread.Sleep(1000); Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch Finish Flag " + currentPC.MACHINECODDE + ":" + currentPC.MOLDNUMBER + ":" + currentPC.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Catch Finish Flag " + currentPC.COLUMNCODE, currentPC.MACHINECODDE); #region 获取该模块下的加工参数 ParameterConfig indexConfig = paraConfigList.First(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNCODE == "MouldNumber"); var indexValue = opcDict[currentPC.MACHINECODDE].ReadtagValue(parameterValueDict[indexConfig.MACHINECODDE + ":" + indexConfig.MOLDNUMBER + ":" + indexConfig.COLUMNCODE]); string machinecode = ""; if(indexValue.ToString()=="1") { machinecode="1H47Q50005"; } else if(indexValue.ToString()=="2") { machinecode="1H47Q50002"; } else if(indexValue.ToString()=="3") { machinecode="1H47Q50007"; } else{ machinecode=""; } //获取加工参数和公用参数 List paraList = paraConfigList .Where(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString() && o.COLUMNCODE != "MouldNumber" ) ) .ToList(); //获取所有的加工参数 foreach (var parameter in paraList) { try { #region 获取参数 ParameterConfig paraConfig = paraConfigList.First( o => o.MACHINECODDE == machinecode && o.COLUMNCODE == parameter.COLUMNCODE && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPVALUE.GetHashCode().ToString() ); var result = new object(); try { string item = parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE; result = opcDict[currentPC.MACHINECODDE].ReadtagValue(parameterValueDict[item]); paraConfig.PARAVALUE = result; Console.WriteLine(item + ":" + result.ToString()); } catch (Exception ex) { } #endregion } catch (Exception ex) { continue; } } #endregion } } #endregion //20171129闫永刚增加对模具号的监控 #region 获取模架号的监控 if (currentPC.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.MOULDNUMBER.GetHashCode().ToString()) { if (itemValue == null) { continue; } Console.WriteLine(itemValue.ToString()); ChatEventArgs e = new ChatEventArgs(); //设备编号 e.MachineCode = machCode; //传输参数的类别 e.MessageType = OpcEnumGeter.MESSAGETYPE.MOULDNUMBER.GetHashCode().ToString(); //传输参数的内容 e.MessageContent = itemValue.ToString(); OpcService opcService = new OpcService(); opcService.ReturnProductCodeToMachine(e); //异步调用服务 } #endregion GC.Collect(); } catch (Exception ex) { Console.WriteLine(ex.Message); continue; } } } catch (Exception ex) { Console.WriteLine("系统出现异常:" + ex.Message); } } /// /// 向设备发送可以操作的指令信息 /// /// public static void SendOperateReadyOrder(List configList) { try { //获取对应的OPC操作对象 opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup( configList[0].MACHINECODDE + ":" + configList[0].MOLDNUMBER + ":WriteData" ); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; //configList = configList.Where(o => o.COLUMNCODE == "MCREADYFLAG2").ToList(); foreach (var configdata in configList) { Console.WriteLine("set " + configdata.MACHINECODDE + ":" + configdata.MOLDNUMBER + ":" + configdata.COLUMNCODE + " " + configdata.PARAVALUE.ToString()); WriteLog.Write("set " + configdata.MACHINECODDE + ":" + configdata.MOLDNUMBER + ":" + configdata.COLUMNCODE + " " + configdata.PARAVALUE.ToString()); //向服务端句柄写入 opcplcConnection.WritetagValue(parameterValueDict[configdata.MACHINECODDE + ":" + configdata.MOLDNUMBER + ":" + configdata.COLUMNCODE], configdata.PARAVALUE); } } catch (Exception ex) { Console.WriteLine(ex.Message); //throw; } } public static void SendSignal(DAI dai) { try { #region 获取操作指令并发送 Console.WriteLine("SendSignal"); Console.WriteLine(dai.WORKCELL_CODE); Console.WriteLine(dai.WORKLOC_CODE); Console.WriteLine(dai.DA_CODE); Console.WriteLine(dai.Result.ToString()); Console.WriteLine(dai.MOULD_CODE); List orderList = sendOrderList .Where(o => o.WORKCELL_CODE == dai.WORKCELL_CODE && o.WORKLOC_CODE == dai.WORKLOC_CODE && o.DA_CODE == dai.DA_CODE && o.SIGNALTYPE == OpcEnumGeter.SENDORDERTYPE.OPERATEORDER.GetHashCode().ToString() && o.RESULTVALUE == dai.Result && o.MOULDCODE==dai.MOULD_CODE ).ToList(); if (orderList.Count > 0) { //获取对应的OPC操作对象 opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup( orderList[0].MACHINECODDE + ":" + orderList[0].MOLDNUMBER + ":WriteData" ); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; foreach (var con in orderList) { opcplcConnection.WritetagValue(parameterValueDict[con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE], con.WRITEVALUE); Console.WriteLine("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); WriteLog.Write("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); } } #endregion #region 获取配置指令并发送 if (string.IsNullOrEmpty(dai.MATERIAL_CODE) == false) { List configList = sendOrderList .Where(o => o.WORKCELL_CODE == dai.WORKCELL_CODE && o.WORKLOC_CODE == dai.WORKLOC_CODE && o.DA_CODE == dai.DA_CODE && o.SIGNALTYPE == OpcEnumGeter.SENDORDERTYPE.CONFIGORDER.GetHashCode().ToString() && o.MOLDNUMBER == dai.MOULD_CODE && o.MATERIAL.Contains(dai.MATERIAL_CODE) ).ToList(); if (configList.Count > 0) { //获取对应的OPC操作对象 opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup( configList[0].MACHINECODDE + ":" + configList[0].MOLDNUMBER + ":WriteData" ); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; foreach (var con in configList) { opcplcConnection.WritetagValue(parameterValueDict[con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE], con.WRITEVALUE); Console.WriteLine("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); WriteLog.Write("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); } } } #endregion #region 获取回推放行指令并发送 List recoveryList = sendOrderList .Where(o => o.WORKCELL_CODE == dai.WORKCELL_CODE && o.WORKLOC_CODE == dai.WORKLOC_CODE && o.SIGNALTYPE == OpcEnumGeter.SENDORDERTYPE.RECOVERYORDER.GetHashCode().ToString() && o.MOLDNUMBER == dai.MOULD_CODE && o.DA_CODE == dai.DA_CODE ).ToList(); if (recoveryList.Count > 0) { //获取对应的OPC操作对象 opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup( recoveryList[0].MACHINECODDE + ":" + recoveryList[0].MOLDNUMBER + ":WriteData" ); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; foreach (var con in recoveryList) { opcplcConnection.WritetagValue(parameterValueDict[con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE], con.WRITEVALUE); Console.WriteLine("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); WriteLog.Write("set " + con.MACHINECODDE + ":" + con.MOLDNUMBER + ":" + con.COLUMNCODE + " " + con.WRITEVALUE.ToString()); } } #endregion } catch (Exception ex) { } } /// /// 获取设备的模架号 /// /// /// public static int GetMoulderOfMachine(string machineCode) { int mouldNumber = 0; List paraList = paraConfigList .Where(o => o.MACHINECODDE == machineCode && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.MOULDNUMBER.GetHashCode().ToString() ) .ToList(); if (paraList.Count > 0) { ParameterConfig moulder = paraList[0]; string item = moulder.MACHINECODDE + ":" + moulder.MOLDNUMBER + ":" + moulder.COLUMNCODE; mouldNumber = Convert.ToInt32(MonitorConnection.ReadtagValue(parameterValueDict[item])); Console.WriteLine(mouldNumber.ToString()); } return mouldNumber; } /// /// 获取参数信息 /// /// /// private static ParameterConfig GetResultParameterConfig(ParameterConfig parameter) { ParameterConfig paraConfig = new ParameterConfig(); #region 属性复制 paraConfig.COLUMNCODE = parameter.COLUMNCODE; paraConfig.COLUMNTYPE = parameter.COLUMNTYPE; paraConfig.DATATYPE = parameter.DATATYPE; paraConfig.DBNUMBER = parameter.DBNUMBER; paraConfig.DEALTYPE = parameter.DEALTYPE; paraConfig.MACHINECODDE = parameter.MACHINECODDE; paraConfig.MOLDNUMBER = parameter.MOLDNUMBER; paraConfig.OPERATETYPE = parameter.OPERATETYPE; paraConfig.PROCESSTYPE = parameter.PROCESSTYPE; //paraConfig.PARAVALUE = parameter.PARAVALUE; paraConfig.TABLENAME = parameter.TABLENAME; #endregion return paraConfig; } public static void Exit() { if (opcplcConnection != null) { opcplcConnection.ReleaseResource(); opcplcConnection.DisconnectConnectRemoteServer(); } if (MonitorConnection != null) { MonitorConnection.ReleaseResource(); MonitorConnection.DisconnectConnectRemoteServer(); } if (opcDict.Count > 0) { foreach (OPCPLCAutomation val in opcDict.Values) { val.ReleaseResource(); val.DisconnectConnectRemoteServer(); } } GC.Collect(); } /// /// 用来模拟完成信号 /// /// public static void InVokeComplete(string order) { //设置延迟2秒 //因为plc刷新频率 //个别情况获取不到值可以适当的延长等待时间 List strArray = order.Split(':').ToList(); //获取该标记信息 ParameterConfig currentPC = null; try { currentPC = paraConfigList.First(o => o.MACHINECODDE == strArray[0] && o.MOLDNUMBER == strArray[1] && o.COLUMNCODE == strArray[2]); } catch (Exception ex) { Console.WriteLine("不存在" + order + ""); return; } if (currentPC.COLUMNTYPE != "1") { Console.WriteLine(order + "不是完成信号"); return; } string machCode = strArray[0]; string moldNumber = strArray[1]; List resultList = new List(); #region 获取该模块下的加工参数 List getParaList = new List(); //获取加工参数和公用参数 List paraList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && ( o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString() || o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPVALUE.GetHashCode().ToString() ) ) .ToList(); //获取所有的加工参数 foreach (var parameter in paraList) { //临时存储值不获取值 if (parameter.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.TEMPVALUE.GetHashCode().ToString()) { ParameterConfig paraConfig = GetResultParameterConfig(parameter); paraConfig.PARAVALUE = parameter.PARAVALUE; resultList.Add(paraConfig); Console.WriteLine(paraConfig.MACHINECODDE + ":" + paraConfig.MOLDNUMBER + ":" + paraConfig.COLUMNCODE + " " + ((paraConfig.PARAVALUE == null) ? " " : paraConfig.PARAVALUE.ToString())); WriteLog.Write(paraConfig.COLUMNCODE + " " + ((paraConfig.PARAVALUE == null) ? " " : paraConfig.PARAVALUE.ToString()), paraConfig.MACHINECODDE); continue; } try { #region 获取参数 ParameterConfig paraConfig = GetResultParameterConfig(parameter); var result = new object(); try { string item = parameter.MACHINECODDE + ":" + parameter.MOLDNUMBER + ":" + parameter.COLUMNCODE; OPCPLCAutomation m = opcDict[currentPC.MACHINECODDE]; result = m.ReadtagValue(opcItemDict[item]); Console.WriteLine(paraConfig.COLUMNCODE + " " + ((result == null) ? " " : result.ToString())); //result = opcDict[currentPC.MACHINECODDE].ReadtagValue(parameterValueDict[item]); } catch (Exception ex) { Console.WriteLine(paraConfig.COLUMNCODE + ":" + ex.Message); WriteLog.Write(paraConfig.COLUMNCODE + ":" + ex.Message, currentPC.MACHINECODDE); } if (result != null) { paraConfig.PARAVALUE = result; Console.WriteLine(paraConfig.MACHINECODDE + ":" + paraConfig.MOLDNUMBER + ":" + paraConfig.COLUMNCODE + " " + ((result == null) ? " " : result.ToString())); WriteLog.Write(paraConfig.COLUMNCODE + " " + ((result == null) ? " " : result.ToString()), paraConfig.MACHINECODDE); } resultList.Add(paraConfig); #endregion } catch (Exception ex) { continue; } } #endregion #region 处理已经读取完加工参数标记 //目前主要针对浇注设备 //浇注设备读取完加工参数后要将加工参数读取完成标记位修改为true if (paraConfigList.Count(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString() ) > 0) { List collectedList = paraConfigList.Where(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNTYPE == OpcEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString()) .ToList(); opcplcConnection.KepGroup = opcplcConnection.KepGroups.GetOPCGroup(collectedList[0].MACHINECODDE + ":" + collectedList[0].MOLDNUMBER.ToString() + ":WriteData"); opcplcConnection.KepItems = opcplcConnection.KepGroup.OPCItems; foreach (var p in collectedList) { //获取对应的OPC操作对象 //获取对应的服务端句柄 //向服务端句柄写入 opcplcConnection.WritetagValue(parameterValueDict[p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE], true); Console.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Set Collected true" + p.MACHINECODDE + ":" + p.MOLDNUMBER + ":" + p.COLUMNCODE); WriteLog.Write(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " Set Collected true " + p.COLUMNCODE, p.MACHINECODDE); } } #endregion #region 将参数信息传递到web服务中 client.SubmitParameters(JsonConvertHelper.GetSerializes(resultList)); #endregion #region 加工步骤返回工控机信息 Thread.Sleep(2000); //该处需要例外处理一下 //浇注设备浇注完成后记录先输出浇注机的加工参数 //模架浇注完成后再输出模架的加工参数 //浇注的实际参数是浇注加+浇注模架参数的合集 //Q5的浇注模架和浇注机不是同一个厂家,交互起来麻烦 //所以先返回浇注机参数,将参数暂存,再获取浇注模架参数进行合并 //浇注机的浇注完成的参数名称是PouringFinish //定义参数信息 ChatEventArgs e = new ChatEventArgs(); //设备编号 e.MachineCode = machCode; //传输参数的类别 e.MessageType = OpcEnumGeter.MESSAGETYPE.PROCESSFINISH.GetHashCode().ToString(); //传输参数的内容 e.MessageContent = resultList[0].MOLDNUMBER; OpcService opcService = new OpcService(); opcService.ReturnProductCodeToMachine(e); //异步调用服务 #endregion Console.WriteLine("调用完成!"); } } }