Remote control
The dashboard and mobile app can drive a claimed kiosk over the WebSocket: reload the page, restart the app, reboot the whole device, fetch logs, push an update. This page documents what each command does, how long it takes, and when to reach for it.
Where to find the commands
Every claimed sign has a Commands card on its detail page:
- Dashboard:
Events → [event] → [sign] → Overview → Commands - Mobile: Sign detail screen → row of action buttons
Both surfaces drive the same sign the same way. Pick whichever is closer to where you are.
Every command reports back. When you fire Refresh Content, Restart App, Reboot Device, or Background mode, the dashboard waits for the sign to answer and then tells you the outcome — confirmed by the sign, failed (with a reason), or no confirmation if the sign didn't respond in time. Update Sign App and Fetch logs show their own live status instead. You no longer have to guess whether a command actually landed.
This page covers commands one sign at a time. To fire the same command at a whole event's fleet — or on a schedule — see Bulk actions & schedules.
The commands
Refresh Content
Reloads the assigned URL on the kiosk.
| Property | Value |
|---|---|
| Backend → kiosk event | sign:refresh |
| Wall impact | Brief blank moment (under 1 second), then the page reloads |
| Expected duration | 2-3 seconds end to end |
| Sign state during | Stays online |
| Use case | Content authors pushed an update; you want to be sure every wall sees it |
Refresh Content is the safest, lightest command. It's the first thing to try when something looks wrong with what's on the wall.
Restart App
Exits the sign app process. The watchdog from Crash recovery restarts it within ~60 seconds.
| Property | Value |
|---|---|
| Backend → kiosk event | sign:reboot |
| Wall impact | The wall briefly shows the desktop or splash, then the sign app reappears with the assigned URL |
| Expected duration | 30-60 seconds |
| Sign state during | Briefly Offline, then Online |
| Use case | The sign app is misbehaving but Windows itself looks fine — first-line fix |
Restart App is non-destructive. The desktop sign re-reads its config from disk, replays the last assigned URL from the cache, and resumes.
Reboot Device
Restarts the entire Windows machine. The kiosk goes through a full boot cycle: BIOS → Windows → auto-login → sign app → URL.
| Property | Value |
|---|---|
| Backend → kiosk event | sign:reboot_device |
| Wall impact | Full BIOS POST screen, Windows boot logo, brief desktop, then the sign app |
| Expected duration | 60-120 seconds (depends on hardware) |
| Sign state during | Offline for ~90 s, then Online |
| Use case | Restart App didn't fix it. Driver state, network stack, or unidentified Windows-level weirdness. |
The kiosk user has shutdown privilege granted in Kiosk configuration, so the reboot doesn't require an interactive logon prompt.
If Reboot Device returns "permission denied" in the dashboard, the shutdown privilege grant didn't apply — see Troubleshooting → Sign won't claim for re-applying.
Fetch logs
Pulls the kiosk's sign.log and any rotated archives, then surfaces them in the dashboard.
| Property | Value |
|---|---|
| Backend → kiosk event | sign:fetch_logs |
| Wall impact | None |
| Expected duration | 5-15 seconds depending on log size |
| Sign state during | Stays online |
| Use case | Triaging a misbehaving sign before rebooting (rebooting destroys evidence) |
The fetched bundle appears in the Logs card on the sign detail page. From there you can:
- View the contents inline (Ctrl/Cmd-F to search)
- Copy to clipboard
- Download as a
.zip - Attach to a support ticket
For what these logs contain, where they live on the kiosk, and how to read the rotation history, see Log locations.
Capture before you reboot
Always Fetch logs before a destructive command if you want to know why the sign was misbehaving. A reboot resets the symptom and clears the in-memory state that made the log informative.
Update Sign App
Downloads the current desktop sign build and restarts the sign to install it. One click runs the whole flow — there's no separate install step to come back for.
| Property | Value |
|---|---|
| Backend → kiosk event | sign:update |
| Confirm dialog | "The sign downloads the update and restarts itself to install it. Its screen goes to an 'Updating…' notice for a minute or two." |
| What you see | Live status on the sign detail page: Waiting for sign to respond → Downloading update… N% → Update downloaded — installing… → Installing update — sign will restart… → Update complete — running vX.Y.Z |
| Expected duration | 30 s – 5 min to download (depends on size and connection), then a minute or two to install and come back |
| Sign state during | Online while downloading; briefly offline during the install and restart, then online again |
| Use case | Bringing one sign current, on your schedule (see Stability over features) |
The button itself tells you whether there's anything to do, because it reads the same update server the sign installs from. Versions below are examples — the button always shows real ones:
| Button reads | Meaning |
|---|---|
Update Sign App (1.6.3) | The sign is behind; pressing it installs 1.6.3 |
Up to date (1.6.3) | Nothing to install — disabled |
Ahead of feed (1.7.0-rc1) | The sign is running a build the update server doesn't serve — disabled, and worth investigating (usually a hand-installed build) |
Update Sign App with no version | The update server couldn't be read; the sign will install whatever it's serving when the command lands |
Update via USB (sign on v1.4.1) | This sign's build predates remote updates (they need v1.5.2 or later) — reimage or update it in person; see Installing DisplaySync |
The kiosk pulls update binaries from updates.displaysync.live. If you've blocked that destination at the venue firewall, the download fails — see Network requirements.
Signs never update on their own. There is no automatic update-during-event behavior: a sign downloads and installs only when a person or a policy tells it to. Roll a fleet by triggering each sign when it's safe to restart — or use Bulk update, which does exactly this five signs at a time and skips whatever's offline.
For release notes on what's in each version, see Desktop sign release notes.
Safety: token freshness and room scoping
Destructive commands — Restart App, Reboot Device, Update Sign App, and Fetch logs — carry a backend-minted command token (a 32-byte random hex string from crypto.randomBytes) and a timestamp. The kiosk validates:
- The token is present and non-empty
- The timestamp is within 30 seconds of the kiosk's clock
If either check fails, the command is rejected and the dashboard sees an error. This prevents replay attacks — you can't capture a "reboot" command and re-issue it later, because the timestamp falls outside the freshness window.
Cross-org leakage is prevented separately by Socket.IO room scoping: a command intended for a sign in org X is published to that org's room, and only kiosks subscribed to that room receive it. The kiosk doesn't authenticate the token's origin.
The lighter-weight command (Refresh Content) skips token validation. It's idempotent and side-effect-free enough that the WebSocket session itself is the trust boundary.
You don't have to do anything to opt into any of this — it's how every command moves between dashboard and kiosk by default.
If a command starts failing with timestamp errors, check the kiosk's clock. NTP misconfiguration on the venue network is the usual cause. See Network requirements → DHCP, DNS, NTP.
Offline command queueing
When the dashboard already shows a sign as offline, its command buttons are disabled — you'll see "Sign is offline — commands cannot be sent." Wait for the sign to reconnect (or troubleshoot the offline state) before issuing a command.
If a sign drops while a command is in flight, the dashboard reports no confirmation from the sign. A command that was already on its way will still be delivered if the sign reconnects within about 30 seconds; past that it's discarded rather than landing on a sign that's moved on. Don't rely on the replay for anything you can't simply re-issue — re-fire once the sign is back online to be sure.
In a bulk wave, offline signs don't queue at all: they resolve as Skipped with the reason offline, so the wave panel tells you exactly who missed it. See Bulk actions → The wave panel.
Audit trail
Every remote command is logged to the sign's Audit tab on its detail page:
- Who issued the command (user email + role)
- Which command
- Timestamp
- Result (confirmed, failed, or timed out)
Useful for "who rebooted lobby-east-03 at 3 PM during the keynote?" conversations. The audit log persists with the sign's history regardless of reclaim/relink cycles.
Failure modes
| Symptom | Likely cause | Fix |
|---|---|---|
| "No confirmation from the sign" | Sign dropped offline, or the kiosk clock drifted past the command's freshness window | Re-issue once the sign is back online; if it keeps happening, check the kiosk clock (see below) and the offline state |
| Reboot Device "permission denied" | Shutdown privilege not granted to kiosk user | Re-run shutdown privilege grant |
| Refresh succeeds but content didn't change | Browser-side cache | Ensure your content sets sane Cache-Control headers, or use a cache-busting query string |
| Fetch logs returns empty | Logs directory not writable, or log rotation cleared everything | Check kiosk user's permissions on the logs dir; restart sign app to recreate |
| Update timing out | Venue blocking updates.displaysync.live | Allowlist the host or pre-deploy the update via image rebuild |
| Every command button is greyed out | The sign is offline, or your event role is below technician | The card says which: "Sign is offline — commands cannot be sent." or "Requires technician role or higher on this event." |
| Update Sign App is greyed out | The sign is already on the current build, or ahead of it | Read the button label — Up to date or Ahead of feed names the case |
Background mode
Background mode lets you put a sign into a "telemetry-only" state — the wall is dark and silent, but the kiosk keeps reporting heartbeats and accepting remote commands. Reach for it when:
- A sign is powered but not displaying — storage, transit, pre-event venue prep
- The screen is being used for something else (a browser, an RDP session) and you want the sign quiet in the meantime
- You want a sign physically in place at a venue but visually off until showtime
What it does
| Aspect | Background on | Background off (default) |
|---|---|---|
| Kiosk window | Hidden | Visible (the wall) |
| Audio | Muted | Audible |
| Renderer frame rate | Throttled | Normal (~60 fps) |
| Watchdogs | Paused | Active |
| Heartbeat | Continues with mode: 'background' | Continues with mode: 'active' |
| Sign state in dashboard | online with a "Background" badge | online |
backgroundMode in sign-config.json | true | false |
The watchdog pause is the subtle bit: with the display hidden and frame rate throttled, the FrameWatchdog and PageWatchdog would otherwise interpret silence as a fault and reload-loop. They're paused to keep background mode quiet.
How to turn it on
Two ways, equivalent in effect:
- Dashboard: sign detail page → Enter Background button. The confirm dialog explains it: the sign hides its display and keeps reporting heartbeat + system metrics.
- Local hotkey:
Ctrl+Shift+Bat the kiosk. See Hotkeys → Ctrl+Shift+B.
To turn it off: same routes — Exit Background button or Ctrl+Shift+B again. Exiting restores the display and resumes the assigned content.
The mobile app has the same Enter Background / Exit Background toggle on the sign detail screen.
Persistence across reboot
backgroundMode: true is written to sign-config.json (see File locations). A sign that boots with this flag set comes up silently — no splash window, no audio, just the heartbeat. This is the gotcha: if an operator forgets to exit before next morning, the wall comes back from a power cycle still dark.
The visual indicator that background mode is active is the Background badge on the sign in the dashboard. If a sign shows online but no content is visible at the venue, the badge is your first check.
Pre-Sysprep gotcha
Don't bake backgroundMode: true into a captured image — every kiosk cloned from that image will cold-boot silent on first deployment. Almost always wrong; see Kiosk configuration → Background mode at deployment time.
What's next
- Bulk actions & schedules — the same commands fired at a whole event, plus standing scheduled refreshes
- Monitoring — health cards on the sign detail page that contextualize when to reach for these commands
- Troubleshooting — symptom-indexed playbook for when the commands themselves don't fix it
- Notifications — alerts that fire when commands fail