Zum Inhalt springen

Anleitung

Alarme und Bedingungen

Ereignis-Nodes mit Bedingungen: Dialog- und Feedback-Bedingungen, Alarm-Bedingungen bis zu Grenzwert-Alarmen.

Anleitung

Alarme und Bedingungen ​

Ereignis-Nodes mit Bedingungen melden Ereignisse, die an den Zustand einer Bedingung geknüpft sind. Diese Seite zeigt, wie ein Client die Ereignisdaten der einzelnen Bedingungsarten verarbeitet, von einfachen Bedingungen bis zu Grenzwert-Alarmen, und wie er die Bedingungen eines OPC AE Servers (Alarms & Events) empfängt.

Bedingungen ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcEventOpcConditionOpcEventSeverity

Die Klasse OpcCondition ist eine Spezialisierung der Klasse OpcEvent, die die Seite Ereignisse vorstellt. Sie stellt Ereignisdaten bereit, die an bestimmte Bedingungen geknüpft sind. Der Server löst ein solches Ereignis nur aus, wenn die Bedingung zutrifft, die dem Ereignis-Node zugeordnet ist. Die Ereignisdaten enthalten Informationen über den Zustand der Bedingung und Informationen, die an die Auswertung der Bedingung geknüpft sind. Diese Informationen können je nach Anwendungsfall unterschiedlich komplex sein. Deshalb ist OpcCondition die Basisklasse aller Ereignisdaten, an die eine Bedingung geknüpft ist.

Neben den allgemeinen Eigenschaften eines Ereignisses aus der Basisklasse OpcEvent liefert eine Instanz von OpcCondition weitere Informationen, die für die Verarbeitung im Client wichtig sein können. Die Eigenschaft IsRetained zeigt, ob der Server das Ereignis allgemein als relevant für Clients beurteilt. Die Eigenschaft IsEnabled zeigt, ob die Bedingung aktiviert oder deaktiviert ist. Ob ein Alarm aktiv ist, zeigt dagegen die Eigenschaft IsActive der Alarm-Bedingungen (Abschnitt Alarm-Bedingungen).

csharp
private static void HandleLocalEvents(
        object sender,
        OpcEventReceivedEventArgs e)
{
    var condition = e.Event as OpcCondition;
 
    if (condition != null && condition.IsRetained) {
        Console.Write((condition.ClientUserId ?? "Comment") + ":");
        Console.WriteLine(condition.Comment);
    }
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim condition = TryCast(e.Event, OpcCondition)

    If condition IsNot Nothing AndAlso condition.IsRetained Then
        Console.Write(If(condition.ClientUserId, "Comment") & ":")
        Console.WriteLine(condition.Comment)
    End If
End Sub

Wenn der Client die Bedingung nicht weiter auswerten soll, deaktiviert er sie:

csharp
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
    var condition = e.Event as OpcCondition;
 
    if (condition.IsEnabled && condition.Severity < OpcEventSeverity.Medium)
        condition.Disable(client);
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim condition = TryCast(e.Event, OpcCondition)

    If condition.IsEnabled AndAlso condition.Severity < OpcEventSeverity.Medium Then
        condition.Disable(client)
    End If
End Sub

Zusätzlich kann der Client einen Kommentar zum aktuellen Zustand der Bedingung hinzufügen:

csharp
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
    var condition = e.Event as OpcCondition;
 
    if (condition != null)
        condition.AddComment(client, "Evaluated by me!");
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim condition = TryCast(e.Event, OpcCondition)

    If condition IsNot Nothing Then
        condition.AddComment(client, "Evaluated by me!")
    End If
End Sub

Dialog-Bedingungen ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcConditionOpcDialogConditionOpcEventSeverityOpcDialogRequestedEventArgs

Die Klasse OpcDialogCondition ist eine Spezialisierung von OpcCondition. Die Bedingung dieses Ereignisses ist ein Dialog mit den Abonnenten. Eine solche Bedingung besteht aus einer Meldung (engl. Prompt) und Antwortoptionen (engl. Response Options). Dazu kommen drei Angaben: Die Eigenschaft DefaultResponse nennt die Option, die standardmäßig ausgewählt sein sollte. Die Eigenschaft OkResponse nennt die Option zur Bestätigung des Dialogs, die Eigenschaft CancelResponse die Option zum Abbruch. Wenn der Server ein solches Ereignis auslöst, wartet er, bis einer der Abonnenten mit einer der vorgegebenen Antwortoptionen antwortet. Die Operationen, die an den Dialog geknüpft sind, setzen also eine Antwort voraus: auf eine Aufgabenstellung, eine Frage, eine Information oder eine Warnung. So verarbeitet der Client die Informationen des Ereignisses und meldet die Antwort an den Server zurück:

csharp
private void HandleLocalEvents(
        object sender,
        OpcEventReceivedEventArgs e)
{
    var condition = e.Event as OpcDialogCondition;
 
    if (condition != null && condition.IsActive) {
        Console.WriteLine(condition.Prompt);
        Console.WriteLine("    Options:");
 
        var responseOptions = condition.ResponseOptions;
 
        for (int index = 0; index < responseOptions.Length; index++) {
            Console.Write("      [{0}] = {1}", index, responseOptions[index].Value);
 
            if (index == condition.DefaultResponse)
                Console.Write(" (default)");
 
            Console.WriteLine();
        }
 
        var respond = string.Empty;
        var respondOption = condition.DefaultResponse;
 
        do {
            Console.Write("Enter the number of the option and press Enter to respond: ");
            respond = Console.ReadLine();
 
            if (string.IsNullOrEmpty(respond))
                break;
        } while (!int.TryParse(respond, out respondOption));
 
        condition.Respond(client, respondOption);
 
        // The dialog has been answered, the DialogRequested event is not raised.
        e.Handled = true;
    }
}
vbnet
Private Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim condition = TryCast(e.Event, OpcDialogCondition)

    If condition IsNot Nothing AndAlso condition.IsActive Then
        Console.WriteLine(condition.Prompt)
        Console.WriteLine("    Options:")

        Dim responseOptions = condition.ResponseOptions

        For index As Integer = 0 To responseOptions.Length - 1
            Console.Write("      [{0}] = {1}", index, responseOptions(index).Value)

            If index = condition.DefaultResponse Then
                Console.Write(" (default)")
            End If

            Console.WriteLine()
        Next

        Dim respond = String.Empty
        Dim respondOption = condition.DefaultResponse

        Do
            Console.Write("Enter the number of the option and press Enter to respond: ")
            respond = Console.ReadLine()

            If String.IsNullOrEmpty(respond) Then
                Exit Do
            End If
        Loop While Not Integer.TryParse(respond, respondOption)

        condition.Respond(client, respondOption)

        'The dialog has been answered, the DialogRequested event is not raised.
        e.Handled = True
    End If
End Sub

Neben dem Standardverfahren zur Ereignisbehandlung bietet die Klasse OpcClient das Ereignis DialogRequested. Wenn der Client Ereignisdaten vom Typ OpcDialogCondition empfängt und kein Handler die Eigenschaft Handled der Ereignisargumente auf true gesetzt hat, löst der Client das Ereignis DialogRequested aus. Darüber verarbeiten Sie den Dialog. Wenn ein Handler den Dialog bereits selbst beantwortet, setzen Sie deshalb wie im vorherigen Beispiel die Eigenschaft Handled. Andernfalls beantwortet der Client den Dialog ein zweites Mal. Mit DialogRequested ist die Handhabung der Ereignisdaten etwas einfacher, weil der Ereignishandler sie typisiert erhält:

csharp
client.DialogRequested += HandleDialogRequested;
...
private static void HandleDialogRequested(
        object sender,
        OpcDialogRequestedEventArgs e)
{
    // Just use the default response, here.
    e.SelectedResponse = e.Dialog.DefaultResponse;
}
vbnet
AddHandler client.DialogRequested, AddressOf HandleDialogRequested
...
Private Shared Sub HandleDialogRequested( _
        ByVal sender As Object, _
        ByVal e As OpcDialogRequestedEventArgs)
    'Just use the default response, here.
    e.SelectedResponse = e.Dialog.DefaultResponse
End Sub

Setzen Sie nur die Eigenschaft SelectedResponse der Ereignisargumente. Die Methode Respond der Klasse OpcDialogCondition ruft OpcClient nach dem Ereignishandler selbst auf. Wenn SelectedResponse beim Standardwert -1 bleibt oder außerhalb der Antwortoptionen liegt, sendet der Client keine Antwort.

Feedback-Bedingungen ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcEventOpcConditionOpcAcknowledgeableConditionOpcEventSeverity

Die Klasse OpcAcknowledgeableCondition ist eine Spezialisierung von OpcCondition. Sie ist die Basisklasse für Bedingungen, die ein Feedback anfordern. Ein solches Ereignis funktioniert wie eine Meldung mit Rückschein: Wenn seine Bedingung erfüllt ist, sendet der Server die Meldung und fordert ein Feedback an. Der Rückschein, also das Feedback, kann weitere Abläufe steuern oder Hinweise und Warnungen einfach quittieren. Die OPC-UA-Spezifikation (Teil 9) sieht dafür zwei Arten von Feedback vor. Die Quittierung (engl. Acknowledge) bestätigt, dass die Meldung zur Kenntnis genommen wurde. Die Bestätigung (engl. Confirm) bestätigt im Anschluss, dass die Ursache der Meldung behoben ist. Diese zweite Stufe ist optional, nicht jeder Server verwendet sie. Für beide Arten stellen die Ereignisse die Methoden Acknowledge und Confirm bereit. Die beiden Zustände sind unabhängig voneinander: Eine Quittierung setzt nicht zugleich die Bestätigung und umgekehrt. Optional geben Sie bei der Quittierung und bei der Bestätigung einen Kommentar der bearbeitenden Person an. So implementieren Sie eine Quittierung als Feedback:

csharp
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
    var condition = e.Event as OpcAcknowledgeableCondition;
 
    if (condition != null && !condition.IsAcked) {
        Console.WriteLine($"Acknowledgment is required for condtion: {condition.ConditionName}");
        Console.WriteLine($"  -> {condition.Message}");
        Console.Write("Enter your acknowlegment comment and press Enter to acknowledge: ");
 
        var comment = Console.ReadLine();
        condition.Acknowledge(client, comment);
    }
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim condition = TryCast(e.Event, OpcAcknowledgeableCondition)

    If condition IsNot Nothing AndAlso Not condition.IsAcked Then
        Console.WriteLine("Acknowledgment is required for condtion: {0}", condition.ConditionName)
        Console.WriteLine("  -> {0}", condition.Message)
        Console.Write("Enter your acknowlegment comment and press Enter to acknowledge: ")

        Dim comment = Console.ReadLine()
        condition.Acknowledge(client, comment)
    End If
End Sub

Bei der Verarbeitung solcher Ereignisse prüft der Client zusätzlich, ob das Ereignis bereits bestätigt (Eigenschaft IsConfirmed) oder quittiert (Eigenschaft IsAcked) wurde. Der Server definiert die Interpretation des Feedbacks und die darauf folgende Logik stets selbst. Ob ein Server beide Feedback-Arten nutzt oder nur eine, entscheidet also das Team, das ihn entwickelt. Im besten Fall unterstützt ein Server mindestens die Methode Acknowledge, da die Spezifikation die Bestätigung als optionale zweite Stufe nach der Quittierung vorsieht.

Alarm-Bedingungen ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcAlarmConditionOpcAcknowledgeableConditionOpcEventSeverity

Die wohl wichtigste Implementierung von OpcAcknowledgeableCondition in OPC UA ist die Klasse OpcAlarmCondition. Ereignisse dieser Klasse verhalten sich wie ein Nachttischwecker. Ein solches Ereignis wird aktiv (Eigenschaft IsActive), wenn die verknüpfte Bedingung erfüllt ist. Beim Wecker ist das zum Beispiel das Erreichen der Weckzeit. Ein Alarm, der zwar eine Weckzeit hat, aber beim Erreichen nicht aktiv werden soll, heißt unterdrückter Alarm (engl. suppressed alarm, Eigenschaften IsSuppressed und IsSuppressedOrShelved). Wenn ein Alarm aktiv wird, kann der Server ihn zurückstellen (engl. shelved): einmalig („One Shot Shelving“) oder zeitlich („Timed Shelving“). Ob ein Alarm unterdrückt oder zurückgestellt ist, zeigt die Eigenschaft IsSuppressedOrShelved. Wie lange ein Alarm höchstens zurückgestellt sein darf, zeigt die Eigenschaft MaxTimeShelved.

csharp
private static void HandleLocalEvents(
        object sender,
        OpcEventReceivedEventArgs e)
{
    var alarm = e.Event as OpcAlarmCondition;
 
    if (alarm != null) {
        Console.Write($"Alarm {alarm.ConditionName} is");
        Console.WriteLine($"{(alarm.IsActive ? "active" : "inactive")}!");
    }
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim alarm = TryCast(e.Event, OpcAlarmCondition)

    If alarm IsNot Nothing Then
        Console.Write("Alarm {0} is", alarm.ConditionName)
        Console.WriteLine("{0}!", If(alarm.IsActive, "active", "inactive"))
    End If
End Sub

Diskrete Alarme ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcDiscreteAlarmOpcOffNormalAlarmOpcTripAlarm

Für die Ereignisdaten von OpcAlarmCondition gibt es mehrere Spezialisierungen für bestimmte Arten von Alarmen. Bei ihnen beschreibt bereits die Art des Alarms seine Form, seinen Grund oder seinen Inhalt genauer. Eine Unterklasse solcher selbstbeschreibenden Alarme sind die diskreten Alarme. Ihre Basis ist die Klasse OpcDiscreteAlarm. Sie steht für Alarme, deren Eingang nur eine bestimmte Anzahl möglicher Werte annehmen kann, zum Beispiel wahr und falsch oder läuft, angehalten und beendet. Wenn ein Alarm einen diskreten Zustand darstellt, der als nicht normal gilt, beschreibt ihn die Klasse OpcOffNormalAlarm oder eine ihrer Unterklassen. Auf den Zustand, der als normal gilt, verweist die Eigenschaft NormalStateId. Eine weitere Konkretisierung dieser Alarmklasse bietet das SDK mit der Klasse OpcTripAlarm. Dieser Alarm wird aktiv, wenn an einem überwachten Gerät ein anomaler Fehler auftritt, zum Beispiel wenn der Motor wegen Überlastung abschaltet.

csharp
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
    var alarm = e.Event as OpcDiscreteAlarm;
 
    if (alarm != null) {
        if (alarm is OpcTripAlarm)
            Console.WriteLine("Trip Alarm!");
        else if (alarm is OpcOffNormalAlarm)
            Console.WriteLine("Off Normal Alarm!");
    }
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim alarm = TryCast(e.Event, OpcDiscreteAlarm)

    If alarm IsNot Nothing Then
        If TypeOf alarm Is OpcTripAlarm Then
            Console.WriteLine("Trip Alarm!")
        ElseIf TypeOf alarm Is OpcOffNormalAlarm Then
            Console.WriteLine("Off Normal Alarm!")
        End If
    End If
End Sub

Grenzwert-Alarme ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcLimitAlarm

Wenn der Server prozessspezifische Grenzwerte prüft und das Ergebnis bei Über- oder Unterschreitung veröffentlicht, ist die Klasse OpcLimitAlarm der zentrale Einstieg in die Klassen der Grenzwert-Alarme (engl. limit alarms). Diese Klasse unterteilt Grenzwerte in bis zu vier Stufen. In der Reihenfolge ihrer metrischen Ordnung heißen sie LowLow, Low, High und HighHigh. Laut Definition muss der Server nicht alle Grenzwerte definieren.

csharp
private static void HandleLocalEvents(
        object sender,
        OpcEventReceivedEventArgs e)
{
    var alarm = e.Event as OpcLimitAlarm;
 
    if (alarm != null) {
        Console.Write(alarm.LowLowLimit);
        Console.Write(" ≤ ");
        Console.Write(alarm.LowLimit);
        Console.Write(" ≤ ");
        Console.Write(alarm.HighLimit);
        Console.Write(" ≤ ");
        Console.Write(alarm.HighHighLimit);
    }
}
vbnet
Private Shared Sub HandleLocalEvents( _
        ByVal sender As Object, _
        ByVal e As OpcEventReceivedEventArgs)
    Dim alarm = TryCast(e.Event, OpcLimitAlarm)

    If alarm IsNot Nothing Then
        Console.Write(alarm.LowLowLimit)
        Console.Write(" ≤ ")
        Console.Write(alarm.LowLimit)
        Console.Write(" ≤ ")
        Console.Write(alarm.HighLimit)
        Console.Write(" ≤ ")
        Console.Write(alarm.HighHighLimit)
    End If
End Sub

Ausschließliche Grenzwert-Alarme ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcLimitAlarmOpcExclusiveLimitAlarmOpcExclusiveDeviationAlarmOpcExclusiveLevelAlarmOpcExclusiveRateOfChangeAlarm

Die Klasse OpcExclusiveLimitAlarm ist eine Unterklasse von OpcLimitAlarm. Wie ihr Name sagt, definiert sie Grenzwert-Alarme für ausschließliche Grenzen. Die Grenzwerte eines solchen Alarms schließen sich gegenseitig aus. Wenn ein Grenzwert über- oder unterschritten ist, kann also nicht zugleich ein anderer Grenzwert über- oder unterschritten sein.

In OPC UA gibt es drei weitere Spezialisierungen der Klasse OpcExclusiveLimitAlarm.

OpcExclusiveDeviationAlarm

Dieser Alarm meldet, dass der Wert um mehr als die Grenzwerte von einem Sollwert abweicht. Auf den Node des Sollwerts verweist die Eigenschaft SetpointNodeId.

OpcExclusiveLevelAlarm

Dieser Alarm meldet eine Grenzwertüberschreitung, typischerweise an einem Instrument wie einem Temperatursensor. Er wird aktiv, wenn der beobachtete Wert über einem oberen oder unter einem unteren Grenzwert liegt.

OpcExclusiveRateOfChangeAlarm

Dieser Alarm meldet eine ungewöhnliche oder fehlende Änderung eines gemessenen Werts, bezogen auf die Geschwindigkeit der Änderung. Er wird aktiv, wenn die Änderungsrate des Werts einen definierten Grenzwert über- oder unterschreitet.

Nicht-ausschließliche Grenzwert-Alarme ​

Beteiligte TypenOpcClientOpcEventReceivedEventArgsOpcLimitAlarmOpcNonExclusiveLimitAlarmOpcNonExclusiveDeviationAlarmOpcNonExclusiveLevelAlarmOpcNonExclusiveRateOfChangeAlarm

Die Klasse OpcNonExclusiveLimitAlarm ist eine Unterklasse von OpcLimitAlarm. Wie ihr Name sagt, definiert sie Grenzwert-Alarme für nicht-ausschließliche Grenzen. Die Grenzwerte eines solchen Alarms schließen sich gegenseitig nicht aus. Wenn ein Grenzwert über- oder unterschritten ist, kann also zugleich ein anderer Grenzwert über- oder unterschritten sein. Die verletzten Grenzen prüfen Sie mit den Eigenschaften IsLowLow, IsLow, IsHigh und IsHighHigh der Ereignisdaten.

In OPC UA gibt es drei weitere Spezialisierungen der Klasse OpcNonExclusiveLimitAlarm.

OpcNonExclusiveDeviationAlarm

Dieser Alarm meldet, dass der Wert um mehr als die Grenzwerte von einem Sollwert abweicht. Auf den Node des Sollwerts verweist die Eigenschaft SetpointNodeId.

OpcNonExclusiveLevelAlarm

Dieser Alarm meldet eine Grenzwertüberschreitung, typischerweise an einem Instrument wie einem Temperatursensor. Er wird aktiv, wenn der beobachtete Wert über einem oberen oder unter einem unteren Grenzwert liegt.

OpcNonExclusiveRateOfChangeAlarm

Dieser Alarm meldet eine ungewöhnliche oder fehlende Änderung eines gemessenen Werts, bezogen auf die Geschwindigkeit der Änderung. Er wird aktiv, wenn die Änderungsrate des Werts einen definierten Grenzwert über- oder unterschreitet.

Bedingungen eines OPC AE Servers ​

Ereignisse und Bedingungen eines OPC AE Servers empfängt und quittiert der Client mit denselben Methoden. Den Ablauf beschreibt der Abschnitt Alarme und Ereignisse (AE) auf der Seite OPC Classic.