Ben Parry
Ben Parry

Reputation: 35

Why am I getting the error: "Opc.Ua.Variant[]System.InvalidCastException: Object cannot be stored in an array of this type"?

Opc.Ua Call Method Error

I am fairly new to using Opc.Ua and Opc.Ua.Client and I am trying invoke a Scan method on my OPC UA server with the Call method. I have been trying to use the Call method to return a response (IList<object> according to Visual Studio). However when I run my program I get this error:

Error

If I try and change the lists type or try to use something else I get a type error before I can even compile.

The Scan method takes the following Input arguments:

UaExpert Scan Parameters

C#'s Call Method Definition:

C#'s Call Definition

I use these variables and call said method:

NodeId scanMethodNode = new NodeId(7010, 4);
NodeId readPoint1Object = new NodeId(5002, 4);

List<object> inputArgs2 = new List<object>();
inputArgs2.Add(0);
inputArgs2.Add(1);
inputArgs2.Add(false);

IList<object> result  = session.Call(readPoint1Object, scanMethodNode, inputArgs2);

I have found some inconsistencies between what C# thinks is the correct syntax and what the online documentation says. I might have missed something due to this inconstancy. Any help would be greatly appreciated :)

Upvotes: 1

Views: 984

Answers (1)

Camille G.
Camille G.

Reputation: 3256

Your OPC UA Client need to create a ScanSetting object and pass it to the function as an ExtensionObject. You will need first to load the ScanSetting Type definition from the Server and use it to create a ScanSettings object.

To do so, the easiest way will be to use LoadType from OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes Nuget package

ComplexTypeSystem complexTypeSystem = new ComplexTypeSystem(this.Session);

NodeId nid = new NodeId((uint)3010, (ushort)3);
ExpandedNodeId eni = new ExpandedNodeId(nid); 

Type scanSettingsType = await complexTypeSystem.LoadType(eni).ConfigureAwait(false);
dynamic scanSettings = Activator.CreateInstance(scanSettingsType);
scanSettings.Duration = 0.0; //edited
scanSettings.Cycles = (Int32)0;
scanSettings.DataAvailable = (Boolean)false;
scanSettings.LocationType = (Int32)0; //optional

Then you should be able to call Call like that:

IList<object> result  = session.Call(readPoint1Object, scanMethodNode, new ExtensionObject(scanSettings));

Upvotes: 2

Related Questions