Encoding byte array|OPC UA Implementation: Stacks, Tools, and Samples|Forum|OPC Foundation

Avatar
Search
Forum Scope


Match



Forum Options



Minimum search word length is 3 characters - maximum search word length is 84 characters
Lost password?
sp_Feed sp_PrintTopic sp_TopicIcon
Encoding byte array
Avatar
Sergey Scherbak
Member
Members
Forum Posts: 5
Member Since:
11/22/2021
sp_UserOfflineSmall Offline
1
11/30/2021 - 04:29
sp_Permalink sp_Print sp_EditHistory

Good afternoon!

I'm trying to read data from Minebea OPC UA Server. I made simple OPC UA client on C# and see that OpcAttribute is byte[24].

But I don't understand how convert it from byte array to real meaning.

-------------------------------------------------------

using (var client = new OpcClient("opc.tcp://localhost:4840"))
{
client.Connect();

var node = client.BrowseNode(OpcObjectTypes.ObjectsFolder);

OpcValue weightArray = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.Value);
var weightValueRank = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.ValueRank);
var weightDataType = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.DataType);
var weightArrayDimensions = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.ArrayDimensions);
var weightDescription = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.Description);
var weightNodeCategory = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.NodeCategory);
byte[] byteWeight = (byte[])weightArray.Value;
var generalWeight1 = client.ReadNode("ns=3;s=s1.CurrentWeight");

foreach (int i in byteWeight)
{
Console.WriteLine("weightArray = {0}", i);
}
Console.WriteLine("weightValueRank = {0}", weightValueRank);
Console.WriteLine("weightDataType = {0}", weightDataType);
Console.WriteLine("weightArrDim = {0}", weightArrayDimensions);
Console.WriteLine("weightDesc = {0}", weightDescription);
Console.WriteLine("weightNodeCategory = {0}", weightNodeCategory);

}

-------------------------------------------------------

Bellow is a result

weightArray = 180
weightArray = 200
weightArray = 118
weightArray = 190
weightArray = 159
weightArray = 191
weightArray = 88
weightArray = 57
weightArray = 180
weightArray = 200
weightArray = 118
weightArray = 190
weightArray = 159
weightArray = 191
weightArray = 0
weightArray = 0
weightArray = 0
weightArray = 0
weightArray = 0
weightArray = 0
weightArray = 0
weightArray = 0
weightValueRank = -1
weightDataType = ns=3;i=55
weightArrDim = null
weightDesc = Defines the current value that is measured at the sensor at the current timestamp. Might be a highly fluctuating value.
weightNodeCategory = 2

-------------------------------------------------------

Avatar
Sergey Scherbak
Member
Members
Forum Posts: 5
Member Since:
11/22/2021
sp_UserOfflineSmall Offline
2
11/30/2021 - 04:33
sp_Permalink sp_Print sp_EditHistory

Also I see some description in Minebea OPC UA server user manual, but again it doesn't help me to understand better. What does mean xBPI function?

Image Enlarger

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
3
11/30/2021 - 07:55
sp_Permalink sp_Print

The DataType attribute is ns=3;i=55

You need to look up the Node ns=3;i=55 because that should tell you how to understand the value.

Avatar
Sergey Scherbak
Member
Members
Forum Posts: 5
Member Since:
11/22/2021
sp_UserOfflineSmall Offline
4
11/30/2021 - 09:04
sp_Permalink sp_Print sp_EditHistory

Thanks for the reply, Randy!

I found the link with description about Node ns=3;i=55, but still don't have any progress in getting valuable result.

Scales Data Types Weight Type | OPC UA Online Reference (opcfoundation.org)

 

WeightType TOC Previous Specification

The fields of the WeightType DataType are defined in the following table:

Name Type
WeightType Structure
    gross Double
    net Double
    tare Double

The representation of the WeightType DataType in the address space is shown in the following table:

Name Attribute
NodeId ns=1;i=55
NamespaceUri https://opcfoundation.org/UA/Scales
BrowseName WeightType
IsAbstract False
SubtypeOf AbstractWeightType
Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
5
11/30/2021 - 17:46
sp_Permalink sp_Print sp_EditHistory

The WeightType is a SubType of Structure with 3 fields.

When you read a Subtype of Structure you get a wrapper called ExtensionObject which has the DataType Encoding Id and the Value encoded as an array of bytes.

