Zum Inhalt springen

Anleitung

Subscriptions

Wertänderungen und Ereignisse von Nodes per Subscription abonnieren, Benachrichtigungen behandeln, Subscriptions verwalten und mit Filtern eingrenzen.

Anleitung

Subscriptions ​

Subscriptions erstellen ​

Beteiligte TypenOpcClientOpcNodeIdOpcSubscribeDataChangeOpcSubscribeEventOpcSubscriptionOpcMonitoredItemOpcMonitoredItemCollectionOpcDataChangeReceivedEventHandlerOpcDataChangeReceivedEventArgsOpcEventReceivedEventHandlerOpcEventReceivedEventArgsOpcNotification

Eine Subscription in OPC UA lässt sich mit einem Abonnement vergleichen, das eine oder mehrere Zeitschriften umfasst. Statt Zeitschriften abonniert der Client jedoch Ereignisse von Nodes oder Änderungen ihrer Werte. Für jeden abonnierten Node enthält die Subscription ein MonitoredItem. Je Subscription legen Sie fest, in welchem Intervall der Server die Benachrichtigungen der MonitoredItems veröffentlicht (OpcSubscription.PublishingInterval). Die Benachrichtigungen sind Instanzen von OpcNotification. Die NodeId legt fest, welchen Node der Client abonniert. Standardmäßig überwacht (engl. monitored) der Server das Value-Attribut. Wenn der Server ein anderes Attribut des Nodes überwachen soll, geben Sie das passende OpcAttribute beim Aufruf von SubscribeDataChange oder in der jeweiligen Instanz von OpcSubscribeDataChange an.

Wertänderungen eines Nodes abonnieren:

csharp
OpcSubscription subscription = client.SubscribeDataChange(
        "ns=2;s=Machine/IsRunning",
        HandleDataChanged);
vbnet
Dim subscription As OpcSubscription = client.SubscribeDataChange( _
        "ns=2;s=Machine/IsRunning", _
        AddressOf HandleDataChanged)

Wertänderungen mehrerer Nodes abonnieren:

csharp
OpcSubscribeDataChange[] commands = new OpcSubscribeDataChange[] {
    new OpcSubscribeDataChange("ns=2;s=Machine/IsRunning", HandleDataChanged),
    new OpcSubscribeDataChange("ns=2;s=Machine/Job/Speed", HandleDataChanged)
};
 
OpcSubscription subscription = client.SubscribeNodes(commands);
vbnet
Dim commands As OpcSubscribeDataChange() = New OpcSubscribeDataChange() { _
    New OpcSubscribeDataChange("ns=2;s=Machine/IsRunning", AddressOf HandleDataChanged), _
    New OpcSubscribeDataChange("ns=2;s=Machine/Job/Speed", AddressOf HandleDataChanged) _
}

Dim subscription As OpcSubscription = client.SubscribeNodes(commands)

Benachrichtigungen über Wertänderungen behandeln:

csharp
private static void HandleDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    // Your code to execute on each data change.
    // The 'sender' variable contains the OpcMonitoredItem with the NodeId.
    OpcMonitoredItem item = (OpcMonitoredItem)sender;

    Console.WriteLine(
            "Data Change from NodeId '{0}': {1}",
            item.NodeId,
            e.Item.Value);
}
vbnet
Private Shared Sub HandleDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    'Your code to execute on each data change.
    'The 'sender' variable contains the OpcMonitoredItem with the NodeId.
    Dim item As OpcMonitoredItem = CType(sender, OpcMonitoredItem)

    Console.WriteLine( _
            "Data Change from NodeId '{0}': {1}", _
            item.NodeId, _
            e.Item.Value)
End Sub

Ereignisse eines Nodes abonnieren:

csharp
OpcSubscription subscription = client.SubscribeEvent(
        "ns=2;s=Machine",
        HandleEvent);
vbnet
Dim subscription As OpcSubscription = client.SubscribeEvent( _
        "ns=2;s=Machine", _
        AddressOf HandleEvent)

Ereignisse mehrerer Nodes abonnieren:

csharp
OpcSubscribeEvent[] commands = new OpcSubscribeEvent[] {
    new OpcSubscribeEvent("ns=2;s=Machine", HandleEvent),
    new OpcSubscribeEvent("ns=2;s=Machine/Job", HandleEvent)
};
 
