Files
app/docs/interface/dashboards.md
T

298 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dashboards and panels
A **dashboard** is a grid of widgets bound to message names. It can show values
and send controls across several flows. A **panel** assigns published dashboards
to a paired screen, such as a wall tablet.
## Building one
1. Open **Dashboards → New dashboard**.
2. Enter edit mode, choose **Add widget** and select a type.
3. Bind the widget to a message in its settings. On desktop, drag and resize
tiles on the grid.
4. **Publish** when the dashboard is ready.
Edits stay in a draft; paired screens show the published version. On phones,
tiles stack in one column and dragging is disabled, but settings remain editable.
Controls can publish real values while you edit, so choose their targets with
care. Your new Switch may already be flipping something!
## The widgets
### Display
| Widget | Binds to | Shows |
|---|---|---|
| **Value** | anything | formatted reading, unit and precision |
| **Gauge** | `float`, `int` | reading within a min/max range |
| **Chart** | numeric messages, a query response or run metrics | up to five lines |
| **Bar** | `float`, `int` | up to eight readings with separate scales |
| **Icon** | numbers, booleans or strings | a glyph selected from the value |
| **Text** | — | Markdown |
| **Agenda** | `list` | upcoming items |
| **Forecast** | `list` | an outlook strip |
| **Notification** | `record` | title, body and severity |
| **Media** | `image`, `audio`, `video`, `artifact` | image, audio or video |
| **Player** | `record` | playback status and transport controls |
| **Clock** | — | current time |
| **Website** | — | embedded page or image |
Every widget has a title. **Show title** controls its visibility; the title
still names the widget for accessibility and published values.
### Input
| Widget | Publishes | Settings |
|---|---|---|
| **Button** | fixed value | one-shot action |
| **Buttons** | a value per button | grid of actions |
| **Switch** | `bool` | on/off |
| **Slider** | `float`, `int` | min, max, step; horizontal or vertical |
| **Input** | text or number | free entry |
| **Selector** | selected value | menu or row of choices |
| **Colour** | list or string | HSV, RGB or hex |
Colour defaults to `[h, s, v]`: hue 0–360°, saturation and brightness 0–100%.
**Sends** can select RGB (`[r, g, b]`, 0–255) or hex (`"#rrggbb"`).
HSV and RGB bind to `list`; hex binds to `str`.
Controls publish to their bound messages. The flow canvas shows them as
endpoints feeding the nodes that consume those messages.
Bindings are checked in the editor and on the server. See
[Payload types](../reference/payload-types.md).
## Charts
Choose the chart's data source:
- **Live:** recent numeric message history, updated as values arrive.
- **Query:** publishes a `record` request containing `range_s` and
`interval_s`, then draws a flow's `series` response. Include those fields in
the answer so the chart can reject responses for a different window.
- **Runs:** compares a numeric metric from named runs, a sweep or the latest
runs of a flow. See [Runs](../concepts/runs.md).
Multi-line charts show a legend as well as different colours.
!!! tip "Skip the unfinished bucket"
If your query aggregates into time buckets, leave out the bucket still
filling. Otherwise an incomplete total can look like a sudden drop.
## Media tiles
Media messages contain artifact references; the widget loads the bytes they
name. **Crop or fit** controls image sizing. **Play as it arrives** enables
autoplay, subject to the browser's rules for sound.
For local streams, `volatile=True` artifacts can be pushed over the websocket
with their message. Stored artifacts are fetched individually, as are frames
viewed through a portal. Use occasional snapshots for remote screens.
For continuous video, set **Live stream** to a browser-compatible camera URL.
The browser must be able to reach that URL; enrollment does not expose the
camera itself. See [Media payloads](../reference/payload-types.md#image-audio-video).
## Player tiles
A Player reads a status `record` and publishes commands to a separate `str`
message.
| Status field | Meaning |
|---|---|
| `title`, `artist`, `album` | track details |
| `status` | `play`, `pause`, `stop`, `load` or `off` |
| `position`, `duration` | seconds |
Controls send `toggle`, `next`, `prev` and `seek:<seconds>`. Your receiving
node translates those into device actions. The position advances in the
browser between readings and resets to each fresh reading.
## Website tiles
Set **Address** to a page to embed, or choose **Image** for a snapshot or MJPEG
URL. A website may refuse embedding.
Embedded pages run in a sandbox without cookies or storage by default.
**Trusted site** permits the site's own origin, cookies and storage.
Use it only for a trusted destination. The app blocks trusted embeds of its
own origin, including the portal origin, to protect your session.
## Dashboard settings
Open **Dashboard settings** from the dock. Each setting can hold a fixed value
or follow a message chosen in **Driven by**. The fixed value is the fallback
when no usable message value is available.
| Setting | Choices | Message type |
|---|---|---|
| **Look** | `fluksio`, `material`, `glass` | `str` |
| **Theme** | `system`, `light`, `dark` | `str` |
| **Palette** | ordered hex colours | `list` |
| **Background** | image URL | `str` |
| **Lock** | read-only on/off | `bool` |
To change one on a schedule, have a scheduled node publish its bound message.
### Look and theme
**Fluksio** is the default look. **Material** uses flat tonal cards; **Glass**
uses translucent tiles. Widgets work the same in all three.
Theme follows the chosen preference unless a palette sets the background
colour.
### Palette
Paste a colour list or a [Coolors](https://coolors.co) palette link. Colours
have roles by position:
| Position | Role |
|---|---|
| 1 | background |
| 2 | widget surface |
| 3 | primary controls and first chart line |
| 4 | accent |
| 5 | text |
| 6+ | additional chart lines |
Missing roles are derived, so three colours are enough to get started.
**Rotate** shifts their order. Text contrast is corrected automatically;
failure and success indicators keep their status colours.
### Background and lock
Background draws an image beneath the widgets. Lock disables publishing from
controls and shows **Read-only** when viewing the dashboard. It does not
restrict API permissions and does not disable controls in edit mode.
## Round dashboards
For a round screen such as a rotary knob, set the canvas to **Round** in the
dashboard settings, or pick the **Knob** preset (360×360). A round dashboard is
drawn in the circle its canvas holds, so its canvas is square (`shape: "round"`
forces `canvas_height` to `canvas_width`). Tiles are drawn without a card, and
there is no rail; a panel with several dashboards shows page dots instead.
One Slider, Selector, Colour or Gauge can go **On the ring** (`ring: <widget
id>`): it is drawn along the edge instead of in the grid. Drag along the ring or
use the mouse wheel; one notch is one step, one option or one hue step
(`hue_step`, default 5°, wrapping). The value moves at once and is published
once, 300 ms after the last notch or when the pointer is released. A gauge on
the ring only shows. When the ring is the only widget, its reading is written
large in the middle.
The editor shades what lies outside the circle and warns about tiles whose
corners leave it. Inputs, button grids, charts, forecasts, agendas, websites
and a segmented Selector are marked as a poor fit, but allowed.
### Geometry
Devices that draw dashboards natively use these numbers. They are canvas
pixels, scaled with the canvas; S is the canvas width. Angles are degrees
clockwise from three o'clock.
| Part | Value |
|---|---|
| Face | circle of diameter S at (S/2, S/2); nothing is drawn outside it |
| Ring band | 40 along the edge, only when a ring is set |
| Grid area | the square inset by 12, plus 40 with a ring; columns, rows and cell proportions as on a rectangular canvas. Knob, 4 columns, ring: 256×256, columns 55, rows 30 at a 42 pitch, 6 rows |
| Safe circle | radius S/2 − 40 with a ring, S/2 without; a tile corner outside it is warned about |
| Ring arc | start 120°, sweep 300° (ends at 60°), centre-line radius S/2 − 20, stroke 16 with round caps |
| Slider | track over the sweep, value arc from the start to the value (none at the minimum), handle 28 across |
| Selector | a 6 mark per option at i/(n−1) of the sweep (one option: the middle), the selected one under the handle; no wrap |
| Colour | hue h at h/360 of the sweep, red at both ends; the handle is filled with the colour |
| Gauge | track and value arc, no handle |
| Gap line | centred at y = S − 28, 13 high, at most 160 wide: the title (muted), then the reading unless it is in the middle; a colour has none |
| Page dots | 6 dots 16 apart, centred at y = S − 12; the current one in the text colour, the others muted at half opacity |
| Centre reading | value 72 with its unit at 0.4 em, muted; a Selector's label 36; a colour swatch 96 across with a hairline border |
| Tiles | no surface, border or shadow; padding 8; title 12, muted and centred; a single reading centred |
Paint follows the look: Fluksio draws a muted track, a primary value and a
handle of the ground colour ringed in primary; Material a tonal track and a
primary handle; Glass a translucent track, a glowing value and a white handle.
## Showing one
Open `/view/{name}` for a dashboard-only view with your normal session.
For a dedicated screen, pair a panel.
## Panels: hanging a screen on a wall
As a superuser:
1. Open **Dashboards → Panels**, add a panel and select its dashboards.
2. Enable **Touch friendly** for larger controls.
3. Open the displayed pairing link on the device. It shows a six-character code.
4. Enter that code for the panel, check the device description, then press
**Pair device**.
The screen collects its credential and shows the assigned published dashboards.
Several dashboards get a navigation rail.
A panel credential permits its assigned dashboards, their bound messages and
the artifacts they show. It also permits publishing from its controls and query
charts. On a locked dashboard only the query charts may still publish.
**Unpair screen** revokes a locally paired credential and keeps the panel's
dashboard assignments. Deleting the panel removes the assignment and its
access.
### A screen without a browser
The openpanel firmware, kept in its own repository, draws dashboards as native
widgets on an ESP32-P4 wall panel (Waveshare ESP32-P4-WIFI6-Touch-LCD-7B,
1024×600). Once its config page points it at this instance, it shows the
pairing code itself; enter it as in step 4. It reads the same published
dashboards and live values and draws every widget type with two exceptions,
both shown as a placeholder: a website tile that embeds a page (image tiles
work), and a chart of runs, which a panel credential may not read. Media tiles
play MJPEG streams, pushed frames, images, and H.264 Baseline or MJPEG clips up
to 640×360. Re-encode other clips with the [clip recipe](../code/nodes.md#making-clips-playable-on-an-lvgl-panel).
The device decides what the panel's [I/O](#the-devices-own-io) port names
mean. openpanel serves `gpio.<n>`, `backlight`, `touch`, `mic` and `speaker`,
lists each one's `config` in its README and ignores any other name. A browser
screen serves none of them.
### The device's own I/O
A panel can also act as a node. Under **I/O**, wire a port on the device to a
message:
| Field | Meaning |
|---|---|
| `port` | The device's name for it, such as `gpio.4`, `backlight`, `touch`, `mic` or `speaker`. Lowercase letters, digits, `_` and `.` |
| `direction` | `in`: the device publishes to the message. `out`: the device follows it |
| `message` | A qualified `flow.name`. A flow must declare it, as for a control |
| `config` | A JSON object passed to the device unread, such as `{"pull": "up", "debounce_ms": 50}` |
The credential may publish to its `in` messages even when a dashboard is
locked, and may upload an artifact named after one
(`PUT /artifacts?name=<message>`), which is how a microphone sends a recording.
`out` messages are read only.
!!! note "If the local link is wrong"
Pairing links use `FRONTEND_HOST`. Set it to the app address reachable
from the screen's network.
### A screen somewhere you cannot reach
An [enrolled instance](portal.md) also shows a portal pairing link. Use that
link on the remote screen, then approve its code in the same dialog. The
device description says *via portal*.
The instance enforces the same dashboard and message limits. Remote
credentials are issued by the portal, so **Unpair screen** does not revoke
them; revoke them at the portal. Deleting the panel removes access on the
instance.
## See also
- [Payload types](../reference/payload-types.md)
- [Flows, nodes and messages](../concepts/flows.md)
- [Accounts and the portal](portal.md)