Dynamic properties
The heart of NEXT HMI. Every property has a type and a source — it is either a plain value or a $-keyed object naming where its value comes from. The type a field needs is fixed by the field; you choose a source that produces it. Sources nest, so any property can react to live data with no scripting.
Type vs. source
Two questions answer every property:
- What type does the field need? Decided by the field itself — a label wants a
String, a gauge aFloat. You never pick the type. - Where does the value come from? That's the source you pick — a literal, a tag, the user, a computed comparison…
property value = a source that produces the type the field needs. The editor only ever offers sources that can produce that type, so an impossible binding is impossible to make.
The value types
Any of these can also be an array. An optional format refines the editor without changing the type — a String can present as a URL field, a dropdown, a password mask, a CSS-length or spacing box, a direction/align picker; a Boolean as a Visible/Hidden or Enabled/Disabled toggle.
String, Integer, Float, Boolean, DateTime, Date, Time, Duration, color, icon, image
The sources
Flexible sources carry whatever type the field needs, so they fit almost anywhere. Fixed-type sources each produce one specific type and appear only where it fits.
| Source | Produces | Gives you |
|---|---|---|
$static |
flexible | A fixed value you type or pick (incl. icons & images). |
$var |
flexible | A live datasource / OPC-UA variable. |
$if |
flexible | One of two values chosen by a condition. |
$switch |
flexible | One of many values chosen by a key. |
$widgetProp |
flexible | A value exported by a sibling widget on the page. |
$componentProp |
flexible | A value passed in by the parent component / dialog. |
$result |
flexible | A field of an action's result (in its handlers only). |
$loc · $stringExpr |
String | Translated text, or a template like Tank {1} of {2}. |
$compare · $pageIsActive · $userGroups |
Boolean | A comparison result, whether a page is active, or whether the signed-in user is in one of the listed groups. |
$user |
String / String[] | The signed-in user's name, or their groups. |
$device · $urlParam |
String | This machine's identity (hostname, IP, MAC), or a parameter from the page URL. |
$viewport |
String / Integer | Screen size class, orientation, width, height. |
$time · $random · $alarmCount |
DateTime / Float / Integer | The clock, a random number, a live alarm count. |
$page · $languages |
String / Integer / String[] | Page metadata, and the configured language list. |
$recipe · $recipeList |
String / Boolean / Record[] | Recipe state, and the saved-recipe grid. |
They nest — a worked example
The power is in composition. Here a gauge's colour is driven by a live temperature, its label is translated, and its value is a tag — all in one property block:
"value": { "$var": { "path": "LinePLC:Motor1/Speed" } },
"label": { "$loc": "MotorSpeed" },
"color": {
"$if": {
"condition": { "$compare": {
"left": { "$var": { "path": "LinePLC:Motor1/Temp" } },
"operator": ">", "right": 120
} },
"true": "#e5484d", // hot → red
"false": "#2563eb" // normal → blue
}
}
Passing values into components
A reusable Component declares input properties the parent fills in. Inside, children read them with $componentProp — the whole struct, or one member by slash-path (sensor/fValue). Required members must be supplied; optional ones fall back when absent. Sibling widgets can read each other's exported state with $widgetProp. This is how one "Motor" component drives many motors from different tags.
Coercion, in short
Integer↔Floatconvert freely (Float → Integer rounds).- Numbers and booleans →
Stringuse the field's display format. - A
String→ number only if it parses cleanly, else absent. - Nonsense conversions (image → Float) are rejected by the editor at bind time — never at runtime.