/// <summary> /// 添加Opc项 /// </summary> /// <param name="opcGroup"></param> private void AddOpcGroup(OpcDaCustomGroup opcGroup) { try { //添加OPC组 iOpcServer.AddGroup(opcGroup.GroupName, opcGroup.IsActive, opcGroup.RequestedUpdateRate, opcGroup.ClientGroupHandle, opcGroup.TimeBias.AddrOfPinnedObject(), opcGroup.PercendDeadBand.AddrOfPinnedObject(), opcGroup.LCID, out opcGroup.ServerGroupHandle, out opcGroup.RevisedUpdateRate, ref opcGroup.Riid, out opcGroup.Group); InitIoInterfaces(opcGroup); if (opcGroup.OpcDataCustomItems.Length > 0) { //添加OPC项 AddOpcItem(opcGroup); //激活订阅回调事件 ActiveDataChanged(IOPCGroupStateMgt); } } catch (COMException ex) { throw ex; } finally { if (opcGroup.TimeBias.IsAllocated) { opcGroup.TimeBias.Free(); } if (opcGroup.PercendDeadBand.IsAllocated) { opcGroup.PercendDeadBand.Free(); } } }
/// <summary> /// 异步写入数据 /// </summary> /// <param name="values">要写入的值</param> /// <param name="serverHandle">要写入的项的服务器句柄</param> /// <param name="errors">错误信息,等于表示写入成功,否则写入失败</param> /// <param name="opcGroup">要写入的Opc组</param> public void Write(object[] values, int[] serverHandle, out int[] errors, OpcDaCustomGroup opcGroup) { _iopcAsyncIo2 = (IOPCAsyncIO2)opcGroup.Group; IntPtr pErrors = IntPtr.Zero; errors = new int[values.Length]; if (_iopcAsyncIo2 != null) { try { //异步写入数据 int cancelId; _iopcAsyncIo2.Write(values.Length, serverHandle, values, transactionID + 1, out cancelId, out pErrors); Marshal.Copy(pErrors, errors, 0, values.Length); } catch (COMException ex) { throw ex; } finally { if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); } } } }
/// <summary> /// 加载Opc组配置 /// </summary> /// <param name="strConfigFilePath">配置文件路径</param> public void LoadOpcGroupConfig(string strConfigFilePath) { try { if (!File.Exists(strConfigFilePath)) { return; } XDocument xDoc = XDocument.Load(strConfigFilePath); XElement xElement = xDoc.Element("System").Element("OpcServer"); _strRemoteServerName = xElement.Attribute("ServerName").Value; _strRemoteServerIpAddress = xElement.Attribute("IPAddress").Value; _opcGroups = new List <OpcDaCustomGroup>(); foreach (XElement xElementItem in xElement.Elements()) { var opcDaCustomGroupService = new OpcDaCustomGroup { GroupName = xElementItem.Attribute("GroupName").Value, ClientGroupHandle = Convert.ToInt32(xElementItem.Attribute("ClientHandle").Value), RequestedUpdateRate = Convert.ToInt32(xElementItem.Attribute("UpdateRate").Value), OpcDataCustomItems = LoadOpcItemConfig(xElementItem) }; _opcGroups.Add(opcDaCustomGroupService); } _opcDaCustomAsync = new OpcDaCustomAsync(_opcGroups, _strRemoteServerName, _strRemoteServerIpAddress); _opcDaCustomAsync.OnReadCompleted += ReadCompleted; } catch (COMException ex) { throw ex; } }
public void Write(Dictionary <int, object> itemDictionary, int groupHandle, out int[] pErrors) { var count = itemDictionary.Count(); var values = new object[count]; var serverHandle = new int[count]; pErrors = null; OpcDaCustomGroup group = _opcGroups.First(p => p.ServerGroupHandle == groupHandle); int index = 0; foreach (KeyValuePair <int, object> itemId in itemDictionary) { foreach (var item in group.OpcDataCustomItems) { if (item.ClientHandle == itemId.Key) { values[index] = itemId.Value; serverHandle[index] = item.ServerHandle; index++; } } } try { _opcDaCustomAsync.Write(values, serverHandle, out pErrors, group); } catch (COMException ex) { throw ex; } }
/// <summary> /// 初始化IO接口 /// </summary> /// <param name="opcGroup"></param> public void InitIoInterfaces(OpcDaCustomGroup opcGroup) { int cookie; //组状态管理对象,改变组的刷新率和激活状态 IOPCGroupStateMgt = (IOPCGroupStateMgt)opcGroup.Group; IConnectionPointContainer = (IConnectionPointContainer)opcGroup.Group; Guid iid = typeof(IOPCDataCallback).GUID; IConnectionPointContainer.FindConnectionPoint(ref iid, out IConnectionPoint); //创建客户端与服务端之间的连接 IConnectionPoint.Advise(this, out cookie); }
/// <summary> /// 写单个数据 /// </summary> /// <param name="value">值</param> /// <param name="groupHandle">组ID</param> /// <param name="clientHandle">项ID</param> public void Write(int value, int groupHandle, int clientHandle) { OpcDaCustomGroup group = GetOpcGroup(groupHandle); if (group != null) { int[] pErrors; var serverHanlde = new int[1]; serverHanlde[0] = group.OpcDataCustomItems.First(c => c.ClientHandle == clientHandle).ServerHandle; var values = new object[1]; values[0] = value; _opcDaCustomAsync.Write(values, serverHanlde, out pErrors, group); } }
/// <summary> /// 添加Opc项 /// </summary> /// <param name="opcGroup"></param> private void AddOpcItem(OpcDaCustomGroup opcGroup) { OpcDaCustomItem[] opcDataCustomItemsService = opcGroup.OpcDataCustomItems; IntPtr pResults = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; OPCITEMDEF[] itemDefyArray = new OPCITEMDEF[opcGroup.OpcDataCustomItems.Length]; int i = 0; int[] errors = new int[opcGroup.OpcDataCustomItems.Length]; int[] itemServerHandle = new int[opcGroup.OpcDataCustomItems.Length]; try { foreach (OpcDaCustomItem itemService in opcDataCustomItemsService) { if (itemService != null) { itemDefyArray[i].szAccessPath = itemService.AccessPath; itemDefyArray[i].szItemID = itemService.ItemID; itemDefyArray[i].bActive = itemService.IsActive; itemDefyArray[i].hClient = itemService.ClientHandle; itemDefyArray[i].dwBlobSize = itemService.BlobSize; itemDefyArray[i].pBlob = itemService.Blob; itemDefyArray[i].vtRequestedDataType = itemService.RequestedDataType; i++; } } //添加OPC项组 ((IOPCItemMgt)opcGroup.Group).AddItems(opcGroup.OpcDataCustomItems.Length, itemDefyArray, out pResults, out pErrors); IntPtr Pos = pResults; Marshal.Copy(pErrors, errors, 0, opcGroup.OpcDataCustomItems.Length); for (int j = 0; j < opcGroup.OpcDataCustomItems.Length; j++) { if (errors[j] == 0) { if (j != 0) { Pos = new IntPtr(Pos.ToInt32() + Marshal.SizeOf(typeof(OPCITEMRESULT))); } var result = (OPCITEMRESULT)Marshal.PtrToStructure(Pos, typeof(OPCITEMRESULT)); itemServerHandle[j] = opcDataCustomItemsService[j].ServerHandle = result.hServer; Marshal.DestroyStructure(Pos, typeof(OPCITEMRESULT)); } } } catch (COMException ex) { throw ex; } finally { if (pResults != IntPtr.Zero) { Marshal.FreeCoTaskMem(pResults); } if (pErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(pErrors); } } }