Reputation: 81
I'm triying to read some data form an OPC UA server using opc-ua-client library. Managed to connect to server and read some simple variables, but facing issues when reading structured values. However, I'm able to browse those structured values using 3rd party tools, such as UAExpert.
This is the code snippet:
var readRequest = new ReadRequest
{
NodesToRead = new[] { new ReadValueId { NodeId = NodeId.Parse(nodeId), AttributeId = AttributeIds.Value } }
};
var response = channel.ReadAsync(readRequest).Result;
var result = response.Results[0].GetValueOrDefault<ExtensionObject>();
The point is: how should I cast the ExtensionObject into the underlying real object? Response's body is binary serialized into a System.Byte[] field, and don't know how to deserialize it. I know the fields and types of the structure, so defined it in the code (even decorating with the namespace provided by the server) as follow:
[BinaryEncodingId("nsu=urn:OMRON:NxOpcUaServer:FactoryAutomation;i=5005")]
private class MES_WRITE_STRUCT : Structure
{
uint Message_NUM { get; set; }
//Some other fields
DateTime Time_Stamp { get; set; }
}
Things I've tried (and failed) so far:
Brute-force cast:
var eObject = (MES_WRITE_STRUCT)result.GetValueOrDefault<ExtensionObject>();
Read the response as the expected type rather than using generic object:
var eObject = result.GetValueOrDefault<MES_WRITE_STRUCT>();
Use the Variant property rather than Value (same result as using Value):
result.Variant.GetValue();
Create a binary reader and attempt to deserialize it into expected class.
Maybe I'm using a wrong approach and structured values should be read in a different way. Or even the library does not support structured variables (not much documentation available). Or just using an incorrect type when defining custom class in .NET and hence casting is failing.
I'm totally stuck, any information or guidance is wellcome.
PS: I'm not tied to this library and can switch to another one (preferably with no licenses, but if really worths can consider buying).
Upvotes: 0
Views: 4317
Reputation: 36
Another way is the OPC Foundation .NET Standard client which has an extension library nuget package called complex client. It contains the logic to read the structured type definition from a server from a dictionary (V1.03) or using DataTypeDefinition (V1.04). Based on the obtained type definition the classes for the structured types can be emitted for encoding/decoding the byte string in the extension object at runtime. Please open issues if the complex client has difficulties to decode your structured type.
Upvotes: 1
Reputation: 215
One way would be to use the XML description of the information model (so called nodesets) you wish to consume and use the model compiler from OPC Foundation to generate C# classes out of it. Those classes can be integrated in your solution and used for deserialization.
And example (using the OPC Foundation libraries) could be found here
Upvotes: 1