# Description Implement the released [OPC 40100-1](https://reference.opcfoundation.org/specs/OPC-40100-1) and [OPC 40100-2](https://reference.opcfoundation.org/specs/OPC-40100-2) specifications with generated models, provider-backed runtimes, typed clients, MCP workflows, and DI/Machinery integration. - **Part 1 stays in `Opc.Ua.Vision`** and its client/server packages alongside the distinct Perception model. Provide control/acquisition state machines, jobs and synchronized steps, recipe/product/configuration/result management, file transfers, diagnostics, events, and conditions. - **Part 2 is in `Opc.Ua.MachineVision`, `.Client`, and `.Server`.** Provide asset categories, identification, image-handling aspects, health/maintenance data, topology, and transactional updates. The base Vision assemblies do not reference these optional packages; the Part 2 wire model does not depend on Part 1. - Preserve the release-pinned model bytes, wire namespaces and NodeIds. Perception types are in `Opc.Ua.Vision.Perception`; the AMCM generated namespace remains `Opc.Ua.Vision.MachineVision.AMCM`, and asset client/server extension namespaces remain `Opc.Ua.Vision.Client` and `Opc.Ua.Vision.Server`. - Use `AddOpcUaMachineVision` and `AddOpcUaMachineVisionAMCM` for model loading and factory registration. Each has node-collection, encodeable-factory-builder and node-state-factory-builder overloads. These short entry points delegate to the generated implementations; existing namespace-derived generated names remain available for compatibility. - Support multiple independent named systems/assets under one namespace-owning manager. Reuse injectable providers, file binding, bounded memory stores, optional transactional `IFileSystemProvider` persistence, state machines, telemetry and conformance infrastructure. - Keep one `docs/Vision.md` guide, titled `Machine Vision (OPC 40100-1 and OPC 40100-2)`, and one `Opc.Ua.Mcp.Vision` package. Include deterministic server/client samples. - Expose 17 Machine Vision MCP tools, including capabilities/status, bounded relationships and observation, complete small-file uploads/downloads, management, explicit control, conditions, and chunked transfers. Catalogue counts: 39 Vision-specific, 43 with connection tools, 81 Vision+Robotics, 155 Full. Every Machine Vision wire parameter has a schema description. **Compatibility and limits:** `AddVision()` remains Perception-only unless released parts are selected. Standalone Part 2 uses `AddVision().AddMachineVision()`; Machinery composition uses `AddVisionToMachinery()`. Existing tool defaults and command signatures are preserved. Observation owns and cleans up its subscription: 5 seconds/50 notifications by default, capped at 60 seconds/100 notifications. Complete-file tools are capped at 1 MiB; larger files use chunked transfers. Domain Error values remain distinct from UA service failures. **Versioning:** the seven Vision/MachineVision/MCP packages and their Debug variants follow the repository root version instead of being forced to preview. Vision.OpenUsd and its descendants remain preview-only. Development builds still inherit the root prerelease version. No release version, tag, release branch, publication policy, or feed promotion is changed. **Review actions:** all fourteen review threads have action/evidence replies and are resolved. Changes include the unified guide, Perception namespace, separate Part 2 packages and final naming, multi-system ownership explanation, interrupted-write cleanup, observer failure isolation, complete MCP parameter descriptions, and explicit package inventory. The preview-layout migration topic and the requested ReleaseProcess caveat were removed. The test Publish collector now retries recognized transient failures within one cancellation budget and propagates other exceptions. Commit69b1f5db9applies the requested short loader names and renames standalone hosting to `AddMachineVision`, with callers, tests and documentation updated. The intervening master merge is preserved. ### Verification **Latest API naming changes, verified locally:** | Scope | Result | | --- | --- | | Full Vision suite, net10 | 572 passed, 1 existing skip, 0 failed | | Full Vision suite, net48 | 515 passed, 0 skipped, 0 failed | | Final loader/hosting cases after cross-TFM null-guard adjustment | 9 passed, 0 failed, 0 skipped | | Machine Vision MCP and profile cases | 198 passed, 0 failed, 0 skipped | | Main and MCP AOT test-project compilation | Both built with 0 warnings/errors | | MCP AOT companion, managed execution | 5 passed, 0 failed, 0 skipped; not claimed as native execution | `ModelLoaderNamesRegisterTypedFactories`, `ModelLoaderNamesRejectNullArguments`, and `GeneratedModelsLoadTogetherAndCreateTypedInstances` cover all six loader overloads, fluent return identities, typed instances, namespace coexistence and null guards. Existing standalone Part 2 tests verify idempotent registration, one-owner enforcement and null handling through `AddMachineVision`. No source-generator implementation, CLR namespace, wire identity or model payload was changed for these naming updates. The current69b1f5db9revision is running [CI](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38165826937), [package validation](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38165823359), [MCP usability](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38165826874), [CodeQL](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38165826906), and [Images CI](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38165826884). These runs are not claimed as completed results. **Earlier completed verification:** all seven default-TFM package archives were inspected after the package rename: exact IDs, 27 clean DLLs, correct dependencies/readmes/licenses, and unchanged pinned model hashes. [CI onc75ec4fa6](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/38142519760) passed, including the formerly failing Linux batch and required summary. Its unchanged coverage gate passed at **88.56% lines, 78.96% branches, 84.28% patch** against the 75% patch floor. The later bounded-Publish-helper regressions reproduced 13 failures before the fix and passed afterward; the full mainline triggering fixture passed 67 tests on each of net10/net48. These are historical results, not current full-matrix results. <details> <summary>Executed API naming validation commands and outcomes</summary> Run from the worktree root using the established artifact trees. Dependency builds were performed before the no-build full net10 run; the focused loader/hosting selection was rebuilt and rerun after the final null-guard adjustment. ```powershell $files = 'C:\Users\mschier\.copilot\session-state\deb2ba10-b0e9-4a44-8783-8331bc850814\files' $env:DOTNET_CLI_USE_MSBUILD_SERVER = '0' $env:TEMP = 'C:\Temp\mv-deb2\followup' $env:TMP = $env:TEMP # Passed: 572; Failed: 0; Skipped: 1. dotnet test tests\Opc.Ua.Vision.Tests\Opc.Ua.Vision.Tests.csproj -c Release -f net10.0 --no-build --no-restore --artifacts-path artifacts\vision-followup -p:CustomTestTarget=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --logger 'console;verbosity=minimal' --logger trx --results-directory "$files\vision-api-names-net10" -- 'NUnit.WorkDirectory=C:\Temp\mv-deb2\followup' # Passed: 9; Failed: 0; Skipped: 0, on the final source. dotnet test tests\Opc.Ua.Vision.Tests\Opc.Ua.Vision.Tests.csproj -c Release -f net10.0 --no-restore --artifacts-path artifacts\vision-followup -p:CustomTestTarget=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --filter 'FullyQualifiedName~MachineVisionModelTests|FullyQualifiedName~StandalonePartTwoRegistrationUsesOneOwnerAndOneModelProvider|FullyQualifiedName~StandalonePartTwoRequiresRegistrationAndRejectsCompetingOwnership' --logger 'console;verbosity=minimal' --logger trx --results-directory "$files\vision-api-names-final-model" -- 'NUnit.WorkDirectory=C:\Temp\mv-deb2\followup' # Passed: 198; Failed: 0; Skipped: 0. dotnet test tests\Opc.Ua.Tools.Tests\Opc.Ua.Tools.Tests.csproj -c Release -f net10.0 --no-restore --artifacts-path artifacts\vision-followup -p:CustomTestTarget=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --filter 'FullyQualifiedName~VisionMachineToolsTests|FullyQualifiedName~McpHostBuilderTests|FullyQualifiedName~McpToolProfileCompositionTests' --logger 'console;verbosity=minimal' --logger trx --results-directory "$files\vision-api-names-final-mcp" -- 'NUnit.WorkDirectory=C:\Temp\mv-deb2\followup' $env:TEMP = 'C:\Temp\mv-deb2\followup48' $env:TMP = $env:TEMP # Passed: 515; Failed: 0; Skipped: 0. dotnet test tests\Opc.Ua.Vision.Tests\Opc.Ua.Vision.Tests.csproj -c Debug -f net48 --no-restore --artifacts-path "$files\solution-net48-artifacts" -p:CustomTestTarget=net48 -p:UseSharedCompilation=false -m:1 -nr:false --logger 'console;verbosity=minimal' --logger trx --results-directory "$files\vision-api-names-net48-final" -- 'NUnit.WorkDirectory=C:\Temp\mv-deb2\followup48' ``` Opt-in long-running/stress/durable tiers have not been rerun locally; the unqualified **all tests** checklist item remains open. Original implementation matrix counts are not presented as current results. </details> ## Related Issues - Fixes #4732. The requester reviewed and approved the implementation plan and subsequent packaging/API decisions in the development session. The tracking issue records the design; maintainer architectural discussion/sign-off there is still pending. This PR remains a draft. ## Checklist _Put an `x` in the boxes that apply. You can complete these step by step after opening the PR._ - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [x] I have addressed **all** PR feedback received.
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