Skip to content

How-to guide

Alarms and conditions

Provide event nodes with conditions: dialog and acknowledgeable conditions, alarm conditions up to limit alarms.

This content was machine translated and may contain errors. Read in German

How-to guide

Alarms and conditions ​

Event nodes with conditions report events that are tied to the state of a condition. This page shows how a server provides event nodes for each kind of condition, from simple conditions to limit alarms.

Conditions ​

Types usedOpcServerOpcNodeManagerOpcConditionNodeOpcConditionRetainPolicy

The OpcConditionNode class is a specialization of OpcEventNode, which Provide events on a node introduces. With OpcConditionNode, you define events that are tied to specific conditions. The server should trigger such an event only if the condition of the event node applies. The information of the node also includes the state of this condition and information tied to the evaluation of the condition.

Depending on the use case, this information can vary in complexity. For this reason, OpcConditionNode is the base class of all event nodes tied to a condition. You create such a node like an OpcEventNode. The following sections therefore show only the additional properties.

The IsRetained property states whether a condition is of interest to a client and is reported on a ConditionRefresh. By default, the OPC UA .NET SDK updates it automatically from the states of the condition. The IsRetainedPolicy property defines the rule it follows (enumeration OpcConditionRetainPolicy):

  • EnabledOnly (default of OpcConditionNode): set as long as the condition is enabled.
  • ActiveOrUnacknowledged (default of OpcAcknowledgeableConditionNode and OpcAlarmConditionNode): set as long as the alarm is active or not yet acknowledged.
  • ActiveOrUnconfirmed: set as long as the alarm is active or not yet confirmed.
  • ActiveOnly: set as long as the alarm is active, regardless of acknowledgment.
  • Manual: the SDK does not change the property; the application sets it itself.

Regardless of the rule, IsRetained is never set for a disabled condition. A value of the IsRetained property that you set manually is therefore kept only with the Manual rule:

csharp
var maintenanceEvent = new OpcConditionNode(machineOne, "Maintenance");
 
// Default: EnabledOnly for an OpcConditionNode,
// ActiveOrUnacknowledged for acknowledgeable conditions and alarms.
maintenanceEvent.IsRetainedPolicy = OpcConditionRetainPolicy.Manual;
 
// Interesting for a client yes or no (only kept in case of the Manual policy).
maintenanceEvent.IsRetained = true;
 
// Status of the source the condition is based upon.
maintenanceEvent.Quality = OpcStatusCode.Good;
vbnet
Dim maintenanceEvent = New OpcConditionNode(machineOne, "Maintenance")

'Default: EnabledOnly for an OpcConditionNode,
'ActiveOrUnacknowledged for acknowledgeable conditions and alarms.
maintenanceEvent.IsRetainedPolicy = OpcConditionRetainPolicy.Manual

'Interesting for a client yes or no (only kept in case of the Manual policy).
maintenanceEvent.IsRetained = True

'Status of the source the condition is based upon.
maintenanceEvent.Quality = OpcStatusCode.Good

With the AddComment method and the child node of the same name, a client can change the Comment property of the node. The server responds to the call through the AddCommentCallback property. You evaluate the result of the change with the following properties:

csharp
// Identifier of the user who supplied the Comment
maintenanceEvent.ClientUserId = ...;

// Last comment provided by a user
maintenanceEvent.Comment = ...;
vbnet
' Identifier of the user who supplied the Comment
maintenanceEvent.ClientUserId = ...

' Last comment provided by a user
maintenanceEvent.Comment = ...

On the server side, you change the states of a condition with the methods whose names start with Change, for example ChangeIsEnabled or ChangeComment. These methods are available only once the node exists in the address space. Before that, they throw an InvalidOperationException. If the AutoReportChanges property is set (it is not by default), the node automatically reports an event after each of these changes:

csharp
// Use the Change methods once the node has been added to the address space.
maintenanceEvent.ChangeIsEnabled(this.SystemContext, value: false);
maintenanceEvent.ChangeComment(this.SystemContext, value: "Planned maintenance");
 
// Reports an event whenever one of the Change methods completes.
maintenanceEvent.AutoReportChanges = true;
vbnet
'Use the Change methods once the node has been added to the address space.
maintenanceEvent.ChangeIsEnabled(Me.SystemContext, value:=False)
maintenanceEvent.ChangeComment(Me.SystemContext, value:="Planned maintenance")

'Reports an event whenever one of the Change methods completes.
maintenanceEvent.AutoReportChanges = True

If the same event node should be processed on several tracks in parallel, you can open a new event branch. The CreateBranch method of the node does this. The node stores the unique key of the branch in the BranchId property. The following code shows the most important parts of OpcConditionNode for branches:

csharp
// Uses a new GUID as BranchId.
var maintenanceBranchA = maintenanceEvent.CreateBranch(this.SystemContext);
 
// Uses a custom NodeId as BranchId.
var maintenanceBranchB = maintenanceEvent.CreateBranch(
        this.SystemContext,
        branchId: new OpcNodeId(10001));
vbnet
'Uses a new GUID as BranchId.
Dim maintenanceBranchA = maintenanceEvent.CreateBranch(Me.SystemContext)

'Uses a custom NodeId as BranchId.
Dim maintenanceBranchB = maintenanceEvent.CreateBranch( _
        Me.SystemContext, _
        branchId:=New OpcNodeId(10001))

The BranchId property identifies the branch an event belongs to. A null reference stands for the current state. The LastSeverity property returns the previous severity of the branch.

Dialog conditions ​

Types usedOpcServerOpcNodeManagerOpcDialogConditionNode

The OpcDialogConditionNode class is a specialization of OpcConditionNode. The condition of this node is a dialog with the subscribers. Such a condition consists of a prompt and response options. Three more details complete it: the option selected by default (DefaultResponse property), the option that confirms the dialog (OkResponse property), and the option that cancels it (CancelResponse property). When the server triggers such a dialog event, it waits until one of the subscribers responds. The response is a choice from the given response options.

The condition for further processing of the operations tied to the dialog is therefore the response to a task, a question, a piece of information, or a warning. Once you have created the node as usual, set the properties to fit the use case:

csharp
var outOfMaterial = new OpcDialogConditionNode(machineOne, "MaterialAlert");

outOfMaterial.Message = "Out of Material"; // Generic event message
outOfMaterial.Prompt = "The machine is out of material. Refill material supply to continue.";
outOfMaterial.ResponseOptions = new OpcText[] { "Continue", "Cancel" };
outOfMaterial.DefaultResponse = 0; // Index of ResponseOption to use
outOfMaterial.CancelResponse = 1;  // Index of ResponseOption to use
outOfMaterial.OkResponse = 0;      // Index of ResponseOption to use
vbnet
Dim outOfMaterial As New OpcDialogConditionNode(machineOne, "MaterialAlert")

outOfMaterial.Message = "Out of Material" ' Generic event message
outOfMaterial.Prompt = "The machine is out of material. Refill material supply to continue."
outOfMaterial.ResponseOptions = New OpcText() {"Continue", "Cancel"}
outOfMaterial.DefaultResponse = 0 ' Index of ResponseOption to use
outOfMaterial.CancelResponse = 1 ' Index of ResponseOption to use
outOfMaterial.OkResponse = 0 ' Index of ResponseOption to use

To let the subscribers respond to the dialog, activate it with the ActivateDialog method once the node exists in the address space. You handle the response of a subscriber in the RespondCallback of the node. The RespondDialog method accepts the response and deactivates the dialog again. The LastResponse property returns the response accepted last:

csharp
outOfMaterial.RespondCallback = this.HandleOutOfMaterialResponse;
outOfMaterial.ActivateDialog(this.SystemContext);
...
private OpcStatusCode HandleOutOfMaterialResponse(
        OpcNodeContext<OpcDialogConditionNode> context,
        int selectedResponse)
{
    // Handle the response.
    if (context.Node.OkResponse == selectedResponse)
        ContinueJob();
    else
        CancelJob();
 
    // Apply the response.
    context.Node.RespondDialog(context, selectedResponse);
 
    return OpcStatusCode.Good;
}
vbnet
outOfMaterial.RespondCallback = AddressOf Me.HandleOutOfMaterialResponse
outOfMaterial.ActivateDialog(Me.SystemContext)
...
Private Function HandleOutOfMaterialResponse( _
        ByVal context As OpcNodeContext(Of OpcDialogConditionNode), _
        ByVal selectedResponse As Integer) As OpcStatusCode
    'Handle the response.
    If context.Node.OkResponse = selectedResponse Then
        ContinueJob()
    Else
        CancelJob()
    End If

    'Apply the response.
    context.Node.RespondDialog(context, selectedResponse)

    Return OpcStatusCode.Good
End Function

Acknowledgeable conditions ​

Types usedOpcServerOpcNodeManagerOpcAcknowledgeableConditionNode

The OpcAcknowledgeableConditionNode class is a specialization of OpcConditionNode. It is the base class for conditions that request feedback. When the condition of such an event is met, the server sends a kind of "message with return receipt". The return receipt, that is, the feedback, can control further processes or simply acknowledge notes and warnings. The OPC UA specification (Part 9) provides a feedback mechanism with two kinds of feedback for this. With Acknowledge, the operators confirm that they have taken note of the message. With the optional Confirm, they then report that the cause has been resolved. For both kinds of feedback, the node provides the Acknowledge and Confirm child nodes.

The SDK handles both kinds of feedback independently of each other: acknowledging sets only the Acked state, confirming sets only the Confirmed state. The application defines the order the server requires. With both kinds of feedback, the operators can optionally add a comment. You create such a node as usual. Here too, you can set the states only once the node exists in the address space:

csharp
var outOfProcessableBounds = new OpcAcknowledgeableConditionNode(machineOne, "OutOfBoundsAlert");
 
// Once the node has been added to the address space:
// Define the condition as: Needs to be acknowledged.
outOfProcessableBounds.ChangeIsAcked(this.SystemContext, value: false);
 
// Define the condition as: Needs to be confirmed.
outOfProcessableBounds.ChangeIsConfirmed(this.SystemContext, value: false);
vbnet
Dim outOfProcessableBounds = New OpcAcknowledgeableConditionNode(machineOne, "OutOfBoundsAlert")

'Once the node has been added to the address space:
'Define the condition as: Needs to be acknowledged.
outOfProcessableBounds.ChangeIsAcked(Me.SystemContext, value:=False)

'Define the condition as: Needs to be confirmed.
outOfProcessableBounds.ChangeIsConfirmed(Me.SystemContext, value:=False)

Later in the process, you check received feedback with the IsAcked and IsConfirmed properties of the node:

csharp
if (outOfProcessableBounds.IsAcked) {
    ...
}

if (outOfProcessableBounds.IsConfirmed) {
    ...
}
vbnet
If outOfProcessableBounds.IsAcked Then
    ...
End If

If outOfProcessableBounds.IsConfirmed Then
    ...
End If

The server responds to the feedback of a client through the AcknowledgeCallback and ConfirmCallback properties. The server itself acknowledges or confirms a condition with the Acknowledge and Confirm methods:

csharp
outOfProcessableBounds.AcknowledgeCallback = (context, eventId, comment) => {
    Console.WriteLine("Acknowledged: {0}", comment);
    return OpcStatusCode.Good;
};
 
// Acknowledge or confirm the condition on the server side.
outOfProcessableBounds.Acknowledge(this.SystemContext, comment: "Acknowledged by the server");
outOfProcessableBounds.Confirm(this.SystemContext);
vbnet
outOfProcessableBounds.AcknowledgeCallback = Function(context, eventId, comment)
    Console.WriteLine("Acknowledged: {0}", comment)
    Return OpcStatusCode.Good
End Function

'Acknowledge or confirm the condition on the server side.
outOfProcessableBounds.Acknowledge(Me.SystemContext, comment:="Acknowledged by the server")
outOfProcessableBounds.Confirm(Me.SystemContext)

The server must always define its own interpretation of the feedback and the logic that follows. Whether a server uses both kinds of feedback or only one is up to the development team. A server should support at least Acknowledge. According to the specification, Confirm is optional.

Alarm conditions ​

Types usedOpcServerOpcNodeManagerOpcAlarmConditionNode

Probably the most important implementation of OpcAcknowledgeableConditionNode in OPC UA is the OpcAlarmConditionNode class. With it, you define event nodes that behave like a bedside alarm clock. The node becomes active (IsActive property) when the linked condition is met. For the alarm clock, this is reaching the wake-up time, for example. An alarm that has a wake-up time but should not become active when that time is reached is called a suppressed alarm (IsSuppressed and IsSuppressedOrShelved properties). You can shelve an active alarm (IsSuppressedOrShelved property). An alarm can be shelved once ("One Shot Shelving") or for a period of time ("Timed Shelving") (Shelving property). You can also unshelve an alarm again (Shelving property).

