Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when loading DataTypes with the same name (different namespace). #1693

Open
izonfreak opened this issue Aug 9, 2024 · 2 comments
Open

Comments

@izonfreak
Copy link

izonfreak commented Aug 9, 2024

Hello,

I was testing the Client with an OPC UA server that implements OPC 40100-1: Machine Vision - Control, Configuration management, recipe management, result management

https://reference.opcfoundation.org/MachineVision/v100/docs/

NodeSet -> https://github.com/OPCFoundation/UA-Nodeset/tree/latest/MachineVision

The problem is that when I try to load the server data types (load_data_types_definitions() ) I get the following error:


  File "C:\Users\aaa\ooo\vvv\EventTest.py", line 42, in main
    await client.load_data_type_definitions()
  File "C:\Users\aaa\AppData\Local\Programs\Python\Python311\Lib\site-packag
es\asyncua\client\client.py", line 864, in load_data_type_definitions
    return await load_data_type_definitions(self, node, overwrite_existing=overw
rite_existing)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^
  File "C:\Users\aaa\AppData\Local\Programs\Python\Python311\Lib\site-packag
es\asyncua\common\structures104.py", line 481, in load_data_type_definitions
    env = await _generate_object(dts.name, dts.sdef, data_type=dts.data_type, lo
g_fail=log_ex)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^
  File "C:\Users\aaa\AppData\Local\Programs\Python\Python311\Lib\site-packag
es\asyncua\common\structures104.py", line 295, in _generate_object
    code = make_structure_code(data_type, name, sdef, log_error=log_fail)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\aaa\AppData\Local\Programs\Python\Python311\Lib\site-packag
es\asyncua\common\structures104.py", line 219, in make_structure_code
    raise RuntimeError(f"Unknown datatype for field: {sfield} in structure:{stru
ct_name}, please report")
RuntimeError: Unknown datatype for field: StructureField(Name='Id', Description=
LocalizedText(Locale='', Text='Id is a system-wide unique name for identifying t
he recipe.'), DataType=NodeId(Identifier=3017, NamespaceIndex=2, NodeIdType=<Nod
eIdType.FourByte: 1>), ValueRank=-1, ArrayDimensions=[], MaxStringLength=0, IsOp
tional=False) in structure:BinaryIdBaseDataType, please report

Process finished with exit code 1

This structure data type BinaryIdBaseDataType is an abstract and is the parent to other data types such as "ConfigurationIdDataType".

image

Since the exception mentions to report it here i am.

Python-Version: 3.11.4
opcua-asyncio Version 1.1.0

@schroeder-
Copy link
Contributor

In our tests we load the machine vision cs

nodes += await opc.opc.import_xml(NODESET_VISION)

So this looks like a problem with the server.

@izonfreak
Copy link
Author

izonfreak commented Sep 2, 2024

Hello @schroeder- ,

The test seems to be for server part. I am trying to connect as a client, and that is where the data type definitions fail. It seems that the problem comes from having a Structure with a field that is not one of the built-in data types.

grafik

In the case BinaryIdBaseDataType has a field that is of TrimmedString which is a sup-type of string (also define in the same xml file). Checking the code in structures104.py ( I am no python expert btw) and it seems that it should work right ? specifically :

  elif sfield.DataType in ua.basetype_by_datatype:
        uatype = ua.basetype_by_datatype[sfield.DataType]

TrimmedString should be an alias for "String" so this should return true.. but somehow it does not.

[Edited]

Adding more information after some debugging. The server I am connecting has the latest base information model by the OPC Foundation. In that latest model they added a new data type also call TrimmedString. This is a case in which a companion specification defines something and then is move to the base standard. That means that in a server that use the latest version of the base standard + the machine vision companion specification there are two TrimmedString data types and this is where the bug is in the SDK.

**
grafik
**

More specifically the problem is that the SDK (in _recursive_parse_basedatatypes function in structures104.py) is only checking names to see if a data type is already register (hasattr) which is not enough to individually identify a data type.

grafik

Then when I try to load the the data types from the server the second TrimmedString from the machine vision companion spec is skip and when is referenced by the BinaryIdBaseDataType result in the failure/exception that I experience. How do I/we proceed with this ? should we just fix this function? this will kinda break a few things since you will not be able to just use ua.TrimmedString to create an instance of a data type. In this case both data types have the same meaning and are identical except on the node id.

Maybe one possible solution would be to add something like a namespace, before loading the data types. In the examples there is this function register_namespace could be possible to expand it so that you provide an namespace for the data types in there ? So that you can then do something like :

    uri = 'http://opcfoundation.org/UA/MachineVision'
    idx = await client.register_namespace(uri, types_namesapce= 'mv')
    await client.load_data_type_definitions()
    string_trimmed = ua.mv.TrimmedString(str(1))

Another options is also to expand load_data_type_definitions() with options to include the namespace information. Note that this probably will be a problem if two nodesets define a datatype with the same name, is not only a problem with the base information model and this particular data type TrimmedString.

PS:I did also try to just import the xml file as a client but I get also an strange error "BadUserAccesDenied" and some other warnings. I also could not import it without setting strict mode to false. Not sure if the problem is also related to the one described here.

    await client.import_xml('schema/Opc.Ua.MachineVision.NodeSet2.xml', strict_mode=False)

@izonfreak izonfreak changed the title Unable to load ExtensionObject (struct) BinaryIdBaseDataType from Machine Vision CS. Error when loading DataTypes with the same name (different namespace). Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants