예제 #1
0
        /// <summary>
        /// Creates an instance of an event.
        /// </summary>
        public BaseEventState CreateInstance(ServerSystemContext context, AeEventTypeState eventType)
        {
            BaseEventState instance = null;

            switch (eventType.EventType.EventTypeMapping)
            {
            case EventTypeMapping.AlarmConditionType: { instance = new AlarmConditionState(null); break; }

            case EventTypeMapping.AuditEventType: { instance = new AuditEventState(null); break; }

            case EventTypeMapping.BaseEventType: { instance = new BaseEventState(null); break; }

            case EventTypeMapping.DeviceFailureEventType: { instance = new DeviceFailureEventState(null); break; }

            case EventTypeMapping.DiscreteAlarmType: { instance = new DiscreteAlarmState(null); break; }

            case EventTypeMapping.NonExclusiveDeviationAlarmType: { instance = new NonExclusiveDeviationAlarmState(null); break; }

            case EventTypeMapping.ExclusiveLevelAlarmType: { instance = new ExclusiveLevelAlarmState(null); break; }

            case EventTypeMapping.LimitAlarmType: { instance = new LimitAlarmState(null); break; }

            case EventTypeMapping.NonExclusiveLevelAlarmType: { instance = new NonExclusiveLevelAlarmState(null); break; }

            case EventTypeMapping.OffNormalAlarmType: { instance = new OffNormalAlarmState(null); break; }

            case EventTypeMapping.SystemEventType: { instance = new SystemEventState(null); break; }

            case EventTypeMapping.TripAlarmType: { instance = new TripAlarmState(null); break; }
            }

            return(instance);
        }
예제 #2
0
        private ServiceResult OnShelve(
            ISystemContext context,
            AlarmConditionState alarm,
            bool shelving,
            bool oneShot,
            double shelvingTime)
        {
            string shelved = "Shelved";
            string dueTo   = "";

            if (shelving)
            {
                if (oneShot)
                {
                    dueTo = " due to OneShotShelve";
                }
                else
                {
                    dueTo = " due to TimedShelve of " + shelvingTime.ToString();
                }
            }
            else
            {
                shelved = "Unshelved";
            }

            alarm.Message.Value = "The alarm is " + shelved + dueTo;
            alarm.SetShelvingState(context, shelving, oneShot, shelvingTime);

            return(ServiceResult.Good);
        }
예제 #3
0
        public override void SetValue(string message = "")
        {
            bool setValue             = false;
            AlarmConditionState alarm = GetAlarm();


            if (ShouldEvent())
            {
                alarm.SetActiveState(SystemContext, IsActive());

                setValue = true;
            }

            if (UpdateSuppression())
            {
                if (message.Length <= 0)
                {
                    message = "Updating due to Shelving State Update: " + alarm.ShelvingState.CurrentState.Value.ToString();
                }
                setValue = true;
            }
            else if (UpdateSuppression())
            {
                if (message.Length <= 0)
                {
                    message = "Updating due to Suppression Update: " + alarm.SuppressedState.Value.ToString();
                }
                setValue = true;
            }

            if (setValue)
            {
                base.SetValue(message);
            }
        }
예제 #4
0
        protected override bool GetRetainState()
        {
            AlarmConditionState alarm = GetAlarm();

            bool retainState = true;

            if (!alarm.ActiveState.Id.Value)
            {
                if (alarm.AckedState.Id.Value)
                {
                    if ((Optional))
                    {
                        if (alarm.ConfirmedState.Id.Value)
                        {
                            retainState = false;
                        }
                    }
                    else
                    {
                        retainState = false;
                    }
                }
            }

            return(retainState);
        }
        private void UpdateAlarm(ConditionState node, SimAlarmStateBackend alarm, string eventId = null)
        {
            ISystemContext context = _nodeManager.SystemContext;

            // remove old event.
            if (node.EventId.Value != null)
            {
                _events.Remove(Utils.ToHexString(node.EventId.Value));
            }

            node.EventId.Value = eventId != null?Encoding.UTF8.GetBytes(eventId) : Guid.NewGuid().ToByteArray();

            node.Time.Value        = DateTime.UtcNow;
            node.ReceiveTime.Value = node.Time.Value;

            // save the event for later lookup.
            _events[Utils.ToHexString(node.EventId.Value)] = node;

            // determine the retain state.
            node.Retain.Value = true;

            if (alarm != null)
            {
                node.Time.Value    = alarm.Time;
                node.Message.Value = new LocalizedText(alarm.Reason);
                node.SetComment(context, alarm.Comment, alarm.UserName);
                node.SetSeverity(context, alarm.Severity);
                node.EnabledState.TransitionTime.Value = alarm.EnableTime;
                node.SetEnableState(context, (alarm.State & SimConditionStatesEnum.Enabled) != 0);

                if (node is AlarmConditionState)
                {
                    AlarmConditionState nodeAlarm = (AlarmConditionState)node;
                    nodeAlarm.SetAcknowledgedState(context, (alarm.State & SimConditionStatesEnum.Acknowledged) != 0);
                    nodeAlarm.SetConfirmedState(context, (alarm.State & SimConditionStatesEnum.Confirmed) != 0);
                    nodeAlarm.SetActiveState(context, (alarm.State & SimConditionStatesEnum.Active) != 0);
                    nodeAlarm.SetSuppressedState(context, (alarm.State & SimConditionStatesEnum.Suppressed) != 0);
                    nodeAlarm.ActiveState.TransitionTime.Value = alarm.ActiveTime;
                    // not interested in inactive alarms
                    if (!nodeAlarm.ActiveState.Id.Value)
                    {
                        nodeAlarm.Retain.Value = false;
                    }
                }
            }
            // check for deleted items.
            if ((alarm.State & SimConditionStatesEnum.Deleted) != 0)
            {
                node.Retain.Value = false;
            }

            // not interested in disabled alarms.
            if (!node.EnabledState.Id.Value)
            {
                node.Retain.Value = false;
            }
        }
예제 #6
0
        /// <summary>
        /// Called when the alarm is shelved.
        /// </summary>
        private ServiceResult OnTimedUnshelve(
            ISystemContext context,
            AlarmConditionState alarm)
        {
            // update the alarm state and produce and event.
            alarm.Message.Value = "The timed shelving period expired.";
            alarm.SetShelvingState(context, false, false, 0);

            base.SetValue(alarm.Message.Value.Text);

            return(ServiceResult.Good);
        }
예제 #7
0
        /// <summary>
        /// Called when the alarm is shelved.
        /// </summary>
        private ServiceResult OnTimedUnshelve(
            ISystemContext context,
            AlarmConditionState alarm)
        {
            // update the alarm state and produce and event.
            alarm.SetShelvingState(context, false, false, 0);
            alarm.Message.Value = "The timed shelving period expired.";

            UpdateAlarm(alarm, null);
            ReportChanges(alarm);

            return(ServiceResult.Good);
        }
예제 #8
0
        /// <summary>
        /// Called when the alarm is shelved.
        /// </summary>
        private ServiceResult OnShelve(
            ISystemContext context,
            AlarmConditionState alarm,
            bool shelving,
            bool oneShot,
            double shelvingTime)
        {
            alarm.SetShelvingState(context, shelving, oneShot, shelvingTime);
            alarm.Message.Value = "The alarm shelved.";

            UpdateAlarm(alarm, null);
            ReportChanges(alarm);

            return(ServiceResult.Good);
        }
예제 #9
0
        /// <summary>
        /// Reports the changes to the alarm.
        /// </summary>
        private void ReportChanges(AlarmConditionState alarm)
        {
            // report changes to node attributes.
            alarm.ClearChangeMasks(m_nodeManager.SystemContext, true);

            // check if events are being monitored for the source.
            if (this.AreEventsMonitored)
            {
                // create a snapshot.
                InstanceStateSnapshot e = new InstanceStateSnapshot();
                e.Initialize(m_nodeManager.SystemContext, alarm);

                // report the event.
                alarm.ReportEvent(m_nodeManager.SystemContext, e);
            }
        }
예제 #10
0
        /// <summary>
        /// Finds the alarm by event id.
        /// </summary>
        /// <param name="eventId">The event id.</param>
        /// <returns>The alarm. Null if not found.</returns>
        private AlarmConditionState FindAlarmByEventId(byte[] eventId)
        {
            if (eventId == null)
            {
                return(null);
            }

            AlarmConditionState alarm = null;

            if (!m_events.TryGetValue(Utils.ToHexString(eventId), out alarm))
            {
                return(null);
            }

            return(alarm);
        }
        private void CreateAlarmSpecificElements(ISystemContext context, AlarmConditionState node, NodeId branchId)
        {
            node.ConfirmedState = new TwoStateVariableState(node);
            node.Confirm        = new AddCommentMethodState(node);

            if (NodeId.IsNull(branchId))
            {
                node.SuppressedState = new TwoStateVariableState(node);
                node.ShelvingState   = new ShelvedStateMachineState(node);
            }

            node.ActiveState = new TwoStateVariableState(node);
            node.ActiveState.TransitionTime       = new PropertyState <DateTime>(node.ActiveState);
            node.ActiveState.EffectiveDisplayName = new PropertyState <LocalizedText>(node.ActiveState);
            node.ActiveState.Create(context, null, BrowseNames.ActiveState, null, false);
        }
예제 #12
0
        /// <summary>
        /// Called when the alarm is confirmed.
        /// </summary>
        private ServiceResult OnConfirm(
            ISystemContext context,
            ConditionState condition,
            byte[] eventId,
            LocalizedText comment)
        {
            AlarmConditionState alarm = FindAlarmByEventId(eventId);

            if (alarm == null)
            {
                return(StatusCodes.BadEventIdUnknown);
            }

            m_source.ConfirmAlarm(alarm.SymbolicName, GetRecordNumber(alarm), comment, GetUserName(context));

            return(ServiceResult.Good);
        }
