PierreRouanet/reachy_mini_surf_report
Reachy Mini · Surf Report
Mobile-first webapp that asks Reachy Mini for the surf report at any spot (or your current location), gets the marine forecast from Open-Meteo, narrates it through the robot's speaker in your favourite surfer personality, and animates a matching body-language reaction from the canonical emotions library.
Built on:
- The `pollen-robotics/reachy_mini` JS SDK (loaded from jsDelivr).
- Open-Meteo Marine API for swell, wind, water temp — free, no key needed.
- OpenAI chat-completions + text-to-speech for the persona narration.
- Vite + TypeScript for a small static-ish build (HF Docker SDK because OpenAI blocks browser CORS for user keys, so we proxy via nginx).
- The skeleton is forked from `tfrere/reachy-mini-minimal-js-conversation-app`, whose
replaceTrackpattern routes synthesized audio to the robot's speakers.
Audio routing (robot = hub)
┌────────┐ robot mic ┌────────┐ POST /v1/chat/completions ┌──────────┐
│ Reachy │ ─────────────────────► │ Browser│ ────────────────────────────► │ OpenAI │
│ Mini │ │ (this │ │ API │
│ daemon │ ◄──────────────────────│ app) │ ◄─── POST /v1/audio/speech ───│ │
└────────┘ TTS audio └────────┘ (MP3, decoded → WebAudio) └──────────┘
via replaceTrack on
the robot's audio
sender (sender of
user's mic, repurposed)If you're not signed in or no robot is connected, the narration falls back to a plain <audio> element on the phone — the app still works without a robot, just without the body-language part.
Personas
Pick one in the settings dialog:
- Longboard Soul Surfer (default) — laid-back, "stoked", session vibes.
- Shortboard Comp — clipped, technical, talks scoring potential.
- Big-Wave Hellman — terse, weather-obsessed, calls out wind direction and period.
- Retro Single-Fin — flowery 70s lingo, "groovy".
- Grom — hyped, lots of "BRO", "FIRING".
Surf data sources
V1 ships Open-Meteo Marine (free, no key). The SurfSource interface in src/surf-source.ts is a clean adapter — drop in a Stormglass / Surfline / Windy adapter (with its own key from the settings dialog) by implementing the same interface. PRs welcome.
Prerequisites
- Node.js 18+
- A Hugging Face account (for the robot signaling layer).
- A Reachy Mini robot online on the signaling server (optional — without a robot the app falls back to the phone speaker).
- A modern browser (WebGPU recommended). Narration runs in-browser via Kokoro-82M (Apache-2.0 ONNX model, ~92 MB cached after first load). No API key required.
Hugging Face OAuth
Deployed on a Space, OAuth "just works" — HF auto-provisions an OAuth app from the hf_oauth: true flag in this README and injects the client ID into the page at serve time.
For local dev, register your own OAuth app once at <https://huggingface.co/settings/applications/new>:
- Homepage URL & Redirect URI:
http://localhost:5173 - Scopes:
openid profile
Paste the resulting Client ID into the settings dialog → Access tab.
Run
npm install
npm run devThen open the printed URL (usually <http://localhost:5173>). First launch:
- Optional: tap Connect Reachy in the top-right to sign in with HF and pick a robot. (Skip this and the report still gets narrated, just from your phone speaker.) Running on localhost? Paste your HF OAuth client ID in the gear icon → Advanced.
- Type a spot name (or tap the location pin) → Go.
- The first narration downloads the Kokoro TTS model (~92 MB, cached in IndexedDB so subsequent visits are instant). After that, Reachy reads you the report in the chosen persona — voice generated on-device — and plays a matching emotion (cheerful for fun waves, displeased for blown-out, etc.).
Build
npm run build
npm run previewThis produces a static dist/ folder served by nginx in the Docker image. No backend or proxy needed — TTS runs entirely client-side via Transformers.js + ONNX Runtime Web.
Limitations
- First narration pays a ~92 MB model download; on slow mobile data this can be slow. WebGPU-enabled browsers (Chrome stable, Safari 26+) synth in roughly real-time; older Safari falls back to CPU/WASM where a short narration can take 5–10 s.
- Voice-in (free-form "talk to Reachy") is deferred to v1.5 — v1 is button-driven (search + "Tell me again").
- Open-Meteo Marine doesn't cover every coastline; very local breaks may be missing.
License
MIT for this glue code. Underlying SDKs and APIs keep their respective licenses.
