Dashboards
Build control panels for operators, rooms and wall panels with tangle-interact: widgets, device layouts, screen sizes, access, kiosks and skins.
Dashboards are the control surfaces people touch: an operator console in the booth, a room panel by the door, a status wall for the building team. You build them in the designer and screens open them in a browser at /d/<id>. Core serves both; nothing else is installed on the screens.
A dashboard has one or more pages of widgets on a grid, with a layout per screen size, a skin, a theme and an access mode. Dashboards are stored in the project.
Open a dashboard
Every published dashboard has an address on the core:
http://<core address>:7340/d/<dashboard id>
For example http://10.0.0.2:7340/d/room-hall. In the builder, Open next to a dashboard opens it in a new tab.
Note: For tablets and panels to reach the dashboard, core must accept other machines (
--listen 0.0.0.0:7340 --allow-remote --insecure-http) and must have a license or run with--demo. The free designer serves only its own computer. See Install.
Address options
Add these to the address after ?, separated by &:
/d/room-template?room=room-3&kiosk=1&cores=10.0.0.2:7340,10.0.0.3:7340&panel=<token>
| Parameter | Meaning |
|---|---|
room | The room for a dashboard made for many rooms (see room templates) |
kiosk=1 | Wall panel mode: stays on this dashboard, keeps the screen awake, and is remembered on the device, so the panel comes back to it after a reboot even if its browser only opens /d/ |
reset=1 | Forget the remembered kiosk settings |
cores | Core nodes to try first. Optional with redundancy: the dashboard learns the other nodes from the one it reaches and follows the primary. See One address for operators. |
panel | An enrolled panel token. Stored on the device and removed from the address bar. |
awake=0 | Kiosk: let the screen sleep |
dim=<minutes> | Kiosk: dim the screen after this many minutes without a touch. A touch wakes it. |
What screens see
- Live state: values, status and timeline positions update as they change. A dashboard subscribes only to what its widgets use.
- When the connection to core drops, a banner says "Disconnected from Tangle. Reconnecting…" and controls are disabled until it is back.
- When a control is pressed, it shows a spinner while core works, and "Failed:" with the reason if the action fails.
- When you publish a new version, screens showing the dashboard reload it on their own.
- A dashboard with several pages shows page tabs at the top.
The builder
Click Dashboards in the designer's project tree. The dashboard list shows each dashboard with its published version and an Open link, and three ways to start:
- New dashboard: type a name and click Create. The builder opens on an empty page named Main. The dashboard is stored when you first click Save draft.
- Generate: make a dashboard from the project (see generated dashboards).
- Click a dashboard's name to edit it.
The editor
| Area | What it holds |
|---|---|
| Top bar | Dashboard name, screen size (Phone, Tablet, Panel, Desktop), Undo and Redo (Cmd+Z and Shift+Cmd+Z, or Ctrl on Windows and Linux), Preview, Regenerate (generated dashboards), Save draft, Publish |
| Palette (left) | Basic controls, Input controls, Widgets, Studio presets, and Devices grouped by room |
| Page (centre) | Page tabs, + Page, and the grid for the chosen screen size |
| Side panel (right) | Inspector of the selected widget, dashboard Settings, published Versions |
| Footer | Problems that block saving, broken bindings, and the preview log |
To build a page:
- Drag a widget from the palette onto the page, or click it to add it at the bottom.
- Move and resize widgets on the grid.
- Select a widget to set its label, bindings and action in the Inspector.
- Press Delete or Backspace to remove the selected widget.
Broken bindings in the footer lists widgets that point at a device, state key or timeline that no longer exists. Click one to select it.
Preview
Tick Preview to see the page as screens will, at the chosen screen size. Presses are only logged ("Would send power.on to device hall-projector"). Tick Live control to send them to core for real. For a room template, pick the room to preview with.
Widgets
| Widget | Shows | Does |
|---|---|---|
| Basic controls | ||
| Button | Its label, lit while Lit when holds | Sends its action; can send another when held |
| Toggle | On, Off or – from its value | Sends action to turn on, offAction to turn off |
| LED | An indicator lamp, lit from its value | Display only |
| Label | Text or a heading (Size Normal, Small, Large or Title) | Display only |
| Picture | A picture or a logo, uploaded or from an address | Display only |
| Shape | A box, a circle or a line | Display only |
| Value | A value with an optional unit | Display only |
| Slider | A level from its value, between min and max (default 0 to 1), as a percentage | Sends its action with the new value while dragging (at most every 200 ms) and on release |
| Input controls | ||
| Select list | A drop-down list | Sends or sets the chosen option |
| Text field | A text or number field | Sends or sets what was typed |
| Keypad | A numeric keypad | Sends or sets the number entered |
| Stepper | A value with − and + keys | Steps the value |
| Colour | A colour picker | Sends or sets the colour |
| Direction pad | Up, down, left, right and centre keys | Sends an action per key (PTZ, menus) |
| XY pad | A two-axis pad | Sends both values |
| Widgets | ||
| Meter | A level bar from its value, min, max | Display only |
| Source selector | One button per entry in options, the current one lit from its value | Sends its action with the chosen value |
| Scene list | One button per scene (from options, or every scene in the project) | Recalls the scene, by default in the dashboard's room |
| Status | A device's status (online, offline...) with its detail | Display only |
| Transport | Play, Pause, Stop (GO, Pause, Stop for a cue list), status and position of a timeline | Drives the timeline |
| Cue + GO | Last and next cue of a timeline, and a large GO button | Sends GO |
| Clock | Time of day, a timeline position, or a device's timecode | Display only |
| Group | A titled container for other widgets, with its own grid | Holds device control groups and status groups |
| Map | A map from the project, with live device status and tracked positions | Tap a device to see its status |
| Web page | Another site or page in a frame (url, http or https) | Optional reload every refresh seconds |
| Camera | A camera's video: MJPEG, snapshots, HLS or WebRTC, or a device's preview stream | With a camera device, a pan, tilt and zoom pad |
| Navigation bar | A row (or column) of buttons to pages, dashboards, maps or addresses | Opens the destination, the current one lit |
| Link | Text or a button to a page, dashboard, map or address | Opens it, optionally in a new tab |
| Executor | A lighting playback fader and its keys | Drives a lighting executor |
| Device log | The log of a device, several devices or a room's devices, filtered by kind and level | Display only |
| List | Rows to choose, reorder or remove, such as a media player's playlist | Sends the chosen row, the new order or the removal |
Studio presets are ready-made controls in the Studio style: Knob, Fader, Lit key, Lit switch, Key row, LED meter, Readout, Status lamp and Faceplate.
See Embedded content for the settings of Map, Web page, Camera, Navigation bar and Link.
Control ids
Every widget has an ID, unique in the whole project. Automations, bindings and the API name a control by its id, and renaming it in the Inspector updates every reference. A control without a binding keeps its value in core, so every screen showing it agrees. Automations set controls with the Set a control step and start on them with the trigger A dashboard control is clicked or changes (see Automations). REST: /api/v1/controls; MCP: list_controls, set_control, press_control, rename_control.
Bindings
A control's properties follow bindings: Value (or Lit when for a button), Label from, Shown when and Enabled when. Each binding has a source:
| Source | Reads |
|---|---|
| Not bound | The value set in the Inspector (always shown and enabled) |
| Device state | A state value of a device, for example Media player tangle.transport.status, with a test such as "is playing" |
| Project variable | A project variable |
| Another control | Another control's value or property |
| Expression | An expression, for example {{visitors}} > 100 or control.value("level") * 100 |
| Fixed value | A constant, for example a source list or a unit |
Timeline widgets bind to a timeline's status, positionMs, lastCue or nextCue, and the system values connection, role, nodeId, license and time are available too. ƒx next to other properties of a control (colours, ranges, text) makes them follow an expression or another control. An expression is live on every screen only once the dashboard is published.
The builder only offers bindings that fit the property (a slider only gets numbers).
Actions
A control's Action is one of:
- Send an intent: a name such as
power.on,input.selectorscene.recall, a target (a device, a room, a tag, or everything) and parameters. A parameter set to"{{value}}"is replaced by the control's value: the slider level, the chosen input, the scene picked. See intents. - Control a timeline: Play, Pause, Stop or GO on a timeline.
- Run an automation: runs an automation, with Parameters (JSON) where
"{{value}}"is the control's value. The automation's conditions are checked. - Set a variable: sets a project variable to a value, or adds to it.
A button can also do something else when held: When held takes any of these actions, sent instead of the normal action once the button is held for the hold time (default 0.8 s). A thin line fills along the button's bottom edge while it is held.
Dashboard intents have priority 30, so a running timeline or automation (50) wins over a panel press on the same device. Older dashboards that use "$value" still work.
Confirmation
For critical actions, set Confirmation on the widget:
| Setting | Behaviour |
|---|---|
None (none) | Acts on the first press |
Press twice (confirm) | The first press arms it ("Press again to confirm"); a second press within 3 seconds sends it |
Press and hold (hold) | Press and hold for the hold time (default 0.8 seconds); releasing early cancels |
Device controls and layouts
Modules can describe ready-made controls for their devices and group them into named layouts. The PJLink module, for example, offers:
| Layout | Controls |
|---|---|
| Compact | Power and status |
| Operator | Power, input, picture mute, status, current input |
| Full | Everything, for technicians: adds power state (warming, cooling) and lamp hours |
To place a device:
- Drag the device from Devices in the palette onto the page (or click it). Devices are listed by room.
- Choose a Layout.
- Tick or untick Controls to show. Ticking a control that is not in the layout switches to an automatic arrangement of the ticked controls.
- Pick a Control style if the group should not use the dashboard's.
- Click Add to page.
The controls are placed as a group bound to that device, already wired: the power toggle reads tangle.power on and sends power.on and power.off, with the confirmation the module asks for.
A module that declares no controls gets them from its standard capabilities, in one "All controls" layout: power toggle, level slider, mute toggle, current input, current preset and transport status, plus status. The dialog says "This module declares no controls: these come from its capabilities." Module authors define controls in the manifest; see Module SDK.
Pages and screen sizes
A dashboard has one or more pages; screens show them as tabs. Add one with + Page.
Each page has a layout per screen class. Pick the class in the top bar and arrange the grid for it:
| Class | Grid columns | Used when |
|---|---|---|
| Phone | 4 | The window is under 600 px wide |
| Tablet | 12 | 600 px to under 1100 px |
| Desktop | 12 | 1100 px and wider |
| Panel | 12 | Kiosk screens (kiosk=1) 600 px and wider |
You do not have to lay out every class. A class without its own layout uses the nearest class that has one; on a phone, widgets are stacked in one column in reading order (top to bottom, then left to right). Widgets with no position in a layout are added at the bottom. New widgets are added to every layout the page already has.
Inside a group, children share one arrangement across classes and stack on phones when the group is wider than the phone grid.
One dashboard for many rooms
Twenty identical meeting rooms need one dashboard, not twenty. In Settings, tick One dashboard for many rooms (open with ?room=…). Device references then select a device by room, capability or tag (for example "the first device with tangle.power in this room") instead of naming a fixed device, and room targets use the room the dashboard is opened with. Open it with the room in the address:
/d/meeting-room-template?room=meeting-3
Without this option, you can set the dashboard's Room, which scene lists and new widgets use by default.
Access
In Settings, Who can open it:
| Mode | Who | Notes |
|---|---|---|
| Anyone on the network | Every browser that reaches core | The default |
| People with the PIN | Anyone who types the PIN | 4 to 12 digits. After 5 wrong PINs in a minute, the dashboard asks to wait a minute. Core stores only a hash of the PIN. |
| Enrolled panels only | Devices opened with a panel token | Other browsers see "This panel is not enrolled". |
A browser that opens a dashboard gets a session that lasts 12 hours, then asks again (for a PIN dashboard, the PIN). With redundancy, sessions survive a failover.
Enrol a wall panel
- Create a token for the panel on the core:
tangle-core token create --name lobby-panel --scopes read,control
- On the panel, open the dashboard once with the token and kiosk mode:
http://10.0.0.2:7340/d/lobby?kiosk=1&panel=<token>
The panel stores the token, removes it from the address bar and keeps showing the dashboard after reboots. To unenrol it, revoke the token: tangle-core token revoke lobby-panel.
Note: Panel tokens belong to one core. With redundancy, create the panel's token on every node.
Warning: A dashboard session can read the whole project, device settings included (passwords and keys never are). Do not rely on dashboard access modes to hide project details from people on the network.
Generated dashboards
The builder can make a dashboard from what the project already knows. In the dashboard list, under Generate:
| Button | Makes | Skin |
|---|---|---|
| Generate room dashboard | A title, a scene list with the room's scenes (scenes whose actions all use devices of the room), then each device's controls (power, level, mute, input, status) | Lobby, theme follows the device |
| Generate show console | For a timeline. Cue list: last and next cue with a large GO, transport, position. Timecode: transport, timecode display, cues. | Console, dark |
| Generate facility overview | The status of every device, grouped by room, plus a "No room" group | Console |
For a room, tick For every room like this one to make a room template instead.
A generated dashboard is a normal dashboard: edit it freely. When the project changes (new devices, a removed scene), click Regenerate. Widgets for new devices and scenes are added at the bottom, widgets whose source is gone are marked as removed, and everything you changed or added stays as it is.
Skins and themes
Each dashboard has a skin and a theme, set in Settings.
| Skin | Look | Default for |
|---|---|---|
| Console | Dark lighting-desk look, amber accent, condensed uppercase labels, monospace timecode, dense square controls (40 px) | Operators, show consoles, overviews, the builder and the designer |
| Lobby | Stone and sage tones, pill buttons, large rounding, taller controls (44 px) | Room and building panels used by non-technical people |
Theme: Follow the device (light or dark from the screen's setting), Light or Dark. Both skins have both modes, and every text and control colour meets WCAG 2.1 AA contrast.
Fonts are bundled with the UI, so dashboards render the same at venues with no internet. A dashboard with no skin, or an unknown one, renders as Console.
Control styles
The control style draws the controls themselves, inside the skin:
| Style | Look |
|---|---|
| Classic | The skin's flat controls |
| Studio | Knobs, lit keys, faders, LED meters, readouts |
| Skeuomorphism | Brushed metal, rubber keys, pointer knobs, LCD readouts |
| Relief | Soft raised and pressed shapes in flat colours |
The project's default is set in the designer's Settings > Dashboard controls, with each style's highlight colours (Accent: value arcs, fader fills and focus; Display: readout digits). A dashboard, a group or a single control can pick another style in the builder.
Background
Background in Settings takes a colour (with its opacity), an uploaded image or a web address. Widget cards below 100 % lets the background show through the controls' cards.
Units
Devices report in their own units (°C, W, h…). Dashboards show values in the project's system (Metric or Imperial, set in the designer's Settings > Units). A dashboard can pick another in Settings, and a viewer can add ?units=imperial to the address.
Drafts and publishing
Screens always show the published version. While you edit:
- Save draft keeps your work on the core without changing what screens show ("Draft saved. Screens still show the published version.").
- Publish makes the current state the new published version. Screens showing it reload at once.
Before saving or publishing, the builder checks the dashboard and lists problems in the footer under "Cannot save:". Core checks it again.
Versions in the side panel lists every published version with its time and who published it. Restore publishes an old version again as a new version; the others are kept. Drafts and versions are stored in the core's data folder, under dashboards/<project id>/.
Edit without the designer
Dashboards are part of the project, so the REST API and MCP can create and publish them too. The format is the Dashboard schema of the contract: pages, each with widgets and layouts per screen class, plus skin, theme, access, room or roomParam. See Project file.