예제 #13
0
        /// <summary>
        /// Called when the state of an alarm for the source has changed.
        /// </summary>
        private void OnAlarmChanged(UnderlyingSystemAlarm alarm)
        {
            lock (m_nodeManager.Lock)
            {
                // ignore archived alarms for now.
                if (alarm.RecordNumber != 0)
                {
                    NodeId branchId = new NodeId(alarm.RecordNumber, this.NodeId.NamespaceIndex);

                    // find the alarm branch.
                    AlarmConditionState branch = null;

                    if (!m_branches.TryGetValue(alarm.Name, out branch))
                    {
                        m_branches[branchId] = branch = CreateAlarm(alarm, branchId);
                    }

                    // map the system information to the UA defined alarm.
                    UpdateAlarm(branch, alarm);
                    ReportChanges(branch);

                    // delete the branch.
                    if ((alarm.State & UnderlyingSystemAlarmStates.Deleted) != 0)
                    {
                        m_branches.Remove(branchId);
                    }

                    return;
                }

                // find the alarm node.
                AlarmConditionState node = null;

                if (!m_alarms.TryGetValue(alarm.Name, out node))
                {
                    m_alarms[alarm.Name] = node = CreateAlarm(alarm, null);
                }

                // map the system information to the UA defined alarm.
                UpdateAlarm(node, alarm);
                ReportChanges(node);
            }
        }
예제 #14
0
        /// <summary>
        /// Gets the record number associated with tge alarm.
        /// </summary>
        /// <param name="alarm">The alarm.</param>
        /// <returns>The record number; 0 if the alarm is not an archived alarm.</returns>
        private uint GetRecordNumber(AlarmConditionState alarm)
        {
            if (alarm == null)
            {
                return(0);
            }

            if (alarm.BranchId == null || alarm.BranchId.Value == null)
            {
                return(0);
            }

            uint?recordNumber = alarm.BranchId.Value.Identifier as uint?;

            if (recordNumber != null)
            {
                return(recordNumber.Value);
            }

            return(0);
        }
예제 #15
0
        protected override bool UpdateSuppression()
        {
            bool update = false;

            if (Optional)
            {
                AlarmConditionState alarm = GetAlarm();

                if (m_alarmController.ShouldSuppress())
                {
                    alarm.SetSuppressedState(SystemContext, true);
                    update = true;
                }

                if (m_alarmController.ShouldUnsuppress())
                {
                    alarm.SetSuppressedState(SystemContext, false);
                    update = true;
                }
            }
            return(update);
        }
예제 #16
0
        public void Initialize(
            uint alarmTypeIdentifier,
            string name,
            double maxTimeShelved = AlarmDefines.NORMAL_MAX_TIME_SHELVED)
        {
            // Create an alarm and trigger name - Create a base method for creating the trigger, just provide the name

            if (m_alarm == null)
            {
                m_alarm = new AlarmConditionState(m_parent);
            }

            AlarmConditionState alarm = GetAlarm();

            if (Optional)
            {
                if (alarm.SuppressedState == null)
                {
                    alarm.SuppressedState = new TwoStateVariableState(alarm);
                }


                if (alarm.OutOfServiceState == null)
                {
                    alarm.OutOfServiceState = new TwoStateVariableState(alarm);
                }

                if (alarm.ShelvingState == null)
                {
                    alarm.ShelvingState = new ShelvedStateMachineState(alarm);
                    alarm.ShelvingState.Create(SystemContext,
                                               null,
                                               BrowseNames.ShelvingState,
                                               BrowseNames.ShelvingState,
                                               false);
                }
                if (alarm.MaxTimeShelved == null)
                {
                    // Off normal does not create MaxTimeShelved.
                    alarm.MaxTimeShelved = new PropertyState <double>(alarm);
                }
            }


            // Call the base class to set parameters
            base.Initialize(alarmTypeIdentifier, name);

            alarm.SetActiveState(SystemContext, active: false);
            alarm.InputNode.Value = new NodeId(m_trigger.NodeId);

            if (Optional)
            {
                alarm.SetSuppressedState(SystemContext, suppressed: false);
                alarm.SetShelvingState(SystemContext, shelved: false, oneShot: false, shelvingTime: Double.MaxValue);
                alarm.ShelvingState.LastTransition.Value    = new LocalizedText("");
                alarm.ShelvingState.LastTransition.Id.Value = 0;

                alarm.OnShelve               = OnShelve;
                alarm.OnTimedUnshelve        = OnTimedUnshelve;
                alarm.UnshelveTimeUpdateRate = 2000;

                alarm.MaxTimeShelved.Value = maxTimeShelved;

                alarm.LatchedState.Value    = new LocalizedText("");
                alarm.LatchedState.Id.Value = false;
            }
            else
            {
                alarm.ShelvingState = null;
                alarm.LatchedState  = null;
            }

            alarm.AudibleSound   = null;
            alarm.AudibleEnabled = null;
        }
        private ConditionState CreateAlarmOrCondition(SimAlarmStateBackend alarm, NodeId branchId)
        {
            ISystemContext context = _nodeManager.SystemContext;

            ConditionState node;

            // Condition
            if (alarm.AlarmType == AlarmObjectStates.ConditionType)
            {
                node = new ConditionState(this);
            }
            // All alarms inherent from AlarmConditionState
            else
            {
                switch (alarm.AlarmType)
                {
                case AlarmObjectStates.TripAlarmType:
                    node = new TripAlarmState(this);
                    break;

                case AlarmObjectStates.LimitAlarmType:
                    node = new LimitAlarmState(this);
                    break;

                case AlarmObjectStates.OffNormalAlarmType:
                    node = new OffNormalAlarmState(this);
                    break;

                default:
                    node = new AlarmConditionState(this);
                    break;
                }

                // create elements that conditiontype doesn't have
                CreateAlarmSpecificElements(context, (AlarmConditionState)node, branchId);
            }

            CreateCommonFieldsForAlarmAndCondition(context, node, alarm, branchId);

            // This call initializes the condition from the type model (i.e. creates all of the objects
            // and variables requried to store its state). The information about the type model was
            // incorporated into the class when the class was created.
            //
            // This method also assigns new NodeIds to all of the components by calling the INodeIdFactory.New
            // method on the INodeIdFactory object which is part of the system context. The NodeManager provides
            // the INodeIdFactory implementation used here.
            node.Create(
                context,
                null,
                new QualifiedName(alarm.Name, this.BrowseName.NamespaceIndex),
                null,
                true);

            // initialize event information.node
            node.EventType.Value     = node.TypeDefinitionId;
            node.SourceNode.Value    = this.NodeId;
            node.SourceName.Value    = this.SymbolicName;
            node.ConditionName.Value = node.SymbolicName;
            node.Time.Value          = DateTime.UtcNow;
            node.ReceiveTime.Value   = node.Time.Value;
            node.BranchId.Value      = branchId;

            // don't add branches to the address space.
            if (NodeId.IsNull(branchId))
            {
                this.AddChild(node);
            }

            return(node);
        }
