The OPC UA DI vocabulary
A device type of the Devices model (OPC 10000-100, "DI") keeps its process values in a
ParameterSet, its methods in a MethodSet, and arranges both into FunctionalGroups such as
Configuration or Maintenance, each organizing its members with one reference per member. The
di: block says what the type is in DI, and the modeler writes that structure for you.
A di: block is a shorthand, not a new model: before compiling, the modeler expands it into the
plain DSL it stands for, and the NodeSet2 is the same as if you had written that DSL by hand. You
can add any plain key beside di:. The vocabulary comes with the DI extension of the modeler, in
the CLI, the VS Code extension and the online editor.
The examples share this header:
namespaceUri: http://acme.com/UA/Pumps/
version: 1.0.0
publicationDate: "2026-10-10T00:00:00Z"
namespaces:
- di
A device type
objectTypes:
- browseName: PumpType
description: A centrifugal pump, as a DI device.
di:
device:
parameters:
Speed: { dataType: ua:Double, engineeringUnits: revolutions per minute, accessLevel: CurrentRead | CurrentWrite }
Pressure: { dataType: ua:Double, engineeringUnits: bar }
OperatingHours: ua:Double
methods:
Start: {}
Stop: {}
groups:
Operational: [Speed, Pressure, Start, Stop]
Maintenance: [OperatingHours]
identification: [Manufacturer, Model, SerialNumber]
nameplate: [ProductCode]
The kind, here device, picks the DI base type, used as subtypeOf unless the entry states one:
| Kind | Base type |
|---|---|
device | di:DeviceType: a field device, whose eight nameplate Properties are Mandatory |
component | di:ComponentType: a part of a device, a module, a software component |
block | di:BlockType: a function block |
topologyElement | di:TopologyElementType: anything else with parameters and groups |
| Key | Writes |
|---|---|
parameters | the Variables of di:ParameterSet. A value is a DataType, or a variable as you would write it under components: |
methods | the Methods of di:MethodSet: {}, or a method as you would write it under methods: |
groups | a FunctionalGroup per name, organizing its members: parameters, methods or nameplate Properties by name, any other element by path (/Range). { members: [...], optional: true } makes the group Optional |
identification | the di:Identification group, organizing nameplate Properties (and parameters or methods if needed) |
nameplate | Optional nameplate Properties made Mandatory, such as ProductCode or ManufacturerUri |
lock | true makes the di:Lock (LockingServices) part of every instance |
The well-known group names of OPC 10000-100 §4.4.2 (Configuration, Tuning, Maintenance,
Diagnostics, Statistics, Status, Operational, OperationCounters) go to the DI namespace,
as the specification asks: Operational above is di:Operational, and a client that knows DI
recognizes it. Any other name, such as PumpCurve, stays in your namespace.
The same type in plain DSL
objectTypes:
- browseName: PumpType
description: A centrifugal pump, as a DI device.
subtypeOf: di:DeviceType
components:
- browseName: di:ParameterSet
components:
- browseName: Speed
dataType: ua:Double
engineeringUnits: revolutions per minute
accessLevel: CurrentRead | CurrentWrite
- browseName: Pressure
dataType: ua:Double
engineeringUnits: bar
- browseName: OperatingHours
dataType: ua:Double
- browseName: di:MethodSet
methods:
- browseName: Start
- browseName: Stop
- browseName: di:Operational
typeDefinition: di:FunctionalGroupType
- browseName: di:Maintenance
typeDefinition: di:FunctionalGroupType
- browseName: di:Identification
typeDefinition: di:FunctionalGroupType
promotedToMandatory: [di:ProductCode]
references:
- { referenceType: ua:Organizes, source: /di:Operational, target: /di:ParameterSet/Speed }
- { referenceType: ua:Organizes, source: /di:Operational, target: /di:ParameterSet/Pressure }
- { referenceType: ua:Organizes, source: /di:Operational, target: /di:MethodSet/Start }
- { referenceType: ua:Organizes, source: /di:Operational, target: /di:MethodSet/Stop }
- { referenceType: ua:Organizes, source: /di:Maintenance, target: /di:ParameterSet/OperatingHours }
- { referenceType: ua:Organizes, source: /di:Identification, target: /di:Manufacturer }
- { referenceType: ua:Organizes, source: /di:Identification, target: /di:Model }
- { referenceType: ua:Organizes, source: /di:Identification, target: /di:SerialNumber }
Conformant by construction
The DI rules of the modeler check the expanded type like any other, and the vocabulary leaves
them nothing to find: a parameter can only land in ParameterSet
(DSL-W-DI-001), a method in MethodSet
(DSL-W-DI-002), and a group organizes members
of its own type, named once (DSL-E-DI-003).
An instance of the type is written in plain DSL for now; the instance form of the vocabulary
(placement in DeviceSet, nameplate and parameter values) comes next.
Mistakes
- DSL-E-DI-101: a key the block does not know, or a block on an instance.
- DSL-E-DI-102: a group member that names nothing.
- DSL-E-DI-103: a nameplate name that is not Optional on this kind.