OpcSubscription subscription = client.SubscribeNodes(commands);
vbnet
Dim commands As OpcSubscribeEvent() = New OpcSubscribeEvent() { _
    New OpcSubscribeEvent("ns=2;s=Machine", AddressOf HandleEvent), _
    New OpcSubscribeEvent("ns=2;s=Machine/Job", AddressOf HandleEvent) _
}

Dim subscription As OpcSubscription = client.SubscribeNodes(commands)

Benachrichtigungen über Ereignisse behandeln:

csharp
private void HandleEvent(object sender, OpcEventReceivedEventArgs e)
{
    // Your code to execute on each event raise.
}
vbnet
Private Sub HandleEvent(ByVal sender As Object, ByVal e As OpcEventReceivedEventArgs)
    'Your code to execute on each event raise.
End Sub

Subscription konfigurieren: Standardmäßig verwendet eine Subscription einen KeepAliveCount von 10, einen LifetimeCount von 100 und höchstens 1000 Benachrichtigungen je Veröffentlichung (MaxNotificationsPerPublish). Das PublishingInterval ist nicht vorbelegt. Ein Wert von 0 oder kleiner fordert das kleinste vom Server unterstützte Intervall an. Der Client übermittelt Änderungen an der Subscription erst mit dem Aufruf von ApplyChanges an den Server:

csharp
subscription.PublishingInterval = 2000;
 
// Always call apply changes after modifying the subscription; otherwise
// the server will not know the new subscription configuration.
subscription.ApplyChanges();
vbnet
subscription.PublishingInterval = 2000

'Always call apply changes after modifying the subscription; otherwise
'the server will not know the new subscription configuration.
subscription.ApplyChanges()

Mehrere Nodes über eine Subscription abonnieren: Das Beispiel abonniert Wertänderungen mehrerer Nodes über eine einzige Subscription und legt benutzerdefinierte Werte der Eigenschaft Tag der MonitoredItems fest. Die Eigenschaft SamplingInterval legt fest, wie oft der Server den Wert prüft. Der Wert 0 fordert die schnellste Rate an, der Wert -1 verwendet das PublishingInterval der Subscription:

csharp
string[] nodeIds = {
    "ns=2;s=Machine/IsRunning",
    "ns=2;s=Machine/Job/Speed",
    "ns=2;s=Machine/Diagnostics"
};
 
// Create an (empty) subscription to which we will addd OpcMonitoredItems.
OpcSubscription subscription = client.SubscribeNodes();
 
for (int index = 0; index < nodeIds.Length; index++) {
    // Create an OpcMonitoredItem for the NodeId.
    var item = new OpcMonitoredItem(nodeIds[index], OpcAttribute.Value);
    item.DataChangeReceived += HandleDataChanged;
 
    // You can set your own values on the "Tag" property
    // that allows you to identify the source later.
    item.Tag = index;
 
    // Set a custom sampling interval on the 
    // monitored item.
    item.SamplingInterval = 200;
 
    // Add the item to the subscription.
    subscription.AddMonitoredItem(item);
}
 
// After adding the items (or configuring the subscription), apply the changes.
subscription.ApplyChanges();
vbnet
Dim nodeIds As String() = { _
    "ns=2;s=Machine/IsRunning", _
    "ns=2;s=Machine/Job/Speed", _
    "ns=2;s=Machine/Diagnostics" _
}

'Create an (empty) subscription to which we will addd OpcMonitoredItems.
Dim subscription As OpcSubscription = client.SubscribeNodes()

For index As Integer = 0 To nodeIds.Length - 1
    'Create an OpcMonitoredItem for the NodeId.
    Dim item = New OpcMonitoredItem(nodeIds(index), OpcAttribute.Value)
    AddHandler item.DataChangeReceived, AddressOf HandleDataChanged

    'You can set your own values on the "Tag" property
    'that allows you to identify the source later.
    item.Tag = index

    'Set a custom sampling interval on the 
    'monitored item.
    item.SamplingInterval = 200

    'Add the item to the subscription.
    subscription.AddMonitoredItem(item)
Next

'After adding the items (or configuring the subscription), apply the changes.
subscription.ApplyChanges()

Der zugehörige Handler:

csharp
private static void HandleDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    // The tag property contains the previously set value.
    OpcMonitoredItem item = (OpcMonitoredItem)sender;
    
    Console.WriteLine(
            "Data Change from Index {0}: {1}",
            item.Tag,
            e.Item.Value);
}
vbnet
Private Shared Sub HandleDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    'The tag property contains the previously set value.
    Dim item As OpcMonitoredItem = CType(sender, OpcMonitoredItem)

    Console.WriteLine( _
        "Data Change from Index {0}: {1}", _
        item.Tag,
        e.Item.Value)
