Property Values
propertyValues sets values on an instance's members by nesting, mirroring the shape
of the type. It is the alternative to initializers, which
addresses the same variables by path — use whichever reads better for the model at
hand, or both.
Nesting mirrors the type
Each key is a member browse name, alias-qualified like everywhere else in the DSL. A value is either the value to assign, or a nested mapping addressing that member's own children:
instances:
- browseName: Pump1
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
di:Manufacturer: Sterfive
ParameterSet:
Pressure: 4.2
Flow: 120.0
A key that names no member of the enclosing node is an error, not a new node — so a misspelling is reported rather than silently creating something the type never declared.
$value — a variable that also has children
A variable with sub-properties of its own needs a way to say "this one, not a child of
it". The reserved key $value does that:
instances:
- browseName: Pump2
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
Level:
# the variable's OWN value, alongside its sub-properties
$value: 42.0
ua:EngineeringUnits: "%"
ua:EURange:
low: 0.0
high: 100.0
$value is rejected on an Object — only a Variable has a value to set.
Value literals
Because a mapping normally means "recurse into children", the two structures models most often write inline would be ambiguous. Two shapes are therefore read as values:
| Shape | When |
|---|---|
{text, locale?} | the variable's DataType is LocalizedText |
{low, high} | the variable's DataType is Range |
instances:
- browseName: Pump3
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
# {text, locale?} on a LocalizedText is a VALUE, not a child named "text"
di:Manufacturer:
text: Sterfive
locale: en
# {low, high} on a Range is likewise a value
Level:
ua:EURange:
low: 0.0
high: 250.0
The match is exact and deliberate: {txt: "Sterfive"} is not a LocalizedText with a
typo, it is a reference to a child named txt, and you get the usual "cannot find child"
error. That is what keeps a typo from being silently swallowed as a value.
Optional members
Assigning a value implies presence here too, at any depth of the tree — the instance does
not need to repeat the member under optionals::
instances:
- browseName: Pump4
typeDefinition: PumpType
organizedBy: /ua:Objects
# no `optionals:` — assigning a value opts MaintenanceNote in
propertyValues:
MaintenanceNote: "replace seal at 5000 h"
See Initializing an optional member
for the same rule as it applies to initializers:.
Choosing between propertyValues and initializers
Both write values to existing variables; they differ only in how the target is named.
propertyValues | initializers | |
|---|---|---|
| Addressing | nested, mirrors the type | a browse path per entry |
| Placement | on the instance | on the instance, or at the document root |
| Reads well when | setting many values under one parent | setting a few scattered values, or grouping every value in one section |
📄 Full working example — property-values.model.yaml
# yaml-language-server: $schema=../../../../schemas/nodeset2.schema.json
#
# Living documentation example for: s67_property-values.md
# Validate: opcua-modeler generate --input property-values.model.yaml
#
namespaceUri: http://example.com/doc-examples/property-values/
namespaces:
- di
version: 1.0.0
objectTypes:
- browseName: PumpType
subtypeOf: di:DeviceType
components:
- browseName: ParameterSet
typeDefinition: ua:FolderType
components:
- browseName: Pressure
dataType: ua:Double
- browseName: Flow
dataType: ua:Double
- browseName: Level
dataType: ua:Double
typeDefinition: ua:AnalogUnitRangeType
- browseName: MaintenanceNote
dataType: ua:String
modellingRule: Optional
instances:
- browseName: Pump1
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
di:Manufacturer: Sterfive
ParameterSet:
Pressure: 4.2
Flow: 120.0
- browseName: Pump2
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
Level:
# the variable's OWN value, alongside its sub-properties
$value: 42.0
ua:EngineeringUnits: "%"
ua:EURange:
low: 0.0
high: 100.0
- browseName: Pump3
typeDefinition: PumpType
organizedBy: /ua:Objects
propertyValues:
# {text, locale?} on a LocalizedText is a VALUE, not a child named "text"
di:Manufacturer:
text: Sterfive
locale: en
# {low, high} on a Range is likewise a value
Level:
ua:EURange:
low: 0.0
high: 250.0
- browseName: Pump4
typeDefinition: PumpType
organizedBy: /ua:Objects
# no `optionals:` — assigning a value opts MaintenanceNote in
propertyValues:
MaintenanceNote: "replace seal at 5000 h"