Aller au contenu principal

Introducing Declarative Initializers & propertyValues — Next-Level Variable Initialization

· 4 minutes de lecture
Etienne Rossignon
CEO sterfive

In industrial automation and complex information modeling, setting default values for deeply nested instance properties has historically been a tedious chore. Often, it required writing custom server-side bootstrapping code in C#, C++, or TypeScript to run after the server starts up.

With the latest release of OPC UA Modeler, we are excited to announce a massive upgrade to this workflow: Declarative Initializers combined with the brand-new, ultra-intuitive propertyValues: shorthand! Together with first-class IDE LSP Extension support, you can now configure complex default states inside your YAML model with instant autocomplete and zero boilerplate.


The Old Way: Flat Post-Start Boilerplate

When instantiating complex types from companion specifications (e.g., di:DeviceType or robotics:MotionDeviceType), you inherit dozens of nested variables like di:Manufacturer, di:SerialNumber, or physical variables like robotics:Mass.

Without declarative options, developers had to write custom server scripts to traverse the address space, find each target node, verify its data type, and write the value. This disconnected your default values from your information model source of truth.


Feature 1: The initializers: Block

To solve this, OPC UA Modeler introduces the initializers: block. Placed either at the top-level of your model (using full browse paths) or directly inside an instance (using relative browse paths), it allows you to declare initial states cleanly:

# Flat list syntax inside an instance
instances:
- browseName: Robot1
typeDefinition: robotics:MotionDeviceType
organizedBy: /ua:Objects/di:DeviceSet
optionals:
- robotics:FlangeLoad
- robotics:FlangeLoad.robotics:Mass
initializers:
- variable: di:Manufacturer
value: "Sterfive Industrial"
- variable: di:SerialNumber
value: "SN-98765-XF"
- variable: robotics:FlangeLoad/robotics:Mass
value: 12.5
engineeringUnits: "kg"

While flat paths are incredibly robust and precise, they can feel repetitive when dealing with deep trees of components and properties.


Feature 2: Intuitive Key-Value Trees via propertyValues:

To deliver a truly premium developer experience, we've introduced propertyValues:. Instead of listing flat paths, you can now write an intuitive, nested key-value tree that mirrors the exact structure of your OPC UA type.

Look at how clean and elegant the same configuration becomes:

# Elegant key-value nested syntax!
instances:
- browseName: Robot1
typeDefinition: robotics:MotionDeviceType
organizedBy: /ua:Objects/di:DeviceSet
propertyValues:
# Direct metadata variables
di:Manufacturer: "Sterfive Industrial"
di:SerialNumber: "SN-98765-XF"

# Deep nested structures mapped naturally
robotics:FlangeLoad:
robotics:Mass:
$value: 12.5
ua:EngineeringUnits: "kg"

Why propertyValues: is a Game Changer:

  1. No Repetitive Paths: Say goodbye to writing long path segments like Robot1/di:ParameterSet/Temperature/ua:EngineeringUnits. Simply nest your YAML keys!
  2. Smart $value Resolution: When a variable node has a value and its own sub-properties (such as EURange or EngineeringUnits), use the special $value key to define the variable's primary value. The $ prefix is reserved by the modeler compiler to ensure it never collides with standard OPC UA browse names.
  3. Auto-Activation of Optional Components:

    [!TIP] Under the hood, OPC UA Modeler is smart! If a property listed in propertyValues: is marked as Optional in the underlying type definition (like robotics:FlangeLoad), the compiler automatically activates and materializes it for your instance. You don't even need to list it under the optionals: array!


Feature 3: First-Class IDE & LSP Integration

We believe high-quality developer tools should offer instant feedback. That’s why both initializers: and propertyValues: are fully integrated with our OPC UA Modeler IDE Extension:

  • Intelligent Auto-completion: As you type inside the propertyValues: block or the variable: field, the Language Server Protocol (LSP) parses your type definitions in real time, auto-completing valid child browse names and nested properties.
  • Inline Validation & Diagnostics: The extension continuously validates your inputs. If you assign a string to a double, define a duplicate initializer path, or reference a non-existent child node, you’ll get an instant warning directly in your editor.
  • Interactive Tooltips (Hovers): Hover over any key or path segment to see its description, underlying OPC UA DataType, and whether it inherits modeling rules from the companion specification.

IDE LSP Autocomplete & Hover Showcase


Summary of Benefits

  • 100% Declarative: Define initial states as metadata, keeping your information models portable across any server implementation (C#, C++, Node.js, Python).
  • Automatic Engineering Units Coercion: Supply a standard string (like "kg", "°C", "bar"), and the compiler automatically converts it to the proper UNECE Recommendation 20 code.
  • Keep Code and Specs in Sync: Eliminate hundreds of lines of boilerplate initialization code, ensuring your specifications match the live address space perfectly.

Get Started Today

Both features are available in OPC UA Modeler v4.0+! Update your workspace dependencies and compile your YAML models directly into standard XML:

$ opcua-modeler generate --input robot.model.yaml

To explore more advanced examples, head over to the updated Initializers Guide in the documentation!