End Sub

Benachrichtigungen behandeln ​

Beteiligte TypenOpcClientOpcSubscriptionOpcMonitoredItemOpcDataChangeReceivedEventArgsOpcEventReceivedEventArgsOpcNotificationFailedEventArgs

Eine Benachrichtigung über eine Wertänderung oder ein Ereignis durchläuft die Handler in einer festen Reihenfolge. Zuerst erhält sie der Handler des MonitoredItems, zum Beispiel der beim Aufruf von SubscribeDataChange angegebene Handler. Danach folgen das Ereignis DataChangeReceived beziehungsweise EventReceived der Klasse OpcSubscription und schließlich das gleichnamige Ereignis der Klasse OpcClient. Der Client reicht die Benachrichtigung nur weiter, solange kein Handler die Eigenschaft Handled der Ereignisargumente auf true setzt:

csharp
OpcSubscription subscription = client.SubscribeDataChange(
        "ns=2;s=Machine/IsRunning",
        HandleItemDataChanged);
 
subscription.DataChangeReceived += HandleSubscriptionDataChanged;
client.DataChangeReceived += HandleClientDataChanged;
...
private static void HandleItemDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    if (e.Item.Value.Status.IsGood) {
        // Your code to process the value.
 
        // The handlers of the subscription and the client are not called.
        e.Handled = true;
    }
}
 
private static void HandleSubscriptionDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    // Called for notifications not handled by the monitored item.
}
 
private static void HandleClientDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    // Called for notifications not handled by the monitored item or the subscription.
}
vbnet
Dim subscription As OpcSubscription = client.SubscribeDataChange( _
        "ns=2;s=Machine/IsRunning", _
        AddressOf HandleItemDataChanged)

AddHandler subscription.DataChangeReceived, AddressOf HandleSubscriptionDataChanged
AddHandler client.DataChangeReceived, AddressOf HandleClientDataChanged
...
Private Shared Sub HandleItemDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    If e.Item.Value.Status.IsGood Then
        'Your code to process the value.

        'The handlers of the subscription and the client are not called.
        e.Handled = True
    End If
End Sub

Private Shared Sub HandleSubscriptionDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    'Called for notifications not handled by the monitored item.
End Sub

Private Shared Sub HandleClientDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    'Called for notifications not handled by the monitored item or the subscription.
End Sub

Wenn der Client eine Benachrichtigungsnachricht des Servers nicht empfangen kann, erreichen deren Wertänderungen und Ereignisse die MonitoredItems nicht. Das ist zum Beispiel der Fall, wenn sich ein Wert darin nicht dekodieren lässt. Stattdessen löst der Client das Ereignis NotificationFailed aus. Er löst es zuerst an der Subscription aus, zu der die Nachricht gehört. Wenn es dort nicht behandelt wird, löst er es am OpcClient aus. Die Eigenschaft Exception der Ereignisargumente nennt den Grund, zum Beispiel BadDecodingError oder BadEncodingLimitsExceeded.

Der Client fordert eine fehlgeschlagene Nachricht erneut vom Server an, solange der Server sie bereithält. Das Ereignis tritt je Nachricht einmal auf, unabhängig davon, wie oft sie fehlschlägt. Wenn die Nachricht verloren ist, tritt es ein weiteres Mal mit dem Status BadMessageNotAvailable auf. Wenn sich eine Nachricht keiner Subscription zuordnen lässt, meldet sie nur der OpcClient. Die Eigenschaft Subscription der Ereignisargumente ist dann null:

csharp
subscription.NotificationFailed += HandleSubscriptionNotificationFailed;
client.NotificationFailed += HandleClientNotificationFailed;
...
private static void HandleSubscriptionNotificationFailed(
        object sender,
        OpcNotificationFailedEventArgs e)
{
    Console.WriteLine("Notification failed: {0}", e.Exception.Code);
 
    // The OpcClient.NotificationFailed event is not raised for this failure.
    e.Handled = true;
}
 
