- Posts: 95
- Thank you received: 3
Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
DUE TO ADMINISTRATIVE REASONS, WE MAY NOT BE ABLE TO RESPOND (OR TO RESPOND AS QUICKLY AS USUAL) BETWEEN December 30, 2024 - January 6, 2025. WE APOLOGIZE FOR INCONVENIENCE.
- Forum
- Discussions
- QuickOPC-UA in .NET
- Reading, Writing, Subscriptions
- Writing Boolean value results in ArgumentNullException
Writing Boolean value results in ArgumentNullException
If you prepare a special build of QuickOPC library, I will test the issue with that version
Please Log in or Create an account to join the conversation.
Thank you for the explanation.
By "predefined OPC UA Node", I mean nodes in namespace 0 defined in OPC UA Core specifications (specs numbered opcfoundation.org/developer-tools/documents/?type=Specification&classification=Core+UA+Topics ).
The fact that StandardName is empty means that the node has a custom datatype, not defined in the core UA specs.
Most likely, it is a complex custom data type (usually a structure) defined by the server. In such case, QuickOPC has a subsystem to deal with them (see User's Guide), but such types cannot be represented by the TypeCode, so this approach won't work. Less likely, it can be a derived simple custom data type (such as a special integer or float); in that case, the approach with TypeCode should work.
The NamespaceUrlString and Identifier properties of the UANodeId are the ones that tell you what the data type Id. All other properties in UANodeId are bascally derived from them.
If we make a special build/builds of QuickOPC with additional code to troubleshoot the issue, would you be able & willing to test with it?
Regards
Please Log in or Create an account to join the conversation.
It's indirectly related to the Write issue. You suggested using an overload of the WriteValue method providing a valid TypeCode via the typeCode argument.
static public (bool Clamped, bool CompletesAsynchronously) WriteValue(
[NotNull] this IEasyUAClient client,
[NotNull] UAEndpointDescriptor endpointDescriptor,
[NotNull] UANodeDescriptor nodeDescriptor,
[CanBeNull] object value,
TypeCode typeCode)
However, we encountered an issue with detecting the correct type to pass. You shared a link to the article "How to Read DataType Attributes", so we do following:
ValueResult[] valueResultArray = client.ReadMultipleValues(new[]
{
new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", UAAttributeId.DataType)
});
var nodeId = valueResultArray[0].Value as UANodeId;
The final step is to determine which property of the UANodeId object to use to resolve the node type information.
We tried to rely on the property StandardName, but it is empty for the node, which caused the original Write problem.
So, the question is which UANodeId property should we use, and what does 'predefined OPC UA node' mean?
Please Log in or Create an account to join the conversation.
I do not understand your post. The issue you have reported was about an error when writing. But the code posted contains no Write at all. Are you referring to the same issue, or something else? If you want to discuss a different issue, create a new thread on the forums. If you are referring to the same issue, please explain how the code snippets with Read relates to the problem with Write.
The ArgumentNullException you reported is most likely a a QuickOPC issue. But it is impossible to fix it without having a reproducible scenario here. I need either the OPC server, or an ability to connect to it.
It is also not clear to me what the question about StandardName has to do with the issue. StandardName in UANodeId is never null, but it is an empty string if the node Id does not corresponds to predefined OPC UA node.
Regards
Please Log in or Create an account to join the conversation.
Could you help me determine whether the issue is with QuickOPC library or the OPC server?
Here is a snippet of code:
var readArgs = descriptors.Select(d => new UAReadArguments(_endpointDescriptor, d, UAAttributeId.DataType)).ToArray();
ValueResult[] valueResultArray = _opcClient.ReadMultipleValues(readArgs);
var nodeId = valueResultArray[0].Value as UANodeId;
Please Log in or Create an account to join the conversation.
With regard to UInt16: The behavior is by design. See opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Late...ata%20Types%20in%20OPC-UA.html . Without it, VB.NET developers will have hard time processing the data.
You can work with Int32 instead of UInt16 just well.
Best regards
Please Log in or Create an account to join the conversation.
1. This is a WAGO OPC UA server.
2. The server is hosted on the customer's premises, so I can't provide remote access due to access restrictions.
3. I will attempt to suppress JIT optimization if I get permission.
The issue with the uint16 data type in OPC nodes may not be related to this topic.
The scenario is as follows:
ValueResult[] valueResults = opcUaClient.ReadMultipleValues(...);
itemType = valueResults[0].ValueType;
1. Read the OPC node value of type Int16. The typeof(itemType) evaluates to short - correct
2. Read the OPC node value of type UInt16. The typeof(itemType) evaluates to int32 - incorrect
Please Log in or Create an account to join the conversation.
I do not know what you mean by "It does not work for OPC nodes with uint16 type". You may need to explain the steps taken, and the behavior observed.
Obtaining data types: opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Late...d%20DataType%20attributes.html
The exception from the Browse has the same cause as the one you reported before. The server is doing something unusual, and it makes QuickOPC misbehave (which it should not). But I do not have enough information to resolve it. Can you please answer/provide this:
1. Which OPC server are you connecting to?
2. Can we get hold of the server? Or
3. Would it be possible to remotely connect to the server?
4. Please follow my advise from earlier post - repeating here:
Can you try disabling the code optimizations for the process? I have never done that, but it seems that for .NET 6, setting the environment variable COMPlus_JITMinOpts=1 before running the process should do it:
- stackoverflow.com/questions/63959038/how-to-suppress-jit-optimization-in-net-core
- stackoverflow.com/questions/73864832/disable-jit-optimizations-for-specific-net-core-assembly
The idea is that you will end up with the same exception, but better stack trace.
Regards
Please Log in or Create an account to join the conversation.
Sorry for the delayed response.
Your suggestion to use the overload of the WriteValue method resolved the issue. However, we are now facing a new challenge related to passing the correct data type through the TypeCode parameter. It does not work for OPC nodes with uint16 type
Does EasyUAClient provide a method to read the UA node data type?
Additionally, we discovered that the Browse method is also failing on this server.
However, UaExpert client somehow handles this error and does not fail during the 'write value' or 'browse' operations
Below is the stack trace:System.ArgumentNullException: Value cannot be null. (Parameter 'key') at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.BrowseNodesPreprocess(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, List`1[]& sdkNodesToBrowseArray, List`1[]& warningsArray) at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.InternalBrowseNodes(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, UANodeElementCollection[]& nodeElementCollectionArray, List`1[]& warningsArray) at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.BrowseNodes(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, UANodeElementCollection[]& nodeElementCollectionArray, List`1[]& warningsArray) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientSession.BrowseList(List`1 browseList, UANodeElementCollectionResult[] nodeElementCollectionResultArray) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.Browse(ICollection`1 browseListDictionary, UANodeElementCollectionResult[] nodeElementCollectionResultArray) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.BrowseNodes(UABrowseArguments[] browseArgumentsArray, EasyUAAdaptableParameters adaptableParameters) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.<InternalBrowseMultipleNodes>b__95_2(IReadOnlyList`1 list) at OpcLabs.BaseLib.Collections.Generic.Extensions.IReadOnlyListExtension.IfThenElse[TInput,TOutput](IReadOnlyList`1 readOnlyList, Predicate`1 condition, Func`2 thenListSelector, Func`2 elseListSelector) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.InternalBrowseMultipleNodes(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.<>c__DisplayClass41_0.<BrowseMultiple>b__0() at OpcLabs.BaseLib.DisposableObject.DisposeGuard[TResult](Func`1 func, Boolean throwOnDisposed) at OpcLabs.BaseLib.DisposableObject.DisposeGuardNotNull[TResult](Func`1 func, Boolean throwOnDisposed) at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Optimization.Implementation.RequestMergingEasyUAClient.<BrowseMultiple>b__1_0(UABrowseArguments[] array) at OpcLabs.BaseLib.OperationModel.Extensions.IReadOnlyListOfOperationArgumentsExtension.MergingPerform[TArguments,TResult](IReadOnlyList`1 argumentsList, Func`2 arrayOperationFunction) at OpcLabs.EasyOpc.UA.Optimization.Implementation.RequestMergingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.LicensingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.MultiplexingEasyUAClient.<>c.<BrowseMultiple>b__7_0(IEasyUAClient client, IReadOnlyList`1 list) at OpcLabs.BaseLib.Collections.Generic.Extensions.IReadOnlyListExtension.SwitchCase[TInput,TOutput,TKey](IReadOnlyList`1 readOnlyList, Func`2 keySelector, IEqualityComparer`1 keyComparer, Func`3 outputSelector) at OpcLabs.EasyOpc.UA.Implementation.MultiplexingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ErrorTransformingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.EasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray) at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.BrowseOne(IEasyUAClient client, UABrowseArguments browseArguments) at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.Browse(IEasyUAClient client, UABrowseArguments browseArguments) at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.Browse(IEasyUAClient client, UAEndpointDescriptor endpointDescriptor, UANodeDescriptor nodeDescriptor, UABrowseParameters browseParameters) at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.BrowseDataNodes(IEasyUAClient client, UAEndpointDescriptor endpointDescriptor, UANodeDescriptor nodeDescriptor)
UAExpert client reaction
Attachments:
Please Log in or Create an account to join the conversation.
Your suggestion to use the overload of the WriteValue method resolved the issue. However, we are now facing a new challenge related to passing the correct data type through the TypeCode parameter. It does not work for OPC nodes with uint16 type
Does EasyUAClient provide a method to read the UA node data type?
Additionally, we discovered that the Browse method is also failing on this server.
However, UaExpert client somehow handles this error and does not fail during the 'write value' or 'browse' operations
Below is the stack trace:
System.ArgumentNullException: Value cannot be null. (Parameter 'key')
at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.BrowseNodesPreprocess(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, List`1[]& sdkNodesToBrowseArray, List`1[]& warningsArray)
at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.InternalBrowseNodes(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, UANodeElementCollection[]& nodeElementCollectionArray, List`1[]& warningsArray)
at OpcLabs.EasyOpc.UA.Toolkit.Client.UAClientSession.BrowseNodes(UABrowseEntry[] browseEntryArray, Exception[]& exceptionArray, UANodeElementCollection[]& nodeElementCollectionArray, List`1[]& warningsArray)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientSession.BrowseList(List`1 browseList, UANodeElementCollectionResult[] nodeElementCollectionResultArray)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.Browse(ICollection`1 browseListDictionary, UANodeElementCollectionResult[] nodeElementCollectionResultArray)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.EasyUAClientEngine.BrowseNodes(UABrowseArguments[] browseArgumentsArray, EasyUAAdaptableParameters adaptableParameters)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.<InternalBrowseMultipleNodes>b__95_2(IReadOnlyList`1 list)
at OpcLabs.BaseLib.Collections.Generic.Extensions.IReadOnlyListExtension.IfThenElse[TInput,TOutput](IReadOnlyList`1 readOnlyList, Predicate`1 condition, Func`2 thenListSelector, Func`2 elseListSelector)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.InternalBrowseMultipleNodes(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.<>c__DisplayClass41_0.<BrowseMultiple>b__0()
at OpcLabs.BaseLib.DisposableObject.DisposeGuard[TResult](Func`1 func, Boolean throwOnDisposed)
at OpcLabs.BaseLib.DisposableObject.DisposeGuardNotNull[TResult](Func`1 func, Boolean throwOnDisposed)
at OpcLabs.EasyOpc.UA.Implementation.NetSdk.Client.NetSdkEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Optimization.Implementation.RequestMergingEasyUAClient.<BrowseMultiple>b__1_0(UABrowseArguments[] array)
at OpcLabs.BaseLib.OperationModel.Extensions.IReadOnlyListOfOperationArgumentsExtension.MergingPerform[TArguments,TResult](IReadOnlyList`1 argumentsList, Func`2 arrayOperationFunction)
at OpcLabs.EasyOpc.UA.Optimization.Implementation.RequestMergingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.LicensingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.MultiplexingEasyUAClient.<>c.<BrowseMultiple>b__7_0(IEasyUAClient client, IReadOnlyList`1 list)
at OpcLabs.BaseLib.Collections.Generic.Extensions.IReadOnlyListExtension.SwitchCase[TInput,TOutput,TKey](IReadOnlyList`1 readOnlyList, Func`2 keySelector, IEqualityComparer`1 keyComparer, Func`3 outputSelector)
at OpcLabs.EasyOpc.UA.Implementation.MultiplexingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ErrorTransformingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.ForwardingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.Implementation.DelegatingEasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.EasyUAClient.BrowseMultiple(UABrowseArguments[] browseArgumentsArray)
at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.BrowseOne(IEasyUAClient client, UABrowseArguments browseArguments)
at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.Browse(IEasyUAClient client, UABrowseArguments browseArguments)
at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.Browse(IEasyUAClient client, UAEndpointDescriptor endpointDescriptor, UANodeDescriptor nodeDescriptor, UABrowseParameters browseParameters)
at OpcLabs.EasyOpc.UA.IEasyUAClientExtension.BrowseDataNodes(IEasyUAClient client, UAEndpointDescriptor endpointDescriptor, UANodeDescriptor nodeDescriptor)
UAExpert client reaction
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-UA in .NET
- Reading, Writing, Subscriptions
- Writing Boolean value results in ArgumentNullException