Stores the type information provided by the AE server.
        /// <summary>
        /// Updates the type cache.
        /// </summary>
        private void DoMetadataUpdate(object state)
        {
            try
            {
                if (!Server.IsRunning)
                {
                    return;
                }

                ComAeClientManager system = (ComAeClientManager)SystemContext.SystemHandle;
                ComAeClient        client = (ComAeClient)system.SelectClient(SystemContext, true);

                AeTypeCache cache = new AeTypeCache();
                cache.LoadEventTypes(client);

                lock (Lock)
                {
                    if (m_typeCache == null)
                    {
                        m_typeCache = cache;
                    }

                    m_typeCache.EventTypes = cache.EventTypes;
                    m_typeCache.UpdateCache(SystemContext, NamespaceIndex);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error updating event type cache.");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Updates the non-exclusive limit event.
        /// </summary>
        private void UpdateNonExclusiveLimitAlarm(NonExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            bool active = (e.wNewState & Constants.CONDITION_ACTIVE) != 0;
            TwoStateVariableState state = null;

            if (AeTypeCache.IsKnownName(e.szConditionName, "HI HI"))
            {
                instance.HighHighState            = state = new TwoStateVariableState(instance);
                instance.HighHighState.BrowseName = Opc.Ua.BrowseNames.HighHighState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV HI"))
            {
                instance.HighState            = state = new TwoStateVariableState(instance);
                instance.HighState.BrowseName = Opc.Ua.BrowseNames.HighState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO") || AeTypeCache.IsKnownName(e.szSubconditionName, "DV LO"))
            {
                instance.LowState            = state = new TwoStateVariableState(instance);
                instance.LowState.BrowseName = Opc.Ua.BrowseNames.LowState;
            }

            else if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
            {
                instance.LowLowState            = state = new TwoStateVariableState(instance);
                instance.LowLowState.BrowseName = Opc.Ua.BrowseNames.LowLowState;
            }

            if (state != null)
            {
                state.Value = new LocalizedText((active) ? ConditionStateNames.Active : ConditionStateNames.Inactive);
                state.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, active, false);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ComAeSubscriptionClient"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="configuration">The configuration.</param>
        /// <param name="cache">The cache for known types.</param>
        /// <param name="namespaceIndex">The namespace index for the event types.</param>
        /// <param name="manager">The manager.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        public ComAeSubscriptionClient(
            ServerSystemContext context,
            ComAeClientConfiguration configuration,
            AeTypeCache cache,
            ushort namespaceIndex,
            ComAeClientManager manager,
            MonitoredItem monitoredItem)
        {
            m_defaultContext  = context;
            m_separators      = configuration.SeperatorChars;
            m_cache           = cache;
            m_namespaceIndex  = namespaceIndex;
            m_manager         = manager;
            m_refreshComplete = new ManualResetEvent(false);
            m_monitoredItems  = new List <MonitoredItem>();
            m_monitoredItems.Add(monitoredItem);
            m_qualifiedName = null;
            m_isSource      = false;

            NodeHandle  handle = monitoredItem.ManagerHandle as NodeHandle;
            AeAreaState area   = handle.Node as AeAreaState;

            if (area != null)
            {
                m_qualifiedName = area.QualifiedName;
                m_isSource      = false;
            }
            else
            {
                AeSourceState source = handle.Node as AeSourceState;

                if (source != null)
                {
                    m_qualifiedName = source.QualifiedName;
                    m_isSource      = true;
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ComAeSubscriptionClient"/> class.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="configuration">The configuration.</param>
        /// <param name="cache">The cache for known types.</param>
        /// <param name="namespaceIndex">The namespace index for the event types.</param>
        /// <param name="manager">The manager.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        public ComAeSubscriptionClient(
            ServerSystemContext context,
            ComAeClientConfiguration configuration,
            AeTypeCache cache,
            ushort namespaceIndex,
            ComAeClientManager manager,
            MonitoredItem monitoredItem)
        {
            m_defaultContext = context;
            m_separators = configuration.SeperatorChars;
            m_cache = cache;
            m_namespaceIndex = namespaceIndex;
            m_manager = manager;
            m_refreshComplete = new ManualResetEvent(false);
            m_monitoredItems = new List<MonitoredItem>();
            m_monitoredItems.Add(monitoredItem);
            m_qualifiedName = null;
            m_isSource = false;

            NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle;
            AeAreaState area = handle.Node as AeAreaState;

            if (area != null)
            {
                m_qualifiedName = area.QualifiedName;
                m_isSource = false;
            }
            else
            {
                AeSourceState source = handle.Node as AeSourceState;

                if (source != null)
                {
                    m_qualifiedName = source.QualifiedName;
                    m_isSource = true;
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Updates the exclusive limit alarm event.
        /// </summary>
        private void UpdateExclusiveLimitAlarm(ExclusiveLimitAlarmState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            NodeId state = null;
            string text  = null;

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI HI"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_HighHigh;
                text  = ConditionStateNames.HighHighActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "HI"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_High;
                text  = ConditionStateNames.HighActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_Low;
                text  = ConditionStateNames.LowActive;
            }

            if (AeTypeCache.IsKnownName(e.szSubconditionName, "LO LO"))
            {
                state = Opc.Ua.ObjectIds.ExclusiveLimitStateMachineType_LowLow;
                text  = ConditionStateNames.LowLowActive;
            }

            instance.LimitState                         = new ExclusiveLimitStateMachineState(instance);
            instance.LimitState.BrowseName              = Opc.Ua.BrowseNames.LimitState;
            instance.LimitState.CurrentState            = new FiniteStateVariableState(instance.LimitState);
            instance.LimitState.CurrentState.BrowseName = Opc.Ua.BrowseNames.CurrentState;
            instance.LimitState.CurrentState.Value      = text;

            instance.LimitState.CurrentState.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Id, state, false);
        }
Beispiel #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AeEventTypeState"/> class.
        /// </summary>
        public AeEventTypeState(EventType eventType, ushort namespaceIndex)
        {
            m_eventType = eventType;

            // create the name for the event type.
            string name = eventType.Description;

            if (!String.IsNullOrEmpty(eventType.ConditionName))
            {
                name = eventType.ConditionName;
            }

            if (!name.EndsWith("Type"))
            {
                if (eventType.EventTypeId == OpcRcw.Ae.Constants.CONDITION_EVENT)
                {
                    name += "AlarmType";
                }
                else
                {
                    name += "EventType";
                }
            }

            // the attributes.
            this.NodeId      = AeParsedNodeId.Construct(eventType, null, namespaceIndex);
            this.BrowseName  = new QualifiedName(name, namespaceIndex);
            this.DisplayName = eventType.Description;
            this.IsAbstract  = false;
            this.SuperTypeId = AeParsedNodeId.Construct(eventType.EventTypeMapping, namespaceIndex);

            // add the attributes as properties.
            if (eventType.Attributes != null)
            {
                for (int ii = 0; ii < eventType.Attributes.Count; ii++)
                {
                    string propertyName = eventType.Attributes[ii].Description;

                    if (AeTypeCache.IsKnownName(propertyName, "ACK COMMENT"))
                    {
                        continue;
                    }

                    PropertyState property = new PropertyState(this);

                    property.SymbolicName            = propertyName;
                    property.ReferenceTypeId         = Opc.Ua.ReferenceTypeIds.HasProperty;
                    property.TypeDefinitionId        = Opc.Ua.VariableTypeIds.PropertyType;
                    property.ModellingRuleId         = Opc.Ua.ObjectIds.ModellingRule_Optional;
                    property.NodeId                  = AeParsedNodeId.Construct(eventType, propertyName, namespaceIndex);
                    property.BrowseName              = new QualifiedName(propertyName, namespaceIndex);
                    property.DisplayName             = property.BrowseName.Name;
                    property.AccessLevel             = AccessLevels.None;
                    property.UserAccessLevel         = AccessLevels.None;
                    property.MinimumSamplingInterval = MinimumSamplingIntervals.Indeterminate;
                    property.Historizing             = false;

                    bool isArray = false;
                    property.DataType  = ComUtils.GetDataTypeId(eventType.Attributes[ii].VarType, out isArray);
                    property.ValueRank = (isArray) ? ValueRanks.OneDimension : ValueRanks.Scalar;

                    this.AddChild(property);
                }
            }
        }
Beispiel #7
0
        /// <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);
        }
        /// <summary>
        /// Uses the recommended names in the AE specification to map to predefined UA event types.
        /// </summary>
        private void DetermineMapping(EventType eventType)
        {
            for (int ii = 0; ii < eventType.Attributes.Count; ii++)
            {
                if (AeTypeCache.IsKnownName(eventType.Attributes[ii].Description, "ACK COMMENT"))
                {
                    eventType.AckComment = eventType.Attributes[ii];
                    break;
                }
            }

            eventType.EventTypeMapping = EventTypeMapping.BaseEventType;

            if (eventType.EventTypeId == OpcRcw.Ae.Constants.SIMPLE_EVENT)
            {
                if (AeTypeCache.IsKnownName(eventType.Description, "Device Failure"))
                {
                    eventType.EventTypeMapping = EventTypeMapping.DeviceFailureEventType;
                    return;
                }

                if (AeTypeCache.IsKnownName(eventType.Description, "System Message"))
                {
                    eventType.EventTypeMapping = EventTypeMapping.SystemEventType;
                    return;
                }

                eventType.EventTypeMapping = EventTypeMapping.BaseEventType;
                return;
            }

            if (eventType.EventTypeId == OpcRcw.Ae.Constants.TRACKING_EVENT)
            {
                eventType.EventTypeMapping = EventTypeMapping.AuditEventType;
                return;
            }

            if (eventType.EventTypeId == OpcRcw.Ae.Constants.CONDITION_EVENT)
            {
                if (eventType.ConditionName == null)
                {
                    eventType.EventTypeMapping = EventTypeMapping.ConditionClassType;
                    return;
                }

                eventType.EventTypeMapping = EventTypeMapping.AlarmConditionType;

                if (AeTypeCache.IsKnownName(eventType.Description, "Level"))
                {
                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "PVLEVEL"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.ExclusiveLevelAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "SPLEVEL"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.ExclusiveLevelAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "HI HI"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "HI"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "LO"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "LO LO"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.NonExclusiveLevelAlarmType;
                        return;
                    }

                    eventType.EventTypeMapping = EventTypeMapping.LimitAlarmType;
                    return;
                }

                if (AeTypeCache.IsKnownName(eventType.Description, "Deviation"))
                {
                    eventType.EventTypeMapping = EventTypeMapping.NonExclusiveDeviationAlarmType;
                    return;
                }

                if (AeTypeCache.IsKnownName(eventType.Description, "Discrete"))
                {
                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "CFN"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.OffNormalAlarmType;
                        return;
                    }

                    if (AeTypeCache.IsKnownName(eventType.ConditionName, "TRIP"))
                    {
                        eventType.EventTypeMapping = EventTypeMapping.TripAlarmType;
                        return;
                    }

                    eventType.EventTypeMapping = EventTypeMapping.DiscreteAlarmType;
                    return;
                }
            }
        }
        /// <summary>
        /// Updates the type cache.
        /// </summary>
        private void DoMetadataUpdate(object state)
        {
            try
            {
                if (!Server.IsRunning)
                {
                    return;
                }

                ComAeClientManager system = (ComAeClientManager)SystemContext.SystemHandle;
                ComAeClient client = (ComAeClient)system.SelectClient(SystemContext, true);

                AeTypeCache cache = new AeTypeCache();
                cache.LoadEventTypes(client);

                lock (Lock)
                {
                    if (m_typeCache == null)
                    {
                        m_typeCache = cache;
                    }

                    m_typeCache.EventTypes = cache.EventTypes;
                    m_typeCache.UpdateCache(SystemContext, NamespaceIndex);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error updating event type cache.");
            }
        }