Last updated on April 10, 2022
This post shows how to write the model by editing a ModelDesign file with a suitable editor
This Post is part of the OPC UA Information Model Tutorial.
It is recommended that you also read through the following page to get an overview on OPC UA Information modeling:
In this tutorial we are using the example files provided in the following repository:
https://github.com/pro/opcua-modeling-tutorial
Especially the file FooFltModel.xml
A more complete example with heavy use of heavy usage of ModelDesign files and dependencies between them is shown in this project (look into subfolders with the name opcua
):
https://github.com/opcua-skills/plug-and-produce
If you are using Visual Studio, make sure that you set up Visual Studio as mentioned here:
Namespaces
Namespaces help to avoid naming conflicts by prefixing them to variable names. Apart from that, they also split the whole address space in the server into multiple groups.
The following code shows the minimum code required for an empty ModelDesign with comments indicating the designated model components. A lot of the boiler-plate code is concerned with namespaces, which are discussed in this section.
<?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:FooZbrFlt="https://new.foo.com/zebra-compression/flattening-and-subspacefolding/UA/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" TargetNamespace="https://new.foo.com/zebra-compression/flattening-and-subspacefolding/UA/" TargetVersion="0.9.0" TargetPublicationDate="2020-05-01T00:00:00Z" xmlns="http://opcfoundation.org/UA/ModelDesign.xsd"> <Namespaces> <!--No space allowed at the beginning of the namespace URL! Prefix sets the filenames of the generated files. --> <Namespace Name="FooZbrFlt" Prefix="FooFlt">https://new.foo.com/zebra-compression/flattening-and-subspacefolding/UA/</Namespace> <Namespace Name="OpcUa" Version="1.03" PublicationDate="2013-12-02T00:00:00Z">http://opcfoundation.org/UA/</Namespace> </Namespaces> <!-- ObjectType --> <!-- ReferenceType --> <!-- VariableType --> <!-- DataType --> <!-- Object --> <!-- Variable --> <!-- Property --> <!-- Dictionary --> <!-- Method --> <!-- View --> <!-- Instantiate at least one variable (or object, or view, or ...) in namespace. Compiling an empty namespace will fail with error message: Object reference not set to an instance of an object. See https://github.com/OPCFoundation/UA-ModelCompiler/issues/68 --> <View SymbolicName="FooZbrFlt:MyView"> <Description>Dummy view</Description> <References> <Reference IsInverse="true"> <ReferenceType>ua:Organizes</ReferenceType> <TargetId>ua:ObjectsFolder</TargetId> </Reference> </References> </View> </ModelDesign>
The XML element ModelDesign
has the following attributes:
xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd"
- The link leads to a schema file that defines various complexTypes used by OPCFoundation.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- required
xmlns:ua="http://opcfoundation.org/UA/"
- Namespace of all OPCFoundation
xmlns:FooZbrFlt="https://new.foo.com/zebra-compression/flattening-and-subspacefolding/UA/"
- this document may use elements of namespace
FooZbrFlt
. In combination withTargetNamespace
this document may defineObjectType
elements in that namespace as well as use them from that namespace, as long as their names are correctly prefixed withFooZbrFlt:
.
- this document may use elements of namespace
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
TargetNamespace="https://new.foo.com/zebra-compression/flattening-and-subspacefolding/UA/"
- this document defines elements in this namespace
TargetVersion="0.9.0"
- optional, used as auxiliary release meta-information
TargetPublicationDate="2020-05-01T00:00:00Z"
- optional, used as auxiliary release meta-information
xmlns="http://opcfoundation.org/UA/ModelDesign.xsd"
- Default namespace of this document
Methods
Define method types explicitly (grey box) and use them via TypeDefinition
for method nodes as shown for method MyMethod
. Defining methods in-places like MyMethodInPlace
will not expose Input- and OutputArguments to the OPC UA client.
Note: In comparison to Object/ObjectType and Variable/VariableType, Method do not have MethodType.

