/// <summary> /// Handles a user response to a dialog. /// </summary> private ServiceResult OnDialogComplete( ISystemContext context, DialogConditionState dialog, DialogConditionChoice response) { if (m_dialog != null) { DeleteNode(SystemContext, m_dialog.NodeId); m_dialog = null; } return ServiceResult.Good; }
/// <summary> /// Peridically checks the system state. /// </summary> private void OnCheckSystemStatus(object state) { #if CONDITION_SAMPLES lock (Lock) { try { // create the dialog. if (m_dialog == null) { m_dialog = new DialogConditionState(null); CreateNode( SystemContext, ExpandedNodeId.ToNodeId(ObjectIds.Data_Conditions, SystemContext.NamespaceUris), ReferenceTypeIds.HasComponent, new QualifiedName("ResetSystemDialog", m_namespaceIndex), m_dialog); m_dialog.OnAfterResponse = OnDialogComplete; } StatusCode systemStatus = m_system.SystemStatus; m_systemStatusCondition.UpdateStatus(systemStatus); // cycle through different status codes in order to simulate a real system. if (StatusCode.IsGood(systemStatus)) { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.Low); m_system.SystemStatus = StatusCodes.Uncertain; } else if (StatusCode.IsUncertain(systemStatus)) { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.Medium); m_system.SystemStatus = StatusCodes.Bad; } else { m_systemStatusCondition.UpdateSeverity((ushort)EventSeverity.High); m_system.SystemStatus = StatusCodes.Good; } // request a reset if status is bad. if (StatusCode.IsBad(systemStatus)) { m_dialog.RequestResponse( SystemContext, "Reset the test system?", (uint)(int)(DialogConditionChoice.Ok | DialogConditionChoice.Cancel), (ushort)EventSeverity.MediumHigh); } // report the event. TranslationInfo info = new TranslationInfo( "TestSystemStatusChange", "en-US", "The TestSystem status is now {0}.", systemStatus); m_systemStatusCondition.ReportConditionChange( SystemContext, null, new LocalizedText(info), false); } catch (Exception e) { Utils.Trace(e, "Unexpected error monitoring system status."); } } #endif }
/// <summary> /// Prompts the user to enter a comment. /// </summary> public int ShowDialog(DialogConditionState dialog) { // set the prompt. PromptLB.Text = Utils.Format("{0}", BaseVariableState.GetValue(dialog.Prompt)); Dictionary<DialogResult,int> resultMapping = new Dictionary<DialogResult, int>(); // configure the buttons. LocalizedText[] options = BaseVariableState.GetValue(dialog.ResponseOptionSet); switch (options.Length) { case 1: { OkBTN.Text = Utils.Format("{0}", options[0]); ButtonsPN.ColumnStyles[0].Width = 50; ButtonsPN.ColumnStyles[1].Width = 0; ButtonsPN.ColumnStyles[2].Width = 0; ButtonsPN.ColumnStyles[3].Width = 0; ButtonsPN.ColumnStyles[4].Width = 50; resultMapping.Add(DialogResult.OK, 0); break; } case 2: { OkBTN.Text = Utils.Format("{0}", options[0]); Response2BTN.Text = Utils.Format("{0}", options[1]); ButtonsPN.ColumnStyles[0].Width = 33; ButtonsPN.ColumnStyles[1].Width = 0; ButtonsPN.ColumnStyles[2].Width = 34; ButtonsPN.ColumnStyles[3].Width = 0; ButtonsPN.ColumnStyles[4].Width = 33; resultMapping.Add(DialogResult.OK, 0); resultMapping.Add(DialogResult.Retry, 1); break; } case 3: { OkBTN.Text = Utils.Format("{0}", options[0]); Response1BTN.Text = Utils.Format("{0}", options[1]); Response3BTN.Text = Utils.Format("{0}", options[2]); ButtonsPN.ColumnStyles[0].Width = 25; ButtonsPN.ColumnStyles[1].Width = 25; ButtonsPN.ColumnStyles[2].Width = 0; ButtonsPN.ColumnStyles[3].Width = 25; ButtonsPN.ColumnStyles[4].Width = 25; resultMapping.Add(DialogResult.OK, 0); resultMapping.Add(DialogResult.Abort, 1); resultMapping.Add(DialogResult.Ignore, 2); break; } case 4: { OkBTN.Text = Utils.Format("{0}", options[0]); Response1BTN.Text = Utils.Format("{0}", options[1]); Response2BTN.Text = Utils.Format("{0}", options[2]); Response3BTN.Text = Utils.Format("{0}", options[3]); ButtonsPN.ColumnStyles[0].Width = 20; ButtonsPN.ColumnStyles[1].Width = 20; ButtonsPN.ColumnStyles[2].Width = 20; ButtonsPN.ColumnStyles[3].Width = 20; ButtonsPN.ColumnStyles[4].Width = 20; resultMapping.Add(DialogResult.OK, 0); resultMapping.Add(DialogResult.Abort, 1); resultMapping.Add(DialogResult.Retry, 2); resultMapping.Add(DialogResult.Ignore, 3); break; } } // display the dialog. DialogResult result = ShowDialog(); // map the response. int selectedResponse = -1; if (!resultMapping.TryGetValue(result, out selectedResponse)) { return -1; } return selectedResponse; }
/// <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. e.Update(session.SystemContext, filter.SelectClauses, notification); // save the orginal notification. e.Handle = notification; return e; }
/// <summary> /// Called when the dialog receives a response. /// </summary> private ServiceResult OnRespond( ISystemContext context, DialogConditionState dialog, int selectedResponse) { // response 0 means set the source online. if (selectedResponse == 0) { m_source.SetOfflineState(false); } // response 1 means set the source offine. if (selectedResponse == 1) { m_source.SetOfflineState(true); } // other responses mean do nothing. dialog.SetResponse(context, selectedResponse); // dialog no longer interesting once it is deactivated. dialog.Message.Value = "The dialog was deactivated"; dialog.Retain.Value = false; return ServiceResult.Good; }
/// <summary> /// Creates a new dialog condition /// </summary> private DialogConditionState CreateDialog(string dialogName) { ISystemContext context = m_nodeManager.SystemContext; DialogConditionState node = new DialogConditionState(this); node.SymbolicName = dialogName; // specify optional fields. 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); // 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. node.Create( context, null, new QualifiedName(dialogName, this.BrowseName.NamespaceIndex), null, true); this.AddChild(node); // initialize event information. node.EventId.Value = Guid.NewGuid().ToByteArray(); 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.LocalTime.Value = Utils.GetTimeZoneInfo(); node.Message.Value = "The dialog was activated"; node.Retain.Value = true; node.SetEnableState(context, true); node.SetSeverity(context, EventSeverity.Low); // initialize the dialog information. node.Prompt.Value = "Please specify a new state for the source."; node.ResponseOptionSet.Value = s_ResponseOptions; node.DefaultResponse.Value = 2; node.CancelResponse.Value = 2; node.OkResponse.Value = 0; // set up method handlers. node.OnRespond = OnRespond; // this flag needs to be set because the underlying system does not produce these events. node.AutoReportStateChanges = true; // activate the dialog. node.Activate(context); // return the new node. return node; }