public void RemoveMonitoredItem(List <uint> chList) { try { var miList = new List <MonitoredItem>(); foreach (var ch in chList) { foreach (var mi in subscription.MonitoredItems) { if (mi.ClientHandle == ch) { miList.Add(mi); break; } } } subscription.RemoveItems(miList); subscription.ApplyChanges(); if (subscription.MonitoredItemCount == 0) { if (!session.RemoveSubscription(subscription)) { throw new Exception("Removing subscription was failed."); } } } catch (Exception ex) { MessagePassing(ex); Close(); } }
private MonitoredItem AddMonitorItem(NodeId startNodeId, Opc.Ua.EventFilter eventFilter) { var monitorItem = CreateMonitoredItem(startNodeId, eventFilter); monitorItem.Notification += MonitorItem_Notification; _subscription.AddItem(monitorItem); _subscription.ApplyChanges(); monitorItem.Subscription.ConditionRefresh(); return(monitorItem); }
/// <summary> /// /// </summary> public void Close() { foreach (Form form in m_Forms) { form.Close(); } m_Forms.Clear(); foreach (ListViewItem lvi in listView1.Items) { RemoveSessionItem(lvi, false); } m_Subscription.ApplyChanges(); m_Session.RemoveSubscription(m_Subscription); }
private void Subscribe(NodeId[] nodeIds) { var monItems = new List <MonitoredItem>(); var newNodeIds = new List <NodeId>(); lock (_subscribedValues) { for (int i = 0; i < nodeIds.Length; i++) { if (!_subscribedValues.ContainsKey(nodeIds[i])) { var monitoredItem = CreateMonitoredItem(nodeIds[i]); monitoredItem.Notification += MonitoredItem_Notification; monItems.Add(monitoredItem); newNodeIds.Add(nodeIds[i]); _subscribedValues.Add(nodeIds[i], new VariableValue(monitoredItem) { LastRead = DateTimeOffset.UtcNow, Value = new DataValue(Variant.Null) }); } } } if (monItems.Count > 0) { // Force read of current value. InitializeNodeValues(nodeIds); _logger.LogInformation("Subscribing to {0} data values", monItems.Count); _subscription.AddItems(monItems); _subscription.ApplyChanges(); } }
public void RemoveMonitoredItem(Subscription subscription, string monitoredItemNodeId) { var tmp = subscription.MonitoredItems.FirstOrDefault(x => x.StartNodeId.ToString() == monitoredItemNodeId); subscription.RemoveItem(tmp); subscription.ApplyChanges(); }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { m_subscription = new Subscription(); m_subscription.Handle = this; m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = m_areaId; m_monitoredItem.AttributeId = Attributes.EventNotifier; m_monitoredItem.SamplingInterval = 0; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; ChangeFilter(m_filter, false); m_monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
public void CreateMonitoredItem(NodeId nodeId) { if (m_session != null) { Subscription subscription = m_session.DefaultSubscription; if (m_session.AddSubscription(subscription)) { subscription.Create(); } // add the new monitored item. MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.StartNodeId = nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.DisplayName = nodeId.Identifier.ToString(); monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.SamplingInterval = 0; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Notification += MonitoredItem_Notification; subscription.AddItem(monitoredItem); subscription.ApplyChanges(); } }
public void CreateMonitoredItem( Session session, Subscription subscription, NodeId nodeId, MonitoringMode mode) { if (subscription == null) { subscription = session.DefaultSubscription; if (session.AddSubscription(subscription)) { subscription.Create(); } } else { session.AddSubscription(subscription); } // add the new monitored item. MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.StartNodeId = nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.DisplayName = nodeId.Identifier.ToString(); monitoredItem.MonitoringMode = mode; monitoredItem.SamplingInterval = mode == MonitoringMode.Sampling ? 1000 : 0; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); subscription.AddItem(monitoredItem); subscription.ApplyChanges(); }
/// <summary> /// Initializes a new instance of the <see cref="AuditEventForm"/> class. /// </summary> /// <param name="session">The session.</param> /// <param name="subscription">The subscription.</param> public AuditEventForm(Session session, Subscription subscription) { InitializeComponent(); m_session = session; m_subscription = subscription; // a table used to track event types. m_eventTypeMappings = new Dictionary <NodeId, NodeId>(); // the filter to use. m_filter = new FilterDefinition(); m_filter.AreaId = ObjectIds.Server; m_filter.Severity = EventSeverity.Min; m_filter.IgnoreSuppressedOrShelved = true; m_filter.EventTypes = new NodeId[] { ObjectTypeIds.AuditUpdateMethodEventType }; // find the fields of interest. m_filter.SelectClauses = m_filter.ConstructSelectClauses(m_session, ObjectTypeIds.AuditUpdateMethodEventType); // declate callback. m_MonitoredItem_Notification = new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); // create a monitored item based on the current filter settings. m_monitoredItem = m_filter.CreateMonitoredItem(m_session); // set up callback for notifications. m_monitoredItem.Notification += m_MonitoredItem_Notification; m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
public void DeleteMonitoredItem(uint subscriptionId, uint clientHandle) { Subscription sub = GetSubscription(subscriptionId); sub.RemoveItem(sub.FindItemByClientHandle(clientHandle)); sub.ApplyChanges(); }
/// <summary> /// Adds a item to a subscription. /// </summary> public void Subscribe(Subscription subscription, ReferenceDescription reference) { MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.DisplayName = subscription.Session.NodeCache.GetDisplayText(reference); monitoredItem.StartNodeId = (NodeId)reference.NodeId; monitoredItem.NodeClass = (NodeClass)reference.NodeClass; monitoredItem.AttributeId = Attributes.Value; monitoredItem.SamplingInterval = 0; monitoredItem.QueueSize = 1; // add condition fields to any event filter. EventFilter filter = monitoredItem.Filter as EventFilter; if (filter != null) { monitoredItem.AttributeId = Attributes.EventNotifier; monitoredItem.QueueSize = 0; } subscription.AddItem(monitoredItem); subscription.ApplyChanges(); // raise event. if (m_monitorEvent != null) { MonitorEventArgs args = new MonitorEventArgs(subscription, monitoredItem); m_monitorEvent(this, args); } }
void StartMonitoring() { foreach (var item in MonitoredMeasurements) { var nodeId = OpcUaHelper.FindNode(item.Path, ObjectIds.ObjectsFolder, l_session); var sub = new Subscription { PublishingInterval = item.MonitorResolution, PublishingEnabled = true, LifetimeCount = 0, KeepAliveCount = 0, DisplayName = item.Path, Priority = byte.MaxValue }; MonitoredItem monitoredItem = new MonitoredItem() { StartNodeId = nodeId, AttributeId = Attributes.Value, DisplayName = item.Name, SamplingInterval = item.MonitorResolution }; sub.AddItem(monitoredItem); l_session.AddSubscription(sub); sub.Create(); sub.ApplyChanges(); monitoredItem.Notification += (monitored, args) => { var p = (MonitoredItemNotification)args.NotificationValue; MonitorData(item, p.Value); }; } }
/// <summary> /// Moves the grid to the next state. /// </summary> public void Next() { if (m_state == DisplayState.ViewUpdates) { return; } SetDisplayState(++m_state); // clear any selection. foreach (DataGridViewRow row in ResultsDV.Rows) { row.Selected = false; } if (m_subscription != null) { // apply any changes. if (m_state == DisplayState.ApplyChanges) { m_subscription.ApplyChanges(); foreach (DataRow row in m_dataset.Tables[0].Rows) { MonitoredItem monitoredItem = (MonitoredItem)row[0]; UpdateRow(row, monitoredItem.Status); } } } }
public void SubscribedMonitoredItems(ICollection <MonitoredItem> items) { if (_subscription == null || !_subscription.Created) { return; } if (items == null || !items.Any()) { return; } if (_callback != null) { foreach (var monitoredItem in items) { monitoredItem.Notification += _callback.Invoke; } } try { _subscription.AddItems(items); _subscription.ApplyChanges(); } catch (ServiceResultException ex) { if (ex.StatusCode == StatusCodes.BadRequestTimeout) { SysLog.Warn("BadRequestTimeout error message reported from server."); } else { SysLog.Warn("Error reported from server. Message: ", ex); OnCheckConnectionTimerOnElapsed(this, new EventArgs() as ElapsedEventArgs); } } catch (Exception ex) { SysLog.Error("Unexpected error.", ex); OnCheckConnectionTimerOnElapsed(this, new EventArgs() as ElapsedEventArgs); } finally { SetCurrentListMonitoredItemsSubscribed(items); } }
private void subscribeToolStripMenuItem_Click(object sender, EventArgs e) { try { GetTanks(); if (m_session == null) { return; } if (m_subscription != null) { m_session.RemoveSubscription(m_subscription); m_subscription = null; } if (m_subscription == null) { m_subscription = new Subscription(); m_subscription.PublishingEnabled = true; m_subscription.PublishingInterval = 1000; m_subscription.Priority = 1; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 20; m_subscription.MaxNotificationsPerPublish = 1000; m_session.AddSubscription(m_subscription); m_subscription.Create(); } if (monitoredItem == null) { monitoredItem = new MonitoredItem(m_subscription.DefaultItem); monitoredItem.StartNodeId = monitoredItem.AttributeId = Attributes.Value; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.SamplingInterval = 1000; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; // define event handler for this item, and then add to subscription monitoredItem.Notification += new MonitoredItemNotificationEventHandler(monitoredItem_Notification); m_subscription.AddItem(monitoredItem); } m_subscription.ApplyChanges(); if (outputWindow == null) { outputWindow = new SubscriptionOutput(); } } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
private void StartArchive(object parameter) { var interval = SelectedArchiveInfo.ArchiveInterval; if (interval == ArchiveInterval.None) { //_subscription.PublishingEnabled = true; _subscription.SetMonitoringMode(MonitoringMode.Reporting, _subscription.MonitoredItems.ToList()); _subscription.ApplyChanges(); } else { var timer = new Timer(Archive, interval, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds((int)interval)); _timers.Add(interval, timer); } SelectedArchiveInfo.Running = true; }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { if (m_session == null) { return; } m_subscription = new Subscription(); m_subscription.Handle = this; m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = m_nodeId; m_monitoredItem.AttributeId = Attributes.Value; m_monitoredItem.SamplingInterval = (int)SamplingIntervalNP.Value; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; // specify aggregate filter. if (AggregateCB.SelectedItem != null) { AggregateFilter filter = new AggregateFilter(); if (StartTimeCK.Checked) { filter.StartTime = StartTimeDP.Value.ToUniversalTime(); } else { filter.StartTime = DateTime.UtcNow; } filter.ProcessingInterval = (double)ResampleIntervalNP.Value; filter.AggregateType = ((AvailableAggregate)AggregateCB.SelectedItem).NodeId; if (filter.AggregateType != null) { m_monitoredItem.Filter = filter; } } m_monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); SubscriptionStateChanged(); }
/// <summary> /// Handles the Click event of the Browse_MonitorMI control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void Browse_MonitorMI_Click(object sender, EventArgs e) { try { // check if operation is currently allowed. if (m_session == null || BrowseNodesTV.SelectedNode == null) { return; } // can only subscribe to local variables. ReferenceDescription reference = (ReferenceDescription)BrowseNodesTV.SelectedNode.Tag; if (reference.NodeId.IsAbsolute || reference.NodeClass != NodeClass.Variable) { return; } ListViewItem item = CreateMonitoredItem((NodeId)reference.NodeId, Utils.Format("{0}", reference)); m_subscription.ApplyChanges(); MonitoredItem monitoredItem = (MonitoredItem)item.Tag; if (ServiceResult.IsBad(monitoredItem.Status.Error)) { item.SubItems[8].Text = monitoredItem.Status.Error.StatusCode.ToString(); } item.SubItems.Add(monitoredItem.DisplayName); item.SubItems[1].Text = monitoredItem.MonitoringMode.ToString(); item.SubItems[2].Text = monitoredItem.SamplingInterval.ToString(); item.SubItems[3].Text = DeadbandFilterToText(monitoredItem.Filter); MonitoredItemsLV.Columns[0].Width = -2; MonitoredItemsLV.Columns[1].Width = -2; MonitoredItemsLV.Columns[8].Width = -2; } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Monitor the specified tag for changes /// </summary> /// <typeparam name="T">the type of tag to monitor</typeparam> /// <param name="tag">The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name. /// E.g: the tag `foo.bar` monitors the tag `bar` on the folder `foo`</param> /// <param name="callback">the callback to execute when the value is changed. /// The first parameter is a MonitorEvent object which represents the data point, the second is an `unsubscribe` function to unsubscribe the callback</param> public void Monitor <T>(string tag, Action <ReadEvent <T>, Action> callback) { var node = FindNode(tag); var sub = new Subscription { PublishingInterval = _options.DefaultMonitorInterval, PublishingEnabled = true, LifetimeCount = _options.SubscriptionLifetimeCount, KeepAliveCount = _options.SubscriptionKeepAliveCount, DisplayName = tag, Priority = byte.MaxValue }; var item = new MonitoredItem { StartNodeId = node.NodeId, AttributeId = Attributes.Value, DisplayName = tag, SamplingInterval = _options.DefaultMonitorInterval }; sub.AddItem(item); _session.AddSubscription(sub); sub.Create(); sub.ApplyChanges(); item.Notification += (monitoredItem, args) => { var p = (MonitoredItemNotification)args.NotificationValue; var t = p.Value.WrappedValue.Value; Action unsubscribe = () => { sub.RemoveItems(sub.MonitoredItems); sub.Delete(true); _session.RemoveSubscription(sub); sub.Dispose(); }; var monitorEvent = new ReadEvent <T>(); monitorEvent.Value = (T)t; monitorEvent.SourceTimestamp = p.Value.SourceTimestamp; monitorEvent.ServerTimestamp = p.Value.ServerTimestamp; if (StatusCode.IsGood(p.Value.StatusCode)) { monitorEvent.Quality = Quality.Good; } if (StatusCode.IsBad(p.Value.StatusCode)) { monitorEvent.Quality = Quality.Bad; } callback(monitorEvent, unsubscribe); }; }
public void AddItem(string name, bool requestEvent) { var newMonitoredItem = new MonitoredItem(subscription.DefaultItem, true) { DisplayName = name, StartNodeId = new NodeId(name, NAMESPACE), MonitoringMode = requestEvent ? MonitoringMode.Reporting : MonitoringMode.Sampling }; nodeNameHandle.Add(name, newMonitoredItem.ClientHandle); subscription.AddItem(newMonitoredItem); subscription.ApplyChanges(); }
/// <summary> /// Creates a subscription to a monitored item on an OPC UA server /// </summary> public static void CreateMonitoredItem(NodeLookup nodeLookup) { // find the right session using our lookup Session matchingSession = null; foreach (Session session in m_sessions) { char[] trimChars = { '/', ' ' }; if (session.Endpoint.EndpointUrl.TrimEnd(trimChars).Equals(nodeLookup.EndPointURL.ToString().TrimEnd(trimChars), StringComparison.OrdinalIgnoreCase)) { matchingSession = session; break; } } if (matchingSession != null) { Subscription subscription = matchingSession.DefaultSubscription; if (matchingSession.AddSubscription(subscription)) { subscription.Create(); } // get the DisplayName for the node. Node node = matchingSession.ReadNode(nodeLookup.NodeID); string nodeDisplayName = node.DisplayName.Text; if (String.IsNullOrEmpty(nodeDisplayName)) { nodeDisplayName = nodeLookup.NodeID.Identifier.ToString(); } // add the new monitored item. MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.StartNodeId = nodeLookup.NodeID; monitoredItem.AttributeId = Attributes.Value; monitoredItem.DisplayName = nodeDisplayName; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.SamplingInterval = 1000; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); subscription.AddItem(monitoredItem); subscription.ApplyChanges(); } else { Trace("ERROR: Could not find endpoint URL " + nodeLookup.EndPointURL.ToString() + " in active server sessions, NodeID " + nodeLookup.NodeID.Identifier.ToString() + " NOT published!"); Trace("To fix this, please update your publishednodes.json file with the updated endpoint URL!"); } }
/// <summary> /// Apply any changes to the set of items. /// </summary> public void ApplyChanges() { if (m_subscription != null) { m_subscription.ApplyChanges(); foreach (ListViewItem listItem in ItemsLV.Items) { UpdateItem(listItem, listItem.Tag); } AdjustColumns(); } }
/// <summary> /// Updates the items with the current filter. /// </summary> private void UpdateItems() { List <FilterDeclarationField> fields = new List <FilterDeclarationField>(); foreach (FilterDeclarationField field in m_filter.Fields) { // only keep fields that are used. if (field.Selected || field.FilterEnabled) { fields.Add(field); continue; } // add mandatory fields. switch (field.InstanceDeclaration.BrowsePathDisplayText) { case Opc.Ua.BrowseNames.EventId: case Opc.Ua.BrowseNames.EventType: case Opc.Ua.BrowseNames.Time: { field.Selected = true; fields.Add(field); break; } } } m_filter.Fields = fields; // construct filter. EventFilter filter = m_filter.GetFilter(); // update items. for (int ii = 0; ii < m_dataset.Tables[0].Rows.Count; ii++) { MonitoredItem monitoredItem = (MonitoredItem)m_dataset.Tables[0].Rows[ii][0]; monitoredItem.Filter = filter; } // apply changes. m_subscription.ApplyChanges(); // show results. for (int ii = 0; ii < m_dataset.Tables[0].Rows.Count; ii++) { DataRow row = m_dataset.Tables[0].Rows[ii]; MonitoredItem monitoredItem = (MonitoredItem)row[0]; UpdateRow(row, monitoredItem.Status); } }
private void addItemToSubscription(DataItem aItem) { var lMonitoredItem = new MonitoredItem(mSubscription.DefaultItem); lMonitoredItem.StartNodeId = aItem.mNodeId; lMonitoredItem.AttributeId = Attributes.Value; lMonitoredItem.MonitoringMode = MonitoringMode.Reporting; lMonitoredItem.SamplingInterval = aItem.mSampling; lMonitoredItem.QueueSize = 1; lMonitoredItem.DiscardOldest = true; lMonitoredItem.Handle = aItem; aItem.mClientHandle = lMonitoredItem.ClientHandle; mSubscription.AddItem(lMonitoredItem); mSubscription.ApplyChanges(); if (lMonitoredItem.Status.Error != null && StatusCode.IsBad(lMonitoredItem.Status.Error.StatusCode)) { lMonitoredItem.Handle = null; mSubscription.RemoveItem(lMonitoredItem); mSubscription.ApplyChanges(); throw new InvalidOperationException("Creation of data monitored item failed. "); } }
/// <summary> /// Monitor a value from server /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tag"></param> /// <param name="callback"></param> public void MonitorValue <T>(string tag, Action <T, Action> callback) { var node = new NodeId(tag); var sub = new Subscription { PublishingInterval = 0, PublishingEnabled = true, LifetimeCount = 0, KeepAliveCount = 0, DisplayName = tag, Priority = byte.MaxValue }; var item = new MonitoredItem { StartNodeId = node, AttributeId = Attributes.Value, DisplayName = tag, SamplingInterval = 100 }; sub.AddItem(item); m_session.AddSubscription(sub); sub.Create(); sub.ApplyChanges(); item.Notification += (monitoredItem, args) => { var notification = (MonitoredItemNotification)args.NotificationValue; if (notification == null) { return; //如果为空就退出 } var t = notification.Value.WrappedValue.Value; Action unsubscribe = () => { sub.RemoveItems(sub.MonitoredItems); sub.Delete(true); m_session.RemoveSubscription(sub); sub.Dispose(); }; callback?.Invoke((T)t, unsubscribe); }; }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { // create the default subscription. m_subscription = new Subscription(); m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); // a table used to track event types. m_eventTypeMappings = new Dictionary <NodeId, NodeId>(); NodeId knownEventId = ExpandedNodeId.ToNodeId(ObjectTypeIds.SystemCycleStatusEventType, m_session.NamespaceUris); m_knownEventTypes = new Dictionary <NodeId, Type>(); m_knownEventTypes.Add(knownEventId, typeof(SystemCycleStatusEventState)); TypeDeclaration type = new TypeDeclaration(); type.NodeId = ExpandedNodeId.ToNodeId(ObjectTypeIds.SystemCycleStatusEventType, m_session.NamespaceUris); type.Declarations = ClientUtils.CollectInstanceDeclarationsForType(m_session, type.NodeId); // the filter to use. m_filter = new FilterDeclaration(type, null); // declate callback. m_MonitoredItem_Notification = new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); // create a monitored item based on the current filter settings. m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = Opc.Ua.ObjectIds.Server; m_monitoredItem.AttributeId = Attributes.EventNotifier; m_monitoredItem.SamplingInterval = 0; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; m_monitoredItem.Filter = m_filter.GetFilter(); // set up callback for notifications. m_monitoredItem.Notification += m_MonitoredItem_Notification; m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
/// <summary>Monitor a value from server</summary> /// <typeparam name="T"></typeparam> /// <param name="tag"></param> /// <param name="callback"></param> public void MonitorValue <T>(string tag, Action <T, Action> callback) { NodeId nodeId = new NodeId(tag); Subscription sub = new Subscription() { PublishingInterval = 0, PublishingEnabled = true, LifetimeCount = 0, KeepAliveCount = 0, DisplayName = tag, Priority = byte.MaxValue }; MonitoredItem monitoredItem1 = new MonitoredItem() { StartNodeId = nodeId, AttributeId = 13, DisplayName = tag, SamplingInterval = 100 }; sub.AddItem(monitoredItem1); this.m_session.AddSubscription(sub); sub.Create(); sub.ApplyChanges(); monitoredItem1.Notification += (MonitoredItemNotificationEventHandler)((monitoredItem, args) => { MonitoredItemNotification notificationValue = (MonitoredItemNotification)args.NotificationValue; if (notificationValue == null) { return; } object obj1 = notificationValue.Value.WrappedValue.Value; Action action1 = (Action)(() => { sub.RemoveItems(sub.MonitoredItems); sub.Delete(true); this.m_session.RemoveSubscription(sub); sub.Dispose(); }); Action <T, Action> action2 = callback; if (action2 == null) { return; } T obj2 = (T)obj1; Action action3 = action1; action2(obj2, action3); }); }
public static bool CreateMonitoredItem(NodeId nodeId, Session session, MonitoredItemNotificationEventHandler handler) { if (session != null) { // access the default subscription, add it to the session and only create it if successful Subscription subscription = session.DefaultSubscription; if (session.AddSubscription(subscription)) { subscription.Create(); } // add the new monitored item. MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); if (monitoredItem != null) { // Set monitored item attributes // StartNodeId = NodeId to be monitored // AttributeId = which attribute of the node to monitor (in this case the value) // MonitoringMode = When sampling is enabled, the Server samples the item. // In addition, each sample is evaluated to determine if // a Notification should be generated. If so, the // Notification is queued. If reporting is enabled, // the queue is made available to the Subscription for transfer monitoredItem.StartNodeId = nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.DisplayName = nodeId.Identifier.ToString(); monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.SamplingInterval = 0; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Notification += handler; subscription.AddItem(monitoredItem); subscription.ApplyChanges(); return(true); } else { Trace("Error: Could not create monitored item!"); } } else { Trace("Argument error: Session is null!"); } return(false); }
/// <summary> /// Changes the area monitored by the control. /// </summary> public void ChangeArea(NodeId areaId, bool fetchRecent) { m_areaId = areaId; EventsLV.Items.Clear(); if (fetchRecent) { ReadRecentHistory(); } if (m_subscription != null) { MonitoredItem monitoredItem = new MonitoredItem(m_monitoredItem); monitoredItem.StartNodeId = areaId; m_subscription.AddItem(monitoredItem); m_subscription.RemoveItem(m_monitoredItem); m_monitoredItem = monitoredItem; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.ApplyChanges(); } }
public bool AddMonitoredItem(MonitoredItem monitoredItem, Subscription subscription) { try { subscription.AddItem(monitoredItem); subscription.ApplyChanges(); return(true); } catch (Exception e) { Utils.Trace(Utils.TraceMasks.Error, $"{e.Message}"); } return(false); }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { if (m_session == null) { return; } m_subscription = new Subscription(); m_subscription.Handle = this; m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = m_nodeId; m_monitoredItem.AttributeId = Attributes.Value; m_monitoredItem.SamplingInterval = (int)SamplingIntervalNP.Value; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; // specify aggregate filter. if (AggregateCB.SelectedItem != null) { AggregateFilter filter = new AggregateFilter(); if (StartTimeCK.Checked) { filter.StartTime = StartTimeDP.Value.ToUniversalTime(); } else { filter.StartTime = DateTime.UtcNow; } filter.ProcessingInterval = (double)ResampleIntervalNP.Value; filter.AggregateType = ((AvailableAggregate)AggregateCB.SelectedItem).NodeId; if (filter.AggregateType != null) { m_monitoredItem.Filter = filter; } } m_monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); SubscriptionStateChanged(); }
public void CreateMonitoredItem( Session session, Subscription subscription, NodeId nodeId, MonitoringMode mode) { if (subscription == null) { subscription = session.DefaultSubscription; if (session.AddSubscription(subscription)) subscription.Create(); } else { session.AddSubscription(subscription); } // add the new monitored item. MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.StartNodeId = nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.DisplayName = nodeId.Identifier.ToString(); monitoredItem.MonitoringMode = mode; monitoredItem.SamplingInterval = mode == MonitoringMode.Sampling ? 1000 : 0; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Notification += MonitoredItem_Notification; subscription.AddItem(monitoredItem); subscription.ApplyChanges(); }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { if (m_session == null) { return; } m_subscription = new Subscription(); m_subscription.Handle = this; m_subscription.DisplayName = null; m_subscription.PublishingInterval = 500; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = m_nodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.SamplingInterval = 1000; monitoredItem.QueueSize = 1000; monitoredItem.DiscardOldest = true; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(monitoredItem); m_subscription.ApplyChanges(); // verify that the item was created successfully. if (ServiceResult.IsBad(monitoredItem.Status.Error)) { throw new ServiceResultException(monitoredItem.Status.Error); } }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { // create the default subscription. m_subscription = new Subscription(); m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); // a table used to track event types. m_eventTypeMappings = new Dictionary<NodeId, NodeId>(); NodeId knownEventId = ExpandedNodeId.ToNodeId(ObjectTypeIds.SystemCycleStatusEventType, m_session.NamespaceUris); m_knownEventTypes = new Dictionary<NodeId, Type>(); m_knownEventTypes.Add(knownEventId, typeof(SystemCycleStatusEventState)); TypeDeclaration type = new TypeDeclaration(); type.NodeId = ExpandedNodeId.ToNodeId(ObjectTypeIds.SystemCycleStatusEventType, m_session.NamespaceUris); type.Declarations = ClientUtils.CollectInstanceDeclarationsForType(m_session, type.NodeId); // the filter to use. m_filter = new FilterDeclaration(type, null); // declate callback. m_MonitoredItem_Notification = new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); // create a monitored item based on the current filter settings. m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = Opc.Ua.ObjectIds.Server; m_monitoredItem.AttributeId = Attributes.EventNotifier; m_monitoredItem.SamplingInterval = 0; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; m_monitoredItem.Filter = m_filter.GetFilter(); // set up callback for notifications. m_monitoredItem.Notification += m_MonitoredItem_Notification; m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
/// <summary> /// Updates the application after connecting to or disconnecting from the server. /// </summary> private void Server_ConnectComplete(object sender, EventArgs e) { try { m_session = ConnectServerCTRL.Session; if (m_session == null) { StartBTN.Enabled = false; return; } // set a suitable initial state. if (m_session != null && !m_connectedOnce) { m_connectedOnce = true; } // this client has built-in knowledge of the information model used by the server. NamespaceTable wellKnownNamespaceUris = new NamespaceTable(); wellKnownNamespaceUris.Append(Namespaces.Methods); string[] browsePaths = new string[] { "1:My Process/1:State", "1:My Process", "1:My Process/1:Start" }; List<NodeId> nodes = ClientUtils.TranslateBrowsePaths( m_session, ObjectIds.ObjectsFolder, wellKnownNamespaceUris, browsePaths); // subscribe to the state if available. if (nodes.Count > 0 && !NodeId.IsNull(nodes[0])) { m_subscription = new Subscription(); m_subscription.PublishingEnabled = true; m_subscription.PublishingInterval = 1000; m_subscription.Priority = 1; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 20; m_subscription.MaxNotificationsPerPublish = 1000; m_session.AddSubscription(m_subscription); m_subscription.Create(); MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = nodes[0]; monitoredItem.AttributeId = Attributes.Value; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(monitoredItem); m_subscription.ApplyChanges(); } // save the object/method if (nodes.Count > 2) { m_objectNode = nodes[1]; m_methodNode = nodes[2]; } InitialStateTB.Text = "1"; FinalStateTB.Text = "100"; StartBTN.Enabled = true; } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Modifies the sampling interval used. /// </summary> private bool ModifySamplingInterval(Subscription subscription) { if (m_errorEvent.WaitOne(500, false)) { return false; } lock (m_variables) { for (int ii = 0; ii < m_variables.Count; ii++) { foreach (IList<Notification> notification in m_variables[ii].Notifications.Values) { notification.Clear(); } } foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { monitoredItem.SamplingInterval = (int)(monitoredItem.Status.SamplingInterval*2); } } subscription.ApplyChanges(); // check results. bool success = true; foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (ServiceResult.IsBad(monitoredItem.Status.Error)) { TestVariable variable = monitoredItem.Handle as TestVariable; Log( "Could not modify MonitoredItem {0}. NodeId={1}, SamplingInterval={2}", variable.Variable, variable.Variable.NodeId, monitoredItem.SamplingInterval); success = false; } } if (!success) { return false; } if (m_errorEvent.WaitOne(500, false)) { return false; } return true; }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { if (m_subscription != null) { m_subscription.Dispose(); m_subscription = null; } // get the current session. Session session = m_server.Session; if (session == null) { return; } // create the subscription. m_subscription = new Subscription(); m_subscription.PublishingEnabled = Active; m_subscription.PublishingInterval = (int)Math.Max(BufferTime, 1000); m_subscription.KeepAliveCount = (uint)Math.Max(Math.Ceiling(((double)KeepAlive)/m_subscription.PublishingInterval), 10); m_subscription.LifetimeCount = m_subscription.KeepAliveCount*3; m_subscription.MaxNotificationsPerPublish = MaxSize; m_subscription.TimestampsToReturn = TimestampsToReturn.Neither; m_subscription.Priority = 0; m_subscription.FastEventCallback = OnEventNotification; m_subscription.DisableMonitoredItemCache = true; session.AddSubscription(m_subscription); m_subscription.Create(); // update the monitored items. EventFilter filter = m_filter.GetFilter(); MonitoringMode monitoringMode = (Active)?MonitoringMode.Reporting:MonitoringMode.Disabled; foreach (MonitoredItem monitoredItem in m_notifiers.Values) { monitoredItem.Filter = filter; monitoredItem.MonitoringMode = monitoringMode; m_subscription.AddItem(monitoredItem); } m_subscription.ApplyChanges(); }
/// <summary> /// Adds a item to a subscription. /// </summary> private void Subscribe(Subscription subscription, ReferenceDescription reference) { MonitoredItem monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.DisplayName = subscription.Session.NodeCache.GetDisplayText(reference); monitoredItem.StartNodeId = (NodeId)reference.NodeId; monitoredItem.NodeClass = (NodeClass)reference.NodeClass; monitoredItem.AttributeId = Attributes.Value; monitoredItem.SamplingInterval = 0; monitoredItem.QueueSize = 1; // add condition fields to any event filter. EventFilter filter = monitoredItem.Filter as EventFilter; if (filter != null) { monitoredItem.AttributeId = Attributes.EventNotifier; monitoredItem.QueueSize = 0; } subscription.AddItem(monitoredItem); subscription.ApplyChanges(); }
private void BoilerCB_SelectedIndexChanged(object sender, EventArgs e) { try { if (m_session == null) { return; } if (m_subscription != null) { m_session.RemoveSubscription(m_subscription); m_subscription = null; } ReferenceDescription boiler = (ReferenceDescription)BoilerCB.SelectedItem; if (boiler == null) { return; } m_subscription = new Subscription(); m_subscription.PublishingEnabled = true; m_subscription.PublishingInterval = 1000; m_subscription.Priority = 1; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 20; m_subscription.MaxNotificationsPerPublish = 1000; m_session.AddSubscription(m_subscription); m_subscription.Create(); NamespaceTable wellKnownNamespaceUris = new NamespaceTable(); wellKnownNamespaceUris.Append(Namespaces.Boiler); string[] browsePaths = new string[] { "1:PipeX001/1:FTX001/1:Output", "1:DrumX001/1:LIX001/1:Output", "1:PipeX002/1:FTX002/1:Output", "1:LCX001/1:SetPoint", }; List<NodeId> nodes = ClientUtils.TranslateBrowsePaths( m_session, (NodeId)boiler.NodeId, wellKnownNamespaceUris, browsePaths); Control[] controls = new Control[] { InputPipeFlowTB, DrumLevelTB, OutputPipeFlowTB, DrumLevelSetPointTB }; for (int ii = 0; ii < nodes.Count; ii++) { controls[ii].Text = "---"; if (nodes[ii] != null) { MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = nodes[ii]; monitoredItem.AttributeId = Attributes.Value; monitoredItem.Handle = controls[ii]; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(monitoredItem); } } m_subscription.ApplyChanges(); } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Modifies the deadband. /// </summary> private bool ModifyDeadband(Subscription subscription) { if (m_errorEvent.WaitOne(500, false)) { return false; } lock (m_variables) { for (int ii = 0; ii < m_variables.Count; ii++) { foreach (IList<Notification> notification in m_variables[ii].Notifications.Values) { notification.Clear(); } } foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { DataChangeFilter filter =(DataChangeFilter)monitoredItem.Filter; filter.DeadbandValue /= 2; monitoredItem.Filter = filter; } } subscription.ApplyChanges(); // check results. bool success = true; foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (!CheckDeadbandError(monitoredItem)) { success = false; break; } } if (!success) { return false; } if (m_errorEvent.WaitOne(500, false)) { return false; } return true; }
/// <summary> /// Reads an verifies all of the nodes. /// </summary> private bool DoSamplingIntervalTest(bool modifySamplingInterval) { // follow tree from each starting node. bool success = true; // collection writeable variables that don't change during the test. lock (m_variables) { m_lastWriteTime = DateTime.MinValue; m_writeDelayed = false; m_writeTimerCounter++; m_variables.Clear(); // collection writeable variables that don't change during the test. for (int ii = 0; ii < WriteableVariables.Count; ii++) { AddVariableToTest(WriteableVariables[ii], m_variables, false); } // reduce list based on coverage. List<TestVariable> variables = new List<TestVariable>(); int counter = 0; foreach (TestVariable variable in m_variables) { if (!CheckCoverage(ref counter)) { continue; } variables.Add(variable); } // check if there is anything to work with. if (variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } m_variables.Clear(); m_variables.AddRange(variables); ReadEURanges(m_variables); InitialWrite(); // check if there is anything to work with. if (m_variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } Log("Starting SamplingIntervalTest for {0} Variables ({1}% Coverage, Start={2})", m_variables.Count, Configuration.Coverage, m_variables[0].Variable); m_stopped = 0; m_writeInterval = 1000; m_useDeadbandValues = false; m_errorEvent.Reset(); } Subscription subscription = new Subscription(); subscription.PublishingInterval = 500; subscription.PublishingEnabled = true; subscription.Priority = 0; subscription.KeepAliveCount = 1000; subscription.LifetimeCount = 1000; subscription.MaxNotificationsPerPublish = 100; Session.AddSubscription(subscription); subscription.Create(); m_publishingTime = subscription.CurrentPublishingInterval; m_writerTimer = new Timer(DoWrite, m_writeTimerCounter, 0, m_writeInterval); if (m_errorEvent.WaitOne(1000, false)) { success = false; } // create monitored items. if (success) { lock (m_variables) { m_monitoredItems = new Dictionary<uint,TestVariable>(); for (int ii = 0; ii < m_variables.Count; ii++) { // servers that sample data values may not pick up boolean value changes. if (m_variables[ii].DataType == BuiltInType.Boolean) { continue; } VariableNode variable = m_variables[ii].Variable; for (int jj = 2000; jj <= 10000; jj += 1000) { MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = variable.NodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.RelativePath = null; monitoredItem.IndexRange = null; monitoredItem.SamplingInterval = jj; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Filter = null; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.Handle = m_variables[ii]; m_variables[ii].Notifications[monitoredItem.ClientHandle] = new List<Notification>(); m_monitoredItems[monitoredItem.ClientHandle] = m_variables[ii]; subscription.AddItem(monitoredItem); } } } subscription.ApplyChanges(); // check results. foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (ServiceResult.IsBad(monitoredItem.Status.Error)) { TestVariable variable = monitoredItem.Handle as TestVariable; Log( "Could not create MonitoredItem {0}. NodeId={1}, SamplingInterval={2}", variable.Variable, variable.Variable.NodeId, monitoredItem.SamplingInterval); success = false; } } } // modify sampling interval. if (success) { if (modifySamplingInterval) { if (!ModifySamplingInterval(subscription)) { success = false; } } } // wait for first data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } // wait while values are written. lock (m_variables) { m_writeCount = 0; m_startTime = DateTime.UtcNow; } if (success) { double increment = MaxProgress/10; double position = 0; for (int ii = 0; ii < 20; ii++) { if (m_errorEvent.WaitOne(1000, false)) { success = false; break; } position += increment; ReportProgress(position); } } int writeCount = 0; lock (m_variables) { m_stopped = 1; m_endTime = DateTime.UtcNow; writeCount = m_writeCount; m_writerTimer.Dispose(); m_writerTimer = null; } Session.RemoveSubscription(subscription); // wait for last data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } // verify results. if (success) { double duration = CalculateInterval(m_startTime, m_endTime); double expectedWrites = Math.Truncate(duration/m_writeInterval); if (Math.Abs(expectedWrites - writeCount) > 1) { Log( "WARNING: unexpected number of writes for monitored items: Expected={0}, Actual={1}", expectedWrites, writeCount, duration); } lock (m_variables) { int errorCount = 0; foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (errorCount > 10) { break; } TestVariable variable = (TestVariable)monitoredItem.Handle; if (variable.WriteError) { continue; } IList<Notification> notifications = variable.Notifications[monitoredItem.ClientHandle]; // count the number of notifications. int first = -1; for (int ii = 0; ii < notifications.Count; ii++) { if (notifications[ii].Timestamp < m_startTime) { continue; } first = ii; } if (first == -1) { Log( "No notifications for monitored item: {0}, NodeId={1}, SamplingInterval={2}", variable.Variable, variable.Variable.NodeId, monitoredItem.SamplingInterval); success = false; errorCount++; continue; } int actualNotifications = notifications.Count - first; double range = (notifications[notifications.Count-1].Timestamp - notifications[first].Timestamp).TotalMilliseconds; // check that at least one notification was recieved. double expectedNotifications = Math.Truncate(range/monitoredItem.SamplingInterval); if (Math.Abs(expectedNotifications - actualNotifications) > 1) { Log( "Unexpected number of notifications for monitored item: {0}, NodeId={1}, SamplingInterval={2}, Expected={3}, Actual={4}", variable.Variable, variable.Variable.NodeId, monitoredItem.SamplingInterval, expectedNotifications, actualNotifications); StringBuilder buffer = new StringBuilder(); buffer.Append("Notifications:\r\n"); for (int ii = 0; ii < notifications.Count; ii++) { buffer.AppendFormat( "[{0}]\t{1:HH:mm:ss.fff}\t{2}\t{3:HH:mm:ss.fff}\r\n", notifications[ii].SequenceNumber, notifications[ii].Timestamp, notifications[ii].Value.WrappedValue, notifications[ii].Value.SourceTimestamp); } buffer.Append("Values:\r\n"); for (int ii = 0; ii < variable.Values.Count; ii++) { buffer.AppendFormat( "[{0}]\t{1}\t{2:HH:mm:ss.fff}\r\n", ii, variable.Values[ii].WrappedValue, variable.Timestamps[ii]); } Log(buffer.ToString()); success = false; errorCount++; continue; } // check timing. if (!CheckNotificationTiming(monitoredItem, variable, notifications)) { success = false; errorCount++; continue; } } } } lock (m_variables) { Log("Completed SamplingIntervalTest for {0} Nodes", m_variables.Count); } return success; }
/// <summary> /// Connects to a server. /// </summary> private void Server_ConnectMI_Click(object sender, EventArgs e) { try { // disconnect any existing session. Server_DisconnectMI_Click(sender, e); InitialStateTB.Text = "1"; FinalStateTB.Text = "100"; // create the session. EndpointDescription endpointDescription = SelectEndpoint(); EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration); ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration); m_session = Session.Create( m_configuration, endpoint, true, m_configuration.ApplicationName, 60000, null, null); // set up keep alive callback. m_session.KeepAliveInterval = 2000; m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive); // this client has built-in knowledge of the information model used by the server. NamespaceTable wellKnownNamespaceUris = new NamespaceTable(); wellKnownNamespaceUris.Append(Namespaces.Methods); string[] browsePaths = new string[] { "1:My Process/1:State", "1:My Process", "1:My Process/1:Start" }; List<NodeId> nodes = FormUtils.TranslateBrowsePaths( m_session, ObjectIds.ObjectsFolder, wellKnownNamespaceUris, browsePaths); // subscribe to the state if available. if (nodes.Count > 0 && !NodeId.IsNull(nodes[0])) { m_subscription = new Subscription(); m_subscription.PublishingEnabled = true; m_subscription.PublishingInterval = 1000; m_subscription.Priority = 1; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 20; m_subscription.MaxNotificationsPerPublish = 1000; m_session.AddSubscription(m_subscription); m_subscription.Create(); MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = nodes[0]; monitoredItem.AttributeId = Attributes.Value; monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(monitoredItem); m_subscription.ApplyChanges(); } // save the object/method if (nodes.Count > 2) { m_objectNode = nodes[1]; m_methodNode = nodes[2]; } ConnectedLB.Text = "Connected"; ServerUrlLB.Text = endpointDescription.EndpointUrl; LastKeepAliveTimeLB.Text = "---"; } catch (Exception exception) { MessageBox.Show(exception.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Creates the subscription. /// </summary> private void CreateSubscription() { m_subscription = new Subscription(); m_subscription.Handle = this; m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); m_monitoredItem = new MonitoredItem(); m_monitoredItem.StartNodeId = m_areaId; m_monitoredItem.AttributeId = Attributes.EventNotifier; m_monitoredItem.SamplingInterval = 0; m_monitoredItem.QueueSize = 1000; m_monitoredItem.DiscardOldest = true; ChangeFilter(m_filter, false); m_monitoredItem.Notification += new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
/// <summary> /// Initializes a new instance of the <see cref="AuditEventForm"/> class. /// </summary> /// <param name="session">The session.</param> /// <param name="subscription">The subscription.</param> public AuditEventForm(Session session, Subscription subscription) { InitializeComponent(); m_session = session; m_subscription = subscription; // a table used to track event types. m_eventTypeMappings = new Dictionary<NodeId, NodeId>(); // the filter to use. m_filter = new FilterDefinition(); m_filter.AreaId = ObjectIds.Server; m_filter.Severity = EventSeverity.Min; m_filter.IgnoreSuppressedOrShelved = true; m_filter.EventTypes = new NodeId[] { ObjectTypeIds.AuditUpdateMethodEventType }; // find the fields of interest. m_filter.SelectClauses = m_filter.ConstructSelectClauses(m_session, ObjectTypeIds.AuditUpdateMethodEventType); // declate callback. m_MonitoredItem_Notification = new MonitoredItemNotificationEventHandler(MonitoredItem_Notification); // create a monitored item based on the current filter settings. m_monitoredItem = m_filter.CreateMonitoredItem(m_session); // set up callback for notifications. m_monitoredItem.Notification += m_MonitoredItem_Notification; m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); }
/// <summary> /// Updates the application after connecting to or disconnecting from the server. /// </summary> private void Server_ConnectComplete(object sender, EventArgs e) { try { m_session = ConnectServerCTRL.Session; // check for disconnect. if (m_session == null) { if (m_auditEventForm != null) { m_auditEventForm.Close(); m_auditEventForm = null; } return; } // set a suitable initial state. if (m_session != null && !m_connectedOnce) { m_connectedOnce = true; } // create the default subscription. m_subscription = new Subscription(); m_subscription.DisplayName = null; m_subscription.PublishingInterval = 1000; m_subscription.KeepAliveCount = 10; m_subscription.LifetimeCount = 100; m_subscription.MaxNotificationsPerPublish = 1000; m_subscription.PublishingEnabled = true; m_subscription.TimestampsToReturn = TimestampsToReturn.Both; m_session.AddSubscription(m_subscription); m_subscription.Create(); // must specify the fields that the form is interested in. m_filter.SelectClauses = m_filter.ConstructSelectClauses( m_session, NodeId.Parse("ns=2;s=4:2"), NodeId.Parse("ns=2;s=4:1"), ObjectTypeIds.DialogConditionType, ObjectTypeIds.ExclusiveLimitAlarmType, ObjectTypeIds.NonExclusiveLimitAlarmType); // create a monitored item based on the current filter settings. m_monitoredItem = m_filter.CreateMonitoredItem(m_session); // set up callback for notifications. m_monitoredItem.Notification += m_MonitoredItem_Notification; m_subscription.AddItem(m_monitoredItem); m_subscription.ApplyChanges(); // send an initial refresh. Conditions_RefreshMI_Click(sender, e); ConditionsMI.Enabled = true; ViewMI.Enabled = true; } catch (Exception exception) { ClientUtils.HandleException(this.Text, exception); } }
/// <summary> /// Reads an verifies all of the nodes. /// </summary> private bool DoDeadbandTest(bool modifyDeadband) { // follow tree from each starting node. bool success = true; // collection writeable variables that don't change during the test. lock (m_variables) { m_lastWriteTime = DateTime.MinValue; m_writeDelayed = false; m_writeTimerCounter++; m_variables.Clear(); // collection writeable variables that don't change during the test. for (int ii = 0; ii < WriteableVariables.Count; ii++) { AddVariableToTest(WriteableVariables[ii], m_variables, true); } // reduce list based on coverage. List<TestVariable> variables = new List<TestVariable>(); int counter = 0; foreach (TestVariable variable in m_variables) { if (!CheckCoverage(ref counter)) { continue; } variables.Add(variable); } // check if there is anything to work with. if (variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } m_variables.Clear(); m_variables.AddRange(variables); ReadEURanges(m_variables); InitialWrite(); // check if there is anything to work with. if (m_variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } Log("Starting DeadbandTest for {0} Variables ({1}% Coverage, Start={2})", m_variables.Count, Configuration.Coverage, m_variables[0].Variable); m_stopped = 0; m_writeInterval = 1000; m_deadbandCounter = 0; m_useDeadbandValues = true; m_errorEvent.Reset(); } Subscription subscription = new Subscription(); subscription.PublishingInterval = 1000; subscription.PublishingEnabled = true; subscription.Priority = 0; subscription.KeepAliveCount = 100; subscription.LifetimeCount = 100; subscription.MaxNotificationsPerPublish = 100; Session.AddSubscription(subscription); subscription.Create(); m_publishingTime = subscription.CurrentPublishingInterval; m_writerTimer = new Timer(DoWrite, m_writeTimerCounter, 0, m_writeInterval); if (m_errorEvent.WaitOne(1000, false)) { success = false; } DataChangeFilter[] filters = new DataChangeFilter[5]; if (success) { DataChangeFilter filter = new DataChangeFilter(); filter.DeadbandType = (uint)DeadbandType.Absolute; filter.DeadbandValue = 2; filter.Trigger = DataChangeTrigger.StatusValue; filters[0] = filter; filter = new DataChangeFilter(); filter.DeadbandType = (uint)DeadbandType.Absolute; filter.DeadbandValue = 5; filter.Trigger = DataChangeTrigger.StatusValue; filters[1] = filter; filter = new DataChangeFilter(); filter.DeadbandType = (uint)DeadbandType.Absolute; filter.DeadbandValue = 10; filter.Trigger = DataChangeTrigger.StatusValue; filters[2] = filter; filter = new DataChangeFilter(); filter.DeadbandType = (uint)DeadbandType.Percent; filter.DeadbandValue = 1; filter.Trigger = DataChangeTrigger.StatusValue; filters[3] = filter; filter = new DataChangeFilter(); filter.DeadbandType = (uint)DeadbandType.Percent; filter.DeadbandValue = 10; filter.Trigger = DataChangeTrigger.StatusValue; filters[4] = filter; lock (m_variables) { m_monitoredItems = new Dictionary<uint,TestVariable>(); for (int ii = 0; ii < m_variables.Count; ii++) { VariableNode variable = m_variables[ii].Variable; for (int jj = 0; jj < filters.Length; jj++) { if (m_variables[ii].EURange == null && filters[jj].DeadbandType == (uint)DeadbandType.Percent) { continue; } MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = variable.NodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.RelativePath = null; monitoredItem.IndexRange = null; monitoredItem.SamplingInterval = 100; monitoredItem.QueueSize = 0; monitoredItem.DiscardOldest = true; monitoredItem.Filter = filters[jj]; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.Handle = m_variables[ii]; m_variables[ii].Notifications[monitoredItem.ClientHandle] = new List<Notification>(); m_monitoredItems[monitoredItem.ClientHandle] = m_variables[ii]; subscription.AddItem(monitoredItem); } } } subscription.ApplyChanges(); // check results. foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (!CheckDeadbandError(monitoredItem)) { success = false; break; } } } // modify sampling interval. if (success) { if (modifyDeadband) { if (!ModifyDeadband(subscription)) { success = false; } } } // wait for first data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } lock (m_variables) { m_writeCount = 0; m_startTime = DateTime.UtcNow; } if (success) { double increment = MaxProgress/10; double position = 0; for (int ii = 0; ii < 20; ii++) { if (m_errorEvent.WaitOne(1000, false)) { success = false; break; } position += increment; ReportProgress(position); } } int writeCount = 0; lock (m_variables) { m_stopped = 1; m_endTime = DateTime.UtcNow; writeCount = m_writeCount; m_writerTimer.Dispose(); m_writerTimer = null; } Session.RemoveSubscription(subscription); // wait for last data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } if (success) { double duration = CalculateInterval(m_startTime, m_endTime); double expectedWrites = Math.Truncate(duration/m_writeInterval); if (Math.Abs(expectedWrites - writeCount) > 1) { Log( "WARNING: unexpected number of writes for monitored items: Expected={0}, Actual={1}", expectedWrites, writeCount); } lock (m_variables) { int errorCount = 0; foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (ServiceResult.IsBad(monitoredItem.Status.Error)) { continue; } DataChangeFilter filter = monitoredItem.Status.Filter as DataChangeFilter; if (filter == null) { continue; } if (errorCount > 10) { break; } TestVariable variable = (TestVariable)monitoredItem.Handle; double writesPerPublish = m_publishingTime/m_writeInterval; double totalPublishes = duration/m_publishingTime; Range euRange = variable.EURange; if (euRange != null) { if (euRange.High - euRange.Low <= 0) { Log( "Invalid EU range for variable {0}. NodeId={1}, EURange={2}, EURange={3}", variable.Variable, variable.Variable.NodeId, variable.EURangeNode.NodeId, euRange); success = false; errorCount++; continue; } } IList<Notification> notifications = variable.Notifications[monitoredItem.ClientHandle]; for (int ii = 0; ii < notifications.Count-1; ii++) { Notification before = notifications[ii]; Notification after = notifications[ii+1]; decimal difference = CalculateDifference(before.Value.Value, after.Value.Value); if (filter.DeadbandType == (uint)DeadbandType.Absolute) { if (difference < (decimal)filter.DeadbandValue) { Log( "Values did not exceed deadband {0}. NodeId={1}, DeadbandType={2}, Deadband={3}, Before={4}, After={5}", variable.Variable, variable.Variable.NodeId, (DeadbandType)filter.DeadbandType, filter.DeadbandValue, before.Value.WrappedValue, after.Value.WrappedValue); success = false; errorCount++; continue; } } if (filter.DeadbandType == (uint)DeadbandType.Percent) { double range = euRange.High - euRange.Low; if (((double)difference)/range < filter.DeadbandValue/range) { Log( "Values did not exceed deadband {0}. NodeId={1}, DeadbandType={2}, Deadband={3}, Before={4}, After={5}, EURange={6}", variable.Variable, variable.Variable.NodeId, (DeadbandType)filter.DeadbandType, filter.DeadbandValue, before.Value.WrappedValue, after.Value.WrappedValue, euRange); success = false; errorCount++; continue; } } } } } } lock (m_variables) { Log("Completed DeadbandTest for {0} Nodes", m_variables.Count); } return success; }
/// <summary> /// Reads an verifies all of the nodes. /// </summary> private bool DoQueueSizeTest(bool modifyQueueSize) { // follow tree from each starting node. bool success = true; // collection writeable variables that don't change during the test. lock (m_variables) { m_lastWriteTime = DateTime.MinValue; m_writeDelayed = false; m_writeTimerCounter++; m_variables.Clear(); // collection writeable variables that don't change during the test. for (int ii = 0; ii < WriteableVariables.Count; ii++) { AddVariableToTest(WriteableVariables[ii], m_variables, false); } // reduce list based on coverage. List<TestVariable> variables = new List<TestVariable>(); int counter = 0; foreach (TestVariable variable in m_variables) { if (!CheckCoverage(ref counter)) { continue; } variables.Add(variable); } // check if there is anything to work with. if (variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } m_variables.Clear(); m_variables.AddRange(variables); ReadEURanges(m_variables); InitialWrite(); // check if there is anything to work with. if (m_variables.Count == 0) { Log("WARNING: No writeable variables found."); Log(WriteTest.g_WriteableVariableHelpText); return true; } Log("Starting QueueSizeTest for {0} Variables ({1}% Coverage, Start={2})", m_variables.Count, Configuration.Coverage, m_variables[0].Variable); m_stopped = 0; m_writeInterval = 1000; m_useDeadbandValues = false; m_errorEvent.Reset(); } // create subscription. Subscription subscription = new Subscription(); subscription.PublishingInterval = 5000; subscription.PublishingEnabled = true; subscription.Priority = 0; subscription.KeepAliveCount = 100; subscription.LifetimeCount = 100; subscription.MaxNotificationsPerPublish = 100; Session.AddSubscription(subscription); subscription.Create(); m_publishingTime = subscription.CurrentPublishingInterval; m_writerTimer = new Timer(DoWrite, m_writeTimerCounter, 0, m_writeInterval); if (m_errorEvent.WaitOne(1000, false)) { success = false; } // create monitored items. if (success) { lock (m_variables) { m_monitoredItems = new Dictionary<uint,TestVariable>(); for (int ii = 0; ii < m_variables.Count; ii++) { // servers that sample data values may not pick up boolean value changes. if (m_variables[ii].DataType == BuiltInType.Boolean) { continue; } VariableNode variable = m_variables[ii].Variable; for (int jj = 0; jj < 8; jj += 2) { MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = variable.NodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.RelativePath = null; monitoredItem.IndexRange = null; monitoredItem.SamplingInterval = 100; monitoredItem.QueueSize = (uint)jj; monitoredItem.DiscardOldest = true; monitoredItem.Filter = null; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.Handle = m_variables[ii]; m_variables[ii].Notifications[monitoredItem.ClientHandle] = new List<Notification>(); m_monitoredItems[monitoredItem.ClientHandle] = m_variables[ii]; subscription.AddItem(monitoredItem); } for (int jj = 2; jj < 8; jj += 2) { MonitoredItem monitoredItem = new MonitoredItem(); monitoredItem.StartNodeId = variable.NodeId; monitoredItem.AttributeId = Attributes.Value; monitoredItem.RelativePath = null; monitoredItem.IndexRange = null; monitoredItem.SamplingInterval = 100; monitoredItem.QueueSize = (uint)jj; monitoredItem.DiscardOldest = false; monitoredItem.Filter = null; monitoredItem.MonitoringMode = MonitoringMode.Reporting; monitoredItem.Handle = m_variables[ii]; m_variables[ii].Notifications[monitoredItem.ClientHandle] = new List<Notification>(); m_monitoredItems[monitoredItem.ClientHandle] = m_variables[ii]; subscription.AddItem(monitoredItem); } } } subscription.ApplyChanges(); // check results. foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (ServiceResult.IsBad(monitoredItem.Status.Error)) { TestVariable variable = monitoredItem.Handle as TestVariable; Log( "Could not create MonitoredItem {0}. NodeId={1}, QueueSize={2}", variable.Variable, variable.Variable.NodeId, monitoredItem.QueueSize); success = false; } } } // modify sampling interval. if (success) { if (modifyQueueSize) { if (!ModifyQueueSize(subscription)) { success = false; } } } // wait for first data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } // wait to write some values. lock (m_variables) { m_writeCount = 0; m_startTime = DateTime.UtcNow; } if (success) { double increment = MaxProgress/10; double position = 0; for (int ii = 0; ii < 20; ii++) { if (m_errorEvent.WaitOne(1000, false)) { success = false; break; } position += increment; ReportProgress(position); } } int writeCount = 0; lock (m_variables) { m_stopped = 1; m_endTime = DateTime.UtcNow; writeCount = m_writeCount; m_writerTimer.Dispose(); m_writerTimer = null; } Session.RemoveSubscription(subscription); // wait for last data change. if (m_errorEvent.WaitOne(1000, false)) { success = false; } // validate results. if (success) { double duration = CalculateInterval(m_startTime, m_endTime); double expectedWrites = Math.Truncate(duration/m_writeInterval); if (Math.Abs(expectedWrites - writeCount) > 1) { Log( "WARNING: unexpected number of writes for monitored items: Expected={0}, Actual={1}", expectedWrites, writeCount); } lock (m_variables) { int errorCount = 0; foreach (MonitoredItem monitoredItem in subscription.MonitoredItems) { if (errorCount > 10) { break; } TestVariable variable = (TestVariable)monitoredItem.Handle; // ignore values if syntax errors occurred. if (variable.WriteError) { continue; } double samplingInterval = monitoredItem.Status.SamplingInterval; uint queueSize = monitoredItem.Status.QueueSize; bool discardOldest = monitoredItem.Status.DiscardOldest; double writesPerPublish = m_publishingTime/m_writeInterval; double totalPublishes = duration/m_publishingTime; IList<Notification> notifications = variable.Notifications[monitoredItem.ClientHandle]; int actualNotifications = 0; int beforeIndex = 0; int afterIndex = 0; for (int ii = 0; ii < notifications.Count-1; ii++) { actualNotifications++; Notification before = notifications[ii]; Notification after = notifications[ii+1]; double gap = CalculateInterval(before.Value.SourceTimestamp, after.Value.SourceTimestamp); // check gap. if (gap > m_writeInterval + samplingInterval + m_maximumTimingError) { bool unexpectedGap = true; if (queueSize <= 1 || after.Value.StatusCode.Overflow || before.Value.StatusCode.Overflow) { unexpectedGap = false; } if (unexpectedGap) { Log( "Too much time between consecutive samples: {0}, NodeId={1}, QueueSize={2}, DiscardOldest={3}, SampleIndex={4}, Gap={5}", variable.Variable, variable.Variable.NodeId, monitoredItem.Status.QueueSize, monitoredItem.Status.DiscardOldest, ii, gap); success = false; errorCount++; continue; } } // find the value that matches the before value. beforeIndex = -1; for (int jj = 0; jj < variable.Values.Count; jj++) { if (m_comparer.CompareVariant(variable.Values[jj].WrappedValue, before.Value.WrappedValue)) { beforeIndex = jj; break; } } // find the value that matches the after value. afterIndex = -1; for (int jj = beforeIndex+1; jj < variable.Values.Count; jj++) { if (m_comparer.CompareVariant(variable.Values[jj].WrappedValue, after.Value.WrappedValue)) { afterIndex = jj; break; } } // the final write may not have returned. if (variable.Timestamps.Count > 0) { if (variable.Timestamps[variable.Timestamps.Count-1] < after.Value.SourceTimestamp) { continue; } } if (beforeIndex < 0 || afterIndex < 0 || afterIndex <= beforeIndex) { Log( "Could not find matching value for sample: {0}, NodeId={1}, QueueSize={2}, DiscardOldest={3}, BeforeIndex={4}, AfterIndex={5}", variable.Variable, variable.Variable.NodeId, monitoredItem.Status.QueueSize, monitoredItem.Status.DiscardOldest, beforeIndex, afterIndex); success = false; errorCount++; continue; } // validate consecutive samples. if (afterIndex - beforeIndex == 1) { bool unexpectedOverflow = false; if (discardOldest) { if (after.Value.StatusCode.Overflow) { unexpectedOverflow = true; } } else { if (before.Value.StatusCode.Overflow) { // overflow possible if the same value is reported scanned many times. if (CalculateInterval(before.Timestamp, after.Timestamp) < m_publishingTime/2) { unexpectedOverflow = true; } } } if (unexpectedOverflow) { Log( "Unexpected overflow between consecutive samples: {0}, NodeId={1}, QueueSize={2}, DiscardOldest={3}, SampleIndex={4}, Gap={5}", variable.Variable, variable.Variable.NodeId, monitoredItem.Status.QueueSize, monitoredItem.Status.DiscardOldest, ii, gap); success = false; errorCount++; continue; } } else { // check for overflow. bool missingOverflow = false; if (discardOldest) { if (!after.Value.StatusCode.Overflow) { missingOverflow = true; } } else { if (!before.Value.StatusCode.Overflow) { missingOverflow = true; } } // check for legimate overflows. if (missingOverflow) { if (queueSize <= 1) { missingOverflow = false; } else if (writesPerPublish - queueSize <= 1) { missingOverflow = false; } } if (missingOverflow) { Log( "Missing overflow between non-consecutive samples: {0}, NodeId={1}, QueueSize={2}, DiscardOldest={3}, SampleIndex={4}, Gap={5}", variable.Variable, variable.Variable.NodeId, monitoredItem.Status.QueueSize, monitoredItem.Status.DiscardOldest, ii, gap); success = false; errorCount++; continue; } } } } } } lock (m_variables) { Log("Completed QueueSizeTest for {0} Nodes", m_variables.Count); } return success; }
public void Initialize(Session session, Subscription subscription) { m_Session = session; m_Subscription = subscription; listView1.Items.Clear(); // Now monitor the server object for AuditSession Events NodeId serverNodeId = new NodeId(Objects.Server); Node serverNode = m_Session.NodeCache.Find(serverNodeId) as Node; MonitoredItem serverItem = new MonitoredItem(m_Subscription.DefaultItem); serverItem.StartNodeId = serverNode.NodeId; serverItem.NodeClass = NodeClass.Object; m_Subscription.AddItem(serverItem); serverItem.Notification += m_ItemNotification; AddSessions(); m_Subscription.ModifyItems(); m_Subscription.ApplyChanges(); }
public void LoadItems(Session session, List<DiagnosticListViewItem> items, Subscription subscription) { m_Session = session; m_Subscription = subscription; ItemsLV.Items.Clear(); foreach (DiagnosticListViewItem item in items) { MonitoredItem mi = item.CreateMonitoredItem(m_Session, m_Subscription, ItemsLV); if (mi != null) { mi.Notification += m_ItemNotification; item.MonitoredItem = mi; } } m_Subscription.ApplyChanges(); }