using System; using System.Collections; using System.Collections.Generic; using Opc.Ua; using Opc.Ua.Client; namespace IMCS_CCS.Utils.DeviceProtocol { public class FilterDefinition { public NodeId AreaId; public EventSeverity Severity; public IList EventTypes; public bool IgnoreSuppressedOrShelved; public SimpleAttributeOperandCollection SelectClauses; public MonitoredItem CreateMonitoredItem(Session session) { if (this.AreaId == (object)null) this.AreaId = ObjectIds.Server; return new MonitoredItem() { DisplayName = (string)null, StartNodeId = this.AreaId, RelativePath = (string)null, NodeClass = NodeClass.Object, AttributeId = 12, IndexRange = (string)null, Encoding = (QualifiedName)null, MonitoringMode = MonitoringMode.Reporting, SamplingInterval = 0, QueueSize = uint.MaxValue, DiscardOldest = true, Filter = (MonitoringFilter)this.ConstructFilter(session), Handle = (object)this }; } public SimpleAttributeOperandCollection ConstructSelectClauses( Session session, params NodeId[] eventTypeIds) { SimpleAttributeOperandCollection eventFields = new SimpleAttributeOperandCollection(); eventFields.Add(new SimpleAttributeOperand() { TypeDefinitionId = ObjectTypeIds.BaseEventType, AttributeId = 1U, BrowsePath = new QualifiedNameCollection() }); if (eventTypeIds != null) { for (int index = 0; index < eventTypeIds.Length; ++index) this.CollectFields(session, eventTypeIds[index], eventFields); } else this.CollectFields(session, ObjectTypeIds.BaseEventType, eventFields); return eventFields; } public EventFilter ConstructFilter(Session session) { EventFilter eventFilter = new EventFilter(); eventFilter.SelectClauses = this.SelectClauses; ContentFilter contentFilter = new ContentFilter(); ContentFilterElement contentFilterElement1 = (ContentFilterElement)null; if (this.Severity > EventSeverity.Min) { SimpleAttributeOperand attributeOperand = new SimpleAttributeOperand(); attributeOperand.TypeDefinitionId = ObjectTypeIds.BaseEventType; attributeOperand.BrowsePath.Add((QualifiedName)"Severity"); attributeOperand.AttributeId = 13U; contentFilterElement1 = contentFilter.Push(FilterOperator.GreaterThanOrEqual, (object)attributeOperand, (object)new LiteralOperand() { Value = new Variant((ushort)this.Severity) }); } if (!this.IgnoreSuppressedOrShelved) { SimpleAttributeOperand attributeOperand = new SimpleAttributeOperand(); attributeOperand.TypeDefinitionId = ObjectTypeIds.BaseEventType; attributeOperand.BrowsePath.Add((QualifiedName)"SuppressedOrShelved"); attributeOperand.AttributeId = 13U; ContentFilterElement contentFilterElement2 = contentFilter.Push(FilterOperator.Equals, (object)attributeOperand, (object)new LiteralOperand() { Value = new Variant(false) }); if (contentFilterElement1 != null) contentFilterElement1 = contentFilter.Push(FilterOperator.And, (object)contentFilterElement1, (object)contentFilterElement2); else contentFilterElement1 = contentFilterElement2; } if (this.EventTypes != null && this.EventTypes.Count > 0) { ContentFilterElement contentFilterElement2 = (ContentFilterElement)null; for (int index = 0; index < this.EventTypes.Count; ++index) { ContentFilterElement contentFilterElement3 = contentFilter.Push(FilterOperator.OfType, (object)new LiteralOperand() { Value = new Variant(this.EventTypes[index]) }); if (contentFilterElement2 != null) contentFilterElement2 = contentFilter.Push(FilterOperator.Or, (object)contentFilterElement2, (object)contentFilterElement3); else contentFilterElement2 = contentFilterElement3; } if (contentFilterElement1 != null) contentFilter.Push(FilterOperator.And, (object)contentFilterElement1, (object)contentFilterElement2); } eventFilter.WhereClause = contentFilter; return eventFilter; } private void CollectFields( Session session, NodeId eventTypeId, SimpleAttributeOperandCollection eventFields) { ReferenceDescriptionCollection descriptionCollection = FormUtils.BrowseSuperTypes(session, eventTypeId, false); if (descriptionCollection == null) return; Dictionary foundNodes = new Dictionary(); QualifiedNameCollection parentPath = new QualifiedNameCollection(); for (int index = descriptionCollection.Count - 1; index >= 0; --index) this.CollectFields(session, (NodeId)descriptionCollection[index].NodeId, parentPath, eventFields, foundNodes); this.CollectFields(session, eventTypeId, parentPath, eventFields, foundNodes); } private void CollectFields( Session session, NodeId nodeId, QualifiedNameCollection parentPath, SimpleAttributeOperandCollection eventFields, Dictionary foundNodes) { ReferenceDescriptionCollection descriptionCollection = FormUtils.Browse(session, new BrowseDescription() { NodeId = nodeId, BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = ReferenceTypeIds.Aggregates, IncludeSubtypes = true, NodeClassMask = 3U, ResultMask = 63U }, false); if (descriptionCollection == null) return; for (int index = 0; index < descriptionCollection.Count; ++index) { ReferenceDescription referenceDescription = descriptionCollection[index]; if (!referenceDescription.NodeId.IsAbsolute) { QualifiedNameCollection qualifiedNameCollection = new QualifiedNameCollection((IEnumerable)parentPath); qualifiedNameCollection.Add(referenceDescription.BrowseName); if (!this.ContainsPath(eventFields, qualifiedNameCollection)) eventFields.Add(new SimpleAttributeOperand() { TypeDefinitionId = ObjectTypeIds.BaseEventType, BrowsePath = qualifiedNameCollection, AttributeId = referenceDescription.NodeClass == NodeClass.Variable ? 13U : 1U }); NodeId nodeId1 = (NodeId)referenceDescription.NodeId; if (!foundNodes.ContainsKey(nodeId1)) { foundNodes.Add(nodeId1, qualifiedNameCollection); this.CollectFields(session, (NodeId)referenceDescription.NodeId, qualifiedNameCollection, eventFields, foundNodes); } } } } private bool ContainsPath( SimpleAttributeOperandCollection selectClause, QualifiedNameCollection browsePath) { for (int index1 = 0; index1 < selectClause.Count; ++index1) { SimpleAttributeOperand attributeOperand = selectClause[index1]; if (attributeOperand.BrowsePath.Count == browsePath.Count) { bool flag = true; for (int index2 = 0; index2 < attributeOperand.BrowsePath.Count; ++index2) { if (attributeOperand.BrowsePath[index2] != browsePath[index2]) { flag = false; break; } } if (flag) return true; } } return false; } } public static class FormUtils { public static NodeId[] KnownEventTypes = new NodeId[8] { ObjectTypeIds.BaseEventType, ObjectTypeIds.ConditionType, ObjectTypeIds.DialogConditionType, ObjectTypeIds.AlarmConditionType, ObjectTypeIds.ExclusiveLimitAlarmType, ObjectTypeIds.NonExclusiveLimitAlarmType, ObjectTypeIds.AuditEventType, ObjectTypeIds.AuditUpdateMethodEventType }; public static EndpointDescription SelectEndpoint( string discoveryUrl, bool useSecurity) { if (!discoveryUrl.StartsWith("opc.tcp") && !discoveryUrl.EndsWith("/discovery")) discoveryUrl += "/discovery"; Uri discoveryUrl1 = new Uri(discoveryUrl); EndpointConfiguration configuration = EndpointConfiguration.Create(); configuration.OperationTimeout = 5000; EndpointDescription endpointDescription1 = (EndpointDescription)null; using (DiscoveryClient discoveryClient = DiscoveryClient.Create(discoveryUrl1, configuration)) { EndpointDescriptionCollection endpoints = discoveryClient.GetEndpoints((StringCollection)null); for (int index = 0; index < endpoints.Count; ++index) { EndpointDescription endpointDescription2 = endpoints[index]; if (endpointDescription2.EndpointUrl.StartsWith(discoveryUrl1.Scheme)) { if (endpointDescription1 == null) endpointDescription1 = endpointDescription2; if (useSecurity) { if (endpointDescription2.SecurityMode != MessageSecurityMode.None && (int)endpointDescription2.SecurityLevel > (int)endpointDescription1.SecurityLevel) endpointDescription1 = endpointDescription2; } else if (endpointDescription2.SecurityMode == MessageSecurityMode.None) endpointDescription1 = endpointDescription2; } if (endpointDescription1 == null && endpoints.Count > 0) endpointDescription1 = endpoints[0]; } } Uri uri = Opc.Ua.Utils.ParseUri(endpointDescription1.EndpointUrl); if (uri != (Uri)null && uri.Scheme == discoveryUrl1.Scheme) endpointDescription1.EndpointUrl = new UriBuilder(uri) { Host = discoveryUrl1.DnsSafeHost, Port = discoveryUrl1.Port }.ToString(); return endpointDescription1; } public static NodeId FindEventType( MonitoredItem monitoredItem, EventFieldList notification) { EventFilter filter = monitoredItem.Status.Filter as EventFilter; if (filter != null) { for (int index = 0; index < filter.SelectClauses.Count; ++index) { SimpleAttributeOperand selectClause = filter.SelectClauses[index]; if (selectClause.BrowsePath.Count == 1 && selectClause.BrowsePath[0] == (QualifiedName)"EventType") return notification.EventFields[index].Value as NodeId; } } return (NodeId)null; } public static BaseEventState ConstructEvent( Session session, MonitoredItem monitoredItem, EventFieldList notification, Dictionary eventTypeMappings) { NodeId eventType = FormUtils.FindEventType(monitoredItem, notification); if (eventType == (object)null) return (BaseEventState)null; NodeId nodeId = (NodeId)null; if (!eventTypeMappings.TryGetValue(eventType, out nodeId)) { for (int index = 0; index < FormUtils.KnownEventTypes.Length; ++index) { if (FormUtils.KnownEventTypes[index] == (object)eventType) { nodeId = eventType; eventTypeMappings.Add(eventType, eventType); break; } } if (nodeId == (object)null) { ReferenceDescriptionCollection descriptionCollection = FormUtils.BrowseSuperTypes(session, eventType, false); if (descriptionCollection == null) return (BaseEventState)null; for (int index1 = 0; index1 < descriptionCollection.Count; ++index1) { for (int index2 = 0; index2 < FormUtils.KnownEventTypes.Length; ++index2) { if (FormUtils.KnownEventTypes[index2] == (object)descriptionCollection[index1].NodeId) { nodeId = FormUtils.KnownEventTypes[index2]; eventTypeMappings.Add(eventType, nodeId); break; } } if (nodeId != (object)null) break; } } } if (nodeId == (object)null) return (BaseEventState)null; uint? identifier = nodeId.Identifier as uint?; if (!identifier.HasValue) return (BaseEventState)null; BaseEventState baseEventState; switch (identifier.Value) { case 2052: baseEventState = (BaseEventState)new AuditEventState((NodeState)null); break; case 2127: baseEventState = (BaseEventState)new AuditUpdateMethodEventState((NodeState)null); break; case 2782: baseEventState = (BaseEventState)new ConditionState((NodeState)null); break; case 2830: baseEventState = (BaseEventState)new DialogConditionState((NodeState)null); break; case 2915: baseEventState = (BaseEventState)new AlarmConditionState((NodeState)null); break; case 9341: baseEventState = (BaseEventState)new ExclusiveLimitAlarmState((NodeState)null); break; case 9906: baseEventState = (BaseEventState)new NonExclusiveLimitAlarmState((NodeState)null); break; default: baseEventState = new BaseEventState((NodeState)null); break; } EventFilter filter = monitoredItem.Status.Filter as EventFilter; baseEventState.Update(session.SystemContext, filter.SelectClauses, notification); baseEventState.Handle = (object)notification; return baseEventState; } public static ReferenceDescriptionCollection Browse( Session session, BrowseDescription nodeToBrowse, bool throwOnError) { try { ReferenceDescriptionCollection descriptionCollection = new ReferenceDescriptionCollection(); BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection(); nodesToBrowse.Add(nodeToBrowse); BrowseResultCollection results = (BrowseResultCollection)null; DiagnosticInfoCollection diagnosticInfos = (DiagnosticInfoCollection)null; session.Browse((RequestHeader)null, (ViewDescription)null, 0U, nodesToBrowse, out results, out diagnosticInfos); ClientBase.ValidateResponse((IList)results, (IList)nodesToBrowse); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, (IList)nodesToBrowse); while (!StatusCode.IsBad(results[0].StatusCode)) { for (int index = 0; index < results[0].References.Count; ++index) descriptionCollection.Add(results[0].References[index]); if (results[0].References.Count == 0 || results[0].ContinuationPoint == null) return descriptionCollection; ByteStringCollection continuationPoints = new ByteStringCollection(); continuationPoints.Add(results[0].ContinuationPoint); session.BrowseNext((RequestHeader)null, false, continuationPoints, out results, out diagnosticInfos); ClientBase.ValidateResponse((IList)results, (IList)continuationPoints); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, (IList)continuationPoints); } throw new ServiceResultException((ServiceResult)results[0].StatusCode); } catch (Exception ex) { if (throwOnError) throw new ServiceResultException(ex, 2147549184U); return (ReferenceDescriptionCollection)null; } } public static ReferenceDescriptionCollection BrowseSuperTypes( Session session, NodeId typeId, bool throwOnError) { ReferenceDescriptionCollection descriptionCollection1 = new ReferenceDescriptionCollection(); try { BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = typeId; nodeToBrowse.BrowseDirection = BrowseDirection.Inverse; nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasSubtype; nodeToBrowse.IncludeSubtypes = false; nodeToBrowse.NodeClassMask = 0U; nodeToBrowse.ResultMask = 63U; for (ReferenceDescriptionCollection descriptionCollection2 = FormUtils.Browse(session, nodeToBrowse, throwOnError); descriptionCollection2 != null && descriptionCollection2.Count > 0; descriptionCollection2 = FormUtils.Browse(session, nodeToBrowse, throwOnError)) { descriptionCollection1.Add(descriptionCollection2[0]); if (!descriptionCollection2[0].NodeId.IsAbsolute) nodeToBrowse.NodeId = (NodeId)descriptionCollection2[0].NodeId; else break; } return descriptionCollection1; } catch (Exception ex) { if (throwOnError) throw new ServiceResultException(ex, 2147549184U); return (ReferenceDescriptionCollection)null; } } } }