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
StructureChanged bit set when updating array variables for the first time
January 10, 2018
10:46, EET
Avatar
Thomas Reuther
Member
Members
Forum Posts: 33
Member Since:
September 18, 2017
sp_UserOfflineSmall Offline

Dear Prosys,

I am using Java SDK Eval 2.3.2. I have a question why the StructureChanged bit is set in status code when an array is updated for the first time.

I created the address space using UA Modeler. The XML node set file is loaded using UaServer.getAddressSpace.loadModel(InputStream).
The nodes look like this:

<UAVariable DataType="Byte" ValueRank="1" NodeId="ns=1;i=6066" ArrayDimensions="10" BrowseName="1:ByteArray" UserAccessLevel="3" AccessLevel="3">
<DisplayName>ByteArray</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>

To set the initial value I use an instance of IoManagerListener. In method onReadValue() I set a variable value if not set before:

@Override
public boolean onReadValue(ServiceContext serviceContext, NodeId nodeId, UaValueNode variable,
NumericRange indexRange, TimestampsToReturn timestampsToReturn, DateTime minTimestamp, DataValue dataValue)
throws StatusException {
DateTime now = DateTime.currentTime();
dataValue.setSourceTimestamp(now);
dataValue.setServerTimestamp(now);
dataValue.setStatusCode(StatusCode.GOOD);
Random random = new Random();

if (variable.getValue().isNull())
variable.getValue().setValue(new Variant(new UnsignedByte[]{
UnsignedByte.MIN_VALUE,
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
new UnsignedByte(random.nextInt((int)UnsignedByte.L_MAX_VALUE)),
UnsignedByte.MAX_VALUE}));
dataValue.setValue(variable.getValue().getValue());
return true;
}

Now I create a subscription on that variable. When I modify the value using UA Expert (or other client) then the monitored item returns status code GOOD + STRUCTURECHANGED_MASK (0x00008000).

The OPC UA specification says the bit is set whenever the data type encoding changes. I never change explicitly the encoding.

This happens when the length of the array changes (e.g. new array size is 2 instead of 10). Also when the length doesn’t change, either using index range (e.g. “0:1”) or using UA Expert to edit just one of the array values within the value editor.
Any subsequent update of that variable will return GOOD (0x00000000).
This happens to data types Boolean, Byte, DateTime, Double, Guid, Int32 and String. Other data types I don’t use. All arrays are static and have an initial array length of 10.

My server shall be used as simulation server in a test environment. Currently the tests fail because the extra bit is unexpected.

With best regards
Thomas

January 10, 2018
13:23, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1032
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Hi,

Good notice, thanks!

However the issue is not that simple.

Currently the bit is set if the following changes: DataType, ValueRank, ArrayDimensions. And change from the initial one hardcoded in the class also triggers this for ValueRank/ArrayDimentions, therefore that can be considered a bug.

The more problematic issue is that the meaning of the bit seems to have changed between OPC UA Specification versions 1.01 and 1.02. The text of (v 1.01 Part 4 7.33 table 163):
“StructureChanged 15:15 Indicates that the structure of the associated data value has changed since the last
Notification. Clientsshould not process the data value unless they re-read the metadata.
Serversshall set this bit if the DataTypeEncodingused for a Variablechanges. 7.23
describes how the DataTypeEncodingis specified for a Variable.
The bit is also set if the data type Attributeof the Variablechanges. A Variablewith data type
BaseDataTypedoes not require the bit to be set when the data type changes.
Serversshall also set this bit if the ArrayDimensionsor the ValueRank Attributeor the
EnumStrings Propertyof the DataTypeof the Variablechanges.
This bit is provided to warn Clientsthat parse complex data values that their parsing routines
could fail because the serialized form of the data value has changed.
This bit has meaning only for StatusCodesreturned as part of a data change Notificationor
the HistoryRead. StatusCodesused in other contexts shall always set this bit to zero.”

but in (v 1.02 Part 4 7.33 table 163):
“StructureChanged 15:15 Indicates that the structure of the associated data value has changed since the last
Notification. Clients should not process the data value unless they re-read the metadata.
Servers shall set this bit if the DataTypeEncoding used for a Variable changes. 7.23
describes how the DataTypeEncoding is specified for a Variable.
Servers shall also set this bit if the EnumStrings Property of the DataType of the Variable
changes.
This bit is provided to warn Clients that parse complex data values that their parsing routines
could fail because the serialized form of the data value has changed.
This bit has meaning only for StatusCodes returned as part of a data change Notification or
the HistoryRead. StatusCodes used in other contexts shall always set this bit to zero.”

And our implementation is the one from 1.01 era for this functionality.

We need to think about this.

– Bjarne

January 10, 2018
13:26, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1032
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

And the reason why this happens when setting the value is that the value is used internally to store the bits for next notification message, i.e. after changes to the 3 attributes the next value set method call will set the additional bits to the value.

January 10, 2018
14:08, EET
Avatar
Bjarne Boström
Moderator
Moderators
Forum Posts: 1032
Member Since:
April 3, 2012
sp_UserOfflineSmall Offline

Possible workaround would be to set the value twice in a row after loading the model. Then you should not receive the structure change bit.

January 11, 2018
10:26, EET
Avatar
Thomas Reuther
Member
Members
Forum Posts: 33
Member Since:
September 18, 2017
sp_UserOfflineSmall Offline

Hi Bjarne,

thanks for that! 🙂

In my case I do not change DataType or ValueRank. And it happens when I change the ArrayDimension and if I don’t.

Thomas

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 1919

Currently Online:
21 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Heikki Tahvanainen: 402

hbrackel: 144

rocket science: 88

pramanj: 86

Francesco Zambon: 83

Ibrahim: 78

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

Member Stats:

Guest Posters: 0

Members: 730

Moderators: 7

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1529

Posts: 6471

Newest Members:

toneylapham544, rondawolinski7, Marypof5711, roycedelargie91, kourtneyquisenbe, ellis87832073466, zkxwilliemae, gabriellabachus, Deakin, KTP25Zof

Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0

Administrators: admin: 1