States and motion
Two things a widget can do beyond showing a value: change colour with a state, and move along a path as a value sweeps its range. Both are properties of the widget — no logic blocks, no extra variables, and they behave identically on the board's display and in WEBview.
They earn their place on one picture: a row of lamps lit by the bits of a status word, and a marker that walks a scale as a temperature climbs.
States: one widget, three colours
A widget with a state: carries three colours — true, false
and alarm — and a variable that decides which one shows:
- { type: led, rect: [24, 78, 38, 38],
state: { var: running, true_color: "#22C55E",
false_color: "#3A3F4B", alarm_color: "#EF4444" } }
var may be a bool, or an integer with bit: naming which bit to
watch. That is the whole trick behind lighting a panel from a status
word: one integer arrives from a drive, four lamps each watch one bit,
and there is no logic between them.
- { type: led, rect: [24, 78, 38, 38],
state: { var: status_word, bit: 0, style: Motor } }
- { type: led, rect: [74, 78, 38, 38],
state: { var: status_word, bit: 1, style: Motor } }
Named sets
Writing three colours on every lamp gets old. The project can carry named sets and widgets point at them by name:
states:
- { name: Motor, true_color: "#22C55E", false_color: "#3A3F4B",
alarm_color: "#EF4444" }
Recolouring every lamp in the project is then one edit — the same argument that gives styles their existence, applied to the true/false/alarm triple.
Where the alarm colour comes from
The alarm state wins over true/false, and it has two sources:
alarm:— a variable; anything non-zero forces the alarm colour,alarm_ref:— one of the project's own alarms, so a lamp goes red exactly when the alarm table says so.
What the state paints
paint: decides which colour of the widget the state drives:
paint |
What changes | Typical widget |
|---|---|---|
accent (default) |
the active colour | led, switch |
bg |
the background | panel — a strip that tints with RUN |
fg |
the text | label |
Motion: a widget that travels
move: makes a widget walk a straight path as a value sweeps a range:
- { type: led, rect: [24, 212, 24, 24],
state: { var: swing, style: Motor },
move: { var: level, from: [24, 212], to: [420, 212],
min: 0, max: 100 } }
At min the widget sits at from, at max it sits at to, and in
between it is proportionally along the line. Values outside the range
clamp — a bad scale never throws the element off the screen.
For two independent axes, x: and y: each take their own variable
and range:
move:
x: { var: pos_x, min: 0, max: 1500 }
y: { var: pos_y, min: 0, max: 400 }
from: [20, 40]
to: [300, 200]
A filling level, a carriage on a rail, a position on a floor plan — anything that is somewhere between two points reads better moving than as a number.
A complete example
A tank level as a moving marker, and a pump lamp from one bit of a status word:
project:
name: tank_demo
target: preset_s3_ssd1963
resolution: [480, 272]
states:
- { name: Pump, true_color: "#22C55E", false_color: "#3A3F4B",
alarm_color: "#EF4444" }
tags:
- { name: level, datatype: f32, unit: "%", decimals: 0, init: 40 }
- { name: status, datatype: i32 }
screens:
- name: main
widgets:
- { type: label, rect: [20, 12, 200, 24], text: "Tank" }
- { type: panel, rect: [40, 60, 8, 160] }
- { type: led, rect: [28, 204, 32, 32],
state: { var: status, bit: 0, style: Pump },
move: { var: level, from: [28, 204], to: [28, 52],
min: 0, max: 100 } }
- { type: value, rect: [100, 60, 140, 40], tag: level }
The marker rides the strip from the bottom at 0 % to the top at
100 %, and its colour is bit 0 of status — two behaviours, one
widget, no logic.
Worth knowing
- Deadband applies. A state or a position only redraws when the driving variable really changes — a noisy value with no deadband repaints for nothing, on the glass and over the network alike.
- The browser matches the glass. WEBview evaluates the same states and the same paths from the same project — what moves on the display moves in the browser.
- Colour is never the only signal. Roughly one man in twelve cannot separate red from green reliably; give important states a word or a shape as well. See HMIview.