예제 #18
0
        private void MonitorMethodUpdateNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                if (!(e.NotificationValue is EventFieldList notification))
                {
                    return;
                }
                NodeId eventTypeId = null;
                if (!(monitoredItem.Status.Filter is EventFilter filter))
                {
                    return;
                }
                for (int index = 0; index < filter.SelectClauses.Count; index++)
                {
                    SimpleAttributeOperand simpleAttributeOperand = filter.SelectClauses[index];
                    if (simpleAttributeOperand.BrowsePath.Count != 1 ||
                        simpleAttributeOperand.BrowsePath[0] != BrowseNames.EventType)
                    {
                        continue;
                    }
                    eventTypeId = notification.EventFields[index].Value as NodeId;
                }

                // look up the known event type.
                Dictionary <NodeId, NodeId> eventTypeMappings = new Dictionary <NodeId, NodeId>();
                if (eventTypeId == null || NodeId.IsNull(eventTypeId))
                {
                    return;
                }
                if (!eventTypeMappings.TryGetValue(eventTypeId, out NodeId knownTypeId))
                {
                    // check for a known type
                    if (KnownEventTypes.Any(nodeId => nodeId == eventTypeId))
                    {
                        knownTypeId = eventTypeId;
                        eventTypeMappings.Add(eventTypeId, eventTypeId);
                    }

                    // browse for the supertypes of the event type.
                    if (knownTypeId == null)
                    {
                        ReferenceDescriptionCollection supertypes = new ReferenceDescriptionCollection();
                        // find all of the children of the field.
                        BrowseDescription nodeToBrowse = new BrowseDescription
                        {
                            NodeId          = eventTypeId,
                            BrowseDirection = BrowseDirection.Inverse,
                            ReferenceTypeId = ReferenceTypeIds.HasSubtype,
                            IncludeSubtypes = false, // more efficient to use IncludeSubtypes=False when possible.
                            NodeClassMask   = 0,     // the HasSubtype reference already restricts the targets to Types.
                            ResultMask      = (uint)BrowseResultMask.All
                        };

                        ReferenceDescriptionCollection
                            references = _applicationInstanceManager.Browse(nodeToBrowse);
                        while (references != null && references.Count > 0)
                        {
                            // should never be more than one supertype.
                            supertypes.Add(references[0]);
                            // only follow references within this server.
                            if (references[0].NodeId.IsAbsolute)
                            {
                                break;
                            }

                            // get the references for the next level up.
                            nodeToBrowse.NodeId = (NodeId)references[0].NodeId;
                            references          = _applicationInstanceManager.Browse(nodeToBrowse);
                        }

                        // find the first super type that matches a known event type.
                        foreach (ReferenceDescription referenceDescription in supertypes)
                        {
                            foreach (NodeId nodeId in KnownEventTypes)
                            {
                                if (nodeId != referenceDescription.NodeId)
                                {
                                    continue;
                                }
                                knownTypeId = nodeId;
                                eventTypeMappings.Add(eventTypeId, knownTypeId);
                                break;
                            }

                            if (knownTypeId != null)
                            {
                                break;
                            }
                        }
                    }
                }

                if (knownTypeId == null)
                {
                    return;
                }
                // all of the known event types have a UInt32 as identifier.
                uint?id = knownTypeId.Identifier as uint?;
                if (id == null)
                {
                    return;
                }
                // construct the event based on the known event type.
                BaseEventState baseEventState = null;

                switch (id.Value)
                {
                case ObjectTypes.ConditionType:
                {
                    baseEventState = new ConditionState(null);
                    break;
                }

                case ObjectTypes.DialogConditionType:
                {
                    baseEventState = new DialogConditionState(null);
                    break;
                }

                case ObjectTypes.AlarmConditionType:
                {
                    baseEventState = new AlarmConditionState(null);
                    break;
                }

                case ObjectTypes.ExclusiveLimitAlarmType:
                {
                    baseEventState = new ExclusiveLimitAlarmState(null);
                    break;
                }

                case ObjectTypes.NonExclusiveLimitAlarmType:
                {
                    baseEventState = new NonExclusiveLimitAlarmState(null);
                    break;
                }

                case ObjectTypes.AuditEventType:
                {
                    baseEventState = new AuditEventState(null);
                    break;
                }

                case ObjectTypes.AuditUpdateMethodEventType:
                {
                    baseEventState = new AuditUpdateMethodEventState(null);
                    break;
                }

                default:
                {
                    baseEventState = new BaseEventState(null);
                    break;
                }
                }

                // get the filter which defines the contents of the notification.
                filter = monitoredItem.Status.Filter as EventFilter;
                // initialize the event with the values in the notification.
                baseEventState.Update(_applicationInstanceManager.Session.SystemContext, filter.SelectClauses,
                                      notification);
                // save the original notification.
                baseEventState.Handle = notification;
                // construct the audit object.
                if (baseEventState is AuditUpdateMethodEventState audit)
                {
                    // look up the condition type metadata in the local cache.
                    string sourceName = "";
                    if (audit.SourceName.Value != null)
                    {
                        sourceName = Utils.Format("{0}", audit.SourceName.Value);
                    }
                    string type = "";
                    if (audit.TypeDefinitionId != null)
                    {
                        type = Utils.Format("{0}",
                                            _applicationInstanceManager.Session.NodeCache.Find(audit.TypeDefinitionId));
                    }

                    string method = "";
                    if (audit.MethodId != null)
                    {
                        method = Utils.Format("{0}",
                                              _applicationInstanceManager.Session.NodeCache.Find(
                                                  BaseVariableState.GetValue(audit.MethodId)));
                    }

                    string status = "";
                    if (audit.Status != null)
                    {
                        status = Utils.Format("{0}", audit.Status.Value);
                    }

                    string time = "";
                    if (audit.Time != null)
                    {
                        time = Utils.Format("{0:HH:mm:ss.fff}", audit.Time.Value.ToLocalTime());
                    }

                    string message = "";
                    if (audit.Message != null)
                    {
                        message = Utils.Format("{0}", audit.Message.Value);
                    }

                    string inputArguments = "";
                    if (audit.InputArguments != null)
                    {
                        inputArguments = Utils.Format("{0}", new Variant(audit.InputArguments.Value));
                    }


                    InformationDisplay(
                        $"sourceName: {sourceName}, type:{type}, method:{method}, status:{status}, time:{time}, message:{message}, inputArguments:{inputArguments}");
                }
            }
            catch (Exception ex)
            {
                InformationDisplay($"Monitored Item Notification exception: {ex.StackTrace}");
            }
        }