The following code shows an example of the OpcAlarmConditionNode API:

csharp
var overheating = new OpcAlarmConditionNode(machineOne, "OverheatingAlert");
var idle = new OpcAlarmConditionNode(machineOne, "IdleAlert");

...

overheating.ChangeIsActive(this.SystemContext, true);
idle.ChangeIsActive(this.SystemContext, true);

...

if (overheating.IsActive)
    CancelJob();

if (!idle.IsActive)
    ProcessJob();
else if (idle.IsSuppressed)
    SimulateJob();
vbnet
Dim overheating As New OpcAlarmConditionNode(machineOne, "OverheatingAlert")
Dim idle As New OpcAlarmConditionNode(machineOne, "IdleAlert")
'...
overheating.ChangeIsActive(Me.SystemContext, True)
idle.ChangeIsActive(Me.SystemContext, True)

...

If overheating.IsActive Then
    CancelJob()
End If

If Not idle.IsActive Then
    ProcessJob()
ElseIf idle.IsSuppressed Then
    SimulateJob()
End If

On the server side, you suppress an alarm with the ChangeIsSuppressed method and shelve it with the ChangeShelving method:

csharp
// Suppress the alarm, e.g. while the machine is in maintenance.
overheating.ChangeIsSuppressed(this.SystemContext, value: true);
 
// Shelve the alarm for 30 minutes.
overheating.ChangeShelving(
        this.SystemContext,
        shelved: true,
        oneShot: false,
        shelvingTime: TimeSpan.FromMinutes(30));
 
// Unshelve the alarm.
overheating.ChangeShelving(this.SystemContext, shelved: false);
vbnet
'Suppress the alarm, e.g. while the machine is in maintenance.
overheating.ChangeIsSuppressed(Me.SystemContext, value:=True)

'Shelve the alarm for 30 minutes.
overheating.ChangeShelving( _
        Me.SystemContext, _
        shelved:=True, _
        oneShot:=False, _
        shelvingTime:=TimeSpan.FromMinutes(30))

'Unshelve the alarm.
overheating.ChangeShelving(Me.SystemContext, shelved:=False)

Discrete alarms ​

Types usedOpcServerOpcNodeManagerOpcDiscreteAlarmNodeOpcOffNormalAlarmNodeOpcTripAlarmNode

There are several specializations of OpcAlarmConditionNode for specific kinds of alarms. For them, the kind of alarm itself describes its form, its cause, or its content in more detail. One subclass of such self-describing alarms are the discrete alarms. The base of a discrete alarm is the OpcDiscreteAlarmNode class. It defines an alarm state node that classifies types into alarm states. The input for the alarm can take only a certain number of possible values, for example true and false, or running, stopped, and finished. If an alarm should represent a discrete state that is considered not normal, you should use the OpcOffNormalAlarmNode class or one of its subclasses.

Building on this alarm class, the SDK provides a further specialization with the OpcTripAlarmNode class. An OpcTripAlarmNode becomes active when an abnormal fault occurs on a monitored device, for example when the motor shuts down because of overload. To create these nodes:

csharp
var x = new OpcDiscreteAlarmNode(machineOne, "discreteAlert");
var y = new OpcOffNormalAlarmNode(machineOne, "offNormalAlert");
var z = new OpcTripAlarmNode(machineOne, "tripAlert");
vbnet
Dim x As New OpcDiscreteAlarmNode(machineOne, "discreteAlert")
Dim y As New OpcOffNormalAlarmNode(machineOne, "offNormalAlert")
Dim z As New OpcTripAlarmNode(machineOne, "tripAlert")

Limit alarms ​

Types usedOpcServerOpcNodeManagerOpcLimitAlarmNode

If the server should check process-specific limits and publish the result when a value exceeds or falls below them, the OpcLimitAlarmNode class is the entry point to the limit alarm classes. With it, you divide limits into up to four levels.

In the order of their metric ranking, the levels are called LowLow, Low, High, and HighHigh. By definition, not all limits have to be defined. For this reason, you can set the limits you need from the start:

