VariableTypes
Defining Variable Type
Variable Types in OPC UA are used to define the data types of variables in the OPC UA server. They are defined within the variableTypes section the YAML file.
Here is an example of defining a Variable Type called MyVariableType:
variableTypes:
- browseName: MyVariableType
dataType: ua:Double
value: 0
inte
instantiating a Variable Type in a Object Type
Once a Variable Type has been defined, you can create an instance of it by using the properties or components property.
Here is an example of creating an instance of MyVariableType in an Object Type called MyObjectType:
objectTypes:
- browseName: MyObjectType
properties:
- browseName: MyVariable
typeDefinition: MyVariableType
modellingRule: Mandatory # or Optional
By default , the modeler will infer that MyVariable is a Variable by looking at the typeDefinition property.
exposing optional properties of a Variable Type
Variables can have intrinsic properties. Properties or components declared with
modellingRule: Optional are not instantiated by default; an instance must
explicitly opt-in to each one through the optionals: list.
variableTypes:
- browseName: MyVariableType
dataType: ua:Double
value: 0
properties:
- browseName: Units
dataType: ua:String
modellingRule: Optional
instances:
- browseName: MyObject
components:
- browseName: MyVariable
typeDefinition: MyVariableType
optionals:
- Units
the optionals: list — qualified-name rules
Each entry in optionals: is a path through the type hierarchy of the
instance's typeDefinition. Every segment of that path must be expressed as a
qualified browseName, i.e. prefixed with the namespace alias of the
namespace that declares it. The alias is omitted only when the segment lives in
the model's own namespace (the file you are editing).
This rule has been strict since @sterfive/opcua-modeler-ex 4.x. Earlier
versions tolerated bare names because the resolver matched on the leaf
browseName only; the current loader resolves segment-by-segment against the
type tree and will warn (with a "did you mean…?" suggestion) when the namespace
alias is missing or incorrect.
single-segment optional
When the optional element is declared directly on the type, prefix it with the alias of the namespace that declares it.
# robotics:AxisType declares ActualSpeed (Optional) in the robotics namespace
instances:
- browseName: Axis1
typeDefinition: robotics:AxisType
optionals:
- robotics:ActualSpeed # qualified — required
- robotics:ActualAcceleration
nested / deep optionals
When the optional is reached through one or more intermediate components, list
the full path. Segments are separated by .. The colon is reserved for the
alias:browseName qualifier inside a single segment, so each segment carries
its own alias and the segments themselves are joined with dots.
# di:DeviceType declares ParameterSet (in 'di' namespace), and
# robotics:AxisType adds Optional ActualSpeed inside ParameterSet
# (in the 'robotics' namespace).
instances:
- browseName: AxisA
typeDefinition: robotics:AxisType
optionals:
- di:ParameterSet.robotics:ActualSpeed
- di:ParameterSet.robotics:ActualAcceleration
: separates a namespace alias from its browseName within one segment —
it is not a path separator. di:ParameterSet:robotics:ActualSpeed is
malformed; use di:ParameterSet.robotics:ActualSpeed.
The diagnostic emitted by the modeler shows the canonical, fully-qualified form for every reachable optional under the parent type — copy/paste that path into your YAML if you are unsure of the alias chain.
own-namespace segments
Segments declared in your own model can be left unprefixed (the alias own:
is implicit) or explicitly prefixed with own:.
namespaces:
- di
objectTypes:
- browseName: MyDeviceType
subtypeOf: di:DeviceType
properties:
- browseName: SerialNumber
dataType: ua:String
modellingRule: Optional
instances:
- browseName: Device1
typeDefinition: MyDeviceType
optionals:
- SerialNumber # own namespace, alias optional
- own:SerialNumber # equivalent
common mistakes
| Symptom (warning text) | Cause | Fix |
|---|---|---|
Optional "Foo" is not a valid child of type "BarType". It will be ignored | Missing namespace alias on a foreign-namespace segment | Prefix with the alias declaring Foo (e.g. robotics:Foo) |
did you mean "di:ParameterSet.robotics:ActualSpeed" ? | Bare leaf name; modeler resolved a fuzzy match for guidance | Use the suggested fully qualified path |
Optional "X" is not marked as optional in the type definition | The targeted node is Mandatory in the type | Remove from optionals: (or change the type) |