Frequently Asked Questions


PowerShell

Can the SDK also be used in the PowerShell?

Yes, an example of this including a bootstrapper is available on GitHub: OPC UA .NET Samples - PowerShell Client

NuGet Preview

After using an old NuGet Preview (as a download for my NuGet source), I'm not longer able to update to a new version. How can I solve that?

NuGet stores all installed NuGet packages either next to the Visual Studio Solution in the “packages” folder (in case of non-SDK style projects) or in the local NuGet cache (in case of SDK style projects). To be able to update to the official version, the preview packages must be deleted from your own NuGet source and the local NuGet cache. Where the local NuGet cache is located depends on your project.

  • If the SDK is referenced via NuGet (with packages.config file):
    • Close Visual Studio
    • Navigate to the project directory in the Explorer
    • Delete the directory “packages” next to your solution
    • Open the project and build it again
  • If the SDK is referenced via NuGet (without packages.config file):
    • Close Visual Studio
    • Navigate to the local NuGet cache: C:\Users\Username\.nuget\packages
    • Delete the directory “Opc.UaFx.Client” or “Opc.UaFx.Advanced”
    • Open the project and build it again

Now you can update or install the current version using the NuGet client as usual.

.NET Exceptions

When I start my application, I get a ''TypeInitializationException'' when I call an API of the SDK. What does that mean?

This error can occur if the Visual Studio has not updated all binary files used in the project directory after an update to a newer version of the SDK. Therefore, perform the following steps:

  • Close Visual Studio
  • Navigate to the project directory in the Explorer
  • Delete all “bin” and “obj” directories
  • Open the project and build it again

If the execution error persists, the following steps should resolve the problem:

  • If the SDK is referenced from the ZIP archive:
    • all files that are part of the target framework folder in the project were referenced
    • the files were referenced from the correct target framework folder
  • If the SDK is referenced via NuGet (with packages.config file):
    • Close Visual Studio
    • Navigate to the project directory in the Explorer
    • Delete the directory “packages” next to your solution
    • Open the project and build it again
  • If the SDK is referenced via NuGet (without packages.config file):
    • Close Visual Studio
    • Navigate to the local NuGet cache: C:\Users\Username\.nuget\packages
    • Delete the directory “Opc.UaFx.Client” or “Opc.UaFx.Advanced”
    • Open the project and build it again

If none of these approaches solve the problem, send the problem and details about the exception or its InnerException to support@traeger.de.

After about 30 minutes I get a ''LicenseException'' when calling a client API, why?

The OPC UA .NET SDK comes with a test license that can be used for 30 minutes without restrictions for client and server development per application start. If this restriction limits your evaluation options, you can apply for an alternative test license from us free of charge. Just ask our support (via support@traeger.de) or let us advise you directly and clarify open questions with our developers!

When my OPC UA server is running, the client applications receive a response with the code ''BadLicenseExpired'' after approx. 30 minutes, why?

The OPC UA .NET SDK comes with a test license that can be used for 30 minutes without restrictions for client and server development per application start. If this restriction limits your evaluation options, you can apply for an alternative test license from us free of charge. Just ask our support (via support@traeger.de) or let us advise you directly and clarify open questions with our developers!

Client + Server

Is it possible to operate the client and the server simultaneously in just one application?

Yes, it works without problems. Many of our tests are therefore based on code snippets such as the following:

using (var server = new OpcServer()) {
    server.Start();
 
    using (var client = new OpcClient(server.Address)) {
        client.Connect();
        ...
    }
}

OPC UA + S7-Controllers

Why am I not receiving a notification within the set intervals?

The following types are mentioned here: OpcSubscription, OpcMonitoredItem and OpcMonitoredItemStatus.

Various properties can be used to check whether a server supports the desired intervals or whether they are used:

  • The PublishingInterval can be checked via the CurrentPublishingInterval property.
  • The SamplingInterval can be checked via the Status.SamplingInterval property.

The main problem is frequently the configuration of the server. Depending on the S7 controller, only certain minimum values for the settings of the Subscriptions / MonitoredItems are supported. According to Siemens, the following minimum values apply:

Property CPU
1510, 1511, 1512, 1513 1515, 1516, 1505S 1517, 1518, 1507S
Maximum number of subscriptions
with more than 1000 monitored elements
per subscription over all sessions
10 10 10
Maximum number of subscriptions
with more than 1000 monitored elements
per subscription over all sessions
20 20 20
Maximum number of subscriptions
per session
20 20 20
Smallest possible sampling interval 100 ms 100 ms 10 ms
Smallest possible Send interval 500 ms 200 ms 10 ms
Maximum number of sessions 32 48 64
Recommended maximum number
of monitored elements over
all subscriptions
1000 1000 (1505S), 2000 10000

