.NET Based OPC UA Client/Server SDK  2.6.1.422
Lesson 5: Adding Support for Events

This lesson demonstrates how to add Event support to a Server.

We already created a custom EventType in Lesson 2 having two properties, “Temperature” and “State” (see Figure 5.1). Now we will implement the generation of Events.

serverlesson05_adding_event_support.png
Figure 5.1: ControllerEventType

When creating the instances, we have to create an Event hierarchy defining nodes that can be used to subscribe for Events. This should be done by specifying the NotifierParent property in CreateObjectSettings.

From Server Object to Controller Folder:

// Create a Folder for Controllers
CreateObjectSettings settings = new CreateObjectSettings()
{
ParentNodeId = ObjectIds.ObjectsFolder,
ReferenceTypeId = ReferenceTypeIds.Organizes,
RequestedNodeId = new NodeId("Controllers", InstanceNamespaceIndex),
BrowseName = new QualifiedName("Controllers", InstanceNamespaceIndex),
TypeDefinitionId = ObjectTypeIds.FolderType,
// need to create a notifier hierarchy for events to propagate.
NotifierParent = ObjectIds.Server
};
CreateObject(Server.DefaultRequestContext, settings);

From Controller Folder to Controller (i.e. the Event source):

// create object.
settings = new CreateObjectSettings()
{
ParentNodeId = new NodeId("Controllers", InstanceNamespaceIndex),
ReferenceTypeId = ReferenceTypeIds.Organizes,
RequestedNodeId = new NodeId(block.Name, InstanceNamespaceIndex),
BrowseName = new QualifiedName(block.Name, TypeNamespaceIndex),
TypeDefinitionId = typeDefinitionId,
// need to create a notifier hierarchy for events to propagate.
NotifierParent = new NodeId("Controllers", InstanceNamespaceIndex)
};
CreateObject(Server.DefaultRequestContext, settings);

Then we register an event handler at our sample system:

public override void Startup()
{
try
{
Console.WriteLine("Starting Lesson5aNodeManager.");
base.Startup();
// save the namespaces used by this node manager.
InstanceNamespaceIndex = AddNamespaceUri("http://yourcompany.com/lesson04a/");
TypeNamespaceIndex = AddNamespaceUri(yourorganisation.BA.Namespaces.BA);
// load the model.
Console.WriteLine("Loading the Controller Model.");
ImportUaNodeset(Assembly.GetEntryAssembly(), "buildingautomation.xml");
// initialize the underlying system.
m_system.Initialize();
// subscribe to state changed events.
m_system.BlockStateChanged += new BlockStateChangedEventHandler(UnderlyingSystem_BlockStateChanged);

Finally we report the Event. The class GenericEvent stores the Event data. The Initialize method sets the common Event fields. Using the method Set we can set a field defined at our custom EventType. ReportEvent reports the Event to the SDK.

private void UnderlyingSystem_BlockStateChanged(int blockAddress, string blockName, int state)
{
// create the event.
GenericEvent e = new GenericEvent(Server.FilterManager);
// initializ base event type fields
e.Initialize(
null, // EventId created by SDK if null
new NodeId(yourorganisation.BA.ObjectTypes.ControllerEventType, TypeNamespaceIndex), // EventType
new NodeId(blockName, InstanceNamespaceIndex), // SourceNode
blockName, // SourceName
EventSeverity.Medium, // Severity
"A controller state changed."); // Message
// set additional event field State
e.Set(e.ToPath(new QualifiedName(yourorganisation.BA.BrowseNames.State, TypeNamespaceIndex)), state);
// report the event.
ReportEvent(e.SourceNode, e);
}

To test the implementation, open an Event View in UaExpert (choose DocumentAdd… from the menu). Then drag and drop the Server object to the Event View. To trigger an Event, call the methods Start oand Stop on on a controller object (see Figure 5.2).

serverlesson05_expert.png
Figure 5.2: Events in UaExpert