Stores an instance declaration fetched from the server.
예제 #1
0
        /// <summary>
        /// Returns the attribute with the specified attribute id.
        /// </summary>
        public AeEventAttribute GetAttribute(uint attributeId)
        {
            AeEventAttribute attribute = null;

            if (!m_attributes.TryGetValue(attributeId, out attribute))
            {
                return(null);
            }

            return(attribute);
        }
예제 #2
0
        /// <summary>
        /// Uses the BrowsePathDisplayText to compare two attributes.
        /// </summary>
        private static int CompareAttributes(AeEventAttribute x, AeEventAttribute y)
        {
            if (Object.ReferenceEquals(x, y))
            {
                return(0);
            }

            if (Object.ReferenceEquals(x, null))
            {
                return((Object.ReferenceEquals(y, null)) ? 0 : -1);
            }

            return(x.BrowsePathDisplayText.CompareTo(y.BrowsePathDisplayText));
        }
예제 #3
0
        /// <summary>
        /// Converts an event field to a locally useable attribute value.
        /// </summary>
        private object GetLocalAttributeValue(Variant fieldValue, AeEventAttribute attribute)
        {
            // check for null.
            if (fieldValue == Variant.Null)
            {
                return(null);
            }

            // check that the data type is what is expected.
            TypeInfo typeInfo = fieldValue.TypeInfo;

            if (typeInfo == null)
            {
                typeInfo = TypeInfo.Construct(fieldValue);
            }

            if (attribute.BuiltInType != BuiltInType.Variant && typeInfo.BuiltInType != attribute.BuiltInType)
            {
                return(null);
            }

            // check for expected array dimension.
            if (attribute.ValueRank >= 0 && typeInfo.ValueRank == ValueRanks.Scalar)
            {
                return(null);
            }

            if (typeInfo.ValueRank != ValueRanks.Scalar)
            {
                if (attribute.ValueRank == ValueRanks.ScalarOrOneDimension && typeInfo.ValueRank != 1)
                {
                    return(null);
                }

                if (attribute.ValueRank != ValueRanks.Any && attribute.ValueRank != typeInfo.ValueRank)
                {
                    return(null);
                }
            }

            // map to local value.
            return(m_mapper.GetLocalValue(fieldValue));
        }
예제 #4
0
        /// <summary>
        /// Gets the list of categories for the specified event types.
        /// </summary>
        public List <AeEventAttribute> GetAttributes(uint categoryId)
        {
            AeEventCategory category = null;

            if (!m_categories.TryGetValue(categoryId, out category))
            {
                return(null);
            }

            List <AeEventAttribute> attributes = new List <AeEventAttribute>();

            AeEventCategory subType = category;

            while (subType != null)
            {
                for (int ii = 0; ii < subType.Attributes.Count; ii++)
                {
                    AeEventAttribute attribute = subType.Attributes[ii];

                    if (attribute.OverriddenDeclaration == null)
                    {
                        if (!attribute.Hidden)
                        {
                            attributes.Add(attribute);
                        }
                    }
                }

                AeEventCategory superType = null;

                if (!m_eventTypes.TryGetValue(subType.SuperTypeId, out superType))
                {
                    break;
                }

                subType = superType;
            }

            attributes.Sort(CompareAttributes);
            return(attributes);
        }
