.NET Based OPC UA Client/Server SDK


The ModelManager allows the application developer to create classes that represent some portion of the Server address space and to Read from, Write to and Subscribe to the entire object in a single operation. The following steps illustrate what needs to be done to read the few variables which belong to the standard Server object that every Server supports.

A ModelManager object is thread-safe.

Step 1) Define a Model Class

[UaTypeDefinition(NodeId = UnifiedAutomation.Demo.Model.ObjectTypes.BoilerType, NamespaceUri = UnifiedAutomation.Demo.Model.Namespaces.Model)]
public partial class BoilerModel
#region Constructors
public BoilerModel()
#region Public Properties
[UaInstanceDeclaration(NamespaceUri = UnifiedAutomation.Demo.Model.Namespaces.Model)]
public double FillLevelSetPoint { get; set; }
[UaInstanceDeclaration(NamespaceUri = UnifiedAutomation.Demo.Model.Namespaces.Model)]
public double TemperatureSetPoint { get; set; }
[UaInstanceDeclaration(NamespaceUri = UnifiedAutomation.Demo.Model.Namespaces.Model)]
public HeaterStatus HeaterStatus { get; set; }

The attributes used in the example above are defined in the SDK.

The UaTypeDefinition attribute indicates that a class represents an ObjectType or a VariableType in an OPC UA information model. NodeId is the identifier portion of the NodeId which is combined with the NamespaceUri to construct a unique NodeId for the type definition. If the NamespaceUri is not specified, the default OPC UA namespace is assumed.

The UaInstanceDeclaration indicates that a property corresponds to a child of the ObjectType or VariableType represented by the containing class. The BrowseName of the child can be explicitly specified. If it is omitted, the name of the property is used as the BrowseName. If the NamespaceUri is not specified, the default OPC UA namespace is assumed.

Properties with the UaInstanceDeclaration attribute can be other classes with the UaTypeDefinition attribute defined. If this is the case, browse paths with multiple elements can be constructed to access values in the Server address space. If the child is a Variable, the Value of this Variable can get by specifying a property with a UaInstanceDeclaration with IsValue = true and without a BrowseName.

Step 2) Perform Operations with the Model

BoilerModel boiler = new BoilerModel();
NodeId boilerId = UnifiedAutomation.Demo.Model.ObjectIds.Demo_BoilerDemo_Boiler1.ToNodeId(Session.NamespaceUris);
ModelHandle modelHandle = Session.Model.Read(boilerId, boiler);

The code above reads the values for all of the mapped nodes and updates the Model object. When the operation has finished, the values can be accessed by accessing the mapped properties of the Model object as shown.

If errors occur, they are reported in the ModelHandle.LastResults property of the returned ModelHandle from the call. Each element corresponds to an element of the ModelHandle.Mappings property. If an error occurs during a Read, the corresponding property in the Model object is set to its default value.

If the Model is subscribed to, all or part of the Model object is updated whenever an update from the Server arrives. Thread synchronization is taken care by locking the synchronization object provided in the Subscribe request before applying any updates to the Model object.