NEXT HMIDocs
Data / Dynamic properties

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 a Float. 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

  • IntegerFloat convert freely (Float → Integer rounds).
  • Numbers and booleans → String use 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.