OPCFoundation / UA-ModelCompiler

ModelCompiler converts XML files into C# and ANSI C
MIT License
151 stars 94 forks source link

Missing _BinarySchema and/or TypeDictionary_BinarySchema in Opc.Ua.Safety.NodeSet2.xml #130

Closed farhan296 closed 10 months ago

farhan296 commented 1 year ago

I am working on a project that uses Open62541 SDK. My application makes use of Safety Nodesets. When I try to generate source code using Open62541 Nodeset Compiler I get the following error

5>Traceback (most recent call last):
5>  File ".\..\..\..\SDK_Open62541\open62541\tools\generate_datatypes.py", line 95, in <module>
5>    parser.create_types()
5>  File ".\..\..\..\SDK_Open62541\open62541\tools\nodeset_compiler\type_parser.py", line 377, in create_types
5>    self.parse_types()
5>  File ".\..\..\..\SDK_Open62541\open62541\tools\nodeset_compiler\type_parser.py", line 419, in parse_types
5>    self.parseTypeDefinitions(self.outname, f)
5>  File ".\..\..\..\SDK_Open62541\open62541\tools\nodeset_compiler\type_parser.py", line 321, in parseTypeDefinitions
5>    raise RuntimeError("Infinite loop detected or type not found while processing types " +
5>RuntimeError: Infinite loop detected or type not found while processing types MyResponseSPDUDataType: unknonwn subtype ['Safety:OutFlagsType']. If the unknown subtype is 'Bit', then maybe a struct with optional fields is defined wrong in the .bsd-file. If not, maybe you need to import additional types with the --import flag. E.g. '--import=UA_TYPES#/path/to/deps/ua-nodeset/Schema/Opc.Ua.Types.bsd'

While debugging I noticed that the Open62541 nodeset compiler is not including the UAModel.Safety.Types.bsd file generated by the UA-Model Compiler and the reason is that the Opc.Ua.Safety.NodeIds.csv and Opc.Ua.Safety.NodeSet2.xml is missing "_BinarySchema" and/or "TypeDictionary_BinarySchema" nodes which is required by the Open62541 nodeset compiler (see nodeset.py#L431). Is there any workaround for this? Also see the Issue here.

I compile the Safety Nodesets in the following way

Opc.Ua.ModelCompiler.exe compile-nodesets -input .\OPC_Foundation_Safety-files -o2 .\generated_safety -uri http://opcfoundation.org/UA/Safety

copy .\generated_safety .\generated

I compile my App.xml model design file as follows

del .\AppModel.csv

Opc.Ua.ModelCompiler.exe compile -d2 .\AppModel.xml -d2 .\OPC_Foundation_Safety-files\Opc.Ua.Safety.NodeSet2.xml,Safety,Safety -cg .\AppModel.csv -version v105 -o2 .\generated

My App.xml model design is as follows

<?xml version="1.0" encoding="utf-8"?>

<ModelDesign
  xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ua="http://opcfoundation.org/UA/"
  xmlns:Safety="http://opcfoundation.org/UA/Safety"
  xmlns:app="urn:open62541.server.application"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  TargetNamespace="urn:open62541.server.application"
  TargetVersion="0.1.0"
  TargetPublicationDate="2022-05-02T00:00:00Z"
  xmlns="http://opcfoundation.org/UA/ModelDesign.xsd">

  <Namespaces>
    <Namespace Name="app" Prefix="app">urn:open62541.server.application</Namespace>
    <Namespace Name="Safety" Prefix="Safety" PublicationDate="2022-06-28T00:00:00Z" Version="1.05.02">http://opcfoundation.org/UA/Safety</Namespace>
    <Namespace Name="ua" Prefix="ua" Version="1.05.02" PublicationDate="2022-11-01T00:00:00Z">http://opcfoundation.org/UA/</Namespace>
  </Namespaces>

  <DataType SymbolicName="app:MyResponseSPDUDataType" BaseType="Safety:ResponseSPDUDataType" IsAbstract="false">
    <Fields>      
      <Field Name="MyOutSafetyData"  DataType="app:MySafetyData1Type"></Field>
      <Field Name="MyOutNonSafetyData" DataType="app:MyNonSafetyData1Type"></Field>
    </Fields>
  </DataType>

  <DataType SymbolicName="app:MySafetyData1Type" BaseType="ua:Structure" >   
    <Fields>
      <Field Name="Field_1" DataType="ua:UInt32"></Field>
      <Field Name="Field_2" DataType="ua:UInt32"></Field>
      <Field Name="Field_4" DataType="ua:Boolean"></Field>     
    </Fields>
  </DataType>

  <DataType SymbolicName="app:MyNonSafetyData1Type" BaseType="ua:Structure">
    <Fields>
      <Field Name="Item1" DataType="ua:UInt32"></Field>
    </Fields>
  </DataType>

  <!-- ### Object ###-->

  <Object SymbolicName="app:MySafetyProvider" TypeDefinition="Safety:SafetyProviderType">
    <Children>
      <Method SymbolicName="app:MyReadSafetyData">
        <InputArguments>
          <Argument Name="InSafetyConsumerID" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="InMonitoringNumber" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="InFlags" DataType="Safety:InFlagsType" ValueRank="Scalar"></Argument>
        </InputArguments>
        <OutputArguments>
          <Argument Name="OutSafetyData" DataType="app:MySafetyData1Type" ></Argument>
          <Argument Name="OutFlags" DataType="Safety:OutFlagsType" ValueRank="Scalar"></Argument>
          <Argument Name="OutSPDU_ID_1" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutSPDU_ID_2" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutSPDU_ID_3" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutSafetyConsumerID" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutMonitoringNumber" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutCRC" DataType="ua:UInt32" ValueRank="Scalar"></Argument>
          <Argument Name="OutNonSafetyData" DataType="app:MyNonSafetyData1Type" ></Argument>
        </OutputArguments>
      </Method>           
      <Object SymbolicName="app:MySafetyPDUs" TypeDefinition="Safety:SafetyPDUsType">
        <Children>
          <Variable SymbolicName="app:MyRequestSPDU" DataType="Safety:RequestSPDUDataType" TypeDefinition="ua:BaseDataVariableType"></Variable>
          <Variable SymbolicName="app:MyResponseSPDU" DataType="app:MyResponseSPDUDataType" TypeDefinition="ua:BaseDataVariableType"></Variable>
        </Children>
      </Object>
    </Children>

    <References>
      <Reference IsInverse="true">
        <ReferenceType>ua:Organizes</ReferenceType>
        <TargetId>Safety:SafetyACSet</TargetId>
      </Reference>
    </References>
  </Object>   

</ModelDesign>
opcfoundation-org commented 1 year ago

The DataTypeDictionaries have been removed from 1.05 (feature replaced by the DataTypeDefinition Attribute). New nodesets are permitted to omit them. You will need to update your generator to handle this case.

That said, you can submit a mantis issue to the Safety WG asking them to add the DataTypeDictionaries for backward compatibility. See https://mantis.opcfoundation.org/set_project.php?project_id=28&make_default=no.

farhan296 commented 1 year ago

Thank you for the response. I shall create mantis issue as suggested. Further, Is there any example for the usage of DataTypeDefinition Attribute? Do I have to include a DataTypeDefinition block in my ModelDesign file (App.xml) or will the UA-Model compiler generate accordingly?

opcfoundation-org commented 1 year ago

ModelCompiler generates the DataTypeDefinition in the NodeSet.