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).
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);
}
}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 SubWenn der Client die Bedingung nicht weiter auswerten soll, deaktiviert er sie:
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
var condition = e.Event as OpcCondition;
if (condition.IsEnabled && condition.Severity < OpcEventSeverity.Medium)
condition.Disable(client);
}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 SubZusätzlich kann der Client einen Kommentar zum aktuellen Zustand der Bedingung hinzufügen:
private static void HandleLocalEvents(object sender, OpcEventReceivedEventArgs e)
{
var condition = e.Event as OpcCondition;
if (condition != null)
condition.AddComment(client, "Evaluated by me!");
}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 SubDialog-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:
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;
}
}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 SubNeben 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:
client.DialogRequested += HandleDialogRequested;
...
private static void HandleDialogRequested(
object sender,
OpcDialogRequestedEventArgs e)
{
// Just use the default response, here.
e.SelectedResponse = e.Dialog.DefaultResponse;
}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 SubSetzen 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:
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);
}
}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 SubBei 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.
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")}!");
}
}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 SubDiskrete 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.
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!");
}
}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 SubGrenzwert-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.
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);
}
}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 SubAusschließ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.

