Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
UaClient: Reading custom structured DataType without generated code
February 13, 2020
16:56, EET
Avatar
hbrackel
Member
Members
Forum Posts: 135
Member Since:
February 21, 2014
sp_UserOfflineSmall Offline

Good afternoon,

I am looking for a way for an UaClient to read variable values from a server, where the DataType is based on a custom structure DataType. Unfortunately, the namespaces of the type definitions are occasionally updated (they contain the date/month of release), so I cannot use generated code across multiple versions of that server.

Is there a way for a client to dynamically “decode” a custom structure variable value at runtime using SDK support? I remember that v4.x.x of the SDK provides improved support for complex datatypes. It would be great, if you could provide a little code snippet, demonstrating how to decode a DataValue containing a custom structure.

Many thanks,
Hans-Uwe

February 13, 2020
18:25, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

(Long post, sorry, and I think there is a lot more that should be said, but maybe this will do for now, but yes, should be documented a lot better…)

This has been improving with each release. You’ll want version 4.2.0, that would be the best (https://downloads.prosysopc.com/opcua/Prosys_OPC_UA_SDK_for_Java_4_Release_Notes.html#version-4-2-0), unless you connect to an S7 device (see other latest threas of this forum since we have problems with that currently, in case try 4.1.4). Additionally it should be mentioned that with 4.2.0 connecting might take longer (this is currently directly related to the number of custom Structures since we need to read them all), working on improvements on that for the next release.. (which should be soon).

Basically as it is, any Structure can be handled like this, i.e. “dynamically”, since we enhanced the Structure interface to contain all relevant APIs from SDK’s DynamicStructure in 4.x. Note that this example is missing all error handling etc. This is something I can give right now, making a proper full example will take some time. Let me know if you encounter any issues.

NodeId nodeId = …
UaClient client = …
Structure customStructure = (Structure ) client.readValue(nodeId).getValue().getValue();
StructureSpecification customStructureSpecification = customStructure.specification();
for (FieldSpecification fieldSpecification : customStructureSpecification.getFields()) {
// Getting values
Object fieldValue = customStructure.get(fieldSpecification);

// Setting values, the fieldSpecification contains meta-data for types
Object newValue = …;
customStructure.set(fieldSpecification, newValue);
}

i.e. meaning that the SDK is already doing it dynamically in the latest versions.

Additionally it should be mentioned that Structure has toBuilder which will return a Structure.Builder that will build instances of the same type (initializes with current values of fields). The same builder can obtained from the StructureSpecification.toStructureBuilder(). StructureSpecifications can be obtained from UaClient.getEncoderContext().getStructureSpecification(UaNodeId id) after connecting. And UaNodeId is an “upgraded” NodeId (has UaNamespace object instead of the index, and that in turn contains the namespaceuri; I’ll skip details for now, can be discussed later in some other post if needed), can be made with the static factory methods of that class (via NodeId/ExpandedNodeId + NamespaceTable from the client).

February 14, 2020
14:20, EET
Avatar
hbrackel
Member
Members
Forum Posts: 135
Member Since:
February 21, 2014
sp_UserOfflineSmall Offline

Thanks for your quick reply and the code example. I will implement this over the weekend.

If a have a subscription for a structured value, is it possible to “cache” the structure specification and reuse it or do I need to implement the above code for each individual DataValue?

Thanks,
Hans-Uwe

February 14, 2020
15:04, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

I might need clarifications on what exactly you mean by “caching” here.

StructureSpecification instances are immutable, SDK will keep track of them with the TypeDictionary and/or EncoderContext (basically EncoderContext will delegate to TypeDictionary if needed). If your value is always the same type, i.e. your MonitoredDataItemListener handler is not shared between items, then the Structure.specification() is the same java object each time.

May 6, 2020
9:46, EEST
Avatar
hbrackel
Member
Members
Forum Posts: 135
Member Since:
February 21, 2014
sp_UserOfflineSmall Offline

Good morning,

I have finally been able to try out the code snippet below. (still on SDK v4.1.4). Unfortunately, I get a ClassCastException when trying to cast the ExtensionObject to the Structure interface. Any ideas how to circumvent this problem?

Thanks,
Hans-Uwe

NodeId nodeId = …
UaClient client = …
Structure customStructure = (Structure ) client.readValue(nodeId).getValue().getValue();
StructureSpecification customStructureSpecification = customStructure.specification();
for (FieldSpecification fieldSpecification : customStructureSpecification.getFields()) {
// Getting values
Object fieldValue = customStructure.get(fieldSpecification);

// Setting values, the fieldSpecification contains meta-data for types
Object newValue = …;
customStructure.set(fieldSpecification, newValue);
}

May 6, 2020
13:27, EEST
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 983
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

If you see an ExtensionObject, it means that the SDK was not able to decode the Structure (binary-wise they are transmitted as an ExtensionObject within the Variant) for some reason. An ExtensionObject itself is not a Structure, it instead contains the raw binary (or XML or JSON) data plus an encoding id (this is NOT the DataType NodeId). And in some cases within the our SDK it could also hold an already decoded Structure, but if you see an ExtensionObject like that (from the DataValue) then it is not decoded.

You can try passing that ExtensionObject to (UaClient) client.getTypeDictionary().decode(extensionObject). However you’ll most likely get an exception thrown if you received the ExtensionObject in the first place, since SDK should do that part automatically. Basically this API is from the era where this part was not automatic.

Most likely something prevented the TypeDictionary from being properly initialized. If that happened you should see an ERROR or WARN log when you did connect the UaClient. Some servers might define the metadata incorrectly (or it might be missing completely). In those case we cannot do much.

If at all possible, I would recommend to try with the latest version, 4.3.0. One of the main points was improving the initialization process of the TypeDictionary, thus the logging is a lot better there as well. If not all Structure types of the server could not be resolved to StructureSpecifications, it will log on WARN level which could not be resolved. IF the ExtensionObject.getTypeId() you received corresponds to the binary-encoding-id of one of the Structure types that could not be resolved then that is why. And note that the DataType NodeId is different from the binary-encoding-id NodeId (that is the NodeId of HasEncoding non-hierarchical reference target from the DataType that has the BrowseName “Default Binary”).

May 7, 2020
17:44, EEST
Avatar
hbrackel
Member
Members
Forum Posts: 135
Member Since:
February 21, 2014
sp_UserOfflineSmall Offline

I finally upgraded to v4.3.0 of the SDK (took a moment, as I had to update a series of libraries as well). The problem has been solved Smile. The structures are correctly recognized and are decodable using your coded snipped above. Really nice!

As a side effect (?), the strange timeout incidents discussed in another forum entry are no longer occurring. It has really been worth the upgrade.

Thank you very much for your continued support!!

Hans-Uwe

May 8, 2020
17:29, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1010
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Hi Hans-Uwe,

Thanks for confirming. This is great to hear.

BR, Jouni

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 518

Currently Online:
25 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

hbrackel: 135

pramanj: 86

Francesco Zambon: 81

rocket science: 77

Ibrahim: 76

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

TimK: 41

Member Stats:

Guest Posters: 0

Members: 681

Moderators: 16

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1467

Posts: 6261

Newest Members:

graciela2073, sagarchau, elviralangwell4, Donnavek, Eddiefauth, DonaldPooma, fidelduke938316, Jan-Pfizer, DavidROunc, fen.pang@woodside.com

Moderators: Jouni Aro: 1010, Otso Palonen: 32, Tuomas Hiltunen: 5, Pyry: 1, Petri: 0, Bjarne Boström: 983, Heikki Tahvanainen: 402, Jukka Asikainen: 1, moldzh08: 0, Jimmy Ni: 26, Teppo Uimonen: 21, Markus Johansson: 42, Niklas Nurminen: 0, Matti Siponen: 321, Lusetti: 0, Ari-Pekka Soikkeli: 5

Administrators: admin: 1