Open friko16 opened 4 years ago
Decoding custom structure types is not supported by default by the stack. You will need to register your own serialiser for the type, which requires that you know the structure a priori. See the existing implementations for the standard structure types generated inside the EncodeableSerializer class for examples.
In order to support any previously unknown structure in the client, you will need to parse the TypeDictionary provided by the server. That functionality is out of the scope of the stack and you will need an SDK for that or build it yourself.
Thanks for response, @jouniaro . It's been a long time, I gave up on this problem, but now it came back and trying to solve it again.
The reason I am trying to read the whole structure at once is that now I am passing a list of ~30 ReadValueIds to sessionChannel.Read() and the read takes around 200-300ms. The 30 values is a list of primitive opc types being part of a larger structure. To give you a glimpse of it, I am attaching print screen from UaExpert tool for browsing plc:
.
Why does the read take so long ?
this is how I do it:
String[] nodePaths = ...// initialized list of string nodeId's e.g. "DB_601_Trace_OPC.Read.TP[0].Value"
int namespaceIdx = 3;
for (int i = 0; i < nodePaths.length; i++) {
NodeId nodeId = new NodeId(namespaceIdx, nodePaths[i]);
nodesToRead[i] = new ReadValueId(nodeId, Attributes.Value, null,null);
}
ReadRequest req = new ReadRequest(null, maxAge, TimestampsToReturn.Neither, nodesToRead);
ReadResponse res = connection.getSession().Read(req);
This is unbearable for my requirements, I thought reading the whole structure's root will help. I have tested reading a whole structure with node's opcua parallel project (https://node-opcua.github.io/) and the read takes 20-30 ms for whole structure, and no serializaers/desarializers registration is needed, just pure JSON returned.
I have tried a bit with those structure serializers:
private static class MachineType extends AbstractStructure {
public static final ExpandedNodeId ID = new ExpandedNodeId(new NodeId(3, NodePath.dataMachine(0)));
public static final ExpandedNodeId BINARY = new ExpandedNodeId(new NodeId(3, NodePath.dataMachine(0)));
public static final ExpandedNodeId XML = new ExpandedNodeId(new NodeId(3, NodePath.dataMachine(0)));
public ExpandedNodeId getTypeId() {
return ID;
}
public ExpandedNodeId getXmlEncodeId() {
return XML;
}
public ExpandedNodeId getBinaryEncodeId() {
return BINARY;
}
}
private void customStructure(ConnectionHandler connection) {
EncodeableSerializer ser = EncodeableSerializer.getInstance();
ser.addSerializer(new AbstractSerializer(MachineType.class, MachineType.BINARY, MachineType.XML, MachineType.ID) {
public void calcEncodeable(IEncodeable encodeable, IEncoder calculator) throws EncodingException {
MachineType obj = (MachineType) encodeable;
// ENCODING COMMENTED OUT FOR NOW...
// calculator.putQualifiedName(null, (obj==null)?null:obj.getKey() );
// calculator.putVariant(null, (obj==null)?null:obj.getValue() );
}
public void putEncodeable(IEncodeable encodeable, IEncoder encoder) throws EncodingException {
// ENCODING COMMENTED OUT FOR NOW...
// encoder.putQualifiedName("Key", (obj==null)?null:obj.getKey() );
// encoder.putVariant("Value", (obj==null)?null:obj.getValue() );
}
public IEncodeable getEncodeable(IDecoder decoder) throws DecodingException {
MachineType result = new MachineType();
QualifiedName qn = decoder.getQualifiedName("Key");
Variant var = decoder.getVariant("Value");
return result;
}
});
}
but getting an error:
Exception in thread "Thread-0" java.lang.IllegalArgumentException: Only ExpandedNodeIds that contain the URI are allowed as parameter
at org.opcfoundation.ua.encoding.utils.AbstractSerializer.fixAndValidateId(AbstractSerializer.java:58)
at org.opcfoundation.ua.encoding.utils.AbstractSerializer.<init>(AbstractSerializer.java:107)
at org.opcfoundation.ua.encoding.utils.AbstractSerializer.<init>(AbstractSerializer.java:88
Can some one help, as this is a huge limiter for us and prohibits completing the project. The solution can be either reading a list of NodeIs as of now, but speed it up to ~30ms, or solving the read speed by reading the whole structure at once. If reading the whole structure help with read speed, I don't expect someone to provide full implementation of Structure and Serializers, but some pseudo-code would help, doesn't have to compile.
Can
someone help ? I am sitting on this for days and can't figure out how to read a non-leaf, complex data structure:this data structure when viewed in UAExpert expands into multiple leaf nodes with String and boolean leafs.
and I am getting and exception:
with UAExpert tool, I can read that node with no problems and all it's leafs. opcua.1.4.1.jar
I have read in other issue that I need to read namespaceArray and set is as context, but have no idea how to set it, neither are there examples for that. please help.