예제 #19
0
        /// <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="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, NodeId> eventTypeMappings)
        {
            // find the event type.
            var eventTypeId = FindEventType(monitoredItem, notification);

            if (eventTypeId == null)
            {
                return(null);
            }

            // look up the known event type.
            NodeId knownTypeId;

            if (!eventTypeMappings.TryGetValue(eventTypeId, out knownTypeId))
            {
                // check for a known type
                if (KnownEventTypes.Any(t => t == eventTypeId))
                {
                    knownTypeId = eventTypeId;
                    eventTypeMappings.Add(eventTypeId, eventTypeId);
                }

                // browse for the supertypes of the event type.
                if (knownTypeId == null)
                {
                    var supertypes = 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.
                    foreach (var t in supertypes)
                    {
                        foreach (var nodeId in KnownEventTypes)
                        {
                            if (nodeId == t.NodeId)
                            {
                                knownTypeId = nodeId;
                                eventTypeMappings.Add(eventTypeId, knownTypeId);
                                break;
                            }
                        }

                        if (knownTypeId != null)
                        {
                            break;
                        }
                    }
                }
            }

            if (knownTypeId == null)
            {
                return(null);
            }

            // all of the known event types have a UInt32 as identifier.
            var id = knownTypeId.Identifier as uint?;

            if (id == null)
            {
                return(null);
            }

            // construct the event based on the known event type.
            BaseEventState e;

            switch (id.Value)
            {
            case ObjectTypes.ConditionType: { e = new ConditionState(null); break; }

            case ObjectTypes.DialogConditionType: { e = new DialogConditionState(null); break; }

            case ObjectTypes.AlarmConditionType: { e = new AlarmConditionState(null); break; }

            case ObjectTypes.ExclusiveLimitAlarmType: { e = new ExclusiveLimitAlarmState(null); break; }

            case ObjectTypes.NonExclusiveLimitAlarmType: { e = new NonExclusiveLimitAlarmState(null); break; }

            case ObjectTypes.AuditEventType: { e = new AuditEventState(null); break; }

            case ObjectTypes.AuditUpdateMethodEventType: { e = new AuditUpdateMethodEventState(null); break; }

            default:
            {
                e = new BaseEventState(null);
                break;
            }
            }

            // get the filter which defines the contents of the notification.
            var filter = monitoredItem.Status.Filter as EventFilter;

            // initialize the event with the values in the notification.
            if (filter != null)
            {
                e.Update(session.SystemContext, filter.SelectClauses, notification);
            }

            // save the orginal notification.
            e.Handle = notification;
            return(e);
        }
