Skip to main content

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

Its keys are the vocabulary's own words, in camelCase; a node is always an entry with its browseName, as everywhere else in the DSL, never a key.

A device type​

PumpType
objectTypes:
- browseName: PumpType
description: A centrifugal pump, as a DI device.
di:
device:
parameters:
- browseName: Speed
dataType: ua:Double
engineeringUnits: revolutions per minute
accessLevel: CurrentRead | CurrentWrite
- browseName: Pressure
dataType: ua:Double
engineeringUnits: bar
- browseName: OperatingHours
dataType: ua:Double
methods:
- browseName: Start
- browseName: Stop
groups:
- browseName: Operational
members: [Speed, Pressure, Start, Stop]
- browseName: Maintenance
members: [OperatingHours]
identification: [Manufacturer, Model, SerialNumber]
nameplate: [ProductCode]

The kind, here device, picks the DI base type, used as subtypeOf unless the entry states one:

KindBase type
devicedi:DeviceType: a field device, whose eight nameplate Properties are Mandatory
componentdi:ComponentType: a part of a device, a module, a software component
blockdi:BlockType: a function block
topologyElementdi:TopologyElementType: anything else with parameters and groups
KeyWrites
parametersthe Variables of di:ParameterSet, written as under components:
methodsthe Methods of di:MethodSet, written as under methods:
groupsa FunctionalGroup per entry, organizing its members: parameters, methods or nameplate Properties by name, any other element by path (/Range). optional: true makes the group Optional
identificationthe di:Identification group, organizing nameplate Properties (and parameters or methods if needed)
nameplateOptional nameplate Properties made Mandatory, such as ProductCode or ManufacturerUri
locktrue 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
PumpType 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​

On an instance, the block takes values: the nameplate Properties and the parameters, each an entry with its browseName and value. The instance goes to DeviceSet, where DI clients look for Devices, unless the entry states its own placement.

Pump1 in DeviceSet
objectTypes:
- browseName: PumpType
di:
device:
parameters:
- browseName: Speed
dataType: ua:Double
accessLevel: CurrentRead | CurrentWrite
instances:
- browseName: Pump1
typeDefinition: PumpType
di:
device:
nameplate:
- browseName: Manufacturer
value: ACME Pumps
- browseName: SerialNumber
value: "2026-0042"
- browseName: DeviceClass
value: Pump
parameters:
- browseName: Speed
value: 1450
KeyWrites
(placement)organizedBy: /ua:Objects/di:DeviceSet when the entry states none
nameplatepropertyValues: of the nameplate Properties; an Optional one the type leaves out, such as DeviceClass above, is added to optionals: so that it exists to take its value
parametersinitializers: on di:ParameterSet/<name>

Mistakes​

  • DSL-E-DI-101: a key the block does not know (an instance takes only values), or an instance without its typeDefinition.
  • DSL-E-DI-102: a group member that names nothing.
  • DSL-E-DI-103: a nameplate name that is not a DI nameplate Property, or on a type one that is not Optional on this kind.