C++ Based OPC UA Client/Server SDK
1.6.4.457
|
The goal of this lesson is to show how to provide Alarm conditions in the Address Space.
In a first step, we want to indicate that our ControllerType has an alarm condition component. The following figure shows the object representing the Alarm as component of the ControllerType.
Figure 6-1 Object types including the Alarm node StateCondition
The following include and code in nmbuildingautomation.cpp are necessary to add the alarm as instance declaration node to the ControllerType.
The code creates an OffNormalAlarm condition with the name StateCondition as component of the ControllerType. The creation of the OffNormalAlarm object creates all components of this condition.
Add the corresponding define to buildingautomationtypeids.h
In a first step, we are adding a member variable to the class ControllerObject that represents the Alarm condition. We also need an include for the OffNormalAlarmType class. Add the marked lines to controllerobject.h.
In a second step, we are creating the OffNormalAlarm object with its components in ControllerObject::ControllerObject, we create the references and we are setting the initial states of the condition.
In addition to normal objects, the constructor of a condition object takes the NodeId of the source and the source name as additional parameters. The source node is the controller object. After creating the condition object, additional setters are used to set the condition name and initial states of the condition like the AckedState and the EnabledState.
In addition to the HasComponent reference between the controller and the condition object, two more references are created to indicate the event hierarchy. Starting from the controller object a HasEventSource reference to the State variable is created to indicate that changes of the state are triggering events. A HasCondition reference from the State variable to the StateCondition object indicates that the variable has an Alarm condition. The full event hierarchy is explained in the next step.
Change the marked line in controllerobject.cpp
Since we are now using the Controller object as event notifier, the ControllerObject::eventNotifier() method must return SubscribeToEvents.
The object instance and component hierarchy starts at the Objects folder and uses Organizes references in the first levels and HasComponent and HasProperty references in the component hierarchy levels beneath objects. This hierarchy is typically used for browsing by data access or historical data access clients or by clients calling methods.
Clients interested in the event hierarchy are browsing a hierarchy starting from the Server object by following HasNotifier and HasEventSource references. HasCondition references are used to indicate that an Event source has one or more conditions. The node that is the target of a HasNotifier reference can be used to subscribe for events. It must be an Object with the EventNotifier attribute set to SubscribeToEvents. The target of a HasEventSource reference can be a Variable, Object or Method indicating that the node is the source of the event notification. Figure 6-2 shows an example of such an event hierarchy together with the component hierarchy.
The two areas AreaAirConditioner and AreaFurnace are used to group the different objects for event filtering. They reference the corresponding object instances with a HasNotifier reference. The necessary code to create these references and to register the event hierarchy for event filtering is contained in the next code section.
The HasEventSource reference from the controller object to the State variable indicates that this variable is the source of the events from this object. The HasCondition reference from the variable to the Alarm condition object indicates that the condition is based on the State variable. The necessary references were already created inside the ControllerObject class in Step 2: Adding Alarm to Controller object.
Add the following code to nmbuildingautomation.cpp:
This code creates the two area folders, adds them with HasNotifier to the Server object and registers each area for the event filter hierarchy with the EventManager. For this registration, the NodeId of the Server object and the NodeId of the area are passed to the method EventManagerUaNode::registerEventNotifier().
This code adds the HasNotifier reference from the area to the controller object and registers the controller object in the event hierarchy after creating the object.
Figure 6-3 Condition type, Controller type and Condition instance
Figure 6-3 shows
After creating all necessary nodes and references, we need to add the code to change the state of the condition and to trigger the state change events for the condition.
Add the marked code to controllerobject.cpp:
The code is added in the same place where the simple event is triggered. This trigger is based on calling the start or stop methods of the controller. Depending on the controller state, the Alarm Active state, the AckedState and the Retain flag are set. After setting the message text the state change event is triggered by calling triggerEvent on the condition object.
To allow alarm acknowledgment we need to overwrite the method EventManagerUaNode::OnAcknowledge() in the class NmBuildingAutomation.
Add the following code to nmbuildingautomation.cpp:
This code implements the method OnAcknowledge in the class NmBuildingAutomation. It checks if the condition is unacknowleged, changes the state of the AckedState to OpcUa_True, sets the passed comment to the Comment field, sets the client user id to the ClientUserId field and triggers a new state change event.
To test the alarm acknowledgement, connect to the server with UaExpert and select the Event View as described in the previous lesson. Then call the Stop Method on several Controller Objects as described in Lesson 4. The corresponding alarms will show up in the Alarms tab (see figure 6-4).
To acknowledge an alarm, select Acknowledge from the context menu. A dialog window for entering a comment will show up.
Figure 6-4 Alarm Condition acknowledgement