예제 #20
0
        protected override void SetActive(BaseEventState baseEvent, bool activeState)
        {
            AlarmConditionState alarm = GetAlarm(baseEvent);

            alarm.SetActiveState(SystemContext, activeState);
        }
예제 #21
0
        /// <summary>
        /// Updates the alarm with a new state.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="alarm">The alarm.</param>
        private void UpdateAlarm(AlarmConditionState node, UnderlyingSystemAlarm alarm)
        {
            ISystemContext context = m_nodeManager.SystemContext;

            // remove old event.
            if (node.EventId.Value != null)
            {
                m_events.Remove(Utils.ToHexString(node.EventId.Value));
            }

            // update the basic event information (include generating a unique id for the event).
            node.EventId.Value     = Guid.NewGuid().ToByteArray();
            node.Time.Value        = DateTime.UtcNow;
            node.ReceiveTime.Value = node.Time.Value;

            // save the event for later lookup.
            m_events[Utils.ToHexString(node.EventId.Value)] = node;

            // determine the retain state.
            node.Retain.Value = true;

            if (alarm != null)
            {
                node.Time.Value    = alarm.Time;
                node.Message.Value = new LocalizedText(alarm.Reason);

                // update the states.
                node.SetEnableState(context, (alarm.State & UnderlyingSystemAlarmStates.Enabled) != 0);
                node.SetAcknowledgedState(context, (alarm.State & UnderlyingSystemAlarmStates.Acknowledged) != 0);
                node.SetConfirmedState(context, (alarm.State & UnderlyingSystemAlarmStates.Confirmed) != 0);
                node.SetActiveState(context, (alarm.State & UnderlyingSystemAlarmStates.Active) != 0);
                node.SetSuppressedState(context, (alarm.State & UnderlyingSystemAlarmStates.Suppressed) != 0);

                // update other information.
                node.SetComment(context, alarm.Comment, alarm.UserName);
                node.SetSeverity(context, alarm.Severity);

                node.EnabledState.TransitionTime.Value = alarm.EnableTime;
                node.ActiveState.TransitionTime.Value  = alarm.ActiveTime;

                // check for deleted items.
                if ((alarm.State & UnderlyingSystemAlarmStates.Deleted) != 0)
                {
                    node.Retain.Value = false;
                }

                // handle high alarms.
                ExclusiveLimitAlarmState highAlarm = node as ExclusiveLimitAlarmState;

                if (highAlarm != null)
                {
                    highAlarm.HighLimit.Value = alarm.Limits[0];

                    if ((alarm.State & UnderlyingSystemAlarmStates.High) != 0)
                    {
                        highAlarm.SetLimitState(context, LimitAlarmStates.High);
                    }
                }

                // handle high-low alarms.
                NonExclusiveLimitAlarmState highLowAlarm = node as NonExclusiveLimitAlarmState;

                if (highLowAlarm != null)
                {
                    highLowAlarm.HighHighLimit.Value = alarm.Limits[0];
                    highLowAlarm.HighLimit.Value     = alarm.Limits[1];
                    highLowAlarm.LowLimit.Value      = alarm.Limits[2];
                    highLowAlarm.LowLowLimit.Value   = alarm.Limits[3];

                    LimitAlarmStates limit = LimitAlarmStates.Inactive;

                    if ((alarm.State & UnderlyingSystemAlarmStates.HighHigh) != 0)
                    {
                        limit |= LimitAlarmStates.HighHigh;
                    }

                    if ((alarm.State & UnderlyingSystemAlarmStates.High) != 0)
                    {
                        limit |= LimitAlarmStates.High;
                    }

                    if ((alarm.State & UnderlyingSystemAlarmStates.Low) != 0)
                    {
                        limit |= LimitAlarmStates.Low;
                    }

                    if ((alarm.State & UnderlyingSystemAlarmStates.LowLow) != 0)
                    {
                        limit |= LimitAlarmStates.LowLow;
                    }

                    highLowAlarm.SetLimitState(context, limit);
                }
            }

            // not interested in disabled or inactive alarms.
            if (!node.EnabledState.Id.Value || !node.ActiveState.Id.Value)
            {
                node.Retain.Value = false;
            }
        }
예제 #22
0
        /// <summary>
        /// Creates a new alarm for the source.
        /// </summary>
        /// <param name="alarm">The alarm.</param>
        /// <param name="branchId">The branch id.</param>
        /// <returns>The new alarm.</returns>
        private AlarmConditionState CreateAlarm(UnderlyingSystemAlarm alarm, NodeId branchId)
        {
            ISystemContext context = m_nodeManager.SystemContext;

            AlarmConditionState node = null;

            // need to map the alarm type to a UA defined alarm type.
            switch (alarm.AlarmType)
            {
            case "HighAlarm":
            {
                ExclusiveDeviationAlarmState node2 = new ExclusiveDeviationAlarmState(this);
                node            = node2;
                node2.HighLimit = new PropertyState <double>(node2);
                break;
            }

            case "HighLowAlarm":
            {
                NonExclusiveLevelAlarmState node2 = new NonExclusiveLevelAlarmState(this);
                node = node2;

                node2.HighHighLimit = new PropertyState <double>(node2);
                node2.HighLimit     = new PropertyState <double>(node2);
                node2.LowLimit      = new PropertyState <double>(node2);
                node2.LowLowLimit   = new PropertyState <double>(node2);

                node2.HighHighState = new TwoStateVariableState(node2);
                node2.HighState     = new TwoStateVariableState(node2);
                node2.LowState      = new TwoStateVariableState(node2);
                node2.LowLowState   = new TwoStateVariableState(node2);

                break;
            }

            case "TripAlarm":
            {
                node = new TripAlarmState(this);
                break;
            }

            default:
            {
                node = new AlarmConditionState(this);
                break;
            }
            }

            node.SymbolicName = alarm.Name;

            // add optional components.
            node.Comment        = new ConditionVariableState <LocalizedText>(node);
            node.ClientUserId   = new PropertyState <string>(node);
            node.AddComment     = new AddCommentMethodState(node);
            node.ConfirmedState = new TwoStateVariableState(node);
            node.Confirm        = new AddCommentMethodState(node);

            if (NodeId.IsNull(branchId))
            {
                node.SuppressedState = new TwoStateVariableState(node);
                node.ShelvingState   = new ShelvedStateMachineState(node);
            }

            // adding optional components to children is a little more complicated since the
            // necessary initilization strings defined by the class that represents the child.
            // in this case we pre-create the child, add the optional components
            // and call create without assigning NodeIds. The NodeIds will be assigned when the
            // parent object is created.
            node.EnabledState = new TwoStateVariableState(node);
            node.EnabledState.TransitionTime       = new PropertyState <DateTime>(node.EnabledState);
            node.EnabledState.EffectiveDisplayName = new PropertyState <LocalizedText>(node.EnabledState);
            node.EnabledState.Create(context, null, BrowseNames.EnabledState, null, false);

            // same procedure add optional components to the ActiveState component.
            node.ActiveState = new TwoStateVariableState(node);
            node.ActiveState.TransitionTime       = new PropertyState <DateTime>(node.ActiveState);
            node.ActiveState.EffectiveDisplayName = new PropertyState <LocalizedText>(node.ActiveState);
            node.ActiveState.Create(context, null, BrowseNames.ActiveState, null, false);

            // specify reference type between the source and the alarm.
            node.ReferenceTypeId = ReferenceTypeIds.HasComponent;

            // This call initializes the condition from the type model (i.e. creates all of the objects
            // and variables requried to store its state). The information about the type model was
            // incorporated into the class when the class was created.
            //
            // This method also assigns new NodeIds to all of the components by calling the INodeIdFactory.New
            // method on the INodeIdFactory object which is part of the system context. The NodeManager provides
            // the INodeIdFactory implementation used here.
            node.Create(
                context,
                null,
                new QualifiedName(alarm.Name, this.BrowseName.NamespaceIndex),
                null,
                true);

            // don't add branches to the address space.
            if (NodeId.IsNull(branchId))
            {
                this.AddChild(node);
            }

            // initialize event information.node
            node.EventType.Value     = node.TypeDefinitionId;
            node.SourceNode.Value    = this.NodeId;
            node.SourceName.Value    = this.SymbolicName;
            node.ConditionName.Value = node.SymbolicName;
            node.Time.Value          = DateTime.UtcNow;
            node.ReceiveTime.Value   = node.Time.Value;
            node.BranchId.Value      = branchId;

            // set up method handlers.
            node.OnEnableDisable = OnEnableDisableAlarm;
            node.OnAcknowledge   = OnAcknowledge;
            node.OnAddComment    = OnAddComment;
            node.OnConfirm       = OnConfirm;
            node.OnShelve        = OnShelve;
            node.OnTimedUnshelve = OnTimedUnshelve;

            // return the new node.
            return(node);
        }
        /// <summary>
        /// Does any initialization required before the address space can be used.
        /// </summary>
        /// <remarks>
        /// The externalReferences is an out parameter that allows the node manager to link to nodes
        /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and
        /// should have a reference to the root folder node(s) exposed by this node manager.
        /// </remarks>
        public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            lock (Lock)
            {
                // check if the type model needs to be loaded.
                if (NamespaceIndexes.Length > 1)
                {
                    LoadPredefinedNodes(SystemContext, externalReferences);
                }

                IList <IReference> references = null;

                // create the root node.
                string serverName = m_configuration.ServerName;

                if (String.IsNullOrEmpty(serverName))
                {
                    serverName = "ComAeServer";
                }

                AeAreaState root = new AeAreaState(SystemContext, String.Empty, serverName, NamespaceIndex);
                root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder);

                // link root to objects folder.
                if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references))
                {
                    externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>();
                }

                references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId));

                // link root to server object.
                if (!externalReferences.TryGetValue(ObjectIds.Server, out references))
                {
                    externalReferences[ObjectIds.Server] = references = new List <IReference>();
                }

                references.Add(new NodeStateReference(ReferenceTypeIds.HasNotifier, false, root.NodeId));

                // create the status node.
                ComServerStatusState status = new ComServerStatusState(root);
                status.ReferenceTypeId = ReferenceTypeIds.Organizes;

                // get the type namepace for the browse name.
                int typeNamepaceIndex = Server.NamespaceUris.GetIndex(Namespaces.ComInterop);

                if (typeNamepaceIndex < 0)
                {
                    typeNamepaceIndex = NamespaceIndex;
                }

                status.Create(
                    SystemContext,
                    AeModelUtils.ConstructIdForInternalNode("ServerStatus", NamespaceIndex),
                    new QualifiedName("ServerStatus", (ushort)typeNamepaceIndex),
                    null,
                    true);

                root.AddChild(status);

                // store root folder in the pre-defined nodes.
                AddPredefinedNode(SystemContext, root);
                AddRootNotifier(root);

                // create the COM server.
                m_system.Initialize(SystemContext, m_configuration, status, Lock, OnServerReconnected);

                // create a template condition that can be used to initialize static metadata.
                m_templateAlarm = new AlarmConditionState(null);
                m_templateAlarm.SymbolicName = "TemplateAlarm";

                m_templateAlarm.Create(
                    SystemContext,
                    null,
                    new QualifiedName(m_templateAlarm.SymbolicName, NamespaceIndex),
                    null,
                    false);

                m_templateAlarm.Acknowledge.OnCall = OnAcknowledge;
                StartMetadataUpdates(DoMetadataUpdate, null, 5000, m_configuration.MaxReconnectWait);
            }
        }
