4

I can't seem to figure this one out:

Before writing to a tag I need to know what data type it is expecting(the value that mywrite function receives is always a string).

I realise you have to read the datatype from the server and here's my code to do so, but I'm at a loss as to how to use the information returned:

var nodesToRead = BuildReadValueIdCollection(node.DisplayName, Attributes.DataType);

                    DataValueCollection readResults;
                    DiagnosticInfoCollection diag;
                    _session.Read(
                        requestHeader: null,
                        maxAge: 0,
                        timestampsToReturn: TimestampsToReturn.Neither,
                        nodesToRead: nodesToRead,
                        results: out readResults,
                        diagnosticInfos: out diag);
                    var val = readResults[0];

What do I do with val to determine what the datatype is?

Do I use Val.Value or Val.WrappedValue or Val.WrappedValue.Value (whatever the difference is ?)

The tag I've been using to test has returned Val = "i=6".....

What is this referring to?

What datatype is "6" and

how do I convert val to something I can use.

Any help would be greatly appreciated.

Thanks

New
  • 675
  • 1
  • 11
  • 21
Muckers Mate
  • 399
  • 8
  • 23

4 Answers4

6

Reading from the DataType attribute returns a NodeID of the OPC UA type. It can be one of the "standard" types defined in the OPC UA spec, or something specific to the server. The standard types reside in namespace 0, which is your case (as there is no "ns=..." part in the displayed Node ID), and "i=6" stands for Int32.

There are many types with pre-defined Node IDs, and you need to consult the OPC UA specs, or the nodeset files that come with the stacks/SDKs (e.g. Opc.Ua.NodeSet.xml), to figure out what they mean.

ZbynekZ
  • 1,532
  • 10
  • 16
  • Thanks for this, very useful. Do I have to convert the Node to a string to be able to perform comparison ( i.e. case "i=6" : vartype = Int32 ... etc)? – Muckers Mate Oct 26 '16 at 11:23
  • In .NET stack from OPC Foundation, if that's what we are discussing here, the value should be of Opc.Ua.NodeId type, This type has properties like (ushort) NamespaceIndex, IdType, Identifier etc. I recommend using those, or the equality on the NodeId, to make the comparison. The string form is just for making the Node ID legible by humans. – ZbynekZ Oct 26 '16 at 12:13
1

The value is a NodeId referring to the data type node. You can compare the value to known NodeId values (DataTypeIds in .NET or something, not sure about this right away) or you will need to find the data type node from the address space.

Jouni Aro
  • 2,099
  • 14
  • 30
1

In recent version, node-opcua client has been extended with a utility function ClientSession#getBuiltInDataType that does this for you.

var nodeId = coerceNodeId("ns=411;s=Scalar_Simulation_Int64");
session.getBuiltInDataType(nodeId,function(err,dataType){
     if(!err){
       console.log("Use data Type",dataType," to write into UAVariable", nodeId.toString();
    }
});    
Etienne
  • 16,249
  • 3
  • 26
  • 31
0

We use this extension method to determine the C# type of nodes:

public static Type GetSystemType(this Session session, NodeId nodeId)
{
  var currentValue = session.ReadValue(nodeId);
  var builtInType = currentValue.WrappedValue.TypeInfo.BuiltInType;
  var valueRank = currentValue.WrappedValue.TypeInfo.ValueRank;

  return TypeInfo.GetSystemType(builtInType, valueRank);
}

It is somewhat a hack but it works well.