Skip to content

ModelCompiler generates Variables with duplicate NodeIds #224

@bengeisler

Description

@bengeisler

The ModelCompiler generates NodeSet2.xml files with duplicate NodeIds in some cases. I'll describe a minimal example that reproduces this:

Let's say I have some DataType FooStruct which is a Structure:

    <UADataType NodeId="ns=1;i=3000" BrowseName="1:FooStruct">
        <DisplayName>FooStruct</DisplayName>
        <References>
            <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5001</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5002</Reference>
        </References>
        <Definition Name="1:FooStruct">
            <Field DataType="Boolean" Name="FooItem"/>
        </Definition>
    </UADataType>

It has just one field, namely FooItem of type Boolean.

Now, I'll derive a VariableType from this:

    <UAVariableType DataType="ns=1;i=3000" NodeId="ns=1;i=2000" BrowseName="1:FooVariableType">
        <DisplayName>FooVariableType</DisplayName>
        <References>
            <Reference ReferenceType="HasSubtype" IsForward="false">i=63</Reference>
            <Reference ReferenceType="HasComponent">ns=1;i=6015</Reference>
        </References>
    </UAVariableType>

This gives me a InstanceDeclaration of FooItem, the field of the struct just created:

    <UAVariable DataType="Boolean" NodeId="ns=1;i=6015" BrowseName="1:FooItem" ParentNodeId="ns=1;i=2000" UserAccessLevel="3" AccessLevel="3">
        <DisplayName>FooItem</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
            <Reference ReferenceType="HasModellingRule">i=78</Reference>
        </References>
    </UAVariable>

Now I go on to create an ObjectType:

    <UAObjectType NodeId="ns=1;i=1000" BrowseName="1:FooObjectType">
        <DisplayName>FooObjectType</DisplayName>
        <References>
            <Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference>
            <Reference ReferenceType="HasComponent">ns=1;i=6016</Reference>
        </References>
    </UAObjectType>

that has one child:

    <UAVariable DataType="ns=1;i=3000" NodeId="ns=1;i=6016" BrowseName="1:Foo" ParentNodeId="ns=1;i=1000" UserAccessLevel="3" AccessLevel="3">
        <DisplayName>Foo</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">ns=1;i=2000</Reference>
            <Reference ReferenceType="HasModellingRule">i=78</Reference>
            <Reference ReferenceType="HasComponent">ns=1;i=6015</Reference>
        </References>
    </UAVariable>

which has a HasTypeDefinition reference that points to the previously created VariableType FooVariableType.

Now comes the issue: when running this file through the ModelCompiler:

docker run \
-v $(pwd):/nodesets \
--rm ghcr.io/opcfoundation/ua-modelcompiler:latest compile \
-d2 /nodesets/model/foo.xml,foo.com \
-d2 /nodesets/schema/ua/Opc.Ua.NodeSet2.xml,Opc.Ua \
-o2 generated/foo

this generates two Variable nodes with the same NodeId:

  <UAVariable NodeId="ns=1;i=6015" BrowseName="1:FooItem" ParentNodeId="ns=1;i=2000" DataType="Boolean" AccessLevel="3">
    <DisplayName>FooItem</DisplayName>
    <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasModellingRule">i=78</Reference>
      <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=2000</Reference>
    </References>
  </UAVariable>
  <UAVariable NodeId="ns=1;i=6015" BrowseName="1:FooItem" ParentNodeId="ns=1;i=6016" DataType="Boolean" AccessLevel="3">
    <DisplayName>FooItem</DisplayName>
    <References>
      <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
      <Reference ReferenceType="HasModellingRule">i=78</Reference>
      <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=6016</Reference>
    </References>
  </UAVariable>

In my opinion, the ModelCompiler should never create a Node with the same id multiple times.
In this specific case it should only generate the first node with the ParentNodeId ns=1;i=2000
In any case, if it were to create the same NodeId again, it should abort the process with an error message.

Attached two files:
foo.xml is the input provided to the ModelCompiler
foo.com.NodeSet2.xml is the generated output

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions