Thanks for reading this post. I am gratefull for every help!
Goal:
I am trying to write a ValueNode with the same value, but different timestamp on an Eclipse Milo OpcUa Server. I'm doing all this with Java 11 and Milo 0.3.7.
I tested it among others with the example in the github project. I modified the function addScalarNodes in the class ExampleNamespace to write the same value with an updated timestamp once a second. Checking the node with UaExpert, the timestamp remains on the same value. Only if I update the value too, the timestamp updates.
private void addScalarNodes(UaFolderNode rootNode) {
UaFolderNode scalarTypesFolder = new UaFolderNode(
getNodeContext(),
newNodeId("HelloWorld/ScalarTypes"),
newQualifiedName("ScalarTypes"),
LocalizedText.english("ScalarTypes")
);
getNodeManager().addNode(scalarTypesFolder);
rootNode.addOrganizes(scalarTypesFolder);
for (Object[] os : STATIC_SCALAR_NODES) {
String name = (String) os[0];
NodeId typeId = (NodeId) os[1];
Variant variant = (Variant) os[2];
UaVariableNode node = new UaVariableNode.UaVariableNodeBuilder(getNodeContext())
.setNodeId(newNodeId("HelloWorld/ScalarTypes/" + name))
.setAccessLevel(ubyte(AccessLevel.getMask(AccessLevel.READ_WRITE)))
.setUserAccessLevel(ubyte(AccessLevel.getMask(AccessLevel.READ_WRITE)))
.setBrowseName(newQualifiedName(name))
.setDisplayName(LocalizedText.english(name))
.setDataType(typeId)
.setTypeDefinition(Identifiers.BaseDataVariableType)
.build();
node.setValue(new DataValue(variant));
node.setAttributeDelegate(new ValueLoggingDelegate());
getNodeManager().addNode(node);
scalarTypesFolder.addOrganizes(node);
if (name.equals("Boolean")) {
Thread t = new Thread(() -> {
while (true) {
try {
Thread.sleep(1000L);
node.setValue(new DataValue(new Variant(Boolean.FALSE)));
System.out.println(node.getValue().getSourceTime());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
t.start();
}
}
}
My Question(s):
1) Is updating the timestamp only allowed in OPC UA specs.
2) How can I achive this with Milo?
Thanks in advance!
EDIT I check the timestamp by active reading:
Server-side writing:
private void handleValueUpdate(Object value, DateTime dateTime) {
node.setValue(new DataValue(
new Variant(value),
StatusCode.GOOD,
dateTime));
}
Client-side reading:
VariableNode variableNode = getOpcClient().getAddressSpace().getVariableNode(new NodeId(namespaceIndex, nodeIdentifier)).get();
return variableNode.readValue().get().getSourceTime();
Are you checking by reading (refreshing attributes pane) or with a subscription and monitored item?
If you're using MonitoredItems the default MonitoringFilter when not otherwise specified uses DataChangeTrigger.StatusValue
, which includes changes to value or quality, but not timestamp, so most clients will not ask for or receive timestamp-only changes by default.