10:46, EET
September 18, 2017
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:
<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:
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
13:23, EET
April 3, 2012
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
13:26, EET
April 3, 2012
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, KTP25ZofModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1