csharp
var positionLimit = new OpcLimitAlarmNode(
        machineOne, "PositionLimit", OpcLimitAlarmStates.HighHigh | OpcLimitAlarmStates.LowLow);

positionLimit.HighHighLimit = 120; // e.g. mm
positionLimit.LowLowLimit = 0;     // e.g. mm
vbnet
Dim positionLimit As New OpcLimitAlarmNode(
        machineOne, "PositionLimit", OpcLimitAlarmStates.HighHigh Or OpcLimitAlarmStates.LowLow)

positionLimit.HighHighLimit = 120 ' e.g. mm
positionLimit.LowLowLimit = 0 ' e.g. mm

Exclusive limit alarms ​

Types usedOpcServerOpcNodeManagerOpcExclusiveLimitAlarmNode

The OpcExclusiveLimitAlarmNode class is a subclass of OpcLimitAlarmNode. As its name says, it defines limit alarms for exclusive limits. The limits of such an alarm are mutually exclusive. If one limit is exceeded or undershot, no other limit can be exceeded or undershot at the same time. The state machine in the Limit property of the node describes the violated limit. You set it with the ChangeLimitState method:

csharp
var temperatureLimit = new OpcExclusiveLevelAlarmNode(
        machineOne,
        "TemperatureLimit",
        supportedLimits: OpcLimitAlarmStates.High | OpcLimitAlarmStates.HighHigh);
 
temperatureLimit.HighLimit = 80;      // e.g. degree Celsius
temperatureLimit.HighHighLimit = 100; // e.g. degree Celsius
 
// Once the node has been added to the address space:
temperatureLimit.ChangeIsActive(this.SystemContext, value: true);
temperatureLimit.ChangeLimitState(this.SystemContext, value: OpcLimitAlarmStates.High);
vbnet
Dim temperatureLimit = New OpcExclusiveLevelAlarmNode( _
        machineOne, _
        "TemperatureLimit", _
        supportedLimits:=OpcLimitAlarmStates.High Or OpcLimitAlarmStates.HighHigh)

temperatureLimit.HighLimit = 80      'e.g. degree Celsius
temperatureLimit.HighHighLimit = 100 'e.g. degree Celsius

'Once the node has been added to the address space:
temperatureLimit.ChangeIsActive(Me.SystemContext, value:=True)
temperatureLimit.ChangeLimitState(Me.SystemContext, value:=OpcLimitAlarmStates.High)

OPC UA has three further specializations of OpcExclusiveLimitAlarmNode.

OpcExclusiveDeviationAlarmNode

Use this kind of alarm if the server monitors how far a value deviates from its setpoint. You specify the node of the setpoint with the SetpointNodeId property.

OpcExclusiveLevelAlarmNode

This kind of alarm usually reports that a limit is exceeded, typically on an instrument such as a temperature sensor. The alarm becomes active when the observed value is above an upper limit or below a lower limit.

OpcExclusiveRateOfChangeAlarmNode

This kind of alarm usually reports an unusual or missing change of a measured value, relative to the speed at which the value changes. The alarm becomes active when the rate of change of the value exceeds or falls below a defined limit.

Non-exclusive limit alarms ​

Types usedOpcServerOpcNodeManagerOpcNonExclusiveLimitAlarmNode

The OpcNonExclusiveLimitAlarmNode class is a subclass of OpcLimitAlarmNode. As its name says, it defines limit alarms for non-exclusive limits. The limits of such an alarm are not mutually exclusive. If one limit is exceeded or undershot, another limit can be exceeded or undershot at the same time. You check the violated limits with the IsLowLow, IsLow, IsHigh, and IsHighHigh properties of the node.

OPC UA has three further specializations of OpcNonExclusiveLimitAlarmNode.

OpcNonExclusiveDeviationAlarmNode

Use this kind of alarm if the server monitors how far a value deviates from its setpoint. You specify the node of the setpoint with the SetpointNodeId property.

OpcNonExclusiveLevelAlarmNode

This kind of alarm usually reports that a limit is exceeded, typically on an instrument such as a temperature sensor. The alarm becomes active when the observed value is above an upper limit or below a lower limit.

OpcNonExclusiveRateOfChangeAlarmNode

This kind of alarm usually reports an unusual or missing change of a measured value, relative to the speed at which the value changes. The alarm becomes active when the rate of change of the value exceeds or falls below a defined limit.