예제 #24
0
        /// <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);
            }
        }
예제 #25
0
        /// <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="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, NodeId> eventTypeMappings)
        {
            // find the event type.
            NodeId eventTypeId = FindEventType(monitoredItem, notification);

            if (eventTypeId == null)
            {
                return(null);
            }

            // look up the known event type.
            NodeId knownTypeId = null;

            if (!eventTypeMappings.TryGetValue(eventTypeId, out knownTypeId))
            {
                // check for a known type
                for (int jj = 0; jj < KnownEventTypes.Length; jj++)
                {
                    if (KnownEventTypes[jj] == eventTypeId)
                    {
                        knownTypeId = eventTypeId;
                        eventTypeMappings.Add(eventTypeId, eventTypeId);
                        break;
                    }
                }

                // browse for the supertypes of the event type.
                if (knownTypeId == null)
                {
                    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++)
                    {
                        for (int jj = 0; jj < KnownEventTypes.Length; jj++)
                        {
                            if (KnownEventTypes[jj] == supertypes[ii].NodeId)
                            {
                                knownTypeId = KnownEventTypes[jj];
                                eventTypeMappings.Add(eventTypeId, knownTypeId);
                                break;
                            }
                        }

                        if (knownTypeId != null)
                        {
                            break;
                        }
                    }
                }
            }

            if (knownTypeId == null)
            {
                return(null);
            }

            // all of the known event types have a UInt32 as identifier.
            uint?id = knownTypeId.Identifier as uint?;

            if (id == null)
            {
                return(null);
            }

            // construct the event based on the known event type.
            BaseEventState e = null;

            switch (id.Value)
            {
            case ObjectTypes.ConditionType: { e = new ConditionState(null); break; }

            case ObjectTypes.DialogConditionType: { e = new DialogConditionState(null); break; }

            case ObjectTypes.AlarmConditionType: { e = new AlarmConditionState(null); break; }

            case ObjectTypes.ExclusiveLimitAlarmType: { e = new ExclusiveLimitAlarmState(null); break; }

            case ObjectTypes.NonExclusiveLimitAlarmType: { e = new NonExclusiveLimitAlarmState(null); break; }

            case ObjectTypes.AuditEventType: { e = new AuditEventState(null); break; }

            case ObjectTypes.AuditUpdateMethodEventType: { e = new AuditUpdateMethodEventState(null); break; }

            default:
            {
                e = new BaseEventState(null);
                break;
            }
            }

            // 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.
            if (session is null)
            {
                return(null);
            }
            e.Update(session.SystemContext, filter.SelectClauses, notification);

            // save the orginal notification.
            e.Handle = notification;

            return(e);
        }