/// <summary> /// Updates the display with a new value for a monitored variable. /// </summary> private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e); return; } try { EventFieldList notification = e.NotificationValue as EventFieldList; if (notification == null) { return; } // check the type of event. NodeId eventTypeId = FormUtils.FindEventType(monitoredItem, notification); // ignore unknown events. if (NodeId.IsNull(eventTypeId)) { return; } // check for refresh start. if (eventTypeId == ObjectTypeIds.RefreshStartEventType) { ConditionsLV.Items.Clear(); return; } // check for refresh end. if (eventTypeId == ObjectTypeIds.RefreshEndEventType) { return; } // construct the condition object. ConditionState condition = FormUtils.ConstructEvent( m_session, monitoredItem, notification, m_eventTypeMappings) as ConditionState; if (condition == null) { return; } // look for existing entry. ListViewItem item = null; for (int ii = 0; ii < ConditionsLV.Items.Count; ii++) { ConditionState current = (ConditionState)ConditionsLV.Items[ii].Tag; // the combination of a condition and branch id uniquely identify an item in the display. if (current.NodeId == condition.NodeId && BaseVariableState.GetValue(current.BranchId) == BaseVariableState.GetValue(condition.BranchId)) { // match found but watch out for out of order events (async processing can cause this to happen). if (BaseVariableState.GetValue(current.Time) > BaseVariableState.GetValue(condition.Time)) { return; } item = ConditionsLV.Items[ii]; break; } } // create a new entry. if (item == null) { item = new ListViewItem(String.Empty); item.SubItems.Add(String.Empty); // Condition item.SubItems.Add(String.Empty); // Branch item.SubItems.Add(String.Empty); // Type item.SubItems.Add(String.Empty); // Severity item.SubItems.Add(String.Empty); // Time item.SubItems.Add(String.Empty); // State item.SubItems.Add(String.Empty); // Message item.SubItems.Add(String.Empty); // Comment ConditionsLV.Items.Add(item); } // look up the condition type metadata in the local cache. INode type = m_session.NodeCache.Find(condition.TypeDefinitionId); // Source if (condition.SourceName != null) { item.SubItems[0].Text = Utils.Format("{0}", condition.SourceName.Value); } else { item.SubItems[0].Text = null; } // Condition if (condition.ConditionName != null) { item.SubItems[1].Text = Utils.Format("{0}", condition.ConditionName.Value); } else { item.SubItems[1].Text = null; } // Branch if (condition.BranchId != null && !NodeId.IsNull(condition.BranchId.Value)) { item.SubItems[2].Text = Utils.Format("{0}", condition.BranchId.Value); } else { item.SubItems[2].Text = null; } // Type if (type != null) { item.SubItems[3].Text = Utils.Format("{0}", type); } else { item.SubItems[3].Text = null; } // Severity if (condition.Severity != null) { item.SubItems[4].Text = Utils.Format("{0}", (EventSeverity)condition.Severity.Value); } else { item.SubItems[4].Text = null; } // Time if (condition.Time != null) { item.SubItems[5].Text = Utils.Format("{0:HH:mm:ss.fff}", condition.Time.Value.ToLocalTime()); } else { item.SubItems[5].Text = null; } // State if (condition.EnabledState != null && condition.EnabledState.EffectiveDisplayName != null) { item.SubItems[6].Text = Utils.Format("{0}", condition.EnabledState.EffectiveDisplayName.Value); } else { item.SubItems[6].Text = null; } // Message if (condition.Message != null) { item.SubItems[7].Text = Utils.Format("{0}", condition.Message.Value); } else { item.SubItems[7].Text = null; } // Comment if (condition.Comment != null) { item.SubItems[8].Text = Utils.Format("{0}", condition.Comment.Value); } else { item.SubItems[8].Text = null; } item.Tag = condition; // set the color based on the retain bit. if (!BaseVariableState.GetValue(condition.Retain)) { item.ForeColor = Color.DimGray; } else { if (NodeId.IsNull(BaseVariableState.GetValue(condition.BranchId))) { item.ForeColor = Color.Empty; } else { item.ForeColor = Color.DarkGray; } } // adjust the width of the columns. for (int ii = 0; ii < ConditionsLV.Columns.Count; ii++) { ConditionsLV.Columns[ii].Width = -2; } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <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); }
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> /// Updates the display with a new value for a monitored variable. /// </summary> private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e); return; } try { EventFieldList notification = e.NotificationValue as EventFieldList; if (notification == null) { return; } // check the type of event. NodeId eventTypeId = FormUtils.FindEventType(monitoredItem, notification); // ignore unknown events. if (NodeId.IsNull(eventTypeId)) { return; } // construct the audit object. AuditUpdateMethodEventState audit = FormUtils.ConstructEvent( m_session, monitoredItem, notification, m_eventTypeMappings) as AuditUpdateMethodEventState; if (audit == null) { return; } ListViewItem item = new ListViewItem(String.Empty); item.SubItems.Add(String.Empty); // Source item.SubItems.Add(String.Empty); // Type item.SubItems.Add(String.Empty); // Method item.SubItems.Add(String.Empty); // Status item.SubItems.Add(String.Empty); // Time item.SubItems.Add(String.Empty); // Message item.SubItems.Add(String.Empty); // Arguments // look up the condition type metadata in the local cache. INode type = m_session.NodeCache.Find(audit.TypeDefinitionId); // Source if (audit.SourceName != null) { item.SubItems[0].Text = Utils.Format("{0}", audit.SourceName.Value); } else { item.SubItems[0].Text = null; } // Type if (type != null) { item.SubItems[1].Text = Utils.Format("{0}", type); } else { item.SubItems[1].Text = null; } // look up the method metadata in the local cache. INode method = m_session.NodeCache.Find(BaseVariableState.GetValue(audit.MethodId)); // Method if (method != null) { item.SubItems[2].Text = Utils.Format("{0}", method); } else { item.SubItems[2].Text = null; } // Status if (audit.Status != null) { item.SubItems[3].Text = Utils.Format("{0}", audit.Status.Value); } else { item.SubItems[3].Text = null; } // Time if (audit.Time != null) { item.SubItems[4].Text = Utils.Format("{0:HH:mm:ss.fff}", audit.Time.Value.ToLocalTime()); } else { item.SubItems[4].Text = null; } // Message if (audit.Message != null) { item.SubItems[5].Text = Utils.Format("{0}", audit.Message.Value); } else { item.SubItems[5].Text = null; } // Arguments if (audit.InputArguments != null) { item.SubItems[6].Text = Utils.Format("{0}", new Variant(audit.InputArguments.Value)); } else { item.SubItems[6].Text = null; } item.Tag = audit; EventsLV.Items.Add(item); // adjust the width of the columns. for (int ii = 0; ii < EventsLV.Columns.Count; ii++) { EventsLV.Columns[ii].Width = -2; } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Updates the display with a new value for a monitored variable. /// </summary> private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e); return; } try { EventFieldList notification = e.NotificationValue as EventFieldList; if (notification == null) { return; } // check the type of event. NodeId eventTypeId = FormUtils.FindEventType(monitoredItem, notification); // ignore unknown events. if (NodeId.IsNull(eventTypeId)) { return; } // check for refresh start. if (eventTypeId == ObjectTypeIds.RefreshStartEventType) { ConditionsLV.Items.Clear(); return; } // check for refresh end. if (eventTypeId == ObjectTypeIds.RefreshEndEventType) { return; } // construct the condition object. ConditionState condition = FormUtils.ConstructEvent( m_session, monitoredItem, notification, m_eventTypeMappings) as ConditionState; if (condition == null) { return; } ListViewItem item = null; item = new ListViewItem(String.Empty); item.SubItems.Add(String.Empty); // Condition item.SubItems.Add(String.Empty); // Branch item.SubItems.Add(String.Empty); // Type item.SubItems.Add(String.Empty); // Severity item.SubItems.Add(String.Empty); // Time item.SubItems.Add(String.Empty); // State item.SubItems.Add(String.Empty); // Message item.SubItems.Add(String.Empty); // Comment //ConditionsLV.Items.Add(item); // look up the condition type metadata in the local cache. INode type = m_session.NodeCache.Find(condition.TypeDefinitionId); // Source if (condition.SourceName != null) { item.SubItems[0].Text = Utils.Format("{0}", condition.SourceName.Value); } else { item.SubItems[0].Text = null; } // Condition if (condition.ConditionName != null) { item.SubItems[1].Text = Utils.Format("{0}", condition.ConditionName.Value); } else { item.SubItems[1].Text = null; } // Branch if (condition.BranchId != null && !NodeId.IsNull(condition.BranchId.Value)) { item.SubItems[2].Text = Utils.Format("{0}", condition.BranchId.Value); } else { item.SubItems[2].Text = null; } // Type if (type != null) { item.SubItems[3].Text = Utils.Format("{0}", type); } else { item.SubItems[3].Text = null; } // Severity if (condition.Severity != null) { item.SubItems[4].Text = Utils.Format("{0}", (EventSeverity)condition.Severity.Value); } else { item.SubItems[4].Text = null; } // Time if (condition.Time != null) { item.SubItems[5].Text = Utils.Format("{0:HH:mm:ss.fff}", condition.Time.Value.ToLocalTime()); } else { item.SubItems[5].Text = null; } // State if (condition.EnabledState != null && condition.EnabledState.EffectiveDisplayName != null) { item.SubItems[6].Text = Utils.Format("{0}", condition.EnabledState.EffectiveDisplayName.Value); } else { item.SubItems[6].Text = null; } // Message if (condition.Message != null) { item.SubItems[7].Text = Utils.Format("{0}", condition.Message.Value); } else { item.SubItems[7].Text = null; } // Comment if (condition.Comment != null) { item.SubItems[8].Text = Utils.Format("{0}", condition.Comment.Value); } else { item.SubItems[8].Text = null; } item.Tag = condition; // set the color based on the retain bit. if (!BaseVariableState.GetValue(condition.Retain)) { item.ForeColor = Color.DimGray; } else { if (NodeId.IsNull(BaseVariableState.GetValue(condition.BranchId))) { item.ForeColor = Color.Empty; } else { item.ForeColor = Color.DarkGray; } } //ConditionsLV.Items.Add(item); ConditionsLV.Items.Insert(0, item); // adjust the width of the columns. if (this.ColumnAutoAdjust) { for (int ii = 0; ii < ConditionsLV.Columns.Count; ii++) { ConditionsLV.Columns[ii].Width = -2; } } //TODO: Add this as a menu option //ConditionsLV.EnsureVisible(ConditionsLV.Items.Count -1); while (ConditionsLV.Items.Count > MaximumItems) { ConditionsLV.Items.RemoveAt(ConditionsLV.Items.Count - 1); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }