FreeOpcUa / opcua-asyncio

OPC UA library for python >= 3.7
GNU Lesser General Public License v3.0
1.09k stars 355 forks source link

Possible inconsisent handling of custom datatypes on multiple servers using load_data_type_definitions() #1678

Open nictop17 opened 1 month ago

nictop17 commented 1 month ago

Usage of NamespaceIndex for custom DataType-Classes

When I had two OPC UA servers import the same NodeSets but in different order and wanted to access them with clients, I realized that the handling of custom datatypes by the method load_data_type_definitions() could possibly be inconsistent.

As can be seen from the following class created by the method, the NamespaceIndex in the NodeId is used to identify the datatype. However, this is dependent on the order of the namespaces on the respective server. The definition of the same datatype can therefore be located on different servers in the same namespace, but does not have to have the same namespaceIndex. If the generated class is now to be used across servers, there are inconsistencies in the way the values are written.

@dataclass
class Box:

    '''
    Box structure autogenerated from StructureDefinition object
    '''

    data_type = ua.NodeId.from_string('''ns=5;i=3003''')

    BoxID: ua.Int16 = ua.Int16(0)
    Components: typing.List[ua.Component] = field(default_factory=list)
    BoxType: ua.BoxType = ua.BoxType.Type_A

Is this intentional or should the namespaceUri be used here instead of the namespaceIndex to ensure consistency regardless of the import sequence?

I have already tried the parameter overwrite_existing of the load_data_type_definitions()-method, but unfortunately it solves the problem only superficially

I may also not understand exactly how it works, in which case an explanation could also help :)

Example

When trying to read from the first server and write to the second, UaExpert shows the Value of the Variable with custom datatype Box as follows: image

Env

Using Asyncua==1.1.5

AndreasHeine commented 1 month ago

the namedspace array gets filled in the order of registration of the namespaces only idx 0 and 1 are stable!

clients need to be aware of that and should always store uris (expanded nodeids) instead of the idx... or the namespace array alongside the nodeids, so it can be translated and checked against the server after connect.

https://www.linkedin.com/posts/andreasheine-dev_opcua-iiot-industry40-activity-7193695455258529792-2VNV?utm_source=share&utm_medium=member_android

nictop17 commented 1 month ago

Yes, I am of exactly the same opinion.

For this reason, i thought using the NamespaceIndex instead of the Uri when creating the classes in the ua module could be a problem. However, the NamespaceArray is kept in every ua.Client() and could therefore be used for translation. But Im not sure if this is the case and could be the reason for my error described above