private OpcRcw.Da.OPCITEMDEF[] GetOPCITEMDEFs(OpcItem[] input) { OpcRcw.Da.OPCITEMDEF[] output = null; if (input != null) { output = new OpcRcw.Da.OPCITEMDEF[input.Length]; for (int ii = 0; ii < input.Length; ii++) { output[ii] = new OpcRcw.Da.OPCITEMDEF(); output[ii].szItemID = input[ii].ItemName; output[ii].szAccessPath = input[ii].ItemPath ?? String.Empty; output[ii].bActive = 1; //todo //output[ii].vtRequestedDataType = 2; output[ii].vtRequestedDataType = (short)VarEnum.VT_EMPTY; //(short)HD.OPC.Client.Core.Com.Interop.GetType(input[ii].ReqType); //output[ii].vtRequestedDataType = 4; output[ii].hClient = input[ii].ClientHandle.GetHashCode(); output[ii].dwBlobSize = 0; output[ii].pBlob = IntPtr.Zero; } } return(output); }
private bool AddItem(OPCItem item) { bool flag = true; OPCITEMDEF[] pItemArray = new OPCITEMDEF[1]; pItemArray[0].szAccessPath = ""; pItemArray[0].szItemID = item.OPCItemName; pItemArray[0].bActive = item.IsActive ? 1 : 0; pItemArray[0].hClient = item.ClientHandler; pItemArray[0].dwBlobSize = 0; pItemArray[0].pBlob = IntPtr.Zero; pItemArray[0].vtRequestedDataType = 0; IntPtr zero = IntPtr.Zero; IntPtr ppErrors = IntPtr.Zero; try { ((IOPCItemMgt) this.group).AddItems(1, pItemArray, out zero, out ppErrors); int[] destination = new int[1]; Marshal.Copy(ppErrors, destination, 0, 1); if (destination[0] == 0) { OPCITEMRESULT opcitemresult = (OPCITEMRESULT) Marshal.PtrToStructure(zero, typeof(OPCITEMRESULT)); item.ServerHandler = opcitemresult.hServer; return flag; } flag = false; throw new Exception("在组中添加项不成功,原因:" + this.parent.GetLastError(destination[0])); } finally { if (zero != IntPtr.Zero) { Marshal.FreeCoTaskMem(zero); zero = IntPtr.Zero; } if (ppErrors != IntPtr.Zero) { Marshal.FreeCoTaskMem(ppErrors); ppErrors = IntPtr.Zero; } } return flag; }
/// <summary> /// Adds all items to the group that have not already been added. /// </summary> public void AddItems() { // count the number of items to add. List <GroupItem> itemsToAdd = new List <GroupItem>(); lock (Lock) { for (int ii = 0; ii < m_items.Count; ii++) { if (!m_items[ii].Created) { itemsToAdd.Add(m_items[ii]); } } } // check if nothing to do. if (itemsToAdd.Count == 0) { return; } // create item definitions. int count = itemsToAdd.Count; OpcRcw.Da.OPCITEMDEF[] definitions = new OpcRcw.Da.OPCITEMDEF[count]; for (int ii = 0; ii < count; ii++) { definitions[ii] = new OpcRcw.Da.OPCITEMDEF(); definitions[ii].szItemID = itemsToAdd[ii].ItemId; definitions[ii].bActive = (itemsToAdd[ii].Active) ? 1 : 0; definitions[ii].szAccessPath = String.Empty; definitions[ii].vtRequestedDataType = (short)VarEnum.VT_EMPTY; definitions[ii].hClient = itemsToAdd[ii].ClientHandle; } // initialize output parameters. IntPtr pResults = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; // add items to group. string methodName = "IOPCItemMgt.AddItems"; try { IOPCItemMgt server = BeginComCall <IOPCItemMgt>(methodName, true); server.AddItems( count, definitions, out pResults, out pErrors); } catch (Exception e) { ComUtils.TraceComError(e, methodName); for (int ii = 0; ii < itemsToAdd.Count; ii++) { itemsToAdd[ii].ErrorId = Marshal.GetHRForException(e); } return; } finally { EndComCall(methodName); } // unmarshal output parameters. int[] serverHandles = GetItemResults(ref pResults, count, true); int[] errors = ComUtils.GetInt32s(ref pErrors, count, true); // save handles and error codes. for (int ii = 0; ii < count; ii++) { GroupItem item = itemsToAdd[ii]; item.ServerHandle = serverHandles[ii]; item.ErrorId = errors[ii]; if (item.ErrorId >= 0) { itemsToAdd[ii].Created = true; } } /* * Utils.Trace( * "Group {0} AddItems({4}/{5}) {1}/{2}ms {3}%", * m_clientHandle, * m_samplingInterval, * m_actualSamplingInterval, * m_deadband, * itemsToAdd.Count, * m_items.Count); */ }
/// <summary> /// Adds all items to the group that have not already been added. /// </summary> public void AddItems() { // count the number of items to add. List<GroupItem> itemsToAdd = new List<GroupItem>(); lock (Lock) { for (int ii = 0; ii < m_items.Count; ii++) { if (!m_items[ii].Created) { itemsToAdd.Add(m_items[ii]); } } } // check if nothing to do. if (itemsToAdd.Count == 0) { return; } // create item definitions. int count = itemsToAdd.Count; OpcRcw.Da.OPCITEMDEF[] definitions = new OpcRcw.Da.OPCITEMDEF[count]; for (int ii = 0; ii < count; ii++) { definitions[ii] = new OpcRcw.Da.OPCITEMDEF(); definitions[ii].szItemID = itemsToAdd[ii].ItemId; definitions[ii].bActive = (itemsToAdd[ii].Active) ? 1 : 0; definitions[ii].szAccessPath = String.Empty; definitions[ii].vtRequestedDataType = (short)VarEnum.VT_EMPTY; definitions[ii].hClient = itemsToAdd[ii].ClientHandle; } // initialize output parameters. IntPtr pResults = IntPtr.Zero; IntPtr pErrors = IntPtr.Zero; // add items to group. string methodName = "IOPCItemMgt.AddItems"; try { IOPCItemMgt server = BeginComCall<IOPCItemMgt>(methodName, true); server.AddItems( count, definitions, out pResults, out pErrors); } catch (Exception e) { ComUtils.TraceComError(e, methodName); for (int ii = 0; ii < itemsToAdd.Count; ii++) { itemsToAdd[ii].ErrorId = Marshal.GetHRForException(e); } return; } finally { EndComCall(methodName); } // unmarshal output parameters. int[] serverHandles = GetItemResults(ref pResults, count, true); int[] errors = ComUtils.GetInt32s(ref pErrors, count, true); // save handles and error codes. for (int ii = 0; ii < count; ii++) { GroupItem item = itemsToAdd[ii]; item.ServerHandle = serverHandles[ii]; item.ErrorId = errors[ii]; if (item.ErrorId >= 0) { itemsToAdd[ii].Created = true; } } /* Utils.Trace( "Group {0} AddItems({4}/{5}) {1}/{2}ms {3}%", m_clientHandle, m_samplingInterval, m_actualSamplingInterval, m_deadband, itemsToAdd.Count, m_items.Count); */ }
/// <summary> /// IOPCItemMgt::ValidateItems - Determines if an item is valid. /// Also returns information about the item such as canonical datatype, etc. /// </summary> public void ValidateItems( int dwCount, OPCITEMDEF[] pItemArray, int bBlobUpdate, out System.IntPtr ppValidationResults, out System.IntPtr ppErrors) { lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); // validate arguments. if (dwCount == 0 || pItemArray == null || dwCount != pItemArray.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } try { int[] errors = new int[dwCount]; OPCITEMRESULT[] results = new OPCITEMRESULT[dwCount]; for (int ii = 0; ii < dwCount; ii++) { results[ii].hServer = 0; results[ii].dwBlobSize = 0; results[ii].pBlob = IntPtr.Zero; results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY; results[ii].dwAccessRights = 0; results[ii].wReserved = 0; // parse node id. NodeId nodeId = Server.ItemIdToNodeId(pItemArray[ii].szItemID); if (nodeId == null) { errors[ii] = ResultIds.E_INVALIDITEMID; continue; } // find node. VariableNode variable = m_session.NodeCache.Find(nodeId) as VariableNode; if (variable == null) { errors[ii] = ResultIds.E_INVALIDITEMID; continue; } // validated the requested datatype. if (pItemArray[ii].vtRequestedDataType != 0) { if (ComUtils.GetSystemType(pItemArray[ii].vtRequestedDataType) == null) { errors[ii] = ResultIds.E_BADTYPE; continue; } } // fill in metadata. results[ii].vtCanonicalDataType = (short)m_server.DataTypeToVarType(variable.DataType, variable.ValueRank); results[ii].dwAccessRights = ComUtils.GetAccessRights(variable.AccessLevel); if (results[ii].vtCanonicalDataType == (short)VarEnum.VT_VARIANT) { results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY; } errors[ii] = ResultIds.S_OK; } // marshal the results. ppValidationResults = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMRESULT))*dwCount); IntPtr pos = ppValidationResults; for (int ii = 0; ii < dwCount; ii++) { Marshal.StructureToPtr(results[ii], pos, false); pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT))); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { throw ComUtils.CreateComException(e); } } }
/// <summary> /// IOPCItemMgt::AddItems - Adds one or more items to a group. /// </summary> public void AddItems( int dwCount, OPCITEMDEF[] pItemArray, out System.IntPtr ppAddResults, out System.IntPtr ppErrors) { lock (m_lock) { if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL); // validate arguments. if (dwCount == 0 || pItemArray == null || dwCount != pItemArray.Length) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } try { // compile set of item modifications. int[] errors = new int[dwCount]; OPCITEMRESULT[] results = new OPCITEMRESULT[dwCount]; List<Item> itemsToAdd = new List<Item>(); for (int ii = 0; ii < dwCount; ii++) { OPCITEMDEF itemToAdd = pItemArray[ii]; // initialize result structure. results[ii].hServer = 0; results[ii].dwBlobSize = 0; results[ii].pBlob = IntPtr.Zero; results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY; results[ii].dwAccessRights = 0; results[ii].wReserved = 0; // parse node id. NodeId nodeId = Server.ItemIdToNodeId(itemToAdd.szItemID); if (nodeId == null) { errors[ii] = ResultIds.E_INVALIDITEMID; continue; } // find node. VariableNode variable = m_session.NodeCache.Find(nodeId) as VariableNode; if (variable == null) { errors[ii] = ResultIds.E_INVALIDITEMID; continue; } // validated the requested datatype. if (itemToAdd.vtRequestedDataType != 0) { if (ComUtils.GetSystemType(itemToAdd.vtRequestedDataType) == null) { errors[ii] = ResultIds.E_BADTYPE; continue; } } // fill in metadata. results[ii].vtCanonicalDataType = (short)m_server.DataTypeToVarType(variable.DataType, variable.ValueRank); results[ii].dwAccessRights = ComUtils.GetAccessRights(variable.AccessLevel); if (results[ii].vtCanonicalDataType == (short)VarEnum.VT_VARIANT) { results[ii].vtCanonicalDataType = (short)VarEnum.VT_EMPTY; } // create an item. Item item = new Item(); item.ItemId = itemToAdd.szItemID; item.ClientHandle = itemToAdd.hClient; item.ServerHandle = ii; // save this temporarily to correlate response to request list. item.Active = itemToAdd.bActive != 0; item.ReqType = (VarEnum)itemToAdd.vtRequestedDataType; item.Variable = variable; // check if the item supports deadband. INode euRange = m_session.NodeCache.Find(nodeId, ReferenceTypeIds.HasProperty, false, true, Opc.Ua.BrowseNames.EURange); if (euRange != null) { item.DeadbandSupported = true; } // create a monitored item. MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.MonitoringMode = (item.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled; monitoredItem.SamplingInterval = m_updateRate; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Encoding = null; monitoredItem.Filter = null; monitoredItem.IndexRange = null; if (m_deadband != 0 && item.DeadbandSupported) { DataChangeFilter filter = new DataChangeFilter(); filter.DeadbandType = (uint)(int)DeadbandType.Percent; filter.DeadbandValue = m_deadband; filter.Trigger = DataChangeTrigger.StatusValue; monitoredItem.Filter = filter; } item.MonitoredItem = monitoredItem; itemsToAdd.Add(item); // update the subscription. m_subscription.AddItem(monitoredItem); } if (itemsToAdd.Count > 0) { // create monitored items on the UA server. m_subscription.ApplyChanges(); foreach (Item item in itemsToAdd) { // check for error during add. int index = item.ServerHandle; MonitoredItem monitoredItem = item.MonitoredItem; if (ServiceResult.IsBad(monitoredItem.Status.Error)) { errors[index] = Server.MapReadStatusToErrorCode(monitoredItem.Status.Error.StatusCode); m_subscription.RemoveItem(monitoredItem); continue; } // save server handle. results[index].hServer = item.ServerHandle = Utils.ToInt32(monitoredItem.ClientHandle); // add an entry in the cache. CreateCacheEntry(item); // index item. m_items[item.ServerHandle] = item; } } // marshal the results. ppAddResults = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMRESULT))*dwCount); IntPtr pos = ppAddResults; for (int ii = 0; ii < dwCount; ii++) { Marshal.StructureToPtr(results[ii], pos, false); pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMRESULT))); } // marshal error codes. ppErrors = ComUtils.GetInt32s(errors); } catch (Exception e) { throw ComUtils.CreateComException(e); } } }