Source: What are the system limits of the OPC UA Server with S7-1500 with firmware V2.8.x?

Which limit values a server supports can be checked via various nodes in the path /Objects/Server/ServerCapabilities and below that in the node OperationLimits. A client application has no influence on these settings.

OpcObjectNode vs. OpcFolderNode

What is the difference between ''OpcObjectNode'' and ''OpcFolderNode'', when should which node be used?

The following types are mentioned here: OpcObjectNode and OpcFolderNode.

The difference is semantic in nature. While OpcFolderNode is a subclass of OpcObjectNode, its use is differentiated as follows:
  • OpcObjectNode groups nodes, which are also in a physical relationship to each other
  • OpcFolderNode groups nodes, which are more in a logical relationship to each other
The documentation for the OpcObjectNode states:
Defines a logical unit for displaying more complex information than OpcVariableNode. Objects are used to represent systems, system components, real objects and software objects.
From a more abstract perspective, objects are used to group variables and other objects in the address space. Therefore, objects should be used if some common structures/groups of objects and/or variables are to be described. Simple objects with only one value (e.g. a simple heat sensor) can also be modeled as variables. However, expansion mechanisms should be considered (e.g. a complex heat sensor subtype could have multiple values) and whether this object should be made available as an object in the GUI of the client or only as a value. If a modeler has doubts about which solution the object should use with a variable, the solution with the object should be preferred.

The documentation for the OpcFolderNode states:

Defines a node to organize the address space in a hierarchy of nodes. They represent the root node of a subtree and have no other semantics.

Because the OpcFolderNode is a subclass of the OpcObjectNode, there is no direct structural difference between the two types. An explicit difference is the ReferenceType used. The OpcFolderNode uses the Organizes reference type, while the OpcObjectNode uses the HasComponent reference type. The difference in the reference types used also reflects the purpose of the two types of nodes described above. In simple terms, the following can be defined:

  • OpcObjectNode groups nodes, which are also in a physical relationship to each other
  • OpcFolderNode groups nodes, which are more in a logical relationship to each other

OpcNodeId

Is it possible to change the separator character in NodeIds?

The following types are mentioned here: OpcNodeId and OpcNominalNodeIdFactory.

Yes, the standard NodeIdFactory must be changed as follows:

OpcNodeId.Factory = new OpcNominalNodeIdFactory() {
    Separator = '.'
};

OpcMethodNode

Is it possible to return multiple values via an OpcMethodNode?

The following types are mentioned here: OpcMethodNode and OpcArgumentAttribute.

Yes, by using return, ref and/or out values. However, it should be noted that ref values are used as input and as output arguments. The definition of such an OpcMethodNode could look like this:

private delegate void CalculateDelegate(
        int a,
        int b,
        ref int c,
        out int additionResult,
        out int differenceResult);
 
private void Calculate(
        [OpcArgument("a", Description = "The left operand.")]
        int a,
        [OpcArgument("b", Description = "The right operand.")]
        int b,
        [OpcArgument("c", Description = "Factor")]
        ref int c,
        [OpcArgument("add", Description = "The result of addition.")]
        out int additionResult,
        [OpcArgument("diff", Description = "The result of difference.")]
        out int differenceResult)
{
    additionResult = (a + b) * c;
    differenceResult = (a - b) * c;
}
 
this.methodNode = new OpcMethodNode(
        this.folderNode,
        nameof(Calculate),
        new CalculateDelegate(this.Calculate));

OpcVariableNode

Is there a way to limit the writing of values of an untyped OpcVariableNode to a certain data type?

The following types are mentioned here: OpcVariableNode, OpcVariableValue and OpcWriteVariableValueContext.

Yes, by checking the value to be written using a user-defined callback routine. Such a callback routine could then look like this:

this.variableNode.WriteVariableValueCallback = this.WriteToNode;
 
// Deny write of a specific type of value.
private OpcVariableValue WriteToNode(
        OpcWriteVariableValueContext context,
        OpcVariableValue value)
{
    if (!(value.Value is short))
        value.Status.Update(OpcStatusCode.BadTypeMismatch);
 
    return value;
}

Is it possible to convert the value to be written for an untyped OpcVariableNode into a certain data type?

The following types are mentioned here: OpcVariableNode, OpcVariableValue and OpcWriteVariableValueContext.

Yes, with the help of a user-defined callback routine, the value can be converted to the desired target data types before writing. The procedure could look something like this:

// Inline change type of value to the expected type.
private OpcVariableValue WriteToNode(
        OpcWriteVariableValueContext context,
        OpcVariableValue value)
{
    if (!(value.Value is short)) {
        value = new OpcVariableValue(
                Convert.ChangeType(value.Value, typeof(short)),
                value.Timestamp ?? DateTime.UtcNow,
                value.Status);
    }
 
    return value;
}