Skip to content

The widgets of a board

The catalogue is listed in the order the Add widget menu offers it: the everyday tile first, then the big charts, then the supporting kinds — and right at the end the one kind that changes data.

Widget Shows Needs
KPI tile one large figure with traffic light, target and trend a value tag, optionally a target and a trend tag
Bars with target values per category (line, station) with a target line a tag with a label and a value column
Pareto categories sorted from big to small, with the cumulative share a tag with a category and a quantity
Trend a time series over the selected period a tag with a label column and numeric columns
Table the rows of a query tag a tag
Group table rows folded into blocks that open, with the totals in the block header a tag and at least one group column
Scatter two measurements against each other, one dot per row a tag and both axis columns
Gauge one figure on an arc, with the warning and the limit marked on it a tag; the arc’s ends and the thresholds are optional
Heatmap two classifications against each other, the figure as colour depth a tag, both class columns and the value column
Photo wall the pictures from a tag, large, as tiles a tag and the column holding the file
Text a heading or explanation on the board nothing
Header bar logo, clock and a short status line across the top, with a solid rule underneath nothing; a logo and a status tag are optional
State field a tag value as a word in a colour: running, setting up, fault a tag and the list of states
Fault list what is currently wrong: severity, number, text and how long it has been standing a tag whose rows are the faults, and the text column
Navigation button a large touch button that opens another board, or goes back to the home board a target board by name, or the action Home
Setpoint actual value, recommendation and an input that sends one value to the plant after a confirmation a target tag by path; actual value and recommendation are optional
Period filter the usual ranges two target tags, for start and end
Choice filter a choice whose entries come from a tag a list tag and a target tag
Text filter a typed value a target tag
Active filters what the filters on this board are currently set to, and clears them nothing
Record table master data behind a write target: list, add, correct, retire a record tag
HTML widget your own HTML, SVG, CSS and JavaScript, live-bound to tags the code; what it reads and writes is listed in two lists

The tenant’s own words in a second language

Section titled “The tenant’s own words in a second language”

Your tenant’s content follows the language switch in the top right as soon as someone has entered the translations for it: board names and tabs, widget titles, headings in text widgets, the words behind a state code, the line under a figure — and the column headers of tables, which come out of the query.

The stored text is the key. “Running” is looked up as “Running”. Nothing has to be renamed and nothing prepared: write the translations, and every existing board speaks the new language.

It is maintained under Settings → Translations. Every text this installation displays is listed there with the place it came from beside it, and one column per language to fill in. The list fills itself: whatever a board or a mask displays reports itself when it is saved. So you do not enter what should be translated, only what it should say.

Which languages exist is your decision. A language is created on that same page and appears in the header’s language menu afterwards — even while it holds no words at all. Languages the product itself does not ship are allowed; the menu marks those as “texts only”, because then your own words follow and the program’s own interface does not.

A missing entry is not a gap, it is the answer: the text stays as it is. A half-written translation shows half in the new language and half in the old, and never an empty field or a key name on a wall.

Three things worth knowing:

  • Renaming does not cost the translation. Change a title and its translation moves with it — as long as the old text appears nowhere else and the new one has none of its own yet.
  • The same word gets the same translation everywhere. If “Status” is both a column header and a widget title, both are translated the same way. Where they should differ, word the two places differently.
  • Names are not words. “ERA 01” does not belong in the table: a machine called something else in another language no longer matches its own records.

There is no fixed filter bar above the grid. A filter is placed, moved, sized and removed like any other widget — and as often as a board needs one. A board without filters simply carries no filter widget.

A trend has time along the bottom, and the line between two points claims “this became that”. In a scatter both axes are measurements from the same moment, the rows have no order at all, and the message is the shape of the cloud: a band means the two hang together; a fan means they stop hanging together as one of them grows; a single dot far out on its own is the part where something went wrong.

The question it was built for: process time against area. A long cycle is expected on a big panel — the cloud says at a glance whether a long cycle was the size or the machine. An average cannot answer that; it hides exactly the outliers worth looking at.

The colour column holds a category, not a scale: soiling grade, machine, formwork type. Six categories get their own colour and the remainder is collected into Other — a legend with twenty entries is not a legend. Dots in Other are not clickable: they stand for several categories, so “select this one” has no meaning for them.

Too many dots are thinned, not cut off. Past a few hundred a tile turns to mud, and a shift produces thousands. The widget then takes every k-th row — spread across the whole period — and says underneath that it did (“620 of 1,860”). Keeping the newest N instead would silently narrow the picture to the last hour, changing the very shape the chart exists to show.

