The Vibe Station: Architecture of a Procrastinator
I wanted to write code this weekend. Instead, I spent 12 hours debugging a 3D printer.
If you read my last log, you know I promised to turn my resurrected Raspberry Pi into a "Vibe Station." The goal was simple: play music on my good speakers (JBL Xtreme) while the Pi shows the album art, perfectly synced.
I intended to have a working prototype by now. But reality—specifically, the reality of being an electrical engineering undergrad—intervened. The ARK lab needed cleaning, equipment needed soldering, and my "free time" evaporated into a cloud of flux fumes.
So, today is not a "How I Built It" post. It is a "How I Plan To Build It" post. Welcome to the Architecture Design Document (ADD) for the most over-engineered music player in history.
The Problem: Bluetooth is a Lie
Here is the tragedy I am trying to solve:
Latency: If I cast my phone's audio to the Pi (so it can show visuals), the audio lags by ~2 seconds.
Control: I want "Spotify Connect" features (phone as a remote), but I use YouTube Music because I enjoy suffering.
I need a system where my phone thinks it’s playing music, but actually, it’s just shouting commands at my Odroid server, which then orchestrates the Pi.
The Architecture: "The Split Brain"
I call this the Conductor Pattern. The phone is the conductor, the Odroid is the sheet music, and the Pi is the orchestra.

Here is the stack I decided on (while scrubbing flux off a workbench):
1. The Brain: Odroid XU4 (Rust )
I considered using Node.js for the central server. It’s easy. It’s fast. But I have standards.
I’m going with Rust (specifically Axum + Socketioxide).
Why? Because memory safety on an embedded device isn't just a feature, it's a lifestyle.
The Logic: The server will hold a
Mutex<AppState>. When my phone says "Play Track X," the server locks the state, updates it, and broadcasts the change to the Pi.The Flex: The compiled binary will likely be smaller than the favicon of the Node.js website.
2. The Remote: Android (Kotlin)
This is the scary part. I plan to fork RiMusic (an open-source YT Music client) and perform a lobotomy on it. I need to find PlayerService.kt—the background service that plays audio—and hijack it.
Normal Behavior: App downloads audio -> Plays locally.
My Behavior: App downloads metadata -> Sends
socket.emit("play", id)-> Starts a fake timer so the progress bar moves -> Plays nothing.
It’s smoke and mirrors. The phone is a glorified remote control with a very convincing UI.
3. The Face: Raspberry Pi 3B+ (Vue.js)
The Pi is the "dumb terminal." It will run Chromium in Kiosk mode, pointed at the Odroid’s web server. I’ll use Vue.js for the frontend because updating the DOM manually is so 2015. It will listen for WebSocket events (sync_video, volume_change) and update the UI instantly.
Why didn't I build it yet?
Lab chores. You know how it goes. You walk in to "just fix a loose wire," and suddenly you're recalibrating the Z-axis on an Ender 3 and debugging a drone flight controller that refuses to arm.
I spent the weekend doing hardware maintenance, which means my software productivity was zero. But the room is clean, the scope ready, and my Nighthawk router is still blasting 400Mbps.
Next Steps
The architecture is locked. The repo is initialized (cargo init home-os). Next weekend, I actually write the code.
Task 1: Get the Rust server to echo "Hello World" to the Pi.
Task 2: Break the RiMusic build in Android Studio.
Task 3: Fix the build I just broke.
Stay tuned. Unless something else in the lab breaks.