A tiny Express + WebSocket app that shows a live list of running model trains. An admin page lets you register trains as running or stopped, and the public display updates instantly. Runs are stored in a local SQLite database so you can review daily activity later.
- Pages:
/shows the public display,/adminis for adding/stopping trains, and/activityshows all runs for a selected day. - Live updates: Changes in the admin UI broadcast over WebSockets so the visitor display stays in sync without refreshes.
- Data: Trains and run history are kept in
trains.db(SQLite) viabetter-sqlite3. Each update also writes a run record so you can report on past days. - API:
/api/runningmanages the current running list (GET/POST/PATCH/DELETE) and/api/reports/runs?date=YYYY-MM-DDreturns historical runs.
- Start the server (see platform-specific steps below).
- Visit
/adminto add a running train. Required fields: name, railway, country (emoji flag), power type, train type, year range, and location. - The public display at
/updates immediately. Use the Stop action in/adminto end a run and remove it from the live board. - Visit
/activityand pick a date to see all runs for that day with durations.
- Install Node.js (e.g.,
brew install node). - Install dependencies:
npm install. - Start the server:
npm start(optionallyPORT=4000 npm startto change the port). - Open http://localhost:3000 (or your chosen port) and use
/adminto manage trains.
-
Install prerequisites:
- Node.js 18+ (for ARM64/ARMv7 you can use NodeSource:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -thensudo apt-get install -y nodejs). - Build tools for
better-sqlite3:sudo apt-get install -y build-essential python3 make g++.
- Node.js 18+ (for ARM64/ARMv7 you can use NodeSource:
-
In the project directory, install dependencies:
npm install --production. -
Start the server:
PORT=3000 npm start. The app listens on all interfaces, so other devices on the network can connect. -
Optional: create a
systemdunit for auto-start on boot:[Unit] Description=Train Display After=network.target [Service] WorkingDirectory=/home/pi/whatisrunning ExecStart=/usr/bin/env PORT=3000 /usr/bin/node /home/pi/whatisrunning/server.js Restart=always Environment=NODE_ENV=production [Install] WantedBy=multi-user.target
Save as
/etc/systemd/system/traindisplay.service, then runsudo systemctl daemon-reload && sudo systemctl enable --now traindisplay.
Database files (trains.db) live alongside the code; back up that file if you need to preserve history across reinstalls.