.NET Based OPC UA Client/Server SDK
3.1.3.516
|
In the previous Lesson 2: Extending the Address Space with Real World Data we created a nice object oriented address space, but the data provided by this address space are only initial values. There is no connection to real time data implemented yet.
If the source of the real time data delivers data changes through an event based mechanism, the connection to the data source is very simple. The only thing that needs to be implemented is updating the value of the Variable node when a data change arrives for that variable. All the read and data monitoring is already handled by the SDK.
If the source of the real time data requires data polling, this lesson explains the steps necessary to implement read, monitoring and write access to device data.
The following figure shows the example communication interface used for polling access to the simulated device data.
Methods of the UnderlyingSystem
Runtime Data
In a first step the example device interface including the device simulation must be added to the project.
Add system as a member of the class.
Create the system in the constructor of the NodeManager
Initialize the underlying system
In the previous lesson a fixed set of controllers has been created. This hardcoded object generation will be replaced with information about available controllers provided by the device interface.
Our lesson specific NodeManager is derived from BaseNodeManager class. The project specific information integration is done by overwriting methods of the base class. Startup is overwritten to create the address space. For polling based data integration, we need to overwrite the methods Read and Write.
The value attribute of a variable node can be provided in different ways based on the source of the value. The source can be the in memory node like for server configuration data or it could be in an external device.
Depending on the type of source and communication, different modes can be configured for the variable. For Var1 the mode NodeHandleType.Internal would be used. For Var2 the mode NodeHandleType.ExternalPush would be used. Var3 matches our example and mode NodeHandleType.ExternalPolled is used. The different modes are described in the overview for Data Access, Handle Types and the IIOManager.
In the next steps we need to change variable value handling setting to NodeHandleType.ExternalPolled and we need to provide the address information in variable user data.
In addition, we need to implement Read and Write in the Lesson NodeManager. Read and Write are defined by BaseNodeManager and are overwritten in the Lesson NodeManager.
In a first step, we define the data class for variable user data in the Lesson NodeManager. The Address is used to address the controller. The Offset is used to address the variable inside the controller.
After the variables have been created (the children of the controllers are created together with the object), we need to set the NodeHandleType to ExternalPolled. The method SetVariableConfiguration finds the variable node by using the NodeId of the controller and the BrowseName of the child, and sets the NodeHandleType and UserData (in this example system address in the UnderlyingSystem) that can be used for Read and Write.
For polling the variables of the UnderlyingSystem, we have to override the Read method in the NodeManager. The SystemAddress from the last step is added to the NodeHandle and can be used for reading the variables of the UnderlyingSystem. The values have to be added to DataValues and returned to the caller using the callback that is passed by the transaction.
Writing a value to the UnderlyingSystem is very similar to reading values from the UnderlyingSystem.
Now, the variable Temperature gets its value from the device. We can test this in UaExpert: Drag & drop the variables of a controller to the Data Access View. The Variable value provided by the Read method is shown in the Value column.
In a last step, we add information about the expected range of values for each variable. The OPC UA AnalogItemType contains a property called EURange that provides this information to clients. This property will not change during runtime, so external polling of the range is not needed. We only need to update the value of the in-memory-node.