private static void HandleClientNotificationFailed(
        object sender,
        OpcNotificationFailedEventArgs e)
{
    // The subscription is a null reference in case the message cannot be assigned to one.
    if (e.Subscription == null) {
        Console.WriteLine("Notification failed: {0}", e.Exception.Message);
    }
    else {
        Console.WriteLine(
                "Notification of subscription {0} failed: {1}",
                e.Subscription.Id,
                e.Exception.Message);
    }
}
vbnet
AddHandler subscription.NotificationFailed, AddressOf HandleSubscriptionNotificationFailed
AddHandler client.NotificationFailed, AddressOf HandleClientNotificationFailed
...
Private Shared Sub HandleSubscriptionNotificationFailed( _
        ByVal sender As Object, _
        ByVal e As OpcNotificationFailedEventArgs)
    Console.WriteLine("Notification failed: {0}", e.Exception.Code)

    'The OpcClient.NotificationFailed event is not raised for this failure.
    e.Handled = True
End Sub

Private Shared Sub HandleClientNotificationFailed( _
        ByVal sender As Object, _
        ByVal e As OpcNotificationFailedEventArgs)
    'The subscription is Nothing in case the message cannot be assigned to one.
    If e.Subscription Is Nothing Then
        Console.WriteLine("Notification failed: {0}", e.Exception.Message)
    Else
        Console.WriteLine( _
                "Notification of subscription {0} failed: {1}", _
                e.Subscription.Id, _
                e.Exception.Message)
    End If
End Sub

Wenn das Dekodieren wegen zu großer Werte fehlschlägt, erhöhen Sie die Grenzen der Datenübertragung.

Zusätzlich löst der Client für jede empfangene Benachrichtigung das Ereignis OpcClient.NotificationReceived aus. Das gilt auch für Benachrichtigungen ohne bestimmtes MonitoredItem: Wenn das PublishingInterval einer Subscription abgelaufen ist und der Server zwischenzeitlich keine Benachrichtigung gesendet hat, fordert der Client automatisch eine Aktualisierung an, und der Server antwortet mit einer leeren Benachrichtigung. Meist müssen Sie dieses Ereignis nicht behandeln, weil Sie die relevanten Benachrichtigungen über die Handler der MonitoredItems verarbeiten.

Subscriptions verwalten ​

Beteiligte TypenOpcClientOpcSubscriptionOpcSubscriptionSetupOpcMonitoredItemOpcMonitoringModeOpcMonitoredItemQueueMode

Subscription in einem Schritt anlegen: Über eine Instanz der Klasse OpcSubscriptionSetup legen Sie die MonitoredItems, die Eigenschaften und die Handler der Subscription fest. Die Methode CreateSubscription legt die Subscription dann zusammen mit ihren MonitoredItems auf dem Server an. Wenn der Client nicht verbunden ist, löst CreateSubscription ab Version 2.59 eine OpcException mit dem Status BadServerNotConnected aus. Ein anschließender Aufruf von ApplyChanges ist nicht nötig:

csharp
var setup = new OpcSubscriptionSetup(
        new OpcMonitoredItem("ns=2;s=Machine/IsRunning", OpcAttribute.Value),
        new OpcMonitoredItem("ns=2;s=Machine/Job/Speed", OpcAttribute.Value)) {
    PublishingInterval = 1000,
    DataChangeReceived = HandleDataChanged,
    NotificationFailed = HandleNotificationFailed
};
 
// Creates the subscription including its monitored items on the server.
OpcSubscription subscription = client.CreateSubscription(setup);
vbnet
Dim setup = New OpcSubscriptionSetup( _
        New OpcMonitoredItem("ns=2;s=Machine/IsRunning", OpcAttribute.Value), _
        New OpcMonitoredItem("ns=2;s=Machine/Job/Speed", OpcAttribute.Value)) With { _
    .PublishingInterval = 1000, _
    .DataChangeReceived = AddressOf HandleDataChanged, _
    .NotificationFailed = AddressOf HandleNotificationFailed _
}

'Creates the subscription including its monitored items on the server.
Dim subscription As OpcSubscription = client.CreateSubscription(setup)

Bestehende Subscription steuern: Sie können die Veröffentlichung der Benachrichtigungen anhalten und fortsetzen, die aktuellen Werte erneut anfordern und einzelne MonitoredItems deaktivieren oder entfernen. Die Methoden StopPublishing, StartPublishing, ResendData und ChangeMonitoringMode wirken direkt auf dem Server. Das Entfernen eines MonitoredItems übermittelt der Client erst mit ApplyChanges:

csharp
// Pause and resume the delivery of notifications of the subscription.
subscription.StopPublishing();
subscription.StartPublishing();
 
// Request the current values of all reporting monitored items again.
subscription.ResendData();
 
// Stop the sampling of a single monitored item and remove it afterwards.
subscription.ChangeMonitoringMode(OpcMonitoringMode.Disabled, item);
subscription.RemoveMonitoredItem(item);
 
