/// <summary> /// Collects the fields for the instance node. /// </summary> /// <param name="session">The session.</param> /// <param name="nodeId">The node id.</param> /// <param name="parentPath">The parent path.</param> /// <param name="fields">The event fields.</param> /// <param name="fieldNodeIds">The node id for the declaration of the field.</param> /// <param name="foundNodes">The table of found nodes.</param> private static void CollectFields( Session session, NodeId nodeId, QualifiedNameCollection parentPath, SimpleAttributeOperandCollection fields, List <NodeId> fieldNodeIds, Dictionary <NodeId, QualifiedNameCollection> foundNodes) { // find all of the children of the field. BrowseDescription nodeToBrowse = new BrowseDescription(); nodeToBrowse.NodeId = nodeId; nodeToBrowse.BrowseDirection = BrowseDirection.Forward; nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.Aggregates; nodeToBrowse.IncludeSubtypes = true; nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable); nodeToBrowse.ResultMask = (uint)BrowseResultMask.All; ReferenceDescriptionCollection children = FormUtils.Browse(session, nodeToBrowse, false); if (children == null) { return; } // process the children. for (int ii = 0; ii < children.Count; ii++) { ReferenceDescription child = children[ii]; if (child.NodeId.IsAbsolute) { continue; } // construct browse path. QualifiedNameCollection browsePath = new QualifiedNameCollection(parentPath); browsePath.Add(child.BrowseName); // check if the browse path is already in the list. int index = ContainsPath(fields, browsePath); if (index < 0) { SimpleAttributeOperand field = new SimpleAttributeOperand(); field.TypeDefinitionId = ObjectTypeIds.BaseEventType; field.BrowsePath = browsePath; field.AttributeId = (child.NodeClass == NodeClass.Variable) ? Attributes.Value : Attributes.NodeId; fields.Add(field); fieldNodeIds.Add((NodeId)child.NodeId); } // recusively find all of the children. NodeId targetId = (NodeId)child.NodeId; // need to guard against loops. if (!foundNodes.ContainsKey(targetId)) { foundNodes.Add(targetId, browsePath); CollectFields(session, (NodeId)child.NodeId, browsePath, fields, fieldNodeIds, foundNodes); } } }
/// <summary> /// Constructs an event object from a notification. /// </summary> /// <param name="session">The session.</param> /// <param name="monitoredItem">The monitored item that produced the notification.</param> /// <param name="notification">The notification.</param> /// <param name="knownEventTypes">The known event types.</param> /// <param name="eventTypeMappings">Mapping between event types and known event types.</param> /// <returns> /// The event object. Null if the notification is not a valid event type. /// </returns> public static BaseEventState ConstructEvent( Session session, MonitoredItem monitoredItem, EventFieldList notification, Dictionary <NodeId, Type> knownEventTypes, Dictionary <NodeId, NodeId> eventTypeMappings) { // find the event type. NodeId eventTypeId = FindEventType(monitoredItem, notification); if (eventTypeId == null) { return(null); } // look up the known event type. Type knownType = null; NodeId knownTypeId = null; if (eventTypeMappings.TryGetValue(eventTypeId, out knownTypeId)) { knownType = knownEventTypes[knownTypeId]; } // try again. if (knownType == null) { if (knownEventTypes.TryGetValue(eventTypeId, out knownType)) { knownTypeId = eventTypeId; eventTypeMappings.Add(eventTypeId, eventTypeId); } } // try mapping it to a known type. if (knownType == null) { // browse for the supertypes of the event type. ReferenceDescriptionCollection supertypes = FormUtils.BrowseSuperTypes(session, eventTypeId, false); // can't do anything with unknown types. if (supertypes == null) { return(null); } // find the first supertype that matches a known event type. for (int ii = 0; ii < supertypes.Count; ii++) { NodeId superTypeId = (NodeId)supertypes[ii].NodeId; if (knownEventTypes.TryGetValue(superTypeId, out knownType)) { knownTypeId = superTypeId; eventTypeMappings.Add(eventTypeId, superTypeId); } if (knownTypeId != null) { break; } } // can't do anything with unknown types. if (knownTypeId == null) { return(null); } } // construct the event based on the known event type. BaseEventState e = (BaseEventState)Activator.CreateInstance(knownType, new object[] { (NodeState)null }); // get the filter which defines the contents of the notification. EventFilter filter = monitoredItem.Status.Filter as EventFilter; // initialize the event with the values in the notification. e.Update(session.SystemContext, filter.SelectClauses, notification); // save the orginal notification. e.Handle = notification; return(e); }