## Summary Adds OPC UA WoT Connectivity 1.1 to the stack, together with the Types, source generation, Server and xRegistry work it is built on. This branch is the merge point for the fourteen-PR stack that replaced integration PR #4093; every constituent PR was reviewed and approved separately and is listed below. 414 files changed, +108,936 / -3,199. Roughly 46k added lines of product code, 57k of tests, plus samples, tools and documentation. ## Types - Complete `ExtensionObject` raw-body decoding for binary, XML and JSON bodies by resolving the concrete type through the message context's encodeable factory, and simplify the `Variant` structure helpers by delegating to it (#4128). - Add `IAtomicFileReplace` as an optional `IFileSystem` capability so existing external implementations keep working, with atomic publish for `LocalFileSystem` via `File.Replace`/`File.Move` and for `VirtualFileSystem` by re-keying the in-memory entry (#4128). - Add lossless conversion between WoT documents and NodeSet2 (`Opc.Ua.Wot.WotNodeSetConverter`). A byte-exact `uav:nodeSet` envelope is preserved when requested, the structured `uav:nodes` projection is used when the readable vocabulary is incomplete, and NodeSet2 is otherwise synthesized from readable WoT terms. Unmapped JSON members survive a round trip as pointer-addressed residue (#4131). ## Source generation - Improve the NodeSet to ModelDesign conversion and the generated node state (#4132). - Generate OPC UA models directly from WoT Thing Description files (#4134). ## Server - Add live NodeManager shadow and immediate reload. A reload materializes a new generation beside the active one and switches atomically; the superseded generation is retired gracefully so existing MonitoredItems keep being served until they drain, or immediately when the caller asks for it. Includes the request admission and drain machinery that lets an orderly shutdown wait for admitted requests instead of tearing down underneath them (#4147). - Make subscription transfer between sessions transactional, so a failed transfer leaves neither session holding a partially moved subscription (#4150). ## xRegistry - Allow clients to use explicit registry roots rather than assuming a well-known location (#4130). ## WoT Connectivity - Add the WoT Connectivity 1.1 information model: a registry-first revision layered on the abstract xRegistry base model, incorporating the complete published OPC 10100-1 v1.02 surface as deprecated nodes in the same namespace so existing 1.02 clients keep working (#4139). - Add the protocol binding abstractions and planners that compile WoT forms into executable plans (#4140). - Add the HTTP, Modbus, OPC UA and MQTT binding executors (#4144). - Add the registry and its stores, including document versioning, validation, dependency resolution and refresh (#4146). - Add the registry client (#4142). - Materialize WoT Thing Descriptions into the server address space, deriving types from Thing Models and instances from Thing Descriptions (#4154). - Restore the WoT asset registry bridge so the deprecated 1.02 asset surface is backed by the registry (#4171). - Add the WoT Connectivity samples and complete the documentation (#4156), and restore the remaining coverage and docs (#4172). ## New projects `src/Opc.Ua.WotCon.Bindings`, `src/Opc.Ua.WotCon.Bindings.Mqtt`, `tests/Opc.Ua.WotCon.Bindings.Tests`, `tests/Opc.Ua.WotCon.Samples.Tests`, and the `samples/WotCon` AggregationServer, AggregationClient and FlatTagServer samples. ## Constituent pull requests Merged into this branch top-down, each independently approved: | PR | Title | | --- | --- | | #4128 | [Types] Complete ExtensionObject decoding and add an atomic file replace capability | | #4131 | [Types] Add lossless conversion between WoT documents and NodeSet2 | | #4132 | [SourceGeneration] Improve NodeSet to ModelDesign conversion and generated node state | | #4134 | [SourceGeneration] Generate OPC UA models from WoT Thing Description files | | #4147 | [Server] Add live NodeManager shadow and immediate reload | | #4150 | [Server] Make subscription transfer between sessions transactional | | #4130 | [XRegistry] Allow clients to use explicit registry roots | | #4139 | [WotCon] Add the WoT Connectivity 1.1 information model | | #4140 | [WotCon] Add the WoT protocol binding abstractions and planners | | #4144 | [WotCon] Add the HTTP, Modbus, OPC UA and MQTT binding executors | | #4146 | [WotCon] Add the WoT Connectivity registry and its stores | | #4142 | [WotCon] Add the WoT Connectivity registry client | | #4154 | [WotCon] Materialize WoT Thing Descriptions into the server address space | | #4156 | [WotCon] Add the WoT Connectivity samples and complete the documentation | | #4171 | Restore WoT asset registry bridge | | #4172 | Restore WoT coverage and docs | Supersedes #4093. ## Follow-up The WoT Connectivity and WoT Binding drafts have moved to 1.1-draft2 since this work was authored. Aligning with that revision - the removed group vocabulary, the new projection/View construct, the remaining model vocabulary terms and the two new portable-identity validation rules - is tracked separately and will follow in its own pull request. ## Validation Built for every target framework with zero warnings and zero errors, and validated at the tip of the stack with `Opc.Ua.WotCon.Tests` at 999 passed / 0 failed and `Opc.Ua.Server.Tests` at 4024 passed / 0 failed. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9e6a5abf-3299-4cd1-9855-010fedbf0ad8
OPC UA Model Design File Schema Documentation
Overview
The UA Model Design Schema is a proprietary schema that supports a more visual modelling experience defining OPC UA types and instances. This definition is used by the model compiler and source generator to generate code, documentation, and validate model consistency.
The schema allows modellers to:
- Define Types (ObjectType, VariableType, DataType, ReferenceType)
- Define Instances (Object, Variable, Method, Property)
- Organize entities within Namespaces
- Manage Permissions and Access Restrictions
- Create References between nodes
- Specify Default Values and Parameters
Note: This schema is not part of the official OPC UA specification. The official definition of nodes and references is in the form of .Nodeset2.xml whose schema is defined in OPC UA Part 6 - Annex F. This code is used internally to convert .Nodeset2.xml files to this schema format.
Table of Contents
Document Structure
A valid ModelDesign XML document must:
- Start with a
<ModelDesign>root element - Include a
TargetNamespaceattribute (required) - Optionally define
<Namespaces>and<PermissionSets> - Contain zero or more type and instance declarations
- Optionally include
<Extensions>for custom metadata
Example Model Structure
<?xml version="1.0" encoding="utf-8"?>
<ModelDesign
TargetNamespace="http://example.com/MyModel"
TargetVersion="1.0"
TargetXmlNamespace="http://example.com/MyModel/Types.xsd"
DefaultLocale="en">
<Namespaces>
<Namespace Name="MyNamespace"
Prefix="Example.MyModel">
http://example.com/MyModel
</Namespace>
</Namespaces>
<ObjectType SymbolicName="MyObjectType">
<!-- Type definition -->
</ObjectType>
</ModelDesign>
{
"TargetNamespace": "http://example.com/MyModel",
"TargetVersion": "1.0",
"TargetXmlNamespace": "http://example.com/MyModel/Types.xsd",
"DefaultLocale": "en",
"Namespaces": [
{
"Name": "MyNamespace",
"Prefix": "Example.MyModel",
"Content": "http://example.com/MyModel"
}
],
"ObjectTypes": [
{
"SymbolicName": "MyObjectType"
}
]
}
Core Components
1. Root Element: ModelDesign
The <ModelDesign> element is the container for all model definitions.
Attributes:
TargetNamespace(required) - The URI identifying the namespaceTargetVersion(optional) - Version of the modelTargetPublicationDate(optional) - Publication date (ISO 8601)TargetXmlNamespace(optional) - XML namespace URI (if different from TargetNamespace)DefaultLocale(optional, default: "en") - Default language locale
See also: Namespaces, Permission Management, Extensions
2. Namespace Organization
Namespaces organize OPC UA entities and create numeric indices for browse paths.
<Namespaces>
<Namespace Name="Core"
Prefix="Opc.Ua"
InternalPrefix="Opc.Ua.Server"
XmlNamespace="http://opcfoundation.org/UA/2008/02/Types.xsd"
FilePath="Opc.Ua.Types.xml">
http://opcfoundation.org/UA/
</Namespace>
</Namespaces>
{
"Namespaces": [
{
"Name": "Core",
"Prefix": "Opc.Ua",
"InternalPrefix": "Opc.Ua.Server",
"XmlNamespace": "http://opcfoundation.org/UA/2008/02/Types.xsd",
"FilePath": "Opc.Ua.Types.xml",
"Content": "http://opcfoundation.org/UA/"
}
]
}
Namespace Attributes:
Name- Symbolic identifier for the namespacePrefix- C# namespace for generated classesInternalPrefix- C# namespace for server-only typesXmlNamespace- XML namespace URI (if different from content)XmlPrefix- XML namespace prefixFilePath- Path to separate design fileVersion- Namespace versionPublicationDate- Publication date
3. Permission Management
Permission Management controls access and security for nodes.
Permission Sets (Global)
Define reusable permission configurations at the model level.
<PermissionSets>
<PermissionSet Name="AdminPermissions">
<RolePermission Role="Administrator">
<Permission>All</Permission>
</RolePermission>
<RolePermission Role="Guest">
<Permission>Browse</Permission>
<Permission>Read</Permission>
</RolePermission>
</PermissionSet>
</PermissionSets>
{
"PermissionSets": [
{
"Name": "AdminPermissions",
"RolePermissions": [
{
"Role": "Administrator",
"Permissions": ["All"]
},
{
"Role": "Guest",
"Permissions": ["Browse", "Read"]
}
]
}
]
}
Role-Based Permissions
Each node can have role-specific permissions. Available permissions include:
- Browse - Browse the node
- Read - Read the node value
- Write - Write the node value
- ReadHistory - Read node history
- InsertHistory, ModifyHistory, DeleteHistory
- ReceiveEvents - Subscribe to node events
- Call - Invoke methods
- AddReference, RemoveReference
- DeleteNode, AddNode
- All, AllRead, None
See also: Role-Based Access, Access Restrictions
Type System
The schema defines four main type categories through a type hierarchy:
graph TD
A["NodeDesign<br/>(Base)"] --> B["TypeDesign"]
A --> C["InstanceDesign"]
B --> B1["ObjectTypeDesign"]
B --> B2["VariableTypeDesign"]
B --> B3["DataTypeDesign"]
B --> B4["ReferenceTypeDesign"]
C --> C1["ObjectDesign"]
C --> C2["VariableDesign"]
C --> C3["MethodDesign"]
C --> C4["ViewDesign"]
C2 --> C2a["PropertyDesign"]
B1 --> B1a["EncodingDesign"]
C2 --> C2b["DictionaryDesign"]
3.1 Type Designs (Inherits from TypeDesign)
Type designs define the structure and behavior of types in the information model.
ObjectTypeDesign
Defines the structure of objects in the information model. See Instance Designs for related ObjectDesign.
<ObjectType SymbolicName="MyObjectType"
BaseType="ua:BaseObjectType"
IsAbstract="false"
SupportsEvents="true">
<DisplayName>My Custom Object</DisplayName>
<Description>Describes an instance of MyObjectType</Description>
<Children>
<Variable SymbolicName="Status" TypeDefinition="ua:BaseVariableType" />
<Method SymbolicName="Initialize" />
</Children>
</ObjectType>
{
"ObjectType": {
"SymbolicName": "MyObjectType",
"BaseType": "ua:BaseObjectType",
"IsAbstract": false,
"SupportsEvents": true,
"DisplayName": "My Custom Object",
"Description": "Describes an instance of MyObjectType",
"Children": [
{
"Variable": {
"SymbolicName": "Status",
"TypeDefinition": "ua:BaseVariableType"
}
},
{
"Method": {
"SymbolicName": "Initialize"
}
}
]
}
}
Key Attributes:
BaseType- Parent type (default: BaseObjectType)IsAbstract- Cannot instantiate if trueSupportsEvents- Generates eventsNoClassGeneration- Skip code generation
VariableTypeDesign
Defines the structure of variables in the information model. See Instance Designs for related VariableDesign.
<VariableType SymbolicName="TemperatureType"
DataType="xs:double"
ValueRank="Scalar"
AccessLevel="ReadWrite">
<DefaultValue>
<Double>20.5</Double>
</DefaultValue>
</VariableType>
{
"VariableType": {
"SymbolicName": "TemperatureType",
"DataType": "xs:double",
"ValueRank": "Scalar",
"AccessLevel": "ReadWrite",
"DefaultValue": {
"Double": 20.5
}
}
}
Key Attributes:
DataType- The data type of the variableValueRank- Scalar, Array, ScalarOrArray, OneOrMoreDimensions, ScalarOrOneDimension, AnyArrayDimensions- Dimensions specificationAccessLevel- Read, Write, ReadWrite, HistoryRead, HistoryWrite, HistoryReadWriteMinimumSamplingInterval- Sampling rate in millisecondsHistorizing- Supports historical dataExposesItsChildren- Children are exposed in address space
DataTypeDesign
Defines the structure of data types (complex types). See Complex Types for detailed examples.
<DataType SymbolicName="MyStructure"
IsAbstract="false"
IsOptionSet="false"
IsUnion="false">
<Fields>
<Field Name="Field1" DataType="xs:int" />
<Field Name="Field2" DataType="xs:string" IsOptional="true" />
</Fields>
<Encodings>
<Encoding SymbolicName="MyStructureEncoding">
<!-- Encoding specification -->
</Encoding>
</Encodings>
</DataType>
{
"DataType": {
"SymbolicName": "MyStructure",
"IsAbstract": false,
"IsOptionSet": false,
"IsUnion": false,
"Fields": [
{
"Name": "Field1",
"DataType": "xs:int"
},
{
"Name": "Field2",
"DataType": "xs:string",
"IsOptional": true
}
],
"Encodings": [
{
"SymbolicName": "MyStructureEncoding"
}
]
}
}
Key Attributes:
IsOptionSet- Structure is an option set (bitmask)IsUnion- Structure is a union typeNoArraysAllowed- Instances cannot be arraysForceEnumValues- Force numeric values for enumsNoEncodings- Skip encoding generation
Special Cases:
- OptionSet: Represents a set of flags combined with bitwise operations
- Union: Only one field is active at a time
See also: DataType with Fields, DataType with Encodings
ReferenceTypeDesign
Defines typed References between nodes.
<ReferenceType SymbolicName="MyReference"
BaseType="ua:References"
Symmetric="false">
<InverseName>IsReferencedBy</InverseName>
</ReferenceType>
{
"ReferenceType": {
"SymbolicName": "MyReference",
"BaseType": "ua:References",
"Symmetric": false,
"InverseName": "IsReferencedBy"
}
}
Attributes:
Symmetric- Same reference type applies in both directions
3.2 Instance Designs (Inherits from InstanceDesign)
Instance designs represent actual instances of types in the OPC UA address space. See Type Designs for the corresponding type definitions.
ObjectDesign
Represents an object instance in the address space. Instances of ObjectTypeDesign.
<Object SymbolicName="MyObject"
TypeDefinition="MyObjectType"
ModellingRule="Mandatory"
SupportsEvents="true">
<DisplayName>My Object Instance</DisplayName>
<Children>
<Variable SymbolicName="Status" />
</Children>
</Object>
{
"Object": {
"SymbolicName": "MyObject",
"TypeDefinition": "MyObjectType",
"ModellingRule": "Mandatory",
"SupportsEvents": true,
"DisplayName": "My Object Instance",
"Children": [
{
"Variable": {
"SymbolicName": "Status"
}
}
]
}
}
VariableDesign
Represents a variable instance in the address space. Instances of VariableTypeDesign.
<Variable SymbolicName="Temperature"
TypeDefinition="TemperatureType"
DataType="xs:double"
AccessLevel="Read"
ModellingRule="Mandatory">
<DefaultValue>
<Double>20.0</Double>
</DefaultValue>
</Variable>
{
"Variable": {
"SymbolicName": "Temperature",
"TypeDefinition": "TemperatureType",
"DataType": "xs:double",
"AccessLevel": "Read",
"ModellingRule": "Mandatory",
"DefaultValue": {
"Double": 20.0
}
}
}
PropertyDesign
A specialized VariableDesign used for node properties.
<Property SymbolicName="SerialNumber"
DataType="xs:string"
AccessLevel="Read"
ModellingRule="Mandatory" />
{
"Property": {
"SymbolicName": "SerialNumber",
"DataType": "xs:string",
"AccessLevel": "Read",
"ModellingRule": "Mandatory"
}
}
MethodDesign
Represents a method (callable operation).
<Method SymbolicName="Initialize"
ModellingRule="Mandatory"
NonExecutable="false">
<InputArguments>
<Argument Name="Parameter1" DataType="xs:int" />
</InputArguments>
<OutputArguments>
<Argument Name="Result" DataType="xs:string" />
</OutputArguments>
</Method>
{
"Method": {
"SymbolicName": "Initialize",
"ModellingRule": "Mandatory",
"NonExecutable": false,
"InputArguments": [
{
"Name": "Parameter1",
"DataType": "xs:int"
}
],
"OutputArguments": [
{
"Name": "Result",
"DataType": "xs:string"
}
]
}
}
ViewDesign
Represents a view in the address space.
<View SymbolicName="MyView"
ContainsNoLoops="true"
SupportsEvents="false" />
{
"View": {
"SymbolicName": "MyView",
"ContainsNoLoops": true,
"SupportsEvents": false
}
}
Common Patterns
Node Design Pattern
All nodes share common attributes and child elements:
graph LR
A["NodeDesign"] --> B["Attributes"]
A --> C["Child Elements"]
B --> B1["SymbolicName"]
B --> B2["SymbolicId"]
B --> B3["NumericId/StringId"]
B --> B4["WriteAccess"]
B --> B5["ReleaseStatus"]
B --> B6["Purpose"]
C --> C1["BrowseName"]
C --> C2["DisplayName"]
C --> C3["Description"]
C --> C4["Children"]
C --> C5["References"]
C --> C6["RolePermissions"]
C --> C7["AccessRestrictions"]
Key Attributes (on all nodes):
SymbolicName- Local identifier (required)SymbolicId- Globally unique identifier (auto-generated if not specified)NumericId- UA numeric node IDStringId- UA string node ID (alternative to NumericId)IsDeclaration- Node is declared elsewhere (no code generation)WriteAccess- Bitmask of writable attributesPartNo- Which part of specification defines itCategory- Comma-separated categoriesReleaseStatus- See Release StatusPurpose- See PurposeIsDynamic- Node value may change during runtime
See also: Instance Design Pattern, Validation Indicators
Instance Design Pattern
Instances (Object, Variable, Method) inherit from InstanceDesign:
<Object SymbolicName="MyInstance"
Declaration="ua:BaseObjectType"
TypeDefinition="MyObjectType"
ModellingRule="Mandatory"
MinCardinality="0"
MaxCardinality="0"
PreserveDefaultAttributes="false"
DesignToolOnly="false">
<!-- Content -->
</Object>
{
"Object": {
"SymbolicName": "MyInstance",
"Declaration": "ua:BaseObjectType",
"TypeDefinition": "MyObjectType",
"ModellingRule": "Mandatory",
"MinCardinality": 0,
"MaxCardinality": 0,
"PreserveDefaultAttributes": false,
"DesignToolOnly": false
}
}
Modelling Rules:
None- Not constrainedMandatory- Must be present in instancesOptional- May be presentMandatoryShared- Shared mandatory instanceOptionalPlaceholder- Optional placeholderMandatoryPlaceholder- Mandatory placeholderExposesItsArray- Array elements exposed separatelyCardinalityRestriction- Cardinality is restricted
See also: Node Design Pattern
Reference Pattern
References create semantic relationships between nodes. See ReferenceTypeDesign for type definitions.
<References>
<Reference IsInverse="false" IsOneWay="false">
<ReferenceType>ua:HasComponent</ReferenceType>
<TargetId>MyTargetNode</TargetId>
</Reference>
</References>
{
"References": [
{
"IsInverse": false,
"IsOneWay": false,
"ReferenceType": "ua:HasComponent",
"TargetId": "MyTargetNode"
}
]
}
Attributes:
IsInverse- Reference direction is invertedIsOneWay- Only forward reference exists
Access Control
Access Restrictions
Nodes can specify security requirements:
<AccessRestrictions>SigningRequired</AccessRestrictions>
<AccessRestrictions>EncryptionRequired</AccessRestrictions>
{
"AccessRestrictions": [
"SigningRequired",
"EncryptionRequired"
]
}
Available Restrictions:
SigningRequired- Messages must be signedEncryptionRequired- Messages must be encryptedSessionRequired- Active session requiredSessionWithSigningRequired- Session + signingSessionWithEncryptionRequired- Session + encryption- (AndApplyToBrowse variants) - Restrictions apply to browse operations
See also: Role-Based Access, Permission Management
Role-Based Access
Assign permissions to roles using RolePermissions. See Role-Based Permissions for available permission types.
<RolePermissions Name="MyPermissions" DoNotInheirit="false">
<RolePermission Role="Administrator">
<Permission>All</Permission>
</RolePermission>
<RolePermission Role="User">
<Permission>Browse</Permission>
<Permission>Read</Permission>
</RolePermission>
</RolePermissions>
{
"RolePermissions": {
"Name": "MyPermissions",
"DoNotInherit": false,
"RolePermissions": [
{
"Role": "Administrator",
"Permissions": ["All"]
},
{
"Role": "User",
"Permissions": ["Browse", "Read"]
}
]
}
}
See also: Permission Management, Access Restrictions
Complex Types
DataType with Fields
Fields define the structure of complex DataType definitions.
<DataType SymbolicName="UserIdentity">
<Fields>
<Field Name="UserId" DataType="xs:int" Identifier="1" />
<Field Name="UserName" DataType="xs:string" Identifier="2" />
<Field Name="Email" DataType="xs:string" Identifier="3" IsOptional="true" />
<Field Name="Permissions" DataType="xs:unsignedInt" BitMask="Permissions" />
</Fields>
</DataType>
{
"DataType": {
"SymbolicName": "UserIdentity",
"Fields": [
{
"Name": "UserId",
"DataType": "xs:int",
"Identifier": 1
},
{
"Name": "UserName",
"DataType": "xs:string",
"Identifier": 2
},
{
"Name": "Email",
"DataType": "xs:string",
"Identifier": 3,
"IsOptional": true
},
{
"Name": "Permissions",
"DataType": "xs:unsignedInt",
"BitMask": "Permissions"
}
]
}
}
Field Attributes:
Name- Field identifierDataType- Type of the fieldIdentifier- Unique numeric identifierValueRank- Scalar or ArrayArrayDimensions- Dimensions if arrayBitMask- Named bitmask for flag fieldsAllowSubTypes- Subtypes allowedIsOptional- Field is optional
See also: DataType with Encodings
DataType with Encodings
Encodings define how DataType instances are serialized.
<DataType SymbolicName="MyStructure">
<Encodings>
<Encoding SymbolicName="MyStructureXml"
TypeDefinition="ua:DataTypeEncodingType">
<DisplayName>XML Encoding</DisplayName>
</Encoding>
<Encoding SymbolicName="MyStructureBinary"
TypeDefinition="ua:DataTypeEncodingType">
<DisplayName>Binary Encoding</DisplayName>
</Encoding>
</Encodings>
</DataType>
{
"DataType": {
"SymbolicName": "MyStructure",
"Encodings": [
{
"SymbolicName": "MyStructureXml",
"TypeDefinition": "ua:DataTypeEncodingType",
"DisplayName": "XML Encoding"
},
{
"SymbolicName": "MyStructureBinary",
"TypeDefinition": "ua:DataTypeEncodingType",
"DisplayName": "Binary Encoding"
}
]
}
}
See also: DataType with Fields
Hierarchical Structure
Complete Example with Hierarchy
Demonstrates how ObjectType, Property, Variable, and Method definitions create a complete hierarchy.
<ObjectType SymbolicName="DeviceType">
<DisplayName>Device</DisplayName>
<Children>
<Property SymbolicName="SerialNumber" DataType="xs:string" />
<Variable SymbolicName="Status" DataType="xs:string" />
<Method SymbolicName="Start" />
<Method SymbolicName="Stop" />
<Object SymbolicName="Parameters" TypeDefinition="ParameterGroupType">
<Children>
<Property SymbolicName="Timeout" DataType="xs:int" />
<Property SymbolicName="RetryCount" DataType="xs:int" />
</Children>
</Object>
</Children>
</ObjectType>
{
"ObjectType": {
"SymbolicName": "DeviceType",
"DisplayName": "Device",
"Children": [
{
"Property": {
"SymbolicName": "SerialNumber",
"DataType": "xs:string"
}
},
{
"Variable": {
"SymbolicName": "Status",
"DataType": "xs:string"
}
},
{
"Method": {
"SymbolicName": "Start"
}
},
{
"Method": {
"SymbolicName": "Stop"
}
},
{
"Object": {
"SymbolicName": "Parameters",
"TypeDefinition": "ParameterGroupType",
"Children": [
{
"Property": {
"SymbolicName": "Timeout",
"DataType": "xs:int"
}
},
{
"Property": {
"SymbolicName": "RetryCount",
"DataType": "xs:int"
}
}
]
}
}
]
}
}
Processing Workflow
graph TD
A["XML Design File"] --> B["Validator"]
B --> C["Assigns Numeric IDs"]
B --> D["Generates BrowseNames"]
B --> E["Generates DisplayNames"]
B --> F["Generates Descriptions"]
C --> G["Code Generator"]
D --> G
E --> G
F --> G
G --> H["Generated Code"]
G --> I["Generated Documentation"]
The workflow:
- Design - Model is authored in XML
- Validation - Validator checks consistency (see Schema Validation)
- Augmentation - Auto-generate missing attributes
- Generation - Create code and documentation
- Output - Type classes, instances, constants
Best Practices
Naming Conventions
- SymbolicName: Use PascalCase (e.g.,
TemperatureType,MyObject) - BrowseName: Same as SymbolicName (auto-generated)
- DisplayName: Human-readable label
- ClassName: For types, remove 'Type' suffix (auto-generated)
Type Hierarchy
<!-- ✓ Good: Proper inheritance -->
<VariableType SymbolicName="AnalogItemType"
BaseType="ua:VariableType" />
<VariableType SymbolicName="TemperatureType"
BaseType="AnalogItemType" />
<!-- ✗ Avoid: Unnecessary abstraction levels -->
{
"comment": "Good: Proper inheritance",
"VariableTypes": [
{
"SymbolicName": "AnalogItemType",
"BaseType": "ua:VariableType"
},
{
"SymbolicName": "TemperatureType",
"BaseType": "AnalogItemType"
}
]
}
See also: Type System
Validation Indicators
- Always specify
SymbolicName(see Node Design Pattern) - Use
IsDeclaration="true"for external references - Include descriptions for public types
- Assign unique
NumericIdvalues - Use
ModellingRuleconsistently (see Instance Design Pattern)
Release Status and Purpose
Release Status
Controls visibility and stability of nodes. Used in Node Design Pattern:
<ObjectType SymbolicName="ExperimentalType"
ReleaseStatus="Draft">
<!-- Type under development -->
</ObjectType>
<ObjectType SymbolicName="StableType"
ReleaseStatus="Released">
<!-- Production-ready type -->
</ObjectType>
{
"ObjectTypes": [
{
"SymbolicName": "ExperimentalType",
"ReleaseStatus": "Draft"
},
{
"SymbolicName": "StableType",
"ReleaseStatus": "Released"
}
]
}
Purpose
Indicates intended usage. Used in Node Design Pattern:
<DataType SymbolicName="RequestType" Purpose="ServicesOnly">
<!-- Used only in service definitions -->
</DataType>
<DataType SymbolicName="TempStruct" Purpose="Testing">
<!-- Used for testing only -->
</DataType>
{
"DataTypes": [
{
"SymbolicName": "RequestType",
"Purpose": "ServicesOnly"
},
{
"SymbolicName": "TempStruct",
"Purpose": "Testing"
}
]
}
Schema Validation
The validator performs these checks on ModelDesign documents:
✓ Consistency - All References are valid
✓ Uniqueness - No duplicate SymbolicIds
✓ Completeness - All required attributes present
✓ Type Safety - DataTypes match References
✓ Circular References - No invalid cycles
Extensions
Custom Extensions can be added for tool-specific metadata:
<ModelDesign TargetNamespace="..." >
<!-- Standard content -->
<Extensions>
<Extension>
<CustomMetadata>
<Property Name="Author">John Doe</Property>
<Property Name="Version">1.0</Property>
</CustomMetadata>
</Extension>
</Extensions>
</ModelDesign>
{
"TargetNamespace": "...",
"Extensions": [
{
"CustomMetadata": {
"Author": "John Doe",
"Version": "1.0"
}
}
]
}
See also: Root Element: ModelDesign