No description
Find a file
2026-04-21 09:27:06 +02:00
public build: regenerate bundled output 2026-04-21 09:27:06 +02:00
scripts feat: add uninstall script to cleanly remove kiosk system integrations 2026-04-21 09:27:06 +02:00
src feat: update Dashboard and Settings pages with new widgets and layout system 2026-04-21 09:27:06 +02:00
.gitignore security: gitignore runtime secrets, add config and token templates 2026-04-21 09:27:06 +02:00
bun.lock deps: add React Query 2026-04-21 09:27:06 +02:00
CLAUDE.md Finalize Atomic Design with TailwindCSS, fix Express 5 route compatibility, and verify search API 2026-04-20 18:07:48 +02:00
config.example.json security: gitignore runtime secrets, add config and token templates 2026-04-21 09:27:06 +02:00
package.json deps: add React Query 2026-04-21 09:27:06 +02:00
README.md docs: rewrite README with deployment guide and configuration reference 2026-04-21 09:27:06 +02:00
tailwind.config.js Finalize Atomic Design with TailwindCSS, fix Express 5 route compatibility, and verify search API 2026-04-20 18:07:48 +02:00
tokens.example.json security: gitignore runtime secrets, add config and token templates 2026-04-21 09:27:06 +02:00
tsconfig.json Finalize Atomic Design with TailwindCSS, fix Express 5 route compatibility, and verify search API 2026-04-20 18:07:48 +02:00

walldash

A full-screen kiosk dashboard for a Raspberry Pi, showing public transit departures (SL and SBB), weather, Spotify now-playing, and system stats.

Prerequisites

  • Bun runtime
  • Raspberry Pi running Raspberry Pi OS (tested on Bookworm/Lite + LXDE desktop)
  • Chromium or chromium-browser installed

Quick start (development)

bun install
cp config.example.json config.json   # then fill in your credentials
bun run start

Open http://localhost:3000.

Configuration

Copy config.example.json to config.json and fill in your values:

Field Description
spotify.clientId / spotify.clientSecret Spotify app credentials from developer.spotify.com
weather.plz Swiss postal code (PLZ) for MeteoSwiss forecasts
sl.stationId / sl.stationName Stockholm Lokaltrafik site ID (find via Settings > Search)
sbb.stationId / sbb.stationName Swiss Federal Railways station ID (find via Settings > Search)
refreshRate Polling interval in milliseconds (default: 10000)
alwaysOn true reduces animations and refresh rates for burn-in prevention
layout Maps widget zone names to widget IDs

config.json and tokens.json are gitignored — never commit real credentials.

Raspberry Pi deployment

1. Install the server as a systemd service

bash scripts/setup-systemd.sh

This creates /etc/systemd/system/walldash.service, enables it, and starts it. The server auto-restarts on crash and starts on boot.

systemctl status walldash.service
journalctl -u walldash.service -f

2. Set up the kiosk browser

bash scripts/setup-kiosk.sh

This installs unclutter (hides the cursor), disables screen blanking, and adds a ~/.config/autostart/walldash-kiosk.desktop entry that launches scripts/start-kiosk.sh on login.

start-kiosk.sh waits until the server is ready, then opens Chromium in kiosk mode. If Chromium crashes it restarts automatically.

3. Configure auto-login

Use raspi-configSystem Options → Boot / Auto Login → Desktop Autologin so the kiosk browser starts without manual interaction.

4. Set credentials

Copy and edit config.json on the Pi:

cp config.example.json config.json
nano config.json

For Spotify, open http://<pi-ip>:3000/settings in a browser and follow the OAuth link.

Uninstall

bash scripts/uninstall.sh

Removes the systemd service and autostart entry. The project directory is left untouched.

Build

To regenerate the bundled frontend:

bun run build

Output goes to public/main.js.

Widget zones

┌──────────────────────────────────────────┐
│  header-left          header-right       │
├────────────────────┬─────────────────────┤
│  main-1            │  main-2             │
│                    │                     │
├──────────┬─────────┴──────┬──────────────┤
│ footer-1 │   footer-2     │   footer-3   │
└──────────┴────────────────┴──────────────┘

Available widget IDs: clock, weather, sl, sbb, spotify, system, spacer.