// Always call apply changes after modifying the monitored items.
subscription.ApplyChanges();
vbnet
'Pause and resume the delivery of notifications of the subscription.
subscription.StopPublishing()
subscription.StartPublishing()

'Request the current values of all reporting monitored items again.
subscription.ResendData()

'Stop the sampling of a single monitored item and remove it afterwards.
subscription.ChangeMonitoringMode(OpcMonitoringMode.Disabled, item)
subscription.RemoveMonitoredItem(item)

'Always call apply changes after modifying the monitored items.
subscription.ApplyChanges()

Warteschlange eines MonitoredItems konfigurieren: Wenn mehr Wertänderungen auftreten, als je Veröffentlichung übertragen werden, puffert der Server sie in der Warteschlange des MonitoredItems (QueueSize, standardmäßig 1000). Wenn die Warteschlange voll ist, verwirft der Server standardmäßig den ältesten Wert (OpcMonitoredItemQueueMode.DiscardOldest):

csharp
var item = new OpcMonitoredItem("ns=2;s=Machine/Job/Speed", OpcAttribute.Value);
 
item.SamplingInterval = 100;    // 0 = fastest rate, -1 = publishing interval
item.QueueSize = 10;            // Default: 1000
item.QueueMode = OpcMonitoredItemQueueMode.DiscardOldest;
 
subscription.AddMonitoredItem(item);
subscription.ApplyChanges();
vbnet
Dim item = New OpcMonitoredItem("ns=2;s=Machine/Job/Speed", OpcAttribute.Value)

item.SamplingInterval = 100     '0 = fastest rate, -1 = publishing interval
item.QueueSize = 10             'Default: 1000
item.QueueMode = OpcMonitoredItemQueueMode.DiscardOldest

subscription.AddMonitoredItem(item)
subscription.ApplyChanges()

Änderungsfilter festlegen ​

Beteiligte TypenOpcClientOpcNodeIdOpcSubscribeDataChangeOpcDataChangeFilterOpcDataChangeTriggerOpcDeadbandTypeOpcSubscriptionOpcMonitoredItemOpcMonitoredItemCollectionOpcDataChangeReceivedEventHandlerOpcDataChangeReceivedEventArgsOpcNotification

Über eine Subscription erhält eine Clientanwendung grundsätzlich nur Benachrichtigungen über Änderungen des Status und des Werts eines Nodes. Damit der Server den Client nach anderen Regeln benachrichtigt, legen Sie den Auslöser (engl. Trigger) einer Benachrichtigung fest. Den Auslöser bestimmen Sie über einen Wert der Enumeration OpcDataChangeTrigger. Die folgenden Beispiele abonnieren so Benachrichtigungen über Änderungen des Status, des Werts oder des Zeitstempels eines Nodes.

Wert- und Zeitstempeländerungen eines Nodes abonnieren:

csharp
OpcSubscription subscription = client.SubscribeDataChange(
        "ns=2;s=Machine/IsRunning",
        OpcDataChangeTrigger.StatusValueTimestamp,
        HandleDataChanged);
vbnet
Dim subscription As OpcSubscription = client.SubscribeDataChange( _
        "ns=2;s=Machine/IsRunning", _
        OpcDataChangeTrigger.StatusValueTimestamp, _
        AddressOf HandleDataChanged)

Wert- und Zeitstempeländerungen mehrerer Nodes abonnieren:

csharp
OpcSubscribeDataChange[] commands = new OpcSubscribeDataChange[] {
    new OpcSubscribeDataChange(
            "ns=2;s=Machine/IsRunning",
            OpcDataChangeTrigger.StatusValueTimestamp,
            HandleDataChanged),
    new OpcSubscribeDataChange(
            "ns=2;s=Machine/Job/Speed",
            OpcDataChangeTrigger.StatusValueTimestamp,
            HandleDataChanged)
};
 
OpcSubscription subscription = client.SubscribeNodes(commands);
vbnet
Dim commands As OpcSubscribeDataChange() = New OpcSubscribeDataChange() { _
    New OpcSubscribeDataChange( _
            "ns=2;s=Machine/IsRunning", _
            OpcDataChangeTrigger.StatusValueTimestamp, _
            AddressOf HandleDataChanged), _
    New OpcSubscribeDataChange( _
            "ns=2;s=Machine/Job/Speed", _
            OpcDataChangeTrigger.StatusValueTimestamp, _
            AddressOf HandleDataChanged) _
}

Dim subscription As OpcSubscription = client.SubscribeNodes(commands)

