using System; using System.Collections.Generic; using System.Linq; using System.Web; using QMAPP.FJC.Entity.Basic; using QMAPP.ServicesAgent; using System.Configuration; using OPCPLC; using QMAPP.FJC.Entity; using OpcHost.Concrete; using System.Threading; using OpcHost.Common; using OPCAutomation; namespace OpcHost.Init { public static class ParaInit { //用来存储工控机发起连接服务器建立双通道连接的设备信息 public static List connectMachineList; //用来存储生产设备信息 public static List machineList; //用来存储OPC配置参数与服务端句柄的对应关系 //key:OPC配置参数,样式为 设备号+"-"+模具号+"-"+数据库字段 //value:服务端句柄 public static Dictionary parameterValueDict = new Dictionary(); /// /// 用来存储客户端句柄与设备参数对应关系 /// key:客户端句柄值 /// value:OPC配置参数,样式为 设备号+"-"+模具号+"-"+数据库字段 /// public static Dictionary clientHandleDict = new Dictionary(); //OPC配置参数列表静态变量 public static List paraConfigList; //设备模具参数信息静态变量 public static List moldList; //OPC连接字典静态变量 public static Dictionary opcplcConnectionList = new Dictionary(); public static int clientHandleMaxValue = 0; private static Dictionary colunmConDict = new Dictionary(); #region 初始化 /// /// 初始化相关信息 /// public static void InitParameter() { moldList = new List(); machineList = new List(); //获取数据库中所有的生产设备信息 ServiceAgent wcfAgent = GetServiceAgent(); //opcServer服务器IP string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP"); //opcServer服务名称 string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName"); try { #region 获取数据库中所有的生产设备信息 machineList = wcfAgent.InvokeServiceFunction>(QMAPP.ServicesAgent.B9BasicService.MachineInfoBLL_GetAllList.ToString(), new MachineInfo()); #endregion #region 获取所有的配置信息 paraConfigList = wcfAgent.InvokeServiceFunction>(QMAPP.ServicesAgent.B9BasicService.ParameterConfigBLL_GetList.ToString(), new MachineInfo()); #endregion #region 获取设备模块信息 //对加工参数配置信息按照设备及模具信息进行分组 var objlist = from pc in paraConfigList group pc by new { pc.MACHINECODDE, pc.MOLDNUMBER, pc.CONNECTIONSTRING } into g select new ParameterConfig { MACHINECODDE = g.Key.MACHINECODDE, MOLDNUMBER = g.Key.MOLDNUMBER, CONNECTIONSTRING = g.Key.CONNECTIONSTRING }; //添加到静态变量中 foreach (var ob in objlist) { moldList.Add(new ParameterConfig() { MACHINECODDE = ob.MACHINECODDE, MOLDNUMBER = ob.MOLDNUMBER }); } //按照设备进行排序 moldList = moldList.OrderBy(o => o.MACHINECODDE).ToList(); #endregion #region 加载模块下的加工参数配置信息 //变量所有的模具信息 foreach (var m in moldList) { MachineInfo machineEntity = machineList.First(o => o.MACHINECODDE == m.MACHINECODDE); OPCPLCAutomation gtxConnection = new OPCPLC.OPCPLCAutomation(); gtxConnection.GetListOPCServers(opcServerIP); gtxConnection.ConnectRemoteServer(opcServerName, opcServerIP); //创建组信息 gtxConnection.CreateGroup(m.MACHINECODDE + m.MOLDNUMBER); //获取该模具对应的OPC配置信息 List machineParaConList = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER).ToList(); //遍历该模具下的OPC配置信息 foreach (var pc in machineParaConList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + "-" + m.MOLDNUMBER + "-" + pc.COLUMNCODE; //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; //将字典中的与PLC内存地址向绑定 parameterValueDict[dicKeyStr] = gtxConnection.AddKepItem(itemName); } //添加PLC连接信息 opcplcConnectionList.Add(m.MACHINECODDE + m.MOLDNUMBER, gtxConnection); } #endregion #region 开始对所有的生产设备进行轮询监控 //获取所有的生产设备 List produceMachineList = machineList .Where(o => o.OPERATETYPE == EnumGeter.OPERATETYPE.PRODUCE.GetHashCode().ToString()) .ToList(); //初始化工厂类 OperateFactory factory = new OperateFactory(); //按照机器来创建监控线程 foreach (MachineInfo pm in produceMachineList) { //通过设备的生产类型获取操作类别 EquipOperate opclass = factory.GetConcreteOperateClass(pm); //添加监控线程 Thread t = new Thread(opclass.GetMachineData); t.Start(); } #endregion } catch (Exception) { throw; } } public static void InitParameterMonitor() { moldList = new List(); machineList = new List(); //获取数据库中所有的生产设备信息 ServiceAgent wcfAgent = GetServiceAgent(); try { #region 获取数据库中所有的生产设备信息 machineList = wcfAgent.InvokeServiceFunction>(QMAPP.ServicesAgent.B9BasicService.MachineInfoBLL_GetAllList.ToString(), new MachineInfo()); #endregion #region 获取OPC配置信息 paraConfigList = wcfAgent.InvokeServiceFunction>(QMAPP.ServicesAgent.B9BasicService.ParameterConfigBLL_GetList.ToString(), new MachineInfo()); #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).OrderBy(o => o.MOLDNUMBER).ToList(); #endregion //opcServer服务器IP string opcServerIP = ConfigurationManager.AppSettings.Get("OPCServerIP"); //opcServer服务名称 string opcServerName = ConfigurationManager.AppSettings.Get("OPCServerName"); #region 加载每个模具下的OPC配置参数信息 //遍历该模具下的OPC配置信息 foreach (var m in moldList) { //获取设备信息 MachineInfo machineEntity = machineList.First(o => o.MACHINECODDE == m.MACHINECODDE); #region 添加设备模具下加工参数 List paraAndOperateList = paraConfigList.Where(o => (o.MACHINECODDE == m.MACHINECODDE && m.MOLDNUMBER == m.MOLDNUMBER) && (m.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString()) ).ToList(); if (paraAndOperateList.Count > 0) { //初始化该模具下的OPC连接信息 OPCPLCAutomation paraAndOpeCon = new OPCPLC.OPCPLCAutomation(); paraAndOpeCon.GetListOPCServers(opcServerIP); paraAndOpeCon.ConnectRemoteServer(opcServerName, opcServerIP); paraAndOpeCon.CreateGroup(m.MACHINECODDE + "-" + m.MOLDNUMBER + "-GetData"); foreach (var pc in paraAndOperateList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = pc.MACHINECODDE + "-" + pc.MOLDNUMBER + "-" + pc.COLUMNCODE; //初始化OPC配置参数与服务端句柄字典信息 parameterValueDict.Add(dicKeyStr, 0); //获取OPC中的tagName string itemName = pc.CONNECTIONSTRING; //累计客户端句柄值 clientHandleMaxValue++; //添加到客户端句柄与设备参数字典表中 clientHandleDict.Add(clientHandleMaxValue, dicKeyStr); //通过OPC设备连接信息和客户端句柄获取服务端句柄 //并且将服务句柄与OPC配置信息进行绑定 parameterValueDict[dicKeyStr] = paraAndOpeCon.AddKepItem(itemName, clientHandleMaxValue); colunmConDict.Add(dicKeyStr, m.MACHINECODDE + "-" + m.MOLDNUMBER + "-GetData"); } //添加PLC连接信息 opcplcConnectionList.Add(m.MACHINECODDE + m.MOLDNUMBER + "-GetData", paraAndOpeCon); } #endregion #region 添加设备模具下加工参数 List writeList = paraConfigList .Where(o => o.MACHINECODDE == m.MACHINECODDE && o.MOLDNUMBER == m.MOLDNUMBER && o.COLUMNTYPE == "2") .ToList(); if (writeList.Count > 0) { OPCPLCAutomation gtxConnection = new OPCPLC.OPCPLCAutomation(); gtxConnection.GetListOPCServers(opcServerIP); //连接Opc服务 gtxConnection.ConnectRemoteServer(opcServerName, opcServerIP); gtxConnection.CreateGroup(m.MACHINECODDE + "-" + m.MOLDNUMBER + "-WriteData"); //变该模块下的所有参数信息 foreach (var pc in writeList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = machineEntity.MACHINECODDE + "-" + m.MOLDNUMBER + "-" + pc.COLUMNCODE; //初始化字段信息值为0 parameterValueDict.Add(dicKeyStr, 0); //获取opc中tagName string itemName = pc.CONNECTIONSTRING; clientHandleMaxValue++; clientHandleDict.Add(clientHandleMaxValue, dicKeyStr); //将字典中的与PLC内存地址向绑定 parameterValueDict[dicKeyStr] = gtxConnection.AddKepItem(itemName, clientHandleMaxValue); colunmConDict.Add(dicKeyStr, m.MACHINECODDE + "-" + m.MOLDNUMBER + "-WriteData"); } //添加PLC连接信息 opcplcConnectionList.Add(m.MACHINECODDE + "-" + m.MOLDNUMBER + "-WriteData", gtxConnection); } #endregion #region 添加模具下的加工完成标记和设备读取条码OPC配置信息 List monitorList = paraConfigList.Where(o => (o.MACHINECODDE == m.MACHINECODDE && m.MOLDNUMBER == m.MOLDNUMBER) && (m.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.COMPLETEFLAG.GetHashCode().ToString() || m.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.EQUIPSCANCODE.GetHashCode().ToString()) ).ToList(); //存在加工完成标记和设备读取条码配置信息 if (monitorList.Count > 0) { //初始化该模具下的OPC连接信息 OPCPLCAutomation monitorCon = new OPCPLC.OPCPLCAutomation(); monitorCon.GetListOPCServers(opcServerIP); monitorCon.ConnectRemoteServer(opcServerName, opcServerIP); //创建监控组 monitorCon.CreateGroup(m.MACHINECODDE + "-" + m.MOLDNUMBER + "-Monitor"); monitorCon.KepGroups.DefaultGroupIsActive = true;//激活组。 monitorCon.KepGroups.DefaultGroupDeadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组。 monitorCon.KepGroups.DefaultGroupUpdateRate = 200;//默认组群的刷新频率为200ms monitorCon.KepGroup.UpdateRate = 100;//刷新频率为1秒。 monitorCon.KepGroup.IsSubscribed = true;//使用订阅功能,即可以异步,默认false monitorCon.KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange); //gtxConnection.KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete); foreach (var pc in monitorList) { //初始化字典名称: 设备名称+模块编号+字段名称 string dicKeyStr = pc.MACHINECODDE + "-" + pc.MOLDNUMBER + "-" + pc.COLUMNCODE; //初始化OPC配置参数与服务端句柄字典信息 parameterValueDict.Add(dicKeyStr, 0); //获取OPC中的tagName string itemName = pc.CONNECTIONSTRING; //累计客户端句柄值 clientHandleMaxValue++; //添加到客户端句柄与设备参数字典表中 clientHandleDict.Add(clientHandleMaxValue, dicKeyStr); //通过OPC设备连接信息和客户端句柄获取服务端句柄 //并且将服务句柄与OPC配置信息进行绑定 parameterValueDict[dicKeyStr] = monitorCon.AddKepItem(itemName, clientHandleMaxValue); colunmConDict.Add(dicKeyStr, m.MACHINECODDE + "-" + m.MOLDNUMBER + "-Monitor"); } //添加到OPC连接字典中 opcplcConnectionList.Add(m.MACHINECODDE + "-" + m.MOLDNUMBER + "-Monitor", monitorCon); } #endregion } #endregion } catch (Exception) { throw; } } #endregion /// /// 初始化代理信息 /// /// public static ServiceAgent GetServiceAgent() { try { //创建代理 ServiceAgent agent = new ServiceAgent(); //设置凭据 //agent.ClientCredential.CredentialID = ConfigurationManager.AppSettings["ServiceCredentialID"]; return agent; } catch (Exception ex) { throw ex; } } private static void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps) { try { //延迟半秒 Thread.Sleep(500); for (int i = 1; i <= NumItems; i++) { //获取写入的值 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); #region 完成标记 if (currentPC.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.COMPLETEFLAG.GetHashCode().ToString()) { //如果完成标记表示更新了加 工参数 //获取所有的加工参数 if ((Boolean)itemValue == true) { #region 获取该模块下的加工参数 List paraList = paraConfigList .Where(o => o.MACHINECODDE == machCode && o.MOLDNUMBER == moldNumber && o.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.PARAMETER.GetHashCode().ToString()) .ToList(); //获取所有的加工参数 foreach (var parameter in paraList) { string item = parameter.MACHINECODDE + "-" + parameter.MOLDNUMBER + "-" + parameter.COLUMNCODE; string conListKey = colunmConDict[item]; OPCPLCAutomation con = opcplcConnectionList[conListKey]; var result = con.ReadtagValue(parameterValueDict[item]); if (result != null) { parameter.PARAVALUE = result; } } #endregion #region 处理已经读取完加工参数标记 //获取该设备模具下对应的设备操作就绪配置信息 ParameterConfig writeConfig = paraConfigList.First(o => o.MACHINECODDE == currentPC.MACHINECODDE && o.MOLDNUMBER == currentPC.MOLDNUMBER && o.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.PARAMETERREADED.GetHashCode().ToString()); //获取对应的OPC操作对象 //获取对应的服务端句柄 //向服务端句柄写入 opcplcConnectionList[writeConfig.MACHINECODDE + "-" + writeConfig.MOLDNUMBER + "-WriteData"].WritetagValue(parameterValueDict[writeConfig.MACHINECODDE + "-" + writeConfig.MOLDNUMBER + "-" + writeConfig.COLUMNCODE], true); #endregion //将参数信息传递到web服务中 } } #endregion #region 设备扫描枪扫描条码 if (currentPC.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.EQUIPSCANCODE.GetHashCode().ToString()) { //在双攻通信的条件下,将扫描的条码信息传送到工控机上 PLCService plcService = new PLCService(); plcService.ReturnProductCodeToMachine(itemValue.ToString(), machCode); } #endregion } } catch (Exception ex) { Console.WriteLine("系统出现异常:" + ex.Message); } } /// /// 向设备发送可以操作的指令信息 /// /// public static void SendOperateReadyOrder(ParameterConfig config) { try { //获取该设备模具下对应的设备操作就绪配置信息 ParameterConfig writeConfig = paraConfigList.First(o => o.MACHINECODDE == config.MACHINECODDE && o.MOLDNUMBER == config.MOLDNUMBER && o.COLUMNTYPE == OpcHostEnumGeter.COLUMNTYPE.OPERATEFLAG.GetHashCode().ToString()); //获取对应的OPC操作对象 //获取对应的服务端句柄 //向服务端句柄写入 opcplcConnectionList[writeConfig.MACHINECODDE + "-" + writeConfig.MOLDNUMBER + "-WriteData"].WritetagValue(parameterValueDict[writeConfig.MACHINECODDE + "-" + writeConfig.MOLDNUMBER + "-" + writeConfig.COLUMNCODE], true); } catch (Exception) { throw; } } } }