The KPI tile answers “what is it”; the gauge answers “how much room is left”. Those are different questions, and the second one is the whole point of a maintenance counter: 9,340 m² means nothing on its own, 9,340 of 12,000 with the warning at 10,000 means “order the brushes this week” — from across the hall, without anybody reading the number.

A counter running up towards a limit is set to lower is better. The arc then fills towards trouble, and the traffic light means what it means on any tile — the rule behind it is literally the same function.

A reading past the end of the arc fills it whole rather than wrapping. An over-run has to look like an over-run, not like a fresh start.

Length classes down one side, width classes across the other, count in the cell: that is how “we mostly run 3 to 4 metres by 2.5” becomes a bright patch a person finds in a second.

The distinction that matters: a combination that never occurred and one that occurred zero times are two different facts. A pair that never occurred is left empty — a thin outline only — while a reported zero gets the palest step of the ramp.

Both columns hold classes, not raw measurements; the classes are formed in the tag. Where every label on an axis is a number it sorts numerically — otherwise a size spectrum would read 1200, 400, 800, and that is not a spectrum.

The legend under the map carries five marks, so a depth can be read back as a figure. Where the figure is a fault rate and the question is “where is it worst”, set the colour scale to Heat: pale yellow through orange to red, red for the highest figure. The default stays the board’s own colour, because a map of how often something runs is neither good nor bad.

The table can show a picture column — as a 40-pixel thumbnail in a cell. That is right while the picture is one field of a row somebody is reading. It is wrong when the picture is the row: a photograph of a damaged formwork is evidence, and evidence at 40 pixels is a grey square.

A row without a usable picture is not shown and is counted underneath (“3 without a picture”). Placeholder tiles would fill a wall meant for photographs with grey squares; dropping them silently would let a viewer believe they are seeing every entry.

Nothing is sorted here: the order comes from the tag. A wall that sorted for itself would disagree with the table beside it about which entry is the latest.

Logo, clock and status line sit in one widget on purpose. The number of grid columns depends on how wide the window is (12 / 6 / 2 / 1). Three separate widgets side by side would fold underneath one another on a narrow or portrait screen — a header column instead of a header bar. One widget decides its own inner layout and stays a bar at every width.

The logo is uploaded in the widget’s own setup dialog: SVG, PNG or JPEG, so a customer logo goes up the way it arrives, and the picture you just added is the one the widget uses. The same pictures are available under Navigation, where they can also be used as menu icons — it is one store, reachable from both places. Adding or listing them needs the tenant administrator role; without it the dialog says so and still lets a given id be used. An SVG is rebuilt from a list of permitted drawing elements on the way in — markup can carry a program, and what is stored is the cleaned document rather than the file. A PNG or a JPEG is stored as it is, because there is nothing inside it to rewrite; what is checked is that it really is that format and that it is not absurdly large (512 KB, and at most eight megapixels — a picture that unpacks into a gigabyte is refused at the door). Either way it is served as an image and never placed into the page as markup.

The state chip is optional: name a tag and a small coloured word appears next to the logo, using the same mapping table as the state field. Leave the tag empty and no chip is drawn — a board that already carries a state field should not say the same word twice.

The clock is the clock of the machine showing the board — that is what somebody standing in front of the screen compares it against. A figure computed over the plant’s time zone is a different thing and belongs to the tag that computes it.

The logo is stored by name, not by id. That is not a nicety: a configuration is addressed by name and never by id, and it enforces that by refusing the whole document. One header bar holding a stored id therefore made the entire tenant unsaveable — not “the logo did not travel”, but “nothing travelled”.

Boards set up before this change keep showing their logo. The moment you choose a logo again there, the name is stored and the tenant can be exported once more.

The state field says what the machine is doing

Section titled “The state field says what the machine is doing”

A machine reports its state as a code: 0, 1, fault, RUN. The state field turns that into the word your plant uses, in a colour. What is compared is text, ignoring upper and lower case and surrounding spaces, so 1 and "1" are the same state — but 1 and 1.0 are not, because merging two codes somebody separated is not this widget’s decision.

A value with no entry is shown as it arrived, with a line saying no state is configured for it. That is deliberate: a code nobody mapped is exactly the code somebody needs to see, and a blank card would hide it. Its colour then stays neutral, and so does the card’s when the tag cannot be read at all — a colour has to be justified by a value.

A table shows the rows of a query tag, and for a report that is the right widget. On a wall screen it is the wrong one, and the reason is the empty case: an empty table reads as no data — possibly a broken connection — while an empty fault list is the best news the shift can get and says so, in green, as No fault.

Which faults are current, and in which order they matter, belongs in the tag. The widget draws what the tag returns, in the order it returns it — a widget that re-sorted would quietly disagree with the query somebody wrote, and there would be no way to see which of the two was right. Put the WHERE (what counts as standing) and the ORDER BY (severity before time, on a wall) into the query tag.

