UaModeler  1.2.0.214
 All Pages
HowTo Use the generated files in a Visual Studio Project

This example will describe how to integrate the generated code into Visual Studio 2010 with Service Pack 1 in eight simple steps.

NOTE:
To compile the client with Visual Studio 2010 SP1 you need to have the third-party files compiled with Visual Studio 2010 SP1 as well!

Step 1: Adding files to a Visual Studio Solution

The generated files must be added to the MS Visual Studio project. Right click on the project and add all files (Existing Item...).

Step 2: Add Reference System.Runtime.Serialization

Call “Add Reference ...” in the context menu of the Project and select System.Runtime.Serialization.

Step 3: Add the complex type

The new complex type Vector must be added to the EncodeableFactory.

MessageContext context = new MessageContext();
context.Factory.AddEncodeableType(typeof(Vector));

Step 4: Read a complex variable

We want to read a variable that has the DataType Vector.

To map the NamespaceIndex from the server to the client and vice versa, we need the NamespaceTable of the Session.

NamespaceTable table = session.NamespaceUris;

Using the NamespaceTable and the generated file *Identifiers.cs (in this example “NewNamespaceIdentifiers.cs”) we can determine the NodeId of the variable to read.

//Get the NodeId from *Identifiers.cs
NodeId complexDataId = VariableIds.MyObjectType_DemoVector.ToNodeId(table);

Now we can read the variable.

Vector vector;
ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
ReadValueId readValueId = new ReadValueId()
{
NodeId = complexDataId,
AttributeId = Attributes.Value
};
nodesToRead.Add(readValueId);
List<DataValue> results = session.Read(nodesToRead);
if (results.ToArray().Length == 1)
{
DataValue value = results[0];
ExtensionObject extOb = (ExtensionObject)value.Value;
if (extOb.TypeId.Equals(Vector))
{
vector = (Vector)extOb.Body;
}
}

Step 5: Write a complex variable

vector = new Vector()
{
X = 12.0,
Y = 24.0,
Z = 42.0
};
WriteValueCollection nodesToWrite = new WriteValueCollection();
nodesToWrite.Add(new WriteValue()
{
NodeId = complexDataId,
AttributeId = Attributes.Value,
Value = new DataValue()
{
Value = vector
}
});
session.Write(nodesToWrite);

Step 6: Call a method

Calling a method is described in Unified Automation .NET Client SDK Call-Method tutorial in detail. In this step you can see how to use the custom complex DataType and how to get the NodeIds from the generated files.

// NodeIds from Identifier.cs
NodeId ObjectToCallId = ObjectTypeIds.MyObjectType.ToNodeId(table);
NodeId MethodToCallId = MethodIds.MyObjectType_VectorAdd.ToNodeId(table);
// Set input arguments
List<Variant> inputArguments = new VariantCollection(2);
Vector vector = new Vector()
{
X = 1,
Y = 2,
Z = 3
};
inputArguments.Add(new Variant(vector));
vector = new Vector();
{
X = 3,
Y = 2,
Z = 6
};
inputArguments.Add(new Variant(vector));
// Call the method
List<StatusCode> inputArgumentErrors;
List<Variant> outputArguments;
StatusCode result = session.Call(ObjectToCallId,
MethodToCallId,
inputArguments,
out inputArgumentErrors,
out outputArguments);
// Get the result
foreach (Variant value in outputArguments)
{
Console.WriteLine(value);
if (value.TypeInfo == TypeInfo.Arrays.ExtensionObject)
{
ExtensionObject[] extensionObjects = value.ToExtensionObjectArray();
foreach (ExtensionObject extensionObject in extensionObjects)
{
Vector vector = ExtensionObject.GetObject<Vector>(extensionObject);
}
}
}

Step 7: Subscribe

We subscribe to the same node, that we have read.

// Create Subscription
Subscription subscription = new Subscription(session);
subscription.Create();
// Add MonitoredItem
List<MonitoredItem> monitoredItems = new List<MonitoredItem>();
monitoredItems.Add(new DataMonitoredItem(complexDataId));
subscription.CreateMonitoredItems(monitoredItems);
// Add EventHandler
subscription.DataChanged += new DataChangedEventHandler(Subscription_DataChanged);

Now we implement the callback function. The code shows how to get access to the Vector.

static void Subscription_DataChanged(Subscription subscription, DataChangedEventArgs e)
{
foreach (DataChange dataChange in e.DataChanges)
{
Vector vector = (Vector)((ExtensionObject)dataChange.Value.Value).Body;
}
}

Step 8: Subscribe to Events

subscription.NewEvents += new NewEventsEventHandler(Subscription_NewEvents);
EventMonitoredItem tmpItem = new EventMonitoredItem(UnifiedAutomation.UaBase.ObjectIds.Server);
//Register Event Field
tmpItem.Filter.SelectClauses.Add(new QualifiedName(BrowseNames.Vector, (ushort)subscription.Session.NamespaceUris.IndexOf(Namespaces.NewNamespace)));
monitoredItems.Add(tmpItem);
subscription.CreateMonitoredItems(monitoredItems);

Now we implement the callback function. The code shows how to get access to the Vector.

static void Subscription_NewEvents(Subscription subscription, NewEventsEventArgs e)
{
foreach (NewEvent newEvent in e.Events)
{
UaClient.ItemEventFilter filter = newEvent.MonitoredItem.Filter;
NodeId eventType = filter.GetValue<NodeId>(newEvent.Event, UnifiedAutomation.UaBase.BrowseNames.EventType, NodeId.Null);
QualifiedName browseName = new QualifiedName(BrowseNames.Vector, (ushort)subscription.Session.NamespaceUris.IndexOf(Namespaces.NewNamespace));
Vector vector = filter.GetValue<Vector>(newEvent.Event, browseName, null);
}
}