예제 #5
0
        /// <summary>
        /// Updates the selected attributes for the current filters.
        /// </summary>
        private void UpdatedSelectAttributes()
        {
            SelectedAttributes = new List <AeEventAttribute>();

            // add attributes which always requested.
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.EventId));
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.EventType));
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.SourceName));
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.Time));
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.Message));
            SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.BaseEventType, Opc.Ua.BrowseNames.Severity));

            // add tracking event attributes.
            if ((EventTypes & OpcRcw.Ae.Constants.TRACKING_EVENT) != 0)
            {
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.AuditEventType, Opc.Ua.BrowseNames.ClientUserId));
            }

            // add condition event attributes.
            if ((EventTypes & OpcRcw.Ae.Constants.CONDITION_EVENT) != 0)
            {
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.BranchId));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.ConditionName));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.Quality));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.Comment));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.ClientUserId));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ConditionType, Opc.Ua.BrowseNames.EnabledState, Opc.Ua.BrowseNames.Id));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.AcknowledgeableConditionType, Opc.Ua.BrowseNames.AckedState, Opc.Ua.BrowseNames.Id));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.AlarmConditionType, Opc.Ua.BrowseNames.ActiveState, Opc.Ua.BrowseNames.Id));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.AlarmConditionType, Opc.Ua.BrowseNames.ActiveState, Opc.Ua.BrowseNames.TransitionTime));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.ExclusiveLimitAlarmType, Opc.Ua.BrowseNames.LimitState, Opc.Ua.BrowseNames.CurrentState));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.NonExclusiveLimitAlarmType, Opc.Ua.BrowseNames.HighHighState));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.NonExclusiveLimitAlarmType, Opc.Ua.BrowseNames.HighState));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.NonExclusiveLimitAlarmType, Opc.Ua.BrowseNames.LowState));
                SelectedAttributes.Add(m_mapper.GetAttribute(Opc.Ua.ObjectTypeIds.NonExclusiveLimitAlarmType, Opc.Ua.BrowseNames.LowLowState));
            }

            if (RequestedAttributeIds != null)
            {
                // update list for all requested attributes.
                foreach (KeyValuePair <uint, uint[]> pair in RequestedAttributeIds)
                {
                    for (int ii = 0; ii < pair.Value.Length; ii++)
                    {
                        // check if already in list.
                        bool found = false;

                        for (int jj = 0; jj < SelectedAttributes.Count; jj++)
                        {
                            if (SelectedAttributes[jj] != null && SelectedAttributes[jj].LocalId == pair.Value[ii])
                            {
                                found = true;
                                break;
                            }
                        }

                        if (found)
                        {
                            continue;
                        }

                        // verify that it exists.
                        AeEventAttribute attribute = m_mapper.GetAttribute(pair.Value[ii]);

                        if (attribute != null)
                        {
                            SelectedAttributes.Add(attribute);
                        }
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Translates an event notification in an AE event.
        /// </summary>
        public AeEvent TranslateNotification(Session session, EventFieldList e)
        {
            AeEvent e2 = new AeEvent();

            // extract the required event fields.
            int index = 0;

            e2.EventId    = ExtractField <byte[]>(e, index++, null);
            e2.EventType  = ExtractField <NodeId>(e, index++, null);
            e2.SourceName = ExtractField <string>(e, index++, null);
            e2.Time       = ExtractField <DateTime>(e, index++, DateTime.MinValue);
            e2.Message    = ExtractField <LocalizedText>(e, index++, null);
            e2.Severity   = ExtractField <ushort>(e, index++, 0);

            if ((EventTypes & OpcRcw.Ae.Constants.TRACKING_EVENT) != 0)
            {
                e2.AuditUserId = ExtractField <string>(e, index++, null);
            }

            if ((EventTypes & OpcRcw.Ae.Constants.CONDITION_EVENT) != 0)
            {
                e2.BranchId      = ExtractField <byte[]>(e, index++, null);
                e2.ConditionName = ExtractField <string>(e, index++, null);
                e2.Quality       = ExtractField <StatusCode>(e, index++, StatusCodes.Good);
                e2.Comment       = ExtractField <LocalizedText>(e, index++, null);
                e2.CommentUserId = ExtractField <string>(e, index++, null);
                e2.EnabledState  = ExtractField <bool>(e, index++, false);
                e2.AckedState    = ExtractField <bool>(e, index++, false);
                e2.ActiveState   = ExtractField <bool>(e, index++, false);
                e2.ActiveTime    = ExtractField <DateTime>(e, index++, DateTime.MinValue);
                e2.LimitState    = ExtractField <LocalizedText>(e, index++, null);
                e2.HighHighState = ExtractField <LocalizedText>(e, index++, null);
                e2.HighState     = ExtractField <LocalizedText>(e, index++, null);
                e2.LowState      = ExtractField <LocalizedText>(e, index++, null);
                e2.LowLowState   = ExtractField <LocalizedText>(e, index++, null);

                // condition id is always last.
                e2.ConditionId = ExtractField <NodeId>(e, e.EventFields.Count - 1, null);
            }

            // find the category for the event.
            e2.Category = FindCategory(session, e2);

            // extract any additional attributes.
            if (RequestedAttributeIds != null)
            {
                uint[] attributeIds = null;

                if (!RequestedAttributeIds.TryGetValue(e2.Category.LocalId, out attributeIds))
                {
                    return(e2);
                }

                // nothing more to do.
                if (attributeIds == null || attributeIds.Length == 0)
                {
                    return(e2);
                }

                // search for the requested attributes.
                object[] values = new object[attributeIds.Length];

                for (int ii = 0; ii < attributeIds.Length; ii++)
                {
                    // look for matching attribute.
                    for (int jj = 0; jj < SelectedAttributes.Count; jj++)
                    {
                        if (jj >= e.EventFields.Count)
                        {
                            break;
                        }

                        AeEventAttribute attribute = SelectedAttributes[jj];

                        if (attribute == null || attribute.LocalId != attributeIds[ii])
                        {
                            continue;
                        }

                        values[ii] = GetLocalAttributeValue(e.EventFields[jj], attribute);
                    }
                }

                e2.AttributeValues = values;
            }

            return(e2);
        }
예제 #7
0
        /// <summary>
        /// Assigns a locally unique numeric id to each event type.
        /// </summary>
        private void UpdateEventAttributeMappings(NodeIdMappingSet mappingSet)
        {
            NodeIdMappingCollection mappingsToKeep = new NodeIdMappingCollection();

            // collect all unique declarations.
            List <AeEventAttribute> list = new List <AeEventAttribute>();

            foreach (AeEventCategory type in m_eventTypes.Values)
            {
                for (int ii = 0; ii < type.Attributes.Count; ii++)
                {
                    AeEventAttribute declaration = type.Attributes[ii];

                    // only variables can be attributes.
                    if (declaration.NodeClass != NodeClass.Variable)
                    {
                        continue;
                    }

                    // need to link attributes to any attributes that they override.
                    AeEventCategory subType   = type;
                    AeEventCategory superType = null;

                    while (subType != null)
                    {
                        if (NodeId.IsNull(subType.SuperTypeId) || subType.TypeId == subType.SuperTypeId || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.BaseObjectType)
                        {
                            list.Add(declaration);
                            break;
                        }

                        if (!m_eventTypes.TryGetValue(subType.SuperTypeId, out superType))
                        {
                            break;
                        }

                        for (int jj = 0; jj < superType.Attributes.Count; jj++)
                        {
                            if (superType.Attributes[jj].BrowsePathDisplayText == declaration.BrowsePathDisplayText)
                            {
                                declaration.OverriddenDeclaration = superType.Attributes[jj];
                                declaration = declaration.OverriddenDeclaration;
                                break;
                            }
                        }

                        subType = superType;
                    }
                }
            }

            // look up ids for all attributes in master list.
            Dictionary <uint, AeEventAttribute> attributes = new Dictionary <uint, AeEventAttribute>();

            for (int ii = 0; ii < list.Count; ii++)
            {
                AeEventAttribute declaration = list[ii];

                for (int jj = 0; jj < mappingSet.Mappings.Count; jj++)
                {
                    NodeIdMapping mapping = mappingSet.Mappings[jj];

                    try
                    {
                        // browse display paths always use local namespa indexes.
                        if (declaration.BrowsePathDisplayText != mapping.BrowePath)
                        {
                            continue;
                        }

                        // need to convert the cached type id to a remote id.
                        NodeId localId  = NodeId.Parse(mapping.NodeId);
                        NodeId remoteId = this.GetRemoteNodeId(localId);

                        if (declaration.RootTypeId != remoteId)
                        {
                            continue;
                        }

                        // must update the saved integer id.
                        if (!attributes.ContainsKey(mapping.IntegerId))
                        {
                            declaration.LocalId             = mapping.IntegerId;
                            attributes[declaration.LocalId] = declaration;
                            mappingsToKeep.Add(mapping);
                        }

                        // must assign a new one if a duplicate found.
                        else
                        {
                            declaration.LocalId = 0;
                        }
                    }
                    catch (Exception)
                    {
                        // ignore invalid mappings.
                    }
                }
            }

            // assign new ids.
            uint nextId = 1;

            for (int ii = 0; ii < list.Count; ii++)
            {
                AeEventAttribute declaration = list[ii];

                if (declaration.LocalId == 0)
                {
                    // find a unique id.
                    while (attributes.ContainsKey(nextId))
                    {
                        nextId++;
                    }

                    // assign the id.
                    declaration.LocalId             = nextId;
                    attributes[declaration.LocalId] = declaration;

                    // save the mapping.
                    NodeIdMapping mapping = new NodeIdMapping();
                    mapping.IntegerId = nextId;
                    mapping.NodeId    = this.GetLocalNodeId(declaration.RootTypeId).ToString();
                    mapping.BrowePath = declaration.BrowsePathDisplayText;

                    mappingsToKeep.Add(mapping);
                }
            }

            // update mapping set.
            mappingSet.Mappings = mappingsToKeep;
            m_attributes        = attributes;
        }
예제 #8
0
        /// <summary>
        /// Collects instance declarations nodes from with a type.
        /// </summary>
        public static void CollectInstanceDeclarations(
            Session session,
            ComNamespaceMapper mapper,
            NodeState node,
            AeEventAttribute parent,
            List<AeEventAttribute> instances,
            IDictionary<string, AeEventAttribute> map)
        {
            List<BaseInstanceState> children = new List<BaseInstanceState>();
            node.GetChildren(session.SystemContext, children);
            
            if (children.Count == 0)
            {
                return;
            }

            // process the children.
            for (int ii = 0; ii < children.Count; ii++)
            {
                BaseInstanceState instance = children[ii];

                // only interested in objects and variables.
                if (instance.NodeClass != NodeClass.Object && instance.NodeClass != NodeClass.Variable)
                {
                    return;
                }

                // ignore instances without a modelling rule.
                if (NodeId.IsNull(instance.ModellingRuleId))
                {
                    return;
                }

                // create a new declaration.
                AeEventAttribute declaration = new AeEventAttribute();

                declaration.RootTypeId = (parent != null)?parent.RootTypeId:node.NodeId;
                declaration.NodeId = (NodeId)instance.NodeId;
                declaration.BrowseName = instance.BrowseName;
                declaration.NodeClass = instance.NodeClass;
                declaration.Description = (instance.Description != null)?instance.Description.ToString():null;
                
                // get data type information.
                BaseVariableState variable = instance as BaseVariableState;
 
                if (variable != null)
                {
                    declaration.DataType = variable.DataType;
                    declaration.ValueRank = variable.ValueRank;

                    if (!NodeId.IsNull(variable.DataType))
                    {
                        declaration.BuiltInType = DataTypes.GetBuiltInType(declaration.DataType, session.TypeTree);
                    }
                }

                if (!LocalizedText.IsNullOrEmpty(instance.DisplayName))
                {
                    declaration.DisplayName = instance.DisplayName.Text;
                }
                else
                {
                    declaration.DisplayName = instance.BrowseName.Name;
                }

                if (parent != null)
                {
                    declaration.BrowsePath = new QualifiedNameCollection(parent.BrowsePath);
                    declaration.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(instance.BrowseName));
                    declaration.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, instance.DisplayName);
                }
                else
                {
                    declaration.BrowsePath = new QualifiedNameCollection();
                    declaration.BrowsePathDisplayText = Utils.Format("{0}", instance.BrowseName);
                    declaration.DisplayPath = Utils.Format("{0}", instance.DisplayName);
                }

                declaration.BrowsePath.Add(instance.BrowseName);

                // check if reading an overridden declaration.
                AeEventAttribute overriden = null;

                if (map.TryGetValue(declaration.BrowsePathDisplayText, out overriden))
                {
                    declaration.OverriddenDeclaration = overriden;
                }

                map[declaration.BrowsePathDisplayText] = declaration;

                // only interested in variables.
                if (instance.NodeClass == NodeClass.Variable)
                {
                    instances.Add(declaration);
                }

                // recusively build tree.
                CollectInstanceDeclarations(session, mapper, instance, declaration, instances, map);
            }
        }
예제 #9
0
        /// <summary>
        /// Collects instance declarations nodes from with a type.
        /// </summary>
        public static void CollectInstanceDeclarations(
            Session session,
            ComNamespaceMapper mapper,
            NodeId typeId,
            AeEventAttribute parent,
            List<AeEventAttribute> instances,
            IDictionary<string, AeEventAttribute> map)
        {
            // find the children.
            BrowseDescription nodeToBrowse = new BrowseDescription();

            if (parent == null)
            {
                nodeToBrowse.NodeId = typeId;
            }
            else
            {
                nodeToBrowse.NodeId = parent.NodeId;
            }

            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasChild;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;

            // ignore any browsing errors.
            ReferenceDescriptionCollection references = Browse(session, nodeToBrowse, false);

            if (references == null)
            {
                return;
            }

            // process the children.
            List<NodeId> nodeIds = new List<NodeId>();
            List<AeEventAttribute> children = new List<AeEventAttribute>();

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if (reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                // create a new declaration.
                AeEventAttribute child = new AeEventAttribute();

                child.RootTypeId = typeId;
                child.NodeId = (NodeId)reference.NodeId;
                child.BrowseName = reference.BrowseName;
                child.NodeClass = reference.NodeClass;

                if (!LocalizedText.IsNullOrEmpty(reference.DisplayName))
                {
                    child.DisplayName = reference.DisplayName.Text;
                }
                else
                {
                    child.DisplayName = reference.BrowseName.Name;
                }

                if (parent != null)
                {
                    child.BrowsePath = new QualifiedNameCollection(parent.BrowsePath);
                    child.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(reference.BrowseName));
                    child.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, reference.DisplayName);
                }
                else
                {
                    child.BrowsePath = new QualifiedNameCollection();
                    child.BrowsePathDisplayText = Utils.Format("{0}", reference.BrowseName);
                    child.DisplayPath = Utils.Format("{0}", reference.DisplayName);
                }

                child.BrowsePath.Add(reference.BrowseName);

                // check if reading an overridden declaration.
                AeEventAttribute overriden = null;

                if (map.TryGetValue(child.BrowsePathDisplayText, out overriden))
                {
                    child.OverriddenDeclaration = overriden;
                }

                map[child.BrowsePathDisplayText] = child;

                // add to list.
                children.Add(child);
                nodeIds.Add(child.NodeId);
            }

            // check if nothing more to do.
            if (children.Count == 0)
            {
                return;
            }

            // find the modelling rules.
            List<NodeId> modellingRules = FindTargetOfReference(session, nodeIds, Opc.Ua.ReferenceTypeIds.HasModellingRule, false);

            if (modellingRules != null)
            {
                for (int ii = 0; ii < nodeIds.Count; ii++)
                {
                    children[ii].ModellingRule = modellingRules[ii];

                    // if the modelling rule is null then the instance is not part of the type declaration.
                    if (NodeId.IsNull(modellingRules[ii]))
                    {
                        map.Remove(children[ii].BrowsePathDisplayText);
                    }
                }
            }

            // update the descriptions.
            UpdateInstanceDescriptions(session, children, false);

            // recusively collect instance declarations for the tree below.
            for (int ii = 0; ii < children.Count; ii++)
            {
                if (!NodeId.IsNull(children[ii].ModellingRule))
                {
                    instances.Add(children[ii]);
                    CollectInstanceDeclarations(session, mapper, typeId, children[ii], instances, map);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Finds the targets for the specified reference.
        /// </summary>
        private static void UpdateInstanceDescriptions(Session session, List <AeEventAttribute> instances, bool throwOnError)
        {
            try
            {
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();

                for (int ii = 0; ii < instances.Count; ii++)
                {
                    ReadValueId nodeToRead = new ReadValueId();
                    nodeToRead.NodeId      = instances[ii].NodeId;
                    nodeToRead.AttributeId = Attributes.Description;
                    nodesToRead.Add(nodeToRead);

                    nodeToRead             = new ReadValueId();
                    nodeToRead.NodeId      = instances[ii].NodeId;
                    nodeToRead.AttributeId = Attributes.DataType;
                    nodesToRead.Add(nodeToRead);

                    nodeToRead             = new ReadValueId();
                    nodeToRead.NodeId      = instances[ii].NodeId;
                    nodeToRead.AttributeId = Attributes.ValueRank;
                    nodesToRead.Add(nodeToRead);
                }

                // start the browse operation.
                DataValueCollection      results         = null;
                DiagnosticInfoCollection diagnosticInfos = null;

                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    nodesToRead,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, nodesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

                // update the instances.
                for (int ii = 0; ii < nodesToRead.Count; ii += 3)
                {
                    AeEventAttribute instance = instances[ii / 3];

                    instance.Description = results[ii].GetValue <LocalizedText>(LocalizedText.Null).Text;
                    instance.DataType    = results[ii + 1].GetValue <NodeId>(NodeId.Null);
                    instance.ValueRank   = results[ii + 2].GetValue <int>(ValueRanks.Any);

                    if (!NodeId.IsNull(instance.DataType))
                    {
                        instance.BuiltInType = DataTypes.GetBuiltInType(instance.DataType, session.TypeTree);
                    }
                }
            }
            catch (Exception exception)
            {
                if (throwOnError)
                {
                    throw new ServiceResultException(exception, StatusCodes.BadUnexpectedError);
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Collects instance declarations nodes from with a type.
        /// </summary>
        public static void CollectInstanceDeclarations(
            Session session,
            ComNamespaceMapper mapper,
            NodeState node,
            AeEventAttribute parent,
            List <AeEventAttribute> instances,
            IDictionary <string, AeEventAttribute> map)
        {
            List <BaseInstanceState> children = new List <BaseInstanceState>();

            node.GetChildren(session.SystemContext, children);

            if (children.Count == 0)
            {
                return;
            }

            // process the children.
            for (int ii = 0; ii < children.Count; ii++)
            {
                BaseInstanceState instance = children[ii];

                // only interested in objects and variables.
                if (instance.NodeClass != NodeClass.Object && instance.NodeClass != NodeClass.Variable)
                {
                    return;
                }

                // ignore instances without a modelling rule.
                if (NodeId.IsNull(instance.ModellingRuleId))
                {
                    return;
                }

                // create a new declaration.
                AeEventAttribute declaration = new AeEventAttribute();

                declaration.RootTypeId  = (parent != null)?parent.RootTypeId:node.NodeId;
                declaration.NodeId      = (NodeId)instance.NodeId;
                declaration.BrowseName  = instance.BrowseName;
                declaration.NodeClass   = instance.NodeClass;
                declaration.Description = (instance.Description != null)?instance.Description.ToString():null;

                // get data type information.
                BaseVariableState variable = instance as BaseVariableState;

                if (variable != null)
                {
                    declaration.DataType  = variable.DataType;
                    declaration.ValueRank = variable.ValueRank;

                    if (!NodeId.IsNull(variable.DataType))
                    {
                        declaration.BuiltInType = DataTypes.GetBuiltInType(declaration.DataType, session.TypeTree);
                    }
                }

                if (!LocalizedText.IsNullOrEmpty(instance.DisplayName))
                {
                    declaration.DisplayName = instance.DisplayName.Text;
                }
                else
                {
                    declaration.DisplayName = instance.BrowseName.Name;
                }

                if (parent != null)
                {
                    declaration.BrowsePath            = new QualifiedNameCollection(parent.BrowsePath);
                    declaration.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(instance.BrowseName));
                    declaration.DisplayPath           = Utils.Format("{0}/{1}", parent.DisplayPath, instance.DisplayName);
                }
                else
                {
                    declaration.BrowsePath            = new QualifiedNameCollection();
                    declaration.BrowsePathDisplayText = Utils.Format("{0}", instance.BrowseName);
                    declaration.DisplayPath           = Utils.Format("{0}", instance.DisplayName);
                }

                declaration.BrowsePath.Add(instance.BrowseName);

                // check if reading an overridden declaration.
                AeEventAttribute overriden = null;

                if (map.TryGetValue(declaration.BrowsePathDisplayText, out overriden))
                {
                    declaration.OverriddenDeclaration = overriden;
                }

                map[declaration.BrowsePathDisplayText] = declaration;

                // only interested in variables.
                if (instance.NodeClass == NodeClass.Variable)
                {
                    instances.Add(declaration);
                }

                // recusively build tree.
                CollectInstanceDeclarations(session, mapper, instance, declaration, instances, map);
            }
        }
예제 #12
0
        /// <summary>
        /// Collects instance declarations nodes from with a type.
        /// </summary>
        public static void CollectInstanceDeclarations(
            Session session,
            ComNamespaceMapper mapper,
            NodeId typeId,
            AeEventAttribute parent,
            List <AeEventAttribute> instances,
            IDictionary <string, AeEventAttribute> map)
        {
            // find the children.
            BrowseDescription nodeToBrowse = new BrowseDescription();

            if (parent == null)
            {
                nodeToBrowse.NodeId = typeId;
            }
            else
            {
                nodeToBrowse.NodeId = parent.NodeId;
            }

            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasChild;
            nodeToBrowse.IncludeSubtypes = true;
            nodeToBrowse.NodeClassMask   = (uint)(NodeClass.Object | NodeClass.Variable);
            nodeToBrowse.ResultMask      = (uint)BrowseResultMask.All;

            // ignore any browsing errors.
            ReferenceDescriptionCollection references = Browse(session, nodeToBrowse, false);

            if (references == null)
            {
                return;
            }

            // process the children.
            List <NodeId>           nodeIds  = new List <NodeId>();
            List <AeEventAttribute> children = new List <AeEventAttribute>();

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                if (reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                // create a new declaration.
                AeEventAttribute child = new AeEventAttribute();

                child.RootTypeId = typeId;
                child.NodeId     = (NodeId)reference.NodeId;
                child.BrowseName = reference.BrowseName;
                child.NodeClass  = reference.NodeClass;

                if (!LocalizedText.IsNullOrEmpty(reference.DisplayName))
                {
                    child.DisplayName = reference.DisplayName.Text;
                }
                else
                {
                    child.DisplayName = reference.BrowseName.Name;
                }

                if (parent != null)
                {
                    child.BrowsePath            = new QualifiedNameCollection(parent.BrowsePath);
                    child.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(reference.BrowseName));
                    child.DisplayPath           = Utils.Format("{0}/{1}", parent.DisplayPath, reference.DisplayName);
                }
                else
                {
                    child.BrowsePath            = new QualifiedNameCollection();
                    child.BrowsePathDisplayText = Utils.Format("{0}", reference.BrowseName);
                    child.DisplayPath           = Utils.Format("{0}", reference.DisplayName);
                }

                child.BrowsePath.Add(reference.BrowseName);

                // check if reading an overridden declaration.
                AeEventAttribute overriden = null;

                if (map.TryGetValue(child.BrowsePathDisplayText, out overriden))
                {
                    child.OverriddenDeclaration = overriden;
                }

                map[child.BrowsePathDisplayText] = child;

                // add to list.
                children.Add(child);
                nodeIds.Add(child.NodeId);
            }

            // check if nothing more to do.
            if (children.Count == 0)
            {
                return;
            }

            // find the modelling rules.
            List <NodeId> modellingRules = FindTargetOfReference(session, nodeIds, Opc.Ua.ReferenceTypeIds.HasModellingRule, false);

            if (modellingRules != null)
            {
                for (int ii = 0; ii < nodeIds.Count; ii++)
                {
                    children[ii].ModellingRule = modellingRules[ii];

                    // if the modelling rule is null then the instance is not part of the type declaration.
                    if (NodeId.IsNull(modellingRules[ii]))
                    {
                        map.Remove(children[ii].BrowsePathDisplayText);
                    }
                }
            }

            // update the descriptions.
            UpdateInstanceDescriptions(session, children, false);

            // recusively collect instance declarations for the tree below.
            for (int ii = 0; ii < children.Count; ii++)
            {
                if (!NodeId.IsNull(children[ii].ModellingRule))
                {
                    instances.Add(children[ii]);
                    CollectInstanceDeclarations(session, mapper, typeId, children[ii], instances, map);
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Uses the BrowsePathDisplayText to compare two attributes.
        /// </summary>
        private static int CompareAttributes(AeEventAttribute x, AeEventAttribute y)
        {
            if (Object.ReferenceEquals(x, y))
            {
                return 0;
            }

            if (Object.ReferenceEquals(x, null))
            {
                return (Object.ReferenceEquals(y, null)) ? 0 : -1;
            }

            return x.BrowsePathDisplayText.CompareTo(y.BrowsePathDisplayText);
        }