It is appears your client library is returning an array of bytes because it does not know how to decode WeightType  Structure.

In this case, the Structure is encoded as 3 LSB first IEEE doubles so you could manually decode it easily with BitConvertor.ToDouble(). However, most client libraries have a way to generate DataType serialization code from a NodeSet.

Which client library are you using?

Avatar
Sergey Scherbak
Member
Members
Forum Posts: 5
Member Since:
11/22/2021
sp_UserOfflineSmall Offline
6
12/01/2021 - 02:13
sp_Permalink sp_Print

Hi!

I'm using Opc.UaFx.Client just because I found simple example of connection to OPC Server on the Internet.

And didn't find any simple example how to use original Opc.Ua.Client.

Also I downloaded a lot of projects UA-.NETStandard from gitHub but without documentation it very difficult to use.

https://github.com/OPCFoundati.....ETStandard

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
7
12/01/2021 - 03:48
sp_Permalink sp_Print

You will need to contact the makers of Opc.UaFx.Client and ask them how to handle custom structures.

The NETStandard documentation comes in the form of examples.

Other libraries (Unified, Softing) have tools that ingest a NodeSet and generate code to de-serialize the structure.

You can also write the de-serialization code manually if you have to.

Avatar
Zbynek Zahradnik
Member
Members
Forum Posts: 62
Member Since:
02/24/2014
sp_UserOfflineSmall Offline
8
12/01/2021 - 06:06
sp_Permalink sp_Print sp_EditHistory

This looks like a server conforming to "OPC 40200 - UA CS for Weighing Technology 1.00" specification.

I have tested our QuickOPC .NET client toolkit (https://www.opclabs.com/produc...../downloads ) on latest OPC Interoperability Workshop with a server that supported this companion spec, and it worked fine, including some special cases (something with abstract types was that?) that other client libraries struggled with.

Loading a NodeSet is not necessary in our case, the library will read the datatypes from the server, and return the structures basically as a dictionary with keys corresponding to structure field names.

You can test it out also without any programming using the OpcCmd tool (which is written with QuickOpc) from https://kb.opclabs.com/Tool_Do.....md_Utility , and a command like

uaClient read endpointUrl nodeId

Avatar
Sergey Scherbak
Member
Members
Forum Posts: 5
Member Since:
11/22/2021
sp_UserOfflineSmall Offline
9
12/03/2021 - 03:35
sp_Permalink sp_Print

Good afternoon!

Thanks for the help!

So, before I was able to read data from the node, but the result data was wrong.

OpcValue weightArray = client.ReadNode("ns=3;s=s1.CurrentWeight", OpcAttribute.Value);

byte[] byteWeight = (byte[])weightArray.Value;

 

According to the WeightType structure in the post above, I see that the "gross", "net" and "tare" are 3 double variable in byte[24] array.

I tried to read these variables using BitConverter, but I got wrong data because of not correct value of BitConverter.IsLittleEndian property.

if (BitConverter.IsLittleEndian)
   Array.Reverse(byteWeight);

Without reverse, BitConverter reads the data correctly.

Example

double doubleValue1 = BitConverter.ToDouble(byteWeight, 0);
double doubleValue2 = BitConverter.ToDouble(byteWeight, 8);
double doubleValue3 = BitConverter.ToDouble(byteWeight, 16);
Console.WriteLine("doubleValue1: {0}, doubleValue2: {1}, doubleValue3: {2}", doubleValue1.ToString(), doubleValue2.ToString(), doubleValue3.ToString());

And result is

doubleValue1: 0.189, doubleValue2: 0.189, doubleValue3: 0

 

Now I want to write similar code by using Opc.Ua.Client library instead of Opc.UaFx.Client library.

Where can I find description of methods for the original Opc.Ua.Client library?

Avatar
Randy Armstrong
Admin
Forum Posts: 1564
Member Since:
05/30/2017
sp_UserOfflineSmall Offline
10
12/03/2021 - 13:07
sp_Permalink sp_Print

The first 8 bytes should be a little endian double and you should not need to reverse the array unless you are running on ARM device which is also big endian.

 

See:

https://github.com/OPCFoundati.....AClient.cs

Forum Timezone: America/Phoenix
Most Users Ever Online: 510
Currently Online:
Guest(s) 26
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Forum Stats:
Groups: 2
Forums: 10
Topics: 1435
Posts: 4855