When an OPC UA Alarms & Conditions server generates an event, the EasyUAClient object generates an EventNotification event. For subscription mechanism to be useful, you should hook one or more event handlers to this event. This event is raised for every event generated by a subscribed OPC monitored item.
To be more precise, the EventNotification event is actually generated in other cases, too - if there is any significant occurrence related to the event subscription. This can be for three reasons:
The notification for the EventNotification event contains an EasyUAEventNotificationEventArgs argument. You will find all kind of relevant data in this object. Some properties in this object contain valid information under all circumstances - e.g. Arguments (including Arguments.State). Other properties, such as EventData, contain null references when there is no associated information for them. When the EventData property is not a null reference, it contains a UAEventData object describing the detail of the actual OPC event received from the OPC UA Alarms & Conditions server.
Before further processing, your code should always inspect the value of Exception property of the event arguments. If this property is not a null reference, there has been an error related to the event subscription, the Exception property contains information about the problem, and the EventData property does not contain a valid object.
If the Exception property is a null reference, the notification may be informing you about the fact that a condition refresh is being initiated or is complete (in this case, the RefreshInitiated or RefreshComplete property is 'true'), or that an event subscription has been successfully connected or re-connected (in this case, the EventData property is a null reference). If none of the previous applies, the EventData property contains a valid UAEventData object with details about the actual OPC event generated by the OPC server.
Pseudo-code for the full EventNotification event handler may look similar to this:
if notificationEventArgs.Exception is not null then
An error occurred and the subscription is disconnected, handle it (or ignore)
else if notificationEventArgs.RefreshInitiated then
A “refresh” has been initiated; handle it
else if notificationEventArgs.RefreshComplete then
A “refresh” is complete; handle it
else if notificationEventArgs.EventData is null then
Subscription has been successfully connected or re-connected, handle it (or ignore)
else
Handle the OPC event, details are in notificationEventArgs.EventData. You may use notificationEventArgs.Refresh flag for distinguishing refreshes from original notifications.
The EventNotification event handler is called on a thread determined by the EasyUAClient component. For details, please refer to “Multithreading and Synchronization” chapter under “Advanced Topics”.
The arguments of each event notification (EasyUAEventNotificationEventArgs) have an EventData property (of type UAEventData, described further below), which contains details about the OPC UA event. In addition, common information such as the copy of the input arguments to the subscription, i.e. identification of the endpoint and node (monitored item) which has generated the event, is included. The Exception property (and several related properties) indicates success (when it is a null reference), or a failure (in which case it contains an exception object describing the error).
The UAEventData object contains details about an OPC UA event, i.e. the information that the OPC UA server sends with the event notification. Primarily, it has a FieldResults property, which is a dictionary containing results for each of the fields in the select clauses of the event filter. Each field results is a ValueResult object, i.e. it can either contain the actual value, or an error indication.
In order to make access to at least some of these results easier (without having to go through indexing an element in the dictionary), the UAEventData object also contains a BaseEvent property (of UABaseEventObject type). The UABaseEventObject class contains properties that directly correspond to information contained in the base event type (from which all UA events are derived), such as SourceName, Time, Message, Severity, etc. In case of an error related to a particular field, the corresponding property will contain its default value (e.g. an empty string for a Message).
It should be noted that the FieldResults directory always contains results for the fields you have specified in Select clause of the event filter, but it can contain some additional fields as well. This happens when these fields are necessary for internal processing inside the component. Your code should be able to ignore the results that it has not requested.
Note: Some data returned use complex data types defined by OPC UA, which QuickOPC transforms to its own .NET types. For example, the UATimeZoneData class contains data returned in the UABaseEventObject.LocalTime property (defines the local time that may or may not take daylight saving time into account).