User-Defined Types (UDTs)
A UDT is a template for a piece of equipment. Define a motor once — its members, data types, units, scaling, alarms and address patterns — then stamp out an instance per physical motor with a parameter or two.
Change the definition later and QUBIQ reconciles every instance.
Why
Twenty hand-built motor folders is twenty places to make a mistake and twenty places to fix one. The 21st motor is another hour of work. With a UDT it is thirty seconds, and a definition change propagates everywhere at once.
Definitions
A definition declares parameters and members.
UDT: Motor
parameters:
Device (string) e.g. "M101"
MaxSpeed (number) e.g. 3000
members:
Speed float RPM address: ns=2;s={Device}.ActSpeed eng 0–{MaxSpeed}
Current float A address: ns=2;s={Device}.Current
Running bool address: ns=2;s={Device}.Run
Fault bool address: ns=2;s={Device}.Fault
alarm: on_boolean = true, priority high, "Motor {Device} faulted"
Diagnostics (folder)
RunHours float h address: ns=2;s={Device}.RunHours
| Element | Notes |
|---|---|
| Parameters | Named placeholders written {Param}. Substituted into member names, addresses, descriptions, messages and ranges. |
| Members | Tags with their full property set, and folders for structure. |
| Nested UDTs | A member may itself be a UDT instance, so a Line can contain three Motors. |
| Alarm definitions | Carried on members, so every instance is alarmed identically without extra work. |
| Binding templates | The address pattern; the connection is chosen per instance. |
Instances
An instance is a folder in the namespace, materialised from a definition with concrete parameters.
Instance Line1/Filler/Motor1 Motor {Device: "M101", MaxSpeed: 3000} connection: PLC1
Instance Line1/Filler/Motor2 Motor {Device: "M102", MaxSpeed: 3000} connection: PLC1
Instance Line1/Capper/Motor1 Motor {Device: "M201", MaxSpeed: 1500} connection: PLC2
Materialising creates ordinary namespace nodes, tags and bindings. Everything downstream sees normal tags — screens, alarms, history and scripts need no UDT awareness.
Reconciling changes
Add a member to the definition, fix a unit, adjust an alarm setpoint — then sync.
| Action | Scope |
|---|---|
| Preview the change for one instance | Shows what would be added, changed or removed |
| Sync one instance | That instance |
| Sync every instance | All instances of the definition |
| List instances that have drifted | Everything needing a sync |
Always read the plan before syncing a definition with many instances. It is a dry run, and it is the difference between a confident change and a surprise.
Overrides
Real plants have exceptions: one motor with a different high-speed setpoint, one instrument with a non-standard range.
An override pins a member's property on a single instance. Reconciliation respects it — the member is not reset to the definition's value — and the instance is reported as overridden rather than silently diverging.
Reading overrides needs View the namespace; setting or clearing them needs Manage tags.
One or two per definition is normal. Ten means the definition is wrong — add a parameter instead.
Member context
For alarm tuning on a specific instance, QUBIQ records the member context: which definition member a node came from, and what the definition says versus what this instance has.
| Action | What it does |
|---|---|
| Member context | Shows which definition member a node came from |
| Capture | Adopts the instance's current state as its own |
| Revert alarm | Puts an alarm back to the definition's values |
This is what lets an engineer tune one noisy alarm in the field and later ask "what did the standard say?" — and put it back.
Designing a good UDT
- Parameterise what varies, hard-code what does not. A device identifier and an engineering range vary. A unit does not.
- Include alarms in the definition. The main payoff is consistent alarming across identical equipment.
- Keep members shallow. One folder of structure is fine; four levels makes every path long.
- Name members for the quantity, not the instance —
Speed, neverMotor1Speed. The instance name is already in the path. - Nest deliberately. A
Linecontaining threeMotors is good modelling. A five-level nest is hard to reconcile and hard to read.
Pairing UDTs with embedded views
The visualization counterpart is an embedded view with parameters: author the motor faceplate once, pass the instance path, and reuse it for every motor.
UDT instance Line1/Filler/Motor1
Embedded view MotorFaceplate { tagPath: "Line1/Filler/Motor1" }
Twenty motors then cost one UDT and one view — not twenty folders and twenty screens.
Permissions
Reading definitions and instances needs View the namespace. Creating, editing and deleting definitions — and syncing, overriding or reverting members — needs Manage tags. Creating an instance needs Create tags and folders; deleting one needs Delete tags and folders.