Smartphone-based Human Activity Recognition. Train a 1D CNN on the UCI HAR dataset, ship a single-page PWA that runs inference in the browser, and share predictions live between devices via Supabase Realtime Broadcast.
See docs/ for the design docs.
training/ Python pipeline (download UCI HAR, train CNN + RF, export to TF.js)
web/ Static PWA (HTML/CSS/ES modules, TF.js from CDN, Supabase from CDN)
docs/ Design + brainstorming notes
vercel.json Static hosting config
- Create a Supabase project (free tier). https://supabase.com/dashboard
- No schema, no tables — we use Realtime Broadcast only.
- Copy the Project URL and anon public key from Project Settings → API.
- Copy the config template and fill in your values:
Edit
cp web/js/config.example.js web/js/config.js
web/js/config.jsand paste your URL + anon key.
The PWA ships with a heuristic fallback (STATIONARY/MOVING) so it works end-to-end before the CNN is trained. To get the real 6-class model (requires Python 3.11 — TF 2.15 + tfjs 4.10 don't ship 3.12 wheels):
cd training
/opt/homebrew/bin/python3.11 -m venv .venv && source .venv/bin/activate # brew install python@3.11 if needed
pip install -r requirements.txt
python train.pyThis downloads UCI HAR, trains the CNN + RF baseline, and writes the TF.js model into web/model/. Next time you load the PWA it auto-detects the model and uses the CNN instead of the heuristic.
Any static file server works. Sensor APIs require HTTPS except on localhost:
cd web
python3 -m http.server 8000
# open http://localhost:8000 on your laptop for testingFor phone testing you need HTTPS. Easiest: deploy to Vercel (below) and open the preview URL on your phone.
npm i -g vercel
cd web
vercel # first time: link/create project
vercel --prod # deployVercel auto-detects the static site. vercel.json at the repo root sets the Permissions-Policy header for motion sensors.
- One URL. All devices opening it join the same Supabase Broadcast channel.
- Tracker role. Any device that taps Start tracking grants motion permission, runs the CNN on-device (no data leaves the phone), and broadcasts
{label, confidence, ts}at ~2 Hz. - Viewer role. Any other device on the URL auto-shows the latest prediction in a huge readable label. That's the projector/laptop view while the phone is in a pocket.
- Fallbacks. If Supabase is unreachable, local tracking still works. If motion permission fails, the UI explains what to do. If the CNN isn't deployed yet, the heuristic classifier runs.
- Supabase config filled in, deployed to Vercel.
- Visit URL on presenter laptop (plugged into projector) — should show "WAITING".
- Teammate visits URL on phone, taps Start tracking, grants motion permission, pockets phone.
- Laptop should switch from "WAITING" to a live label.
- Backup: 60 s screen recording of a good run, embedded in slide deck.
- iOS Safari requires a user gesture to request
DeviceMotionEvent.requestPermission()— we call it from the Start tracking button. - Wake Lock is requested while tracking so the screen doesn't sleep in a pocket.
- HTTPS required for sensor access.
localhostis exempt for dev.
Course project for CIS4930, Spring 2026. Not production software. Supabase anon key is public-safe (Broadcast only, no tables, no RLS) for the duration of the course.