Continue with Step 7
Hi, i am using the approach described in the tutorial to create some objects with some methods. I defined method definitions and methods in objects referring to these method definitions via TypDefinition attribute. Then generated .c and .h Files using UA-ModelCompiler and nodeset_compiler.
The problem comes from generated code. It calls UA_Server_addNode for method definitions for nodeID=0 and this call fails, with UA_STATUSCODE_BADPARENTNODEIDINVALID
Will appreciate any help
Hi Max,
as long as your model is syntactically correct, UA-ModelCompiler and nodeset_compiler will compile your model. Without your model and your code it’s hard to help you on your vague description alone, but I would look into your server code before revisiting the model. Here are my recommendations:
* Revisit the following official tutorials:
https://open62541.org/doc/current/tutorial_server_variable.html
https://open62541.org/doc/current/tutorial_server_method.html
Look at the steps they are taking and the functions they are using, especially UA_Server_addMethodNode
Note, that the code listings in above tutorials are taken from the actual open62541 source code over here:
https://github.com/open62541/open62541/tree/master/examples
I recommend you derive your minimal working example (MWE) from the example code from the open62541 github repository.
Note, that the tutorials do not use the function UA_Server_addNode . In fact, I can’t find that function call anywhere in the open62541 repository
https://github.com/open62541/open62541/search?q=UA_Server_addNode
I think that should help you to solve your issue. Good luck!
To check if my recently compiled ModelCompiler (on VS2017) works, I tried to compile the above example (minimum code required for an empty ModelDesign). I expected to get an “empty” NodeSet2 file (without objects).
But unexpected errors occur:
Object reference not set to an instance of an object.
at ModelCompiler.ModelCompilerValidator.Validate2(IList`1 designFilePaths, String identifierFilePath, Boolean generateIds) in C:\GIT\UA-ModelCompiler\ModelCompiler\ModelDesignerValidator.cs:line 1213 at ModelCompiler.ModelGenerator2.ValidateAndUpdateIds(IList`1 designFilePaths, String identifierFilePath, UInt32 startId, String specificationVersion) in C:\GIT\UA-ModelCompiler\ModelCompiler\ModelGenerator2.cs:line 98 at ModelCompiler.Program.ProcessCommandLine2(List`1 tokens) in C:\GIT\UA-ModelCompiler\ModelCompiler\Program.cs:line 422
Was the ModelCompiler not compiled correctly or is it not possible by design to create this empty NodeSet2 file as a first test ?
Hi,
what is the git commit ID of the ModelCompiler you’re using?
Your ModelCompiler is probably compiled correctly, but there is still a chance for bugs. The edge case “empty NodeSet2” is likely to trigger such a bug.
I can’t answer your question with confidence, but I don’t see why you should not be able to create an “empty” NodeSet2 file (I assume that also excludes type definitions etc.).
Can you compile a NodeSet2 with just a single object?
To test this, take https://github.com/Pro/opcua-modeling-tutorial/blob/master/FooFltModel.xml and remove all Type Definitions, so that you’re left with the boiler plate code on top and the object FooZbrFlt:Ape. Change it’s TypeDefinition to something basic.
Let me know of any progress or insights on your side.
It may take me some days to get access to my dev environment and test your question myself.
Kind regards!
Hi Karl,
I have revisited your question, reproduced your issue and reported it to
https://github.com/OPCFoundation/UA-ModelCompiler/issues/68
I have also updated the example ModelDesign with a “view” to make it compilable.
Kind regards
Hi, the processing of namespaces and elements of the design in general can be a bit tricky. It appears that the model compiler imports nodes sequentially. In case a node refers to another node, be it a specialisation, association or composition, the compiler throws an errror when the target of the reference hasn’t been imported yet. I’ve been trying to import multiple namespaces and was forced to put things in sequence. For one, I created a different design file for each namespace that fed one after the other into the model compiler. And circular references imply a ticket to dependency hell.
It strikes me as odd that the import should be so sensitive to dependencies.
Any tips for clever model design in this respect.
Hi Bob,
sorry for my late reply. I can not offer you a solution but I can tell you, that I have experienced the model builder to be sensitive to the order of models/namespaces too.
I did not come up with any best-practice advice to share here with you, but I also have to admit that my models never warranted to thorough search for a general solution since the issue was usually identified and fixed quickly.
Can you give me an example for a circular reference that has some real-world application?