ANSI C Based OPC UA Client/Server/PubSub SDK
1.9.1.442
|
The goal of this lesson is to show how to provide Events in the Address Space.
Files used in this lesson:
Figure 5-1 shows the machine type and the new event type that we will create in this lesson.
Figure 5-1 Machine Type and HeaterSwitchedEventType
In our example, a machine shall send an event if its switch was toggled. Therefore we create a new event type that contains information about the new switch position as well as the current value of the temperature sensor. The new event type will be a subtype of the BaseEventType. For further information about event handling in the SDK, please see Alarms & Events.
New event types and new event fields have to be registered in the SDK, which is done in CustomProvider_RegisterEventTypes (see custom_provider_events.c):
The HeaterSwitchedEventType will have two additional event fields:
The event fields are registered in the SDK using their browse names and the returned local index is stored for later use.
In order to inform clients about the new event type, the respective nodes of the type and the event fields have to be created in the server’s address space:
Nodes that are able to emit events have to be marked as such in the address space. In our case, a reference of type GeneratesEvent from MachineType to HeaterSwitchedEventType is created. This reference is optional and helps clients to determine which events are to be expected by instances of certain object or variable types (see custom_provider.c).
For the instance of the MachineType, a reference of type HasNotifier has to be created from the Server object to the new Machine instance. Using this reference, the area hierarchy described in Alarms & Events is built up.
Furthermore, the SDK and clients need to know that the machine instance is able to emit events. Therefore the EventNotifier attribute of the machine node is set and the machine is registered as EventNotifier in the SDK.
The HeaterSwitch is registered as EventSource in the SDK as well and a reference of type HasEventSource is created between the new Machine instance and its HeaterSwitch property.
Now we are prepared to fire events. In our example, the simulation timer is used to check whether the switch of the machine was toggled. If this is true, a HeaterSwitchedEvent is fired:
The helper function CustomProvider_FireHeaterSwitchedEvent is used to generate and fire the event. It creates a new instance of HeaterSwitchedEventType using the NodeId which was assigned to the event type (see custom_provider.c):
Now the additional event fields are filled with reasonable values. For setting the event fields of the BaseEventType, convenience functions are provided by the SDK.
A unique EventId is created by using the SDK’s helper function UaServer_Events_CreateEventId and depending on the state of the switch, a message is generated. Please remember that the OpcUa_ByteString created by UaServer_Events_CreateEventId needs to be freed by the caller after use.
The custom event fields are filled by using the local indices we retrieved when registering the event fields in Step 1: Adding HeaterSwitchedEventType.
Finally, the event is fired by calling UaServer_Events_FireEvent. As events are fired once and then forgot, we can delete it directly after emission:
After implementing firing of events, we can test if they can be received by a client.
For receiving events with UaExpert, create an Event View by clicking “Add Document”, selecting “Event View”, and clicking “Add” (see Figure 5-2).
Figure 5-2 Create an Event View using UaExpert
Now you can drag and drop either the “Server” or the “MyCustomMachine” object into the Configuration section of the Event View. The client will then subscribe for events that are emitted by the respective object. To trigger an event, you can simply call the method we created in Lesson 4: Adding Support for Methods and toggle the state of the switch. Whenever the method is called our custom event will be fired and displayed in the client (see Figure 5-3).
Figure 5-3 Receive Events using UaExpert