/// <summary> /// Fetches the children from the server. /// </summary> private List <AeBrowseElement> Browse(Session session, AeBrowseElement start, bool isArea) { // browse for notifiers and sources. BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = start.NodeId; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; nodeToBrowse.ResultMask = (uint)(BrowseResultMask.BrowseName); nodeToBrowse.NodeClassMask = (uint)0; if (isArea) { nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasNotifier; nodeToBrowse.IncludeSubtypes = true; } else { nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource; nodeToBrowse.IncludeSubtypes = true; } ReferenceDescriptionCollection references = ComAeUtils.Browse( session, nodeToBrowse, false); if (references == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } List <AeBrowseElement> hits = new List <AeBrowseElement>(); for (int ii = 0; ii < references.Count; ii++) { // ignore remote references. if (references[ii].NodeId.IsAbsolute) { continue; } // need to check if at the end of the tree. if (references[ii].ReferenceTypeId != ReferenceTypeIds.HasEventSource) { nodeToBrowse.NodeId = (NodeId)references[ii].NodeId; ReferenceDescriptionCollection children = ComAeUtils.Browse(session, nodeToBrowse, false); if (!isArea) { if (children != null && children.Count > 0) { continue; } } else { if (children == null || children.Count == 0) { continue; } } } string browseText = m_mapper.GetLocalBrowseName(references[ii].BrowseName); // check for duplicate browse names. for (int jj = 0; jj < hits.Count; jj++) { if (hits[jj].BrowseText == browseText) { hits[jj].Duplicated = true; browseText = null; break; } } // add new element. if (browseText != null) { AeBrowseElement element = new AeBrowseElement(); element.Parent = start; element.NodeId = (NodeId)references[ii].NodeId; element.BrowseText = m_mapper.GetLocalBrowseName(references[ii].BrowseName); element.IsArea = isArea; hits.Add(element); StringBuilder itemId = new StringBuilder(); itemId.Append(start.ItemId); itemId.Append('/'); itemId.Append(element.BrowseText); element.ItemId = itemId.ToString(); } } // remove any duplicates. for (int ii = 0; ii < hits.Count;) { if (hits[ii].Duplicated) { hits.RemoveAt(ii); continue; } ii++; } return(hits); }
/// <summary> /// Sets the active state for a set of items in a group. /// </summary> public void ActivateItems(bool active) { // count the number of items to activate. List <GroupItem> itemsToActivate = new List <GroupItem>(); lock (Lock) { for (int ii = 0; ii < m_items.Count; ii++) { if (m_items[ii].ActiveChanged && m_items[ii].Active == active && m_items[ii].Created) { itemsToActivate.Add(m_items[ii]); } } } // check if nothing to do. if (itemsToActivate.Count == 0) { return; } // build list of items to remove. int count = itemsToActivate.Count; int[] serverHandles = new int[count]; for (int ii = 0; ii < itemsToActivate.Count; ii++) { serverHandles[ii] = itemsToActivate[ii].ServerHandle; } // initialize output parameters. IntPtr pErrors = IntPtr.Zero; string methodName = "IOPCItemMgt.SetActiveState"; try { IOPCItemMgt server = BeginComCall <IOPCItemMgt>(methodName, true); server.SetActiveState( count, serverHandles, (active) ? 1 : 0, out pErrors); } catch (Exception e) { ComUtils.TraceComError(e, methodName); for (int ii = 0; ii < itemsToActivate.Count; ii++) { itemsToActivate[ii].ActiveChanged = false; itemsToActivate[ii].ErrorId = Marshal.GetHRForException(e); } } finally { EndComCall(methodName); } // free returned error array. int[] errors = ComUtils.GetInt32s(ref pErrors, count, true); // save error codes. for (int ii = 0; ii < count; ii++) { itemsToActivate[ii].ActiveChanged = false; itemsToActivate[ii].ErrorId = errors[ii]; } /* * Utils.Trace( * "Group {0} ActivateItems({4}/{5}) {1}/{2}ms {3}%", * m_clientHandle, * m_samplingInterval, * m_actualSamplingInterval, * m_deadband, * active, * itemsToActivate.Count); */ }
/// <summary> /// Marshals an event for return to the client. /// </summary> private OpcRcw.Ae.ONEVENTSTRUCT Translate(AeEvent e) { OpcRcw.Ae.ONEVENTSTRUCT e2 = new ONEVENTSTRUCT(); e2.wNewState = 0; e2.wChangeMask = 0xFF; e2.szSource = e.SourceName; e2.wQuality = ComUtils.GetQualityCode(e.Quality); e2.dwEventType = e.Category.EventType; e2.dwEventCategory = (int)e.Category.LocalId; e2.bAckRequired = 0; e2.dwSeverity = e.Severity; e2.ftTime = ComUtils.GetFILETIME(e.Time); e2.szMessage = (e.Message != null) ? e.Message.Text : null; e2.szActorID = e.AuditUserId; e2.dwCookie = e.Cookie; if (e.AttributeValues != null && e.AttributeValues.Length > 0) { e2.dwNumEventAttrs = e.AttributeValues.Length; e2.pEventAttributes = ComUtils.GetVARIANTs(e.AttributeValues, true); } if ((e2.dwEventType & OpcRcw.Ae.Constants.CONDITION_EVENT) != 0) { e2.szConditionName = e.ConditionName; e2.ftActiveTime = ComUtils.GetFILETIME(e.ActiveTime); e2.bAckRequired = (e.AckedState)?0:1; // set the condition state. e2.wNewState = 0; if (e.EnabledState) { e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ENABLED; } if (e.AckedState) { e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ACKED; } if (e.ActiveState) { e2.wNewState |= OpcRcw.Ae.Constants.CONDITION_ACTIVE; } // set the subcondition if available. if (!LocalizedText.IsNullOrEmpty(e.LowState)) { e2.szSubconditionName = e.LowState.Text; } if (!LocalizedText.IsNullOrEmpty(e.HighState)) { e2.szSubconditionName = e.HighState.Text; } if (!LocalizedText.IsNullOrEmpty(e.LowLowState)) { e2.szSubconditionName = e.LowLowState.Text; } if (!LocalizedText.IsNullOrEmpty(e.HighHighState)) { e2.szSubconditionName = e.HighHighState.Text; } if (!LocalizedText.IsNullOrEmpty(e.LimitState)) { e2.szSubconditionName = e.LimitState.Text; } } if (e2.szMessage == null) { e2.szMessage = String.Empty; } if (e2.szSource == null) { e2.szSource = String.Empty; } if (e2.szConditionName == null) { e2.szConditionName = String.Empty; } if (e2.szSubconditionName == null) { e2.szSubconditionName = String.Empty; } if (e2.szActorID == null) { e2.szActorID = String.Empty; } return(e2); }
/// <summary> /// Gets the result for the read operayoin. /// </summary> /// <param name="context">The context.</param> /// <param name="item">The item.</param> /// <param name="nodeToRead">The node to read.</param> /// <param name="value">The value.</param> /// <param name="diagnosticsMasks">The diagnostics masks.</param> /// <returns></returns> public ServiceResult GetResult( ISystemContext context, DaItemState item, ReadValueId nodeToRead, DataValue value, DiagnosticsMasks diagnosticsMasks) { if (nodeToRead.AttributeId == Attributes.Value) { ServiceResult result = GetItemValue(m_value, value, diagnosticsMasks); if (ServiceResult.IsBad(result)) { return(result); } return(ApplyIndexRangeAndDataEncoding(context, nodeToRead, value)); } switch (nodeToRead.AttributeId) { case Attributes.Description: { string description = this.GetPropertyValue <string>(Opc.Ua.Com.PropertyIds.Description, value, false); if (StatusCode.IsGood(value.StatusCode)) { value.Value = new LocalizedText(description); } break; } case Attributes.DataType: { short datatype = this.GetPropertyValue <short>(Opc.Ua.Com.PropertyIds.DataType, value, false); if (StatusCode.IsGood(value.StatusCode)) { value.Value = ComUtils.GetDataTypeId(datatype); } break; } case Attributes.ValueRank: { short datatype = this.GetPropertyValue <short>(Opc.Ua.Com.PropertyIds.DataType, value, false); if (StatusCode.IsGood(value.StatusCode)) { value.Value = ComUtils.GetValueRank(datatype); } break; } case Attributes.AccessLevel: case Attributes.UserAccessLevel: { int accessRights = this.GetPropertyValue <int>(Opc.Ua.Com.PropertyIds.AccessRights, value, false); if (StatusCode.IsGood(value.StatusCode)) { value.Value = (byte)accessRights; } break; } case Attributes.MinimumSamplingInterval: { float scanRate = this.GetPropertyValue <float>(Opc.Ua.Com.PropertyIds.ScanRate, value, false); if (StatusCode.IsGood(value.StatusCode)) { value.Value = (double)scanRate; } break; } default: { return(StatusCodes.BadAttributeIdInvalid); } } // check if the property value is missing. if (value.StatusCode == StatusCodes.BadNotFound) { return(StatusCodes.BadAttributeIdInvalid); } return(ApplyIndexRangeAndDataEncoding(context, nodeToRead, value)); }
/// <summary> /// 增加设备 /// </summary> /// <param name="dev"></param> /// <returns>设备ID</returns> public string AddDevice(IRunDevice dev) { if (dev == null) { throw new ArgumentNullException("设备驱动", "参数为空"); } if (dev.DeviceParameter.DeviceID != dev.DeviceDynamic.DeviceID) { throw new NotEqualException("参数和动态数据的设备ID不相等"); } String devid = String.Empty; if (dev.DeviceParameter.DeviceID == String.Empty || dev.DeviceDynamic.DeviceID == String.Empty) { devid = this.DeviceManager.BuildDeviceID(); dev.DeviceParameter.DeviceID = devid; dev.DeviceDynamic.DeviceID = devid; try { dev.Initialize(devid); } catch { throw; } } if (DeviceManager.ContainDevice(devid)) { throw new ArgumentException("已经有相同的设备ID存在"); } if (ServerConfig.ControlMode == ControlMode.Singleton) { if (dev.CommunicateType == CommunicateType.NET) { IRunDevice[] netDevices = DeviceManager.GetDevices(CommunicateType.NET); if (netDevices.Length >= 1) //如果是Singleton模式只能有一个网络设备驱动 { throw new IndexOutOfRangeException("当为Singleton模式时,不能增加多个网络设备驱动"); } } } string desc = String.Empty; if (this.DeviceManager.AddDevice(dev.DeviceParameter.DeviceID, dev)) { dev.Setup(this); this.BindDeviceHandler(dev, dev.DeviceType, true); if (dev.DeviceType == DeviceType.Virtual) { desc = "增加虚拟设备"; } else { IController controller = null; if (dev.CommunicateType == CommunicateType.COM) { #region 串口 string key = ComUtils.PortToString(dev.DeviceParameter.COM.Port); IChannel channel = ChannelManager.GetChannel(key); if (channel == null) { IComSession comChannel = new ComSession(dev.DeviceParameter.COM.Port, dev.DeviceParameter.COM.Baud); comChannel.Setup(this); comChannel.Initialize(); comChannel.COMOpen += ComChannel_COMOpen; comChannel.COMClose += ComChannel_COMClose; comChannel.COMError += ComChannel_COMError; comChannel.Open(); channel = (IChannel)comChannel; ChannelManager.AddChannel(key, channel); } controller = ControllerManager.GetController(key); if (controller == null) { controller = new ComController((IComSession)channel); controller.Setup(this); if (ControllerManager.AddController(controller.Key, controller)) { controller.StartController(); } } else { IComController comController = (IComController)controller; if (comController.ComChannel.GetHashCode() != channel.GetHashCode()) { comController.ComChannel = (IComSession)channel; } } desc = String.Format("增加'{0}'串口设备,串口:{1} 波特率:{2}", dev.DeviceParameter.DeviceName, dev.DeviceParameter.COM.Port.ToString(), dev.DeviceParameter.COM.Baud.ToString()); #endregion 串口 } else if (dev.CommunicateType == CommunicateType.NET) { #region 网络 controller = ControllerManager.GetController(SocketController.ConstantKey); if (controller == null) { controller = new SocketController(); controller.Setup(this); if (ControllerManager.AddController(controller.Key, controller)) { controller.StartController(); } } desc = String.Format("增加'{0}'网络设备,IP地址:{1} 端口:{2}", dev.DeviceParameter.DeviceName, dev.DeviceParameter.NET.RemoteIP, dev.DeviceParameter.NET.RemotePort.ToString()); #endregion 网络 } else { desc = "无法识别设备的通讯类型"; } } if (_deviceContainer != null) { _deviceContainer.UpdateDevice(dev.DeviceParameter.DeviceID, dev.GetDeviceContainerItem()); } desc += ",成功"; OnAddDeviceCompleted(dev.DeviceParameter.DeviceID, dev.DeviceParameter.DeviceName, true); } else { desc += ",失败"; OnAddDeviceCompleted(dev.DeviceParameter.DeviceID, dev.DeviceParameter.DeviceName, false); } this.Logger.Info(true, desc); return(devid != String.Empty ? devid : dev.DeviceParameter.DeviceID); }
/// <summary> /// Updates the EUInfo for the items. /// </summary> /// <param name="group">The group.</param> /// <param name="items">The items. Null entries are ignored.</param> public void UpdateItemEuInfo( ComDaGroup group, IList <ComDaGroupItem> items) { // get the session to use for the operation. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // build list of properties that need to be read. BrowsePathCollection browsePaths = new BrowsePathCollection(); for (int ii = 0; ii < items.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)items[ii]; // ignore invalid items or items which have already checked their EU type. if (item == null || item.EuType >= 0) { continue; } BrowsePath browsePath = new BrowsePath(); browsePath.StartingNode = item.NodeId; RelativePathElement element = new RelativePathElement(); element.ReferenceTypeId = ReferenceTypeIds.HasProperty; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = Opc.Ua.BrowseNames.EURange; browsePath.RelativePath.Elements.Add(element); browsePath.Handle = item; browsePaths.Add(browsePath); browsePath = new BrowsePath(); browsePath.StartingNode = item.NodeId; element = new RelativePathElement(); element.ReferenceTypeId = ReferenceTypeIds.HasProperty; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = Opc.Ua.BrowseNames.EnumStrings; browsePath.RelativePath.Elements.Add(element); browsePath.Handle = item; browsePaths.Add(browsePath); } // check if nothing to do. if (browsePaths.Count == 0) { return; } // translate browse paths. BrowsePathResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.TranslateBrowsePathsToNodeIds( null, browsePaths, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, browsePaths); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths); } catch (Exception) { for (int ii = 0; ii < browsePaths.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle; item.EuType = 0; } return; } // build list of properties that need to be read. ReadValueIdCollection propertiesToRead = new ReadValueIdCollection(); for (int ii = 0; ii < results.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle; BrowsePathResult result = results[ii]; if (StatusCode.IsBad(result.StatusCode)) { if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM; } continue; } if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute) { if (item.EuType < 0) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM; } continue; } ReadValueId propertyToRead = new ReadValueId(); propertyToRead.NodeId = (NodeId)result.Targets[0].TargetId; propertyToRead.AttributeId = Attributes.Value; propertyToRead.Handle = item; propertiesToRead.Add(propertyToRead); if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange) { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG; } else { item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED; } } // check if nothing to do. if (propertiesToRead.Count == 0) { return; } // read attribute values from the server. DataValueCollection values = null; try { session.Read( null, 0, TimestampsToReturn.Neither, propertiesToRead, out values, out diagnosticInfos); ClientBase.ValidateResponse(values, propertiesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead); } catch (Exception) { for (int ii = 0; ii < propertiesToRead.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle; item.EuType = 0; } return; } // process results. for (int ii = 0; ii < values.Count; ii++) { ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle; if (StatusCode.IsBad(values[ii].StatusCode)) { item.EuType = 0; continue; } if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG) { Range range = (Range)values[ii].GetValue <Range>(null); if (range == null) { item.EuType = 0; continue; } item.EuInfo = new double[] { range.Low, range.High }; continue; } if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED) { LocalizedText[] texts = (LocalizedText[])values[ii].GetValue <LocalizedText[]>(null); if (texts == null) { item.EuType = 0; continue; } string[] strings = new string[texts.Length]; for (int jj = 0; jj < strings.Length; jj++) { if (!LocalizedText.IsNullOrEmpty(texts[jj])) { strings[jj] = texts[jj].Text; } } item.EuInfo = strings; continue; } } }
/// <summary> /// Validates the items by reading the attributes required to add them to the group. /// </summary> /// <param name="session">The session.</param> /// <param name="group">The group.</param> /// <param name="requests">The requests.</param> /// <param name="items">The items.</param> /// <param name="start">The start index.</param> /// <param name="count">The number of items to process.</param> private void ValidateItems( Session session, ComDaGroup group, ComDaCreateItemRequest[] requests, ComDaGroupItem[] items, int start, int count) { // build list of the UA attributes that need to be read. ReadValueIdCollection attributesToRead = new ReadValueIdCollection(); for (int ii = start; ii < start + count && ii < requests.Length; ii++) { // create the group item. ComDaCreateItemRequest request = requests[ii]; ComDaGroupItem item = items[ii] = new ComDaGroupItem(group, request.ItemId); item.NodeId = m_mapper.GetRemoteNodeId(request.ItemId); item.Active = request.Active; item.ClientHandle = request.ClientHandle; item.RequestedDataType = request.RequestedDataType; item.SamplingRate = -1; item.Deadband = -1; // add attributes. ReadValueId attributeToRead; attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.NodeClass; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.DataType; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.ValueRank; attributesToRead.Add(attributeToRead); attributeToRead = new ReadValueId(); attributeToRead.NodeId = item.NodeId; attributeToRead.AttributeId = Attributes.UserAccessLevel; attributesToRead.Add(attributeToRead); } // read attribute values from the server. DataValueCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; try { session.Read( null, 0, TimestampsToReturn.Neither, attributesToRead, out results, out diagnosticInfos); ClientBase.ValidateResponse(results, attributesToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, attributesToRead); } catch (Exception e) { Utils.Trace(e, "Unexpected error reading attributes for items."); // set default values on error. for (int ii = start; ii < start + count && ii < requests.Length; ii++) { requests[ii].Error = ResultIds.E_INVALIDITEMID; } return; } // process results. int first = 0; for (int ii = start; ii < start + count && ii < requests.Length; ii++, first += 4) { ComDaGroupItem item = items[ii]; // verify node class. NodeClass nodeClass = (NodeClass)results[first].GetValue <int>((int)NodeClass.Unspecified); if (nodeClass != NodeClass.Variable) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // verify data type. NodeId dataTypeId = results[first + 1].GetValue <NodeId>(null); if (dataTypeId == null) { requests[ii].Error = ResultIds.E_INVALIDITEMID; continue; } // get value rank. int valueRank = results[first + 2].GetValue <int>(ValueRanks.Scalar); // update datatypes. BuiltInType builtInType = DataTypes.GetBuiltInType(dataTypeId, session.TypeTree); item.RemoteDataType = new TypeInfo(builtInType, valueRank); item.CanonicalDataType = (short)ComUtils.GetVarType(item.RemoteDataType); // update access rights. byte userAccessLevel = results[first + 3].GetValue <byte>(0); if ((userAccessLevel & AccessLevels.CurrentRead) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_READABLE; } if ((userAccessLevel & AccessLevels.CurrentWrite) != 0) { item.AccessRights |= OpcRcw.Da.Constants.OPC_WRITEABLE; } } }
/// <summary> /// Sets the filtering criteria to be used for the event subscription. /// </summary> /// <param name="dwEventType">Bit mask specifying which event types are of interest</param> /// <param name="dwNumCategories">Length of array of event categories. A length of 0 indicates all categories should be included in the filter.</param> /// <param name="pdwEventCategories">Array of event categories of interest.</param> /// <param name="dwLowSeverity">Lowest severity of interest (inclusive).</param> /// <param name="dwHighSeverity">Highest severity of interest (inclusive).</param> /// <param name="dwNumAreas">Length of array of areas. A length of 0 indicates all areas should be included in the filter.</param> /// <param name="pszAreaList">Array of process area strings of interest - only events or conditions in these areas will be reported.</param> /// <param name="dwNumSources">Length of array of event sources. A length of 0 indicates all sources should be included in the filter.</param> /// <param name="pszSourceList">Array of event sources of interest - only events from these sources will be reported.</param> public void SetFilter(int dwEventType, int dwNumCategories, int[] pdwEventCategories, int dwLowSeverity, int dwHighSeverity, int dwNumAreas, string[] pszAreaList, int dwNumSources, string[] pszSourceList) { try { if (dwEventType == 0 | dwEventType > OpcRcw.Ae.Constants.ALL_EVENTS | pdwEventCategories.Rank > 1 | dwNumCategories != pdwEventCategories.Length | pszAreaList.Rank > 1 | dwNumAreas != pszAreaList.Length | pszSourceList.Rank > 1 | dwNumSources != pszSourceList.Length | dwLowSeverity < 1 | dwLowSeverity > 1000 | dwHighSeverity > 1000 | dwHighSeverity <1 | dwLowSeverity> dwHighSeverity) { throw ComUtils.CreateComException("SetFilter", ResultIds.E_INVALIDARG); } if (dwNumCategories != 0) { for (int i = 0; i < dwNumCategories; i++) { // Make sure we are passed a valid dwEventCategory NodeId catNodeId = m_server.FindEventCatNodeId(pdwEventCategories[i]); if (catNodeId == null) { throw ComUtils.CreateComException("SetFilter", ResultIds.E_INVALIDARG); } } } m_server.RemoveMonitoredItems(m_AreaVector); if (dwNumAreas != 0) { List <string> szAreas = new List <string>(); for (int i = 0; i < dwNumAreas; i++) { szAreas.Add(pszAreaList[i]); } if (szAreas.Count > 0) { m_server.AddMonitoredItems(szAreas); } } if (dwNumSources != 0) { List <string> szSources = new List <string>(); for (int i = 0; i < dwNumSources; i++) { int wildCardLocation = 0; if ((wildCardLocation = pszSourceList[i].IndexOfAny(new char[] { '*', '?', '#', '[', ']', '!', '-' })) != -1) { // The string contains wildcards List <string> items = m_server.ProcessWildCardAreaName(pszSourceList[i], wildCardLocation); if (items.Count == 0) { throw ComUtils.CreateComException("SetFilter", ResultIds.E_INVALIDARG); } foreach (string item in items) { szSources.Add(item); } } else { szSources.Add(pszSourceList[i]); } } //Translate the fully qualified source name to NodeId BrowsePathResultCollection results = m_server.GetBrowseTargets(szSources); for (int i = 0; i < dwNumSources; i++) { if (StatusCode.IsBad(results[i].StatusCode)) { throw ComUtils.CreateComException("SetFilter", ResultIds.E_INVALIDARG); } } } m_dwEventType = dwEventType; m_dwLowSeverity = dwLowSeverity; m_dwHighSeverity = dwHighSeverity; m_EventCategoryVector.Clear(); if (dwNumCategories != 0) { for (int i = 0; i < dwNumCategories; i++) { m_EventCategoryVector.AddUnique(pdwEventCategories[i]); } } m_server.RemoveMonitoredItems(m_AreaVector); m_AreaVector.Clear(); if (dwNumAreas != 0) { for (int i = 0; i < dwNumAreas; i++) { m_AreaVector.AddUnique(pszAreaList[i]); } } m_SourceVector.Clear(); if (dwNumSources != 0) { for (int i = 0; i < dwNumSources; i++) { m_SourceVector.AddUnique(pszSourceList[i]); } } } catch (COMException e) { throw ComUtils.CreateComException(e); } catch (Exception e) { Utils.Trace(e, "Unexpected error in SetFilter"); throw ComUtils.CreateComException(e); } }
/// <summary> /// Converts a remote value to a local value. /// </summary> /// <param name="srcValue">The remote value.</param> /// <param name="srcType">The data type of the remote value.</param> /// <param name="dstType">The data type of the local value.</param> /// <returns>The local value.</returns> private object ConvertRemoteToLocal(object srcValue, BuiltInType srcType, BuiltInType dstType) { // check for null. if (srcValue == null) { return(null); } // must determine the type from the source if the containing array is a variant. if (srcType == BuiltInType.Variant) { TypeInfo typeInfo = TypeInfo.Construct(srcValue); srcType = typeInfo.BuiltInType; if (typeInfo.ValueRank != ValueRanks.Scalar) { return(TypeInfo.CastArray((Array)srcValue, srcType, BuiltInType.Null, ConvertRemoteToLocal)); } } // no conversion by default. object dstValue = srcValue; // apply different conversions depending on the data type. switch (srcType) { case BuiltInType.Guid: { dstValue = ((Uuid)srcValue).ToString(); break; } case BuiltInType.XmlElement: { dstValue = ((XmlElement)srcValue).OuterXml; break; } case BuiltInType.NodeId: { dstValue = GetLocalItemId((NodeId)srcValue); break; } case BuiltInType.ExpandedNodeId: { ExpandedNodeId nodeId = GetLocaleExpandedNodeId((ExpandedNodeId)srcValue); dstValue = nodeId.ToString(); break; } case BuiltInType.QualifiedName: { dstValue = GetLocalBrowseName((QualifiedName)srcValue); break; } case BuiltInType.LocalizedText: { dstValue = ((LocalizedText)srcValue).Text; break; } case BuiltInType.StatusCode: { dstValue = ((StatusCode)srcValue).Code; break; } case BuiltInType.ExtensionObject: { BinaryEncoder encoder = new BinaryEncoder(m_localMessageContext); encoder.WriteExtensionObject(null, (ExtensionObject)srcValue); dstValue = encoder.CloseAndReturnBuffer(); break; } case BuiltInType.Variant: { dstValue = ((Variant)srcValue).Value; break; } default: { if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null) { throw ComUtils.CreateComException(ResultIds.E_BADTYPE); } break; } } // all done. return(dstValue); }
void onSwapChainResized(CSize newSize, double dpiScaling) { createStaticCBuffer(newSize, dpiScaling); ComUtils.clear(ref m_staticCBufferForText); }
public static UID CreateUID(Guid guid) { return(new UIDClass { Value = ComUtils.FormatGuid(guid) }); }
/// <summary> /// Provides a way to move �up� or �down� in a hierarchical space from the current position, or a way to move to a specific position in the area space tree. The target szString must represent an area, rather than a source. /// </summary> /// <param name="dwBrowseDirection">OPCAE_BROWSE_UP, OPCAE_BROWSE_DOWN, or OPCAE_BROWSE_TO</param> /// <param name="szString"> /// For DOWN, the partial area name of the area to move into. This would be one of the strings returned from BrowseOPCAreas. /// For UP this parameter is ignored and should point to a NULL string. /// For BROWSE_TO, the fully qualified area name (as obtained from GetQualifiedAreaName method) or a pointer to a NUL string to go to the root. /// </param> public void ChangeBrowsePosition(OPCAEBROWSEDIRECTION dwBrowseDirection, string szString) { lock (m_lock) { try { switch (dwBrowseDirection) { // move to a specified position or root. case OPCAEBROWSEDIRECTION.OPCAE_BROWSE_TO: { try { // move to root. if (String.IsNullOrEmpty(szString)) { m_browseStack.Clear(); m_browseStack.Push(m_session.NodeCache.Find(Objects.Server)); break; } // Translate the fully qualified area name to NodeId List <string> szAreas = new List <string>(); szAreas.Add(szString); BrowsePathResultCollection results = m_server.GetBrowseTargets(szAreas); if (StatusCode.IsBad(results[0].StatusCode)) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } BrowsePathTarget target = results[0].Targets[0]; INode node = m_session.NodeCache.Find(target.TargetId); if (node == null) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } // build a new browse stack. Stack <INode> browseStack = new Stack <INode>(); if (!FindPathToNode(node, browseStack)) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } // push target node onto stack. browseStack.Push(node); m_browseStack = browseStack; } catch { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } break; } // move to a child branch. case OPCAEBROWSEDIRECTION.OPCAE_BROWSE_DOWN: { // check for invalid name. if (String.IsNullOrEmpty(szString)) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } // find the current node. INode parent = m_browseStack.Peek(); if (parent == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // find the child. INode child = FindChildByName(parent.NodeId, szString); if (child == null) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } // save the new position. m_browseStack.Push(child); break; } // move to a parent branch. case OPCAEBROWSEDIRECTION.OPCAE_BROWSE_UP: { // check for invalid name. if (!String.IsNullOrEmpty(szString)) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // can't move up from root. if (m_browseStack.Count <= 1) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // move up the stack. m_browseStack.Pop(); break; } default: { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } } } catch (COMException e) { throw ComUtils.CreateComException(e); } catch (Exception e) { Utils.Trace(e, "Unexpected error in ChangeBrowsePosition"); throw ComUtils.CreateComException(e); } } }
/// <summary> /// Return an IEnumString for a list of Areas as determined by the passed parameters. /// </summary> /// <param name="dwBrowseFilterType"> /// OPC_AREA - returns only areas. /// OPC_SOURCE - returns only sources.</param> /// <param name="szFilterCriteria">A server specific filter string. A pointer to a NULL string indicates no filtering.</param> /// <param name="ppIEnumString">Where to save the returned interface pointer. NULL if the HRESULT is other than S_OK or S_FALSE.</param> public void BrowseOPCAreas( OPCAEBROWSETYPE dwBrowseFilterType, string szFilterCriteria, out OpcRcw.Comn.IEnumString ppIEnumString) { ppIEnumString = null; if (dwBrowseFilterType != OPCAEBROWSETYPE.OPC_AREA && dwBrowseFilterType != OPCAEBROWSETYPE.OPC_SOURCE) { throw ComUtils.CreateComException("BrowseOPCAreas", ResultIds.E_INVALIDARG); } try { lock (m_lock) { // find the current node. INode parent = null; // ensure browse stack has been initialized. if (m_browseStack.Count == 0) { parent = m_session.NodeCache.Find(Objects.Server); m_browseStack.Push(parent); } parent = m_browseStack.Peek(); if (parent == null) { throw ComUtils.CreateComException("BrowseOPCAreas", ResultIds.E_FAIL); } List <string> names = new List <string>(); IList <INode> children; ////// find children. children = m_session.NodeCache.Find(parent.NodeId, ReferenceTypes.HasEventSource, false, true); // This would also include // the HasNotifier reference which is // a subtype of HasEventSource foreach (INode child in children) { // ignore external nodes. if (child.NodeId.IsAbsolute) { continue; } // ignore non-objects/variables. if ((child.NodeClass & (NodeClass.Object | NodeClass.Variable)) == 0) { continue; } // ignore duplicate browse names. if (names.Contains(child.BrowseName.ToString())) { continue; } // For a node to be an area, it has to have the 'HasNotifier' reference and must // allow event notification (the EventNotifier attribute is set to SubscribeToEvents) // For a node to be a source, it should be the target of the HasEventSource reference if (IsValidNode((NodeId)child.NodeId, child.BrowseName.ToString(), dwBrowseFilterType)) { if (String.IsNullOrEmpty(szFilterCriteria)) { names.Add(child.BrowseName.ToString()); } else { // apply filters if (ComUtils.Match(child.BrowseName.ToString(), szFilterCriteria, true)) { names.Add(child.BrowseName.ToString()); } } } } // create enumerator. ppIEnumString = (OpcRcw.Comn.IEnumString) new EnumString(names); } } catch (Exception e) { Utils.Trace(e, "Unexpected error in BrowseOPCAreas"); throw ComUtils.CreateComException(e); } }
/// <summary> /// Returns the areas or sources that meet search pattern. /// </summary> public List <NodeId> SearchByQualifiedName(string pattern, bool isArea) { Session session = m_server.Session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } List <NodeId> hits = new List <NodeId>(); // check if a wildcard has been specified. int start = -1; for (int ii = 0; ii < pattern.Length; ii++) { if (IsWildcardChar(pattern[ii])) { start = ii; break; } } lock (m_lock) { // no wildcard found. if (start == -1) { AeBrowseElement target = Find(session, pattern, isArea); if (target != null) { hits.Add(target.NodeId); } return(hits); } // find the root where no wildcards exist. int end = start; for (int ii = start; ii >= 0; ii--) { if (pattern[ii] == '/') { end = ii; break; } } // check if the root exists. string rootId = pattern.Substring(0, end); AeBrowseElement root = Find(session, rootId, true); if (root == null) { return(hits); } // update the pattern to look for children of root. pattern = pattern.Substring(end + 1); // check if the pattern has multiple levels. end = pattern.IndexOf('/'); if (end == -1) { List <AeBrowseElement> children = Browse(session, root, pattern, isArea); // remove any duplicates. for (int ii = 0; ii < children.Count; ii++) { hits.Add(children[ii].NodeId); } return(hits); } } return(hits); }
/// <summary> /// Initializes a new instance of the <see cref="DaItemState"/> class. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="itemId">The item id.</param> /// <param name="attribute">The attribute.</param> /// <param name="namespaceIndex">Index of the namespace.</param> public HdaAttributeState( ComHdaClientConfiguration configuration, string itemId, HdaAttribute attribute, ushort namespaceIndex) : base(null) { m_itemId = itemId; m_attribute = attribute; this.NodeId = HdaModelUtils.ConstructIdForHdaItemAttribute(itemId, attribute.Id, namespaceIndex); this.SymbolicName = attribute.Id.ToString(); this.Description = attribute.Description; this.AccessLevel = AccessLevels.CurrentRead; this.UserAccessLevel = AccessLevels.CurrentRead; this.MinimumSamplingInterval = MinimumSamplingIntervals.Indeterminate; this.Historizing = false; this.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasProperty; this.TypeDefinitionId = Opc.Ua.VariableTypeIds.PropertyType; this.Value = null; this.StatusCode = StatusCodes.BadWaitingForInitialData; bool isConfigItem = false; // handle built-in properties. switch (attribute.Id) { default: { bool isArray = false; this.BrowseName = new QualifiedName(this.SymbolicName, namespaceIndex); this.DisplayName = attribute.Name; this.DataType = ComUtils.GetDataTypeId(attribute.DataType, out isArray); this.ValueRank = (isArray)?ValueRanks.OneDimension:ValueRanks.Scalar; break; } case Constants.OPCHDA_ENG_UNITS: { this.BrowseName = Opc.Ua.BrowseNames.EngineeringUnits; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.EUInformation; this.ValueRank = ValueRanks.Scalar; break; } case Constants.OPCHDA_NORMAL_MAXIMUM: { this.BrowseName = Opc.Ua.BrowseNames.EURange; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Range; this.ValueRank = ValueRanks.Scalar; break; } case Constants.OPCHDA_HIGH_ENTRY_LIMIT: { this.BrowseName = Opc.Ua.BrowseNames.InstrumentRange; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Range; this.ValueRank = ValueRanks.Scalar; break; } case Constants.OPCHDA_STEPPED: { this.BrowseName = Opc.Ua.BrowseNames.Stepped; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Boolean; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } case Constants.OPCHDA_DERIVE_EQUATION: { this.BrowseName = Opc.Ua.BrowseNames.Definition; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.String; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } case Constants.OPCHDA_MIN_TIME_INT: { this.BrowseName = Opc.Ua.BrowseNames.MinTimeInterval; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Duration; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } case Constants.OPCHDA_MAX_TIME_INT: { this.BrowseName = Opc.Ua.BrowseNames.MaxTimeInterval; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Duration; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } case Constants.OPCHDA_EXCEPTION_DEV: { this.BrowseName = Opc.Ua.BrowseNames.ExceptionDeviation; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.Double; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } case Constants.OPCHDA_EXCEPTION_DEV_TYPE: { this.BrowseName = Opc.Ua.BrowseNames.ExceptionDeviationFormat; this.DisplayName = this.BrowseName.Name; this.DataType = Opc.Ua.DataTypeIds.ExceptionDeviationFormat; this.ValueRank = ValueRanks.Scalar; isConfigItem = true; break; } } // set the parent id. NodeId parentId = null; if (isConfigItem) { parentId = HdaParsedNodeId.Construct(HdaModelUtils.HdaItemConfiguration, itemId, null, namespaceIndex); } else { parentId = HdaModelUtils.ConstructIdForHdaItem(itemId, namespaceIndex); } this.AddReference(ReferenceTypeIds.HasProperty, true, parentId); }
/// <summary> /// Converts a local value to a remote value. /// </summary> /// <param name="srcValue">The local value.</param> /// <param name="srcType">The data type of the local value.</param> /// <param name="dstType">The data type of the remote value.</param> /// <returns>The remote value.</returns> private object ConvertLocalToRemote(object srcValue, BuiltInType srcType, BuiltInType dstType) { // must determine the type from the source if the containing array is a variant. if (srcType == BuiltInType.Variant) { TypeInfo typeInfo = TypeInfo.Construct(srcValue); srcType = typeInfo.BuiltInType; } // no conversion by default. object dstValue = srcValue; // apply different conversions depending on the data type. switch (dstType) { case BuiltInType.Guid: { dstValue = new Uuid((string)srcValue); break; } case BuiltInType.XmlElement: { XmlDocument document = new XmlDocument(); document.InnerXml = (string)srcValue; dstValue = document.DocumentElement; break; } case BuiltInType.NodeId: { dstValue = GetRemoteNodeId((string)srcValue); break; } case BuiltInType.ExpandedNodeId: { ExpandedNodeId nodeId = ExpandedNodeId.Parse((string)srcValue); dstValue = GetRemoteExpandedNodeId(nodeId); break; } case BuiltInType.QualifiedName: { dstValue = GetRemoteBrowseName((string)srcValue); break; } case BuiltInType.LocalizedText: { dstValue = new LocalizedText((string)srcValue); break; } case BuiltInType.StatusCode: { dstValue = new StatusCode((uint)srcValue); break; } case BuiltInType.ExtensionObject: { BinaryDecoder decoder = new BinaryDecoder((byte[])srcValue, m_localMessageContext); dstValue = decoder.ReadExtensionObject(null); decoder.Close(); break; } default: { if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null) { throw ComUtils.CreateComException(ResultIds.E_BADTYPE); } break; } } // all done. return(dstValue); }
/// <summary> /// Adds the group. /// </summary> /// <param name="groupName">The group name.</param> /// <param name="active">if set to <c>true</c> the group is active.</param> /// <param name="updateRate">The update rate.</param> /// <param name="clientHandle">The client handle.</param> /// <param name="timeBias">The time bias.</param> /// <param name="deadband">The deadband.</param> /// <param name="lcid">The lcid.</param> /// <returns>The new group.</returns> public ComDaGroup AddGroup( string groupName, bool active, int updateRate, int clientHandle, int timeBias, float deadband, int lcid) { TraceState("AddGroup", groupName, active, updateRate, clientHandle, timeBias, deadband, lcid); // check for valid session. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } ComDaGroup group = null; // check for duplicate name. lock (m_lock) { // ensure the name is unique. if (!String.IsNullOrEmpty(groupName)) { if (GetGroupByName(groupName) != null) { throw ComUtils.CreateComException(ResultIds.E_DUPLICATENAME); } } // assign a unique name. else { groupName = Utils.Format("Group{0}", m_groupCounter + 1); } // validate the deadband. if (deadband < 0 || deadband > 100) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } // create the group. group = new ComDaGroup(this, groupName, ++m_groupCounter); m_groups.Add(group); group.ClientHandle = clientHandle; group.Active = active; group.UpdateRate = updateRate; group.TimeBias = timeBias; group.Deadband = deadband; group.Lcid = lcid; if (updateRate < 100) { updateRate = 100; } // create a new subscription. Subscription subscription = new Subscription(); subscription.DisplayName = groupName; subscription.PublishingInterval = updateRate / 2; subscription.KeepAliveCount = 30; subscription.LifetimeCount = 600; subscription.MaxNotificationsPerPublish = 10000; subscription.Priority = 1; subscription.PublishingEnabled = active; subscription.DisableMonitoredItemCache = true; // create the subscription on the server. session.AddSubscription(subscription); try { // create the initial subscription. subscription.Create(); // set the keep alive interval to 30 seconds and the the lifetime interval to 5 minutes. subscription.KeepAliveCount = (uint)((30000 / (int)subscription.CurrentPublishingInterval) + 1); subscription.LifetimeCount = (uint)((600000 / (int)subscription.CurrentPublishingInterval) + 1); // update the subscription. subscription.Modify(); } catch (Exception e) { session.RemoveSubscription(subscription); Utils.Trace((int)Utils.TraceMasks.Error, "Create subscription failed: {0}", e.Message); throw ComUtils.CreateComException(e, ResultIds.E_FAIL); } // update the group. group.ActualUpdateRate = (int)(subscription.CurrentPublishingInterval * 2); group.Subscription = subscription; } return(group); }
/// <summary> /// Enumerates hosts that may be accessed for server discovery. /// </summary> public string[] EnumerateHosts() { return(ComUtils.EnumComputers()); }
/// <summary> /// Validates the items. /// </summary> /// <param name="group">The group.</param> /// <param name="requests">The requests.</param> /// <returns>The items. May contain null is validation failed.</returns> public ComDaGroupItem[] ValidateItems(ComDaGroup group, ComDaCreateItemRequest[] requests) { TraceState("ValidateItems", group.Name); // get the session to use for the operation. Session session = m_session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } // validate items. ComDaGroupItem[] items = new ComDaGroupItem[requests.Length]; for (int ii = 0; ii < requests.Length; ii += 10000) { ValidateItems(session, group, requests, items, ii, 10000); } // process results. for (int ii = 0; ii < requests.Length; ii++) { // check for the results. ComDaCreateItemRequest request = requests[ii]; if (request.Error < 0) { items[ii] = null; continue; } // check access path. if (!String.IsNullOrEmpty(request.AccessPath)) { items[ii] = null; request.Error = ResultIds.E_UNKNOWNPATH; continue; } ComDaGroupItem item = items[ii]; // validate the datatype. if (request.RequestedDataType != 0) { NodeId dataTypeId = ComUtils.GetDataTypeId(request.RequestedDataType); if (NodeId.IsNull(dataTypeId)) { items[ii] = null; request.Error = ResultIds.E_BADTYPE; continue; } bool reqTypeIsArray = (request.RequestedDataType & (short)VarEnum.VT_ARRAY) != 0; bool actualTypeIsArray = (item.CanonicalDataType & (short)VarEnum.VT_ARRAY) != 0; if (reqTypeIsArray != actualTypeIsArray) { items[ii] = null; request.Error = ResultIds.E_BADTYPE; continue; } } // create a new monitored item. MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = item.NodeId; monitoredItem.RelativePath = null; monitoredItem.AttributeId = Attributes.Value; monitoredItem.MonitoringMode = (request.Active)?MonitoringMode.Reporting:MonitoringMode.Disabled; monitoredItem.SamplingInterval = group.UpdateRate / 2; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Filter = null; // update item. item.ServerHandle = (int)monitoredItem.ClientHandle; item.MonitoredItem = monitoredItem; // link the monitored item back to the group item. monitoredItem.Handle = item; // update return parameters. request.ServerHandle = item.ServerHandle; request.CanonicalDataType = item.CanonicalDataType; request.AccessRights = item.AccessRights; request.Error = ResultIds.S_OK; } return(items); }
/// <summary> /// Connects to the specified COM server server. /// </summary> public object CreateServer(Uri uri, UserIdentity identity) { // parse path to find prog id and clsid. string progID = uri.LocalPath; string clsid = null; while (progID.StartsWith("/")) { progID = progID.Substring(1); } int index = progID.IndexOf('/'); if (index >= 0) { clsid = progID.Substring(index + 1); progID = progID.Substring(0, index); } // look up prog id if clsid not specified in the uri. Guid guid = Guid.Empty; if (String.IsNullOrEmpty(clsid)) { // connect to enumerator. Connect(uri.Host, identity); // use OpcEnum to lookup the prog id. guid = CLSIDFromProgID(progID); // check if prog id is actually a clsid string. if (guid == Guid.Empty) { clsid = progID; } } // convert CLSID to a GUID. if (guid == Guid.Empty) { try { guid = new Guid(clsid); } catch (Exception e) { throw ServiceResultException.Create(StatusCodes.BadCommunicationError, e, "COM server URI does not contain a valid CLSID or ProgID."); } } // use normal activation. return(ComUtils.CreateInstance(guid, uri.Host, identity)); #if COM_IMPERSONATION_SUPPORT // set the current thread token. IPrincipal existingPrincipal = Thread.CurrentPrincipal; WindowsPrincipal principal = ComUtils.GetPrincipalFromUserIdentity(identity); try { if (principal != null) { Thread.CurrentPrincipal = principal; } // activate with a license key if one provided. if (identity != null && !String.IsNullOrEmpty(identity.LicenseKey)) { return(ComUtils.CreateInstanceWithLicenseKey(guid, uri.Host, identity, identity.LicenseKey)); } // use normal activation. return(ComUtils.CreateInstance(guid, uri.Host, identity)); } finally { Thread.CurrentPrincipal = existingPrincipal; } #endif }
/// <summary> /// Must called if a COM call returns an unexpected exception. /// </summary> /// <param name="methodName">Name of the method.</param> /// <param name="e">The exception.</param> /// <remarks>Note that some COM calls are expected to return errors.</remarks> protected void ComCallError(string methodName, Exception e) { ComUtils.TraceComError(e, methodName); }
/// <summary> /// Dispatches the event. /// </summary> private BaseEventState DispatchEvent(ONEVENTSTRUCT e) { NodeId typeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex); // find the type. AeEventTypeState eventType = m_cache.FindType(m_defaultContext, typeId); if (eventType == null) { return(null); } // create a new instance. BaseEventState instance = m_cache.CreateInstance(m_defaultContext, eventType); if (instance == null) { return(null); } // fill in fields. UpdateBaseEvent(instance, eventType.EventType, e); if (instance is AuditEventState) { UpdateAuditEvent((AuditEventState)instance, eventType.EventType, e); } if (instance is AlarmConditionState) { UpdateAlarm((AlarmConditionState)instance, eventType.EventType, e); } if (instance is ExclusiveLimitAlarmState) { UpdateExclusiveLimitAlarm((ExclusiveLimitAlarmState)instance, eventType.EventType, e); } else if (instance is NonExclusiveLimitAlarmState) { UpdateNonExclusiveLimitAlarm((NonExclusiveLimitAlarmState)instance, eventType.EventType, e); } // process attributes. bool ackCommentFound = false; object[] values = ComUtils.GetVARIANTs(ref e.pEventAttributes, e.dwNumEventAttrs, false); for (int ii = 0; ii < eventType.EventType.Attributes.Count; ii++) { EventAttribute attribute = eventType.EventType.Attributes[ii]; if (ii >= e.dwNumEventAttrs) { continue; } if (!ackCommentFound && AeTypeCache.IsKnownName(attribute.Description, "ACK COMMENT")) { ConditionState condition = instance as ConditionState; if (condition != null) { condition.Comment = new ConditionVariableState <LocalizedText>(condition); condition.Comment.BrowseName = Opc.Ua.BrowseNames.Comment; condition.Comment.Value = new LocalizedText(values[ii] as string); } ackCommentFound = true; continue; } PropertyState property = new PropertyState(instance); property.SymbolicName = attribute.Description; property.BrowseName = new QualifiedName(property.SymbolicName, m_namespaceIndex); property.Value = values[ii]; instance.AddChild(property); } return(instance); }
public void RemoveDevice(string devid) { IRunDevice dev = DeviceManager.GetDevice(devid); if (dev != null) { string desc = String.Empty; string devname = dev.DeviceParameter.DeviceName; if (DeviceManager.RemoveDevice(dev.DeviceParameter.DeviceID)) { if (dev.DeviceType == DeviceType.Virtual) { desc = "删除虚拟设备"; } else { #region if (dev.CommunicateType == CommunicateType.COM) { IRunDevice[] comDevices = DeviceManager.GetDevices(dev.DeviceParameter.COM.Port.ToString(), CommunicateType.COM); if (comDevices.Length == 0) { string key = ComUtils.PortToString(dev.DeviceParameter.COM.Port); IController controller = ControllerManager.GetController(key); if (controller != null) { controller.IsWorking = false; if (ControllerManager.RemoveController(controller.Key)) { controller.StopController(); controller.Dispose(); IComSession comChannel = (IComSession)((IComController)controller).ComChannel; comChannel.Close(); comChannel.COMOpen -= ComChannel_COMOpen; comChannel.COMClose -= ComChannel_COMClose; comChannel.COMError -= ComChannel_COMError; if (ChannelManager.RemoveChannel(comChannel.Key)) { comChannel.Close(); comChannel.Dispose(); } } } } desc = String.Format("{0},从串口'{1}'删除", dev.DeviceParameter.DeviceName, dev.DeviceParameter.COM.Port.ToString()); } else if (dev.CommunicateType == CommunicateType.NET) { desc = String.Format("{0}-{1},从网络中删除成功", dev.DeviceParameter.DeviceName, dev.DeviceParameter.NET.RemoteIP); } #endregion } GraphicsShowManager.BatchRemoveDevice(dev.DeviceParameter.DeviceID); ServiceManager.BatchRemoveDevice(dev.DeviceParameter.DeviceID); if (_deviceContainer != null) { _deviceContainer.RemoveDevice(dev.DeviceParameter.DeviceID); } dev.DeviceParameter.Delete(); dev.DeviceDynamic.Delete(); dev.Delete(); dev.Dispose(); BindDeviceHandler(dev, dev.DeviceType, false); desc += ",成功"; OnDeleteDeviceCompleted(dev.DeviceParameter.DeviceID, dev.DeviceParameter.DeviceName, true); } else { desc += ",失败"; OnDeleteDeviceCompleted(dev.DeviceParameter.DeviceID, dev.DeviceParameter.DeviceName, false); } Logger.Info(true, desc); } }
/// <summary> /// Updates the condition event. /// </summary> private void UpdateAlarm(AlarmConditionState instance, EventType eventType, ONEVENTSTRUCT e) { instance.NodeId = AeParsedNodeId.ConstructIdForCondition(e.szSource, e.dwEventCategory, e.szConditionName, m_namespaceIndex); // find the condition class. NodeId classId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, null, m_namespaceIndex); AeEventTypeState conditionClassType = m_cache.FindType(m_defaultContext, classId); if (conditionClassType != null) { instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, classId, false); instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, conditionClassType.EventType.Description, false); } else { instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassId, Opc.Ua.ObjectTypeIds.BaseConditionClassType, false); instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionClassName, "BaseConditionClass", false); } instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ConditionName, e.szConditionName, false);; instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ClientUserId, e.szActorID, false); instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Quality, ComUtils.GetQualityCode(e.wQuality), false); bool acknowledged = (e.wNewState & Constants.CONDITION_ACKED) != 0; bool active = (e.wNewState & Constants.CONDITION_ACTIVE) != 0; bool enabled = (e.wNewState & Constants.CONDITION_ENABLED) != 0; bool retain = enabled & (active || !acknowledged); LocalizedText effectiveDisplayName = ConditionStateNames.Inactive; if (!enabled) { effectiveDisplayName = ConditionStateNames.Disabled; } else if (!acknowledged) { effectiveDisplayName = ConditionStateNames.Unacknowledged; } else if (active) { effectiveDisplayName = ConditionStateNames.Active; } instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Retain, true, false); instance.EnabledState = new TwoStateVariableState(instance); instance.EnabledState.BrowseName = Opc.Ua.BrowseNames.EnabledState; instance.EnabledState.Value = new LocalizedText((enabled) ? ConditionStateNames.Enabled : ConditionStateNames.Disabled); instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, enabled, false); instance.EnabledState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, effectiveDisplayName, false); instance.AckedState = new TwoStateVariableState(instance); instance.AckedState.BrowseName = Opc.Ua.BrowseNames.AckedState; instance.AckedState.Value = new LocalizedText((acknowledged) ? ConditionStateNames.Acknowledged : ConditionStateNames.Unacknowledged); instance.AckedState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, acknowledged, false); instance.ActiveState = new TwoStateVariableState(instance); instance.ActiveState.BrowseName = Opc.Ua.BrowseNames.ActiveState; instance.ActiveState.Value = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive); instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false); instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.TransitionTime, ComUtils.GetDateTime(e.ftActiveTime), false); if (!String.IsNullOrEmpty(e.szSubconditionName)) { instance.ActiveState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EffectiveDisplayName, e.szSubconditionName, false); } }
/// <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> /// Acknowledges one or more events. /// </summary> public int[] AcknowledgeEvents( Session session, string comment, string acknowledgerId, AeAcknowledgeRequest[] requests) { if (session == null || !session.Connected) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } StringBuilder buffer = new StringBuilder(); buffer.Append('['); buffer.Append(acknowledgerId); buffer.Append(']'); if (!String.IsNullOrEmpty(comment)) { buffer.Append(comment); } // wrap the comment once. Variant commentToWrite = new Variant(new LocalizedText(buffer.ToString())); int[] errors = new int[requests.Length]; CallMethodRequestCollection methodsToCall = new CallMethodRequestCollection(); for (int ii = 0; ii < requests.Length; ii++) { int cookie = requests[ii].Cookie; AeEvent e = null; lock (m_lock) { // look up the event. if (!m_events.TryGetValue(cookie, out e)) { errors[ii] = ResultIds.E_INVALIDARG; if (cookie < m_counter) { errors[ii] = ResultIds.S_ALREADYACKED; } continue; } if (e.SourceName != requests[ii].SourceName) { errors[ii] = ResultIds.E_INVALIDARG; continue; } if (e.ConditionName != requests[ii].ConditionName) { errors[ii] = ResultIds.E_INVALIDARG; continue; } if (e.ActiveTime != requests[ii].ActiveTime) { errors[ii] = ResultIds.E_INVALIDTIME; continue; } // check that the cookie is still valid. string conditionId = GetConditionId(e); int expectedCookie = 0; if (!m_cookies.TryGetValue(conditionId, out expectedCookie)) { errors[ii] = ResultIds.S_ALREADYACKED; continue; } // check cookie. if (expectedCookie != cookie) { errors[ii] = ResultIds.E_INVALIDARG; continue; } m_events.Remove(cookie); } CallMethodRequest request = new CallMethodRequest(); request.MethodId = Opc.Ua.MethodIds.AcknowledgeableConditionType_Acknowledge; request.ObjectId = e.ConditionId; request.InputArguments.Add(new Variant(e.EventId)); request.InputArguments.Add(commentToWrite); request.Handle = ii; methodsToCall.Add(request); } if (methodsToCall.Count > 0) { try { // call the server. CallMethodResultCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; session.Call( null, methodsToCall, out results, out diagnosticInfos); // verify that the server returned the correct number of results. ClientBase.ValidateResponse(results, methodsToCall); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, methodsToCall); // process results. for (int ii = 0; ii < methodsToCall.Count; ii++) { int index = (int)methodsToCall[ii].Handle; if (StatusCode.IsBad(results[ii].StatusCode)) { errors[ii] = ResultIds.E_FAIL; continue; } } } catch (Exception) { // report error. for (int ii = 0; ii < methodsToCall.Count; ii++) { int index = (int)methodsToCall[ii].Handle; errors[ii] = ResultIds.E_FAIL; } } } return(errors); }
/// <summary> /// Removes the items from the group that have been marked as deleted. /// </summary> public void RemoveItems() { // count the number of items to remove. List <GroupItem> itemsToRemove = new List <GroupItem>(); lock (Lock) { List <GroupItem> itemsToKeep = new List <GroupItem>(); for (int ii = 0; ii < m_items.Count; ii++) { if (m_items[ii].Deleted && m_items[ii].Created) { itemsToRemove.Add(m_items[ii]); continue; } itemsToKeep.Add(m_items[ii]); } m_items = itemsToKeep; } // check if nothing to do. if (itemsToRemove.Count == 0) { return; } // build list of items to remove. int count = itemsToRemove.Count; int[] serverHandles = new int[count]; for (int ii = 0; ii < itemsToRemove.Count; ii++) { serverHandles[ii] = itemsToRemove[ii].ServerHandle; // remove the associated monitored items. if (m_monitoredItems != null) { lock (m_monitoredItems) { m_monitoredItems.Remove(itemsToRemove[ii].ClientHandle); } } } IntPtr pErrors = IntPtr.Zero; string methodName = "IOPCItemMgt.RemoveItems"; try { IOPCItemMgt server = BeginComCall <IOPCItemMgt>(methodName, true); // remove items. server.RemoveItems( count, serverHandles, out pErrors); } catch (Exception e) { ComUtils.TraceComError(e, methodName); for (int ii = 0; ii < itemsToRemove.Count; ii++) { itemsToRemove[ii].Created = false; itemsToRemove[ii].ErrorId = Marshal.GetHRForException(e); } return; } finally { EndComCall(methodName); } // free returned error array. int[] errors = ComUtils.GetInt32s(ref pErrors, count, true); // save error codes. for (int ii = 0; ii < count; ii++) { itemsToRemove[ii].Created = false; itemsToRemove[ii].ErrorId = errors[ii]; } /* * Utils.Trace( * "Group {0} RemoveItems({4}/{5}) {1}/{2}ms {3}%", * m_clientHandle, * m_samplingInterval, * m_actualSamplingInterval, * m_deadband, * itemsToRemove.Count, * m_items.Count); */ }
/// <summary> /// Writes the values for the specified item ids. /// </summary> /// <param name="itemIds">The item ids.</param> /// <param name="values">The values.</param> /// <returns>The results.</returns> public int[] Write(string[] itemIds, DaValue[] values) { int[] results = new int[itemIds.Length]; WriteValueCollection valuesToWrite = new WriteValueCollection(); ComDaReadPropertiesRequest[] requests = new ComDaReadPropertiesRequest[values.Length]; // prepare request. for (int ii = 0; ii < itemIds.Length; ii++) { ComDaReadPropertiesRequest request = requests[ii] = new ComDaReadPropertiesRequest(); request.ItemId = itemIds[ii]; } // need to get the data type of the remote node. m_browseManager.GetPropertyValues(Session, requests, PropertyIds.UaBuiltInType, PropertyIds.UaValueRank); // validate items. for (int ii = 0; ii < requests.Length; ii++) { ComDaReadPropertiesRequest request = requests[ii]; if (request.Error < 0) { results[ii] = request.Error; continue; } int?builtInType = request.Values[0].Value as int?; int?valueRank = request.Values[1].Value as int?; if (builtInType == null || valueRank == null) { results[ii] = ResultIds.E_UNKNOWNITEMID; continue; } // convert value to UA data type. WriteValue valueToWrite = new WriteValue(); valueToWrite.NodeId = m_mapper.GetRemoteNodeId(itemIds[ii]); valueToWrite.AttributeId = Attributes.Value; valueToWrite.Handle = ii; // convert value to UA data type. try { TypeInfo remoteType = new TypeInfo((BuiltInType)builtInType.Value, valueRank.Value); valueToWrite.Value = m_mapper.GetRemoteDataValue(values[ii], remoteType); } catch (Exception e) { results[ii] = ComUtils.GetErrorCode(e, ResultIds.E_BADTYPE); continue; } valuesToWrite.Add(valueToWrite); } // check if nothing to do. if (valuesToWrite.Count == 0) { return(results); } // write the values to the server. int[] remoteResults = m_groupManager.Write(valuesToWrite); // copy results. for (int ii = 0; ii < valuesToWrite.Count; ii++) { results[(int)valuesToWrite[ii].Handle] = remoteResults[ii]; } return(results); }
/// <summary> /// Sets the event filter. /// </summary> public void SetFilter( int eventTypes, ushort lowSeverity, ushort highSeverity, uint[] categoryIds, string[] areas, string[] sources) { ThrowIfDisposed(); lock (m_lock) { // validate event types. if (eventTypes <= 0 || eventTypes > 0x7) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } // validate severity. if (lowSeverity == 0 || highSeverity > 1000 || lowSeverity > highSeverity) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } // validate categories. if (categoryIds != null) { for (int ii = 0; ii < categoryIds.Length; ii++) { if (m_mapper.GetCategory(categoryIds[ii]) == null) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } } } // validate areas. List <NodeId> areasToUse = new List <NodeId>(); if (areas != null) { for (int ii = 0; ii < areas.Length; ii++) { List <NodeId> areaIds = m_browser.SearchByQualifiedName(areas[ii], true); if (areaIds.Count == 0) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } areasToUse.AddRange(areaIds); } } // validate sources. List <NodeId> sourcesToUse = new List <NodeId>(); if (sources != null) { for (int ii = 0; ii < sources.Length; ii++) { List <NodeId> sourceIds = m_browser.SearchByQualifiedName(sources[ii], false); if (sourceIds.Count == 0) { throw ComUtils.CreateComException(ResultIds.E_INVALIDARG); } sourcesToUse.AddRange(sourceIds); } } m_areas = areas; m_sources = sources; UpdateAreaFilter(areasToUse); UpdateSourceFilter(sourcesToUse); m_filter.SetFilter(eventTypes, lowSeverity, highSeverity, categoryIds, m_sourceNodes); } }
/// <summary> /// Moves the current browse position to the specified item. /// </summary> public void BrowseTo(string itemId) { Session session = m_server.Session; if (session == null) { throw ComUtils.CreateComException(ResultIds.E_FAIL); } lock (m_lock) { // check if value has been cached. if (itemId == null) { itemId = String.Empty; } AeBrowseElement element = null; if (m_cache.TryGetValue(itemId, out element)) { m_position = element; return; } // parse the item id looking for a known parent. Stack <string> names = new Stack <string>(); AeBrowseElement root = null; string currentId = itemId; while (!String.IsNullOrEmpty(currentId)) { string parentId = null; string itemName = currentId; int index = currentId.LastIndexOf('/'); if (index >= 0) { parentId = currentId.Substring(0, index); itemName = currentId.Substring(index + 1); } // save time by using an intermediate parent if it has already been cached. if (!String.IsNullOrEmpty(parentId)) { if (m_cache.TryGetValue(parentId, out root)) { names.Push(itemName); break; } } currentId = parentId; names.Push(itemName); root = null; } // use root if no parent found. if (root == null) { root = m_cache[String.Empty]; } // find the element. element = Find(session, itemId, root, names, true); if (element == null) { throw ComUtils.CreateComException(ResultIds.E_INVALIDBRANCHNAME); } // update cache and set position. m_cache[itemId] = element; m_position = element; } }