Two limits, on purpose. The tag limits what it fetches; Lines drawn limits what the tile draws, because how many fit is a property of the tile and not of the plant. What is left over is counted underneath rather than cut off silently.

The severity is mapped to a word and a colour with the same table the state field uses — one vocabulary, so the header, the state field and the fault list cannot end up saying three different words for the same code. A severity with no entry is shown as it arrived, in neutral.

Acknowledging is not part of it. Showing an alarm is what this product does; reporting one to the outside is not built. A list that could be clicked away would also be a list somebody clears instead of fixing.

Section titled “Navigation button: a touch screen as a small operator panel”

A touch monitor at a machine is more useful when it is more than one board: an overview, and behind it the faults, the brush change, the order list. The navigation button is the way between them — one large button per board, sized for a finger at arm’s length: never smaller than 48 pixels, and twice that on a screen in kiosk mode.

Action. Open board shows the board chosen under Target board. Home goes back to the home board set under Kiosk on the board in view — without one, to the board the screen was opened on.

The target is stored by its name, like every reference inside a configuration. If that board is renamed later, the button says underneath that there is no board of that name, and a touch says so too — instead of doing nothing.

Label and icon are optional. Without a label the button carries the name of the target board; the icon comes from a fixed set (house, arrow-left, wrench, triangle-alert, …).

The board opens inside the same page. The button does not switch the menu entry: the address and the highlighted entry keep naming the page the screen was opened on. On a kiosk that is what you want — it is also where Home and the idle return lead.

While the board is being edited the button does nothing, so it can be dragged like any card.

Drilldown: from a figure to the board behind it

Section titled “Drilldown: from a figure to the board behind it”

A KPI tile and a state field can open another board when tapped — from “Availability 71 %” to the board with the downtimes, from “Fault” to the fault list. Choose it under Drilldown board in the widget’s setup; without one the widget stays a plain display.

Optionally with a filter. Drilldown filter tag and Drilldown filter value write one value onto a tag before the board opens — the same kind of tag a filter widget writes, so the board that opens already shows the selection (the line, the machine). An empty value clears that filter.

If the value cannot be written, the board is not opened. It would otherwise show unfiltered figures under a tap that promised a selection, and a message says what happened. A screen running on a display token may not set values: there only a drilldown without a filter opens.

A small arrow in the top corner marks a widget that can be tapped. The board is stored by its name, like the target of a navigation button. While the board is being edited, a tap does nothing.

A setpoint widget sends one value from the board to the machine — an oven temperature, a line speed, a value a query or an AI insight proposes. It shows the actual value, the recommendation and an input that already holds the recommendation. − and + change it by the configured step; all three are sized for a finger, and twice as large on a screen in kiosk mode.

Nothing is sent without a confirmation. Apply opens a dialog that names the old and the new value with its unit, and the target tag. Only Send writes.

The widget shows what the server answered. “Sent to the plant” appears only after the machine acknowledged the value. A tag that goes to no machine says “recorded here” instead. If the value did not reach the plant, the message says so with the reason — for example the broker that is offline. An account or a screen that may not write values is told that as well.

Minimum and maximum lock Apply, with the reason, as soon as the value lies outside. This is a convenience of the widget: the server does not check these limits, so a script or another client can still write a value outside them.

Target tag is typed as a path, like the target of a filter; an outgoing connector tag sends the value to the machine. The recommendation can come from any tag — a query, or an AI insight whose first number is used.

While the board is being edited, the widget writes nothing.

It is the only kind today that may write master data, which is why it sits at the end of the menu rather than between two charts. What it may do is registered individually while it is set up and is checked again by the server on every call. The rest is under Checking and correcting records.

When none of the ready-made kinds shows what you need — a picture of the line in which the brushes that are working light up, a data sheet, a chart of your own — write it yourself. The HTML widget takes HTML, SVG, CSS and JavaScript and runs it on the board.

The code reaches the data through three calls — the same names the scripts use:

Call Does
system.tag.read(path) returns the current value
system.tag.write(path, value) writes a value
system.tag.subscribe(path, (value, info) => …) calls back at once and on every change; info carries quality and timestamp

All three are asynchronous (a promise). For anything that should stay live, subscribe is the call to use.

Every path has to be listed in the setup. Read tags lists what the code may read, Write tags what it may write — and therefore also read. A path that is not listed is refused before anything reaches the server. Whether a write is then allowed is decided by the server, from the rights of whoever is looking at the board: a hall display running on a display token reads, but does not write.

The code runs in isolation. It sees neither the page nor the sign-in and cannot call the API directly, only through the three calls above. The board’s colours are available to it as CSS variables — hsl(var(--primary)), hsl(var(--foreground)), hsl(var(--muted-foreground)), hsl(var(--success)), hsl(var(--warning)), hsl(var(--destructive)) — and a switch between light and dark arrives without a reload.

Words in the viewer’s language. The code reaches your translations (Settings → Translations) through system.i18n:

Call Does
system.i18n.t(text) returns the translation for the board’s language at once, or the text itself when there is none
system.i18n.locale the board’s language, for example de
system.i18n.onChange(() => …) calls back when the translations arrive or change while the widget runs; returns a function that ends it

t is not asynchronous. The translations can arrive a moment after the widget starts, so draw your words in a function and call it again in onChange. When the language is switched, the widget restarts in the new one.

List every text the code passes to system.i18n.t under Texts in the setup, one per line and exactly as written in the code. Only then does it appear on the translation list — the board cannot read words out of the code itself.

Errors stay visible. When the code throws, or a read or write is refused, the message appears at the bottom of the widget and in the diagnostics log. The messages are English, like those from scripts, so they can be searched for — for example "Line.Count" is not listed in this widget's readTags - add it in the widget setup first.

The Insert example button writes a small widget into an empty code field that shows the first path under Read tags live.

The assistant can do it too. Ask it for a widget of your own and it creates an HTML widget; a follow-up sentence (“make the number bigger”) changes that same widget instead of placing a second one beside it.

What a widget shows when something is missing

Section titled “What a widget shows when something is missing”
  • No data source assigned yet — the widget is there but not set up.
  • Unknown widget type — an older board opened by a newer package version. The widget is named rather than shown as a blank card, and the rest of the board stays intact.
  • Could not be loaded / No data in the selected period — the difference matters: one is a fault, the other is a result.
  • Statistics row on the table and the group table: one figure per column — average, sum, minimum, maximum — over every result row, not only the page in view. Underneath it says how many values it was computed over. Without extremes leaves out the highest and the lowest value; when there are too few values for that, it says so instead of quietly computing anyway.
  • Numbers follow the language. In tables, group tables, record tables and on chart axes a decimal is written the way the selected language writes it — “42.8” in English, “42,8” in German — with exactly as many decimals as the value from the query carries: “85.0” stays “85.0”. There is deliberately no thousands separator, because a cell cannot tell a quantity from a year, a counter reading or an order number, and “2,026” would simply be wrong. Values with a leading zero (“000417”), identifiers, dates and texts marked with $t: stay as they are.
  • Photo columns in a table show a thumbnail; a click opens it large.
  • Click writes to tag on bars, trend and Pareto: clicking a category sets a filter value. That is explicitly not writing data — the target is a memory tag holding a selection.
  • The Pareto has a threshold and a maximum number of bars; the rest is folded into Other, with the count beside it.

Language buttons on the screen, and why they have to exist

Section titled “Language buttons on the screen, and why they have to exist”

Presentation mode has no application header, and therefore no language menu. A hall screen was stuck in whatever language its display link was issued with - for a visitor, a shift that reads another language, or an acceptance meeting, there was nothing to change it with.

So the header bar can draw one button per language: DE, EN, and whatever else the tenant has translated. One tap switches immediately - board names, widget titles, the words behind a state, and every value marked as text.

It is off by default, and that is the actual decision: a plant with one language on the floor does not want a control a passing hand can hit. It is switched on per board, in the header bar’s setup dialog. It is only drawn at all when the installation has more than one language - a chooser with one entry is a button that cannot do anything.

The choice holds for this session, not for ever: a display link has no user to remember anything against. After a reload the screen is back in the language of its link - the same way the idle return brings it back to its home board.

No home button of its own in presentation mode any more

Section titled “No home button of its own in presentation mode any more”

Until September 2026 a board in kiosk drew its own small “Home” card in the top left whenever you were not on the home board. It has been removed with nothing in its place. The way back belongs on the board: a navigation widget sits where whoever arranges the screen puts it, in the board’s own look and with its own words. The idle return still brings a forgotten screen home by itself - that needs no button.

Axes: captioned, and not at the drawing area’s expense

Section titled “Axes: captioned, and not at the drawing area’s expense”

Charts now say what their axes are. The upright axis carries the unit if one is configured, and otherwise the name of the value column; the flat axis carries the name of the category column. Both are the words the query already uses - there is nothing extra to enter, and both go through the translation table like every other piece of tenant text.

No height is spent on this. On a hall screen a chart’s height is the scarcest thing it has. So the upright caption is drawn on its side inside that axis’ width, and the flat one beside the end of the axis rather than under it. Only the margin grows.

The upright axis is also no longer a fixed 40 pixels but follows the type size. A chart writes bigger in presentation mode, and “10,000” used to lose its first digit there.