Skip to content

holzerjm/CountDownController

Repository files navigation

Countdown Controller

A simple, low-friction session timer with a separate display page (projector / big screen) and controller page (phone / laptop) that stay in sync. Designed for talks, presentations, debates, breakout sessions — anywhere you need a visible countdown clock that someone in the room can quietly adjust without touching the projector.

status node license


Features

  • Large-format countdown with a separate wall clock underneath
  • Phone-friendly controller with quick presets (1, 2, 3, 5, 10, 15, 20, 30, 45, 60 min) and a custom-duration field
  • Color fade as time runs out — green → yellow → orange → red, configurable threshold
  • Add / remove time on the fly — ±30 s and ±1 m, works while running, paused, or stopped
  • Audible alert when the countdown hits zero
  • Keyboard shortcuts on the display (Space, R, /, F)
  • Cross-device control over your local Wi-Fi via WebSocket
  • Same-browser fallback via the BroadcastChannel API — works even with no network

Requirements

  • Node.js 18 or newer (download)
  • macOS or Linux for the launcher script (timer.sh). Windows users can run node server.js directly.
  • A modern browser (Chrome, Firefox, Safari, Edge)

Installation

git clone https://github.com/holzerjm/CountDownController.git
cd CountDownController
./timer.sh setup

setup checks for Node.js and installs the single dependency (ws).


Running

Command What it does
./timer.sh start Start the server in the foreground (Ctrl+C to stop)
./timer.sh background Start the server in the background, log to timer-server.log
./timer.sh stop Stop a background server
./timer.sh status Check if the server is running
./timer.sh restart Stop, then start
./timer.sh open Open both pages in your default browser
./timer.sh help Show usage

Default port is 8080. Override with an environment variable:

PORT=3000 ./timer.sh start

When the server is running it prints both URLs to the terminal — open them as needed.


Using It

Once the server is up:

  • Display pagehttp://localhost:8080/display Open this on the projector, big screen, or wherever the audience can see it. Press F (or click "Click for fullscreen") for a clean projector view.

  • Controller pagehttp://localhost:8080/controller Open this on your phone or laptop. Use it to start, pause, adjust, and reconfigure the timer.

Controlling from a phone on the same Wi-Fi

./timer.sh start (or status) prints your computer's LAN IP. On your phone, open:

http://<your-computer-ip>:8080/controller

The display can stay on the projector at localhost. Make sure both devices are on the same network and your firewall isn't blocking port 8080.

Controller sections

Section What it does
Controls Start, Pause, Stop, Reset
Quick Presets One-tap durations (1–60 min)
TOA Launch TOA-specific preset durations (8, 25, 10, 5 min)
Custom Duration Pick any minutes + seconds (minimum 10 s)
Adjust Time ±30 s and ±1 m. Works while running, paused, or stopped.
Color Fade Start Slider for when the green-to-red fade begins (50–95 % elapsed)

Display keyboard shortcuts

Key Action
Space Start / Pause toggle
R Reset to full duration
+1 minute
−1 minute
F Toggle fullscreen

How "Adjust Time" behaves

The + and - buttons are intentionally asymmetric, matching how you'd actually use them in a session:

  • +30s / +1m while running or pausedextend the budget. Both the countdown and the "of X:XX" total grow by the delta; elapsed time is preserved. Use this when the speaker is going well and you want to give them more room.
  • -30s / -1m while running or pausedskip the countdown forward. Only the remaining time shrinks; the total stays the same. This makes the color fade react immediately to the new urgency — if subtracting pushes the countdown past 75 % elapsed (or whatever you set), the colors start fading right away. If - would push remaining at or below zero, the timer stops at 00:00.
  • Before the timer has started (READY state) — adjust changes the configured total duration directly.

Troubleshooting

Symptom Fix
Controller can't reach display from another device Same Wi-Fi? Firewall blocking port 8080? Using the LAN IP, not localhost?
Server won't start Run ./timer.sh setup to install ws. Check timer-server.log for errors.
Port already in use PORT=3000 ./timer.sh start
Background server "stuck" ./timer.sh stop clears the stale PID file. If that fails, pkill -f "node server.js".
Pause from the controller doesn't stop the timer Fixed in current code. If you see this, you're on an old version — git pull.

Project layout

.
├── server.js                 # HTTP + WebSocket relay
├── timer-display.html        # Display page (timer logic)
├── timer-controller.html     # Controller page (command emitter)
├── timer.sh                  # Launcher (setup / start / stop / status / ...)
├── package.json              # Node deps (just `ws`)
├── README.md                 # This file
├── ARCHITECTURE.md           # Design + data flow
└── LICENSE                   # MIT

For the technical design — how the pages talk to each other, the timer state machine, and why both BroadcastChannel and WebSocket are used — see ARCHITECTURE.md.


License

MIT — see LICENSE.

About

Session timer with separate display and controller pages — for talks, presentations, and any setting where you need a visible countdown someone in the room can quietly adjust.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors