Inspiration

Anyone who has lived on a dorm floor in college knows the routine: grab your towel, walk down the hall, find every shower taken, walk back, and try again ten minutes later. Knocking is awkward, and there's no way to tell whether someone just started or is about to finish. As four college students, we built NextUp to solve an actual problem we face on campus. We wanted the bathroom itself to tell you when it's your turn, make the wait and the shower a little better, and do it without putting a camera or microphone anywhere near it.

What it does

NextUp is a shower buddy for shared dorm bathrooms.

Before your shower, from your room:

  • Live status: see which stalls are free or in use, updated in real time.
  • Busy hours: charts of today and a typical week show when the showers are quiet, so you can dodge the rush.
  • The line: join from your phone. When a stall frees up, you're pinged right away and it's held for you for two minutes.
  • Hurry: in a rush? Nudge a stall that's in use. A friendly prompt appears on its screen, the person inside answers with a wave of the hand, and your phone shows "seen ✓".

During your shower, on the stall screen:

  • Music with synced lyrics that follow the song playing in the room.
  • What's on at Columbia tonight, pulled from the campus events calendar.
  • A water meter showing your time and estimated water used, compared with an average shower.
  • An animated lion cub that keeps you company and reacts to what's happening.
  • Wave to reply: no buttons and nothing to touch with wet hands.

No app, no login, no cameras and no microphones: a simple distance sensor is all it needs.

How we built it

Hardware: each stall has a Raspberry Pi with a HiLink LD2410C 24 GHz radar (over UART) or an HC-SR04 ultrasonic sensor (with a 1 kΩ / 2 kΩ divider on the echo line), and an 800×480 display.

Device agent (Python): reads the sensor, turns distance and motion into "in use" and "free" with hysteresis, and recognizes a held hand as a reply. Events are queued in SQLite, so nothing is lost if Wi-Fi drops. The agent serves the stall screen locally to Chromium in kiosk mode, so the screen keeps working offline.

Data and rules (Tiger Data): Tiger is both our database and our rule engine. Showers, sensor readings and notifications are TimescaleDB hypertables with compression and retention policies, and busy hours come from continuous aggregates. Who gets the next stall, Hurry cooldowns and simulated traffic for the other stalls are SQL functions, so every client follows the same rules.

Backend and realtime: a FastAPI app on Vercel Functions. Database triggers write every change to an outbox table in the same transaction; the API publishes them through Supabase Realtime, which pushes updates over WebSockets to phones and stall screens. Supabase Cron runs the timers every 10 seconds.

Website: React and Vite on Vercel, with charts for busy hours and water use. Lyrics come from LRCLIB, now-playing info from the room's music player, and events from Columbia's public calendar feed.

Challenges we ran into

  • Sensing people without a camera. Our radar first sent no data at all. We traced it to wiring, switched to an ultrasonic sensor to keep moving, then brought the radar back once we had it working. We learned to calibrate against the empty stall: the "someone's here" threshold has to sit below whatever the sensor sees when nobody is there.
  • Telling a person from a hand. Presence and the wave-to-reply use the same sensor, so we separated them by distance and duration, with a short grace period so a shaky hand still counts.
  • Realtime without a server. Vercel Functions can't hold connections open, so we moved the rules into Tiger and used a transactional outbox with Supabase Realtime to fan updates out to every screen.
  • Two backends, one database. Overnight, two halves of the team built parallel backends on the same Tiger schema. We merged onto one stack without losing any data.

Accomplishments that we're proud of

  • A real stall works end to end: walk in and the website shows "in use", tap Hurry and the stall screen pops up, wave and the phone shows "seen ✓".
  • The whole thing is live on the public internet and works from any phone, no app or login.
  • All the rules live in the database, with automated tests for the rules and the API.
  • Zero cameras and zero microphones, by design.

What we learned

Sensor data is messy: thresholds, hysteresis and calibration matter more than the sensor itself. Putting the rules in the database made it easy for many clients (the Pi, phones and the simulator) to agree on what's happening. And designing for a shower changes everything about the interface: no touch, wet hands, a screen read from a few feet away, and a reply that's a single gesture.

What's next for NextUp

  • Ask the board: a Gemini-powered chat that answers questions like "When should I shower before my 9 a.m.?" from live data.
  • Measured water use: a flow sensor on the pipe to replace the estimate with a real number.
  • Problem reports: flag no hot water or a clogged drain, shown on the stall screen until an RA fixes it.
  • One small board per stall: a custom PCB that combines the Pi connections, the sensor and the chime.
  • A real pilot: one dorm floor.

Built With

Share this project:

Updates

Submission history