/// <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); }
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); }
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); } }
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; } }
/// <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); }
/// <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); }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); } }
/// <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); }
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); }
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); }
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}"); } }
/// <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); }
protected override void SetActive(BaseEventState baseEvent, bool activeState) { AlarmConditionState alarm = GetAlarm(baseEvent); alarm.SetActiveState(SystemContext, activeState); }
/// <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; } }
/// <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); } }
/// <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); } }
/// <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); }