Benachrichtigungen über Wert- und Zeitstempeländerungen behandeln:

csharp
private static void HandleDataChanged(
        object sender,
        OpcDataChangeReceivedEventArgs e)
{
    // Your code to execute on each data change.
    // The 'sender' variable contains the OpcMonitoredItem with the NodeId.
    OpcMonitoredItem item = (OpcMonitoredItem)sender;

    Console.WriteLine(
            "Data Change from NodeId '{0}': {1} at {2}",
            item.NodeId,
            e.Item.Value,
            e.Item.Value.SourceTimestamp);
}
vbnet
Private Shared Sub HandleDataChanged( _
        ByVal sender As Object, _
        ByVal e As OpcDataChangeReceivedEventArgs)
    'Your code to execute on each data change.
    'The 'sender' variable contains the OpcMonitoredItem with the NodeId.
    Dim item As OpcMonitoredItem = CType(sender, OpcMonitoredItem)

    Console.WriteLine( _
            "Data Change from NodeId '{0}': {1} at {2}", _
            item.NodeId, _
            e.Item.Value, _
            e.Item.Value.SourceTimestamp)
End Sub

Den Wert von OpcDataChangeTrigger aus den vorangegangenen Beispielen können Sie ebenso über eine Instanz der Klasse OpcDataChangeFilter festlegen. So verwenden Sie einen einmal definierten Filter für mehrere Subscriptions und MonitoredItems:

csharp
var filter = new OpcDataChangeFilter();
filter.Trigger = OpcDataChangeTrigger.StatusValueTimestamp;
 
OpcSubscription subscriptionA = client.SubscribeDataChange(
        "ns=2;s=Machine/IsRunning",
        filter,
        HandleDataChanged);
 
// or
 
OpcSubscribeDataChange[] commands = new OpcSubscribeDataChange[] {
    new OpcSubscribeDataChange(
            "ns=2;s=Machine/IsRunning",
            filter,
            HandleDataChanged),
    new OpcSubscribeDataChange(
            "ns=2;s=Machine/Job/Speed",
            filter,
            HandleDataChanged)
};
 
OpcSubscription subscriptionB = client.SubscribeNodes(commands);
vbnet
Dim filter = New OpcDataChangeFilter()
filter.Trigger = OpcDataChangeTrigger.StatusValueTimestamp

Dim subscriptionA As OpcSubscription = client.SubscribeDataChange( _
        "ns=2;s=Machine/IsRunning", _
        filter, _
        AddressOf HandleDataChanged)

'or

Dim commands As OpcSubscribeDataChange() = New OpcSubscribeDataChange() { _
    New OpcSubscribeDataChange( _
            "ns=2;s=Machine/IsRunning", _
            filter, _
            AddressOf HandleDataChanged), _
    New OpcSubscribeDataChange( _
            "ns=2;s=Machine/Job/Speed", _
            filter, _
            AddressOf HandleDataChanged) _
}

Dim subscriptionB As OpcSubscription = client.SubscribeNodes(commands)

Nur Wertänderungen ab einer bestimmten Größe melden: Die Eigenschaften DeadbandType und DeadbandValue der Klasse OpcDataChangeFilter legen fest, ab welcher Wertänderung der Server benachrichtigt. Mit OpcDeadbandType.Absolute gibt DeadbandValue die absolute Änderung an, mit OpcDeadbandType.Percent die prozentuale Änderung bezogen auf den Wertebereich des Nodes (EngineeringUnitRange). Ob ein Server einen prozentualen Deadband unterstützt, hängt vom Server und vom Node ab:

csharp
// Report only changes of the value which exceed 0.5 (absolute).
var filter = new OpcDataChangeFilter(OpcDataChangeTrigger.StatusValue) {
    DeadbandType = OpcDeadbandType.Absolute,
    DeadbandValue = 0.5
};
 
OpcSubscription subscription = client.SubscribeDataChange(
        "ns=2;s=Machine/Job/Speed",
        filter,
        HandleDataChanged);
vbnet
'Report only changes of the value which exceed 0.5 (absolute).
Dim filter = New OpcDataChangeFilter(OpcDataChangeTrigger.StatusValue) With { _
    .DeadbandType = OpcDeadbandType.Absolute, _
    .DeadbandValue = 0.5 _
}

Dim subscription As OpcSubscription = client.SubscribeDataChange( _
        "ns=2;s=Machine/Job/Speed", _
        filter, _
        AddressOf HandleDataChanged)