← Projects

Gemi

Personal room-assistant prototype using Gemini Live for lights, music, and an iPad display.

Spring 2025 · AI tooling · Completed personal project

Illustrated GAPI 2025 title slide with glossy 3D lettering over a bright blue sky and clouds
GAPI, the school-project shell around the assistant that became Gemi.

Stack

Stack: SwiftUI · Gemini Live · Gemini 2.0 Flash Thinking · Llama 3.2:3b · Fast Whisper · Orpheus TTS · Spotipy · ISY REST · Random Forest

No wake word. This personal prototype sent voice input through Gemini Live for external AI processing; the loop still had to feel quick enough for conversation.

Log

  1. Spring 2025 — opening

    Google Home Mini used to flip the lights when I asked. Family stopped paying for the subscription, the bridge to our Universal Devices ISY went silent, and the room forgot how to listen.

    Blue problem diagram showing a Google Home style speaker disconnected from a router by a large red X, with the router still connected to a lightbulb and clouds above and below
    The link that died.
  2. What I want

    No keyword. Automatic recognition — is it being spoken to, how many commands. Lights, music, and a clean iPad on the wall as the surface.

  3. The first pipeline

    Streaming mic into speech-to-text, into an LLM, then out through two routes: function calls for the room and text-to-speech back to the user. Magic, but plumbed.

    Blue architecture flowchart with white icons showing Streaming mic to STT to LLM to Function calls and TTS
    Mic in, function calls and voice out.
  4. Lights

    The Universal Devices ISY exposes a REST API — get and set against an XML node tree. Could've wired the whole house, but went with what the assistant would actually need to reach: room, lamp, hallway, bathroom.

  5. Spotify

    PyChromecast first, since the old Google Homes already spoke that language — but it couldn't pick songs by name. Switched to Spotipy 2.25.1, OAuth'd into my account, and pointed playback at my speaker group.

  6. Dual route

    Latency was the gap between assistant and presence. Split voice activation into two parallel tracks — Llama 3.2:3b on the spoken-response track ("yeah, on it"), Gemini 2.0 Flash Thinking on the function-call track. The room could answer out loud while Gemini was still deciding what to actually do.

    Blue voice activation diagram labeling two paths as Spoken Response / Fast and Function Calls / Accurate
    An acknowledgement track beside the room-action track.
  7. STT — Faster-Whisper

    For the first pipeline, I used Faster-Whisper for speech-to-text before the language model. It handled the transcription leg of the mic-to-action-and-voice chain.

  8. LLM — small voice, big brain

    Llama 3.2:3b handled brief acknowledgments like "yeah, got it" while Gemini 2.0 Flash Thinking handled the room-action requests. The split let an acknowledgment start while an action was still being worked out.

  9. TTS — Orpheus over Nari Dia

    Tried Nari Dia 1.6B first — expressive, but too slow for a voice that's supposed to interrupt itself. Orpheus TTS gave back a balance, plus inline tags for laugh, chuckle, and breath that nudge it past flat-affect synthesis.

  10. iPad as mirror

    Inspired by Siri's redesign — the gradient border around the screen edge that pulses with whatever's being spoken. Mounted the iPad on the wall as a mirror with the live camera feed underneath, gradient on top, and a small dark debug terminal overlaid in the corner so I could watch what it was hearing.

  11. Stereo Love

    Demo from the iPad mounted on the wall, gradient border pulsing with the audio. "Can you turn off my hallway lights?" — hallway clicks off through the doorway. "And turn off my room lights too." — overhead goes dark. "Can you play Stereo Love on Spotify?" — Spotipy sends it to my speaker group, and Edward Maya fills the room.

  12. Lamp off, live

    End of the talk, no slide. Raised a hand: "Okay, turn off my lamp." The lamp behind me clicked off. Mic drop without the mic.

    Phone held in a dark bedroom running the Gemi assistant interface while the ceiling lights are on and the room is visible behind it
    The live-control proof: phone interface up, bedroom lights responding.
  13. A friend's note

    Showed gapi v1 to a friend. They said, "really built jarvis just for a school project." Took that as the sign v1 wasn't enough — v2 should be proactive, know where I am, see my emails, control music.

  14. Gemi — the v2 idea

    Next page of the spiral notebook had a robot labeled Gemini standing between two speakers labeled System Input and User Input. The router fed it from the internet — void, chromecast, macbook, iphone — all running into the same listener.

    Spiral notebook sketch labeled System Architecture with a Gemini robot in the center, internet and device inputs flowing toward it, speakers labeled System Input and User Input, and API keys sketched at the bottom
    v2, page one: Gemini as the box between system input and user input.
  15. Tech stack

    Gemini at the center, surrounded by what it had to talk to — Universal Devices for the lights, Google APIs for everything Google, VLC and Google Cast for playback, Scikit-Learn for the presence model, Python on the server side, Swift on the iPad.

  16. Gemini Live

    Swapped the v1 STT-LLM-TTS chain for a single WebSocket to the Gemini Live API. Text, audio, and video out; text and audio back. One connection, real-time, no stitching three models together to fake the cadence.

  17. iBeacon dead end

    First attempt at presence detection: emit iBeacon advertisements from a Bluetooth card and triangulate from fixed receivers. The card refused to output the format. Spent days on it, never got a frame out.

  18. Random Forest, 99.7%

    Switched approaches. An iPhone app logged nearby wireless signal-strength readings, labeled each sample by the room I was standing in (Bedroom, Media, Playroom), and POSTed them to a tiny server. On that four-day dataset, the reported results were RandomForestClassifier 99.7%, KNeighborsClassifier 98.6%, and LinearSVC 98.0%; performance beyond that data was not established. A live prediction came back Playroom 96 / Media 4 / Bedroom 0.

  19. Where it confused itself

    In that dataset, the confusion matrix mixed Playroom with Media — the two rooms that share a wall. The wireless signal couldn't tell which side of the drywall I was on, and honestly neither could I half the time.

  20. Gemi — Gemini Smart Home

    Closing slide: a Wii console box, repackaged. Same proportions, same white plastic, same translucent play button — relabeled 'Gemi' on the console and 'Gemini Smart Home' on the box. The product the room had quietly become.

Result

Demonstrated room controls for lights and Spotify.

What I learned

Splitting a quick spoken response from Gemini's room-action track meant the assistant could acknowledge me while a light or music command was still being handled. The iPad-as-mirror was the other half: not a screen I had to summon, but a surface on the wall that pulsed when the assistant heard me.