Desk pets with a soul — and a speaker. Firmware that turns tiny round-screen ESP32 devices into living pixel-art companions that plug into your smart home.
Meet Leon, a ferret who lives in a magic forest on your desk: he gets hungry, plays fetch, sleeps at night — and when you stream music to him, he throws a full disco party (mirrored ball, lasers, smoke machines included). Works fully standalone, and becomes a first-class Home Assistant device.
Four stats (hunger, energy, joy, hygiene) decay over time; his mood shows in the header and on the RGB LED. Leon wanders, jumps, eats, burrows into the ground and sleeps. The forest follows the real time of day (NTP): sunny day, golden sunset, and a starry night with a lit cabin window and fireflies. Leave him alone and the HUD gives way to an idle clock.
| Day | Golden hour | Night + idle clock | Config menu |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
The scene follows the actual weather at your place (free Open-Meteo API, fetched by the firmware itself over verified TLS — no cloud account, no API key). Every WMO condition has its own look: palette tints, drifting clouds, rain scaled by intensity, snow, fog, hail pellets — and thunderstorms strike visible lightning bolts with a real thunder clap. Sparse ambient sounds (rain patter, forest wind) complete the mood. Swipe up for the forecast screen: today with humidity, plus four days with rain chance. Set your city once in the portal — or let Home Assistant gift the home location automatically.
![]() Clear |
![]() Partly cloudy |
![]() Fog |
![]() Rain |
![]() Showers |
![]() Freezing rain |
![]() Snow |
![]() Snow showers |
![]() Thunderstorm |
![]() Hail |
Ten of the fourteen distinct condition visuals (also: mainly clear, overcast, drizzle, snow grains).

And a clear night is a show of its own: fireflies, glowing mushrooms,
chimney smoke and the occasional shooting star.
The forest dresses up for the calendar (real date over NTP), on top of the live weather:
- 🎄 Christmas — decorated pine with a twinkling star and fairy lights, a snowman, wreath, icicles and candy canes, and Santa's sleigh flying past with a "ho ho ho".
- 🎃 Halloween — a graveyard, a bubbling green cauldron, a glowing jack-o'-lantern, and a witch cackling by on her broom.
- 🌽 Festa Junina — flag garlands, a crackling bonfire, a striped food stall and floating paper lanterns.
- 🎆 New Year — fireworks bursting all day, and the barrage fires right at midnight.
- 🎂 Birthday — Leon's own day (set in the portal / HA): cake, balloons, confetti and "Parabéns pra Você".
| 🎄 Christmas | 🎃 Halloween | 🌽 Festa Junina | 🎆 New Year |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Playable on the touch screen — or from your phone, with the web portal acting as a game controller.
| Games menu | Jump! | Bolinha (fetch) | Genius |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
- Jump! — doodle-jump style: springs, moving and crumbling platforms, NVS high score.
- Bolinha — fetch: throw the tennis ball, Leon chases it with real physics and brings it back.
- Genius — Simon-says on the round bezel: four color arcs, the RGB LED and an authentic tone per color.
Each device serves a React portal from flash at http://critter.local: live
stats over WebSocket, remote actions, settings, and game controllers. Its
centerpiece is a live mirror of the real screen — the firmware streams the
actual canvas (~20 fps) — and the mirror is interactive: tap and swipe on
it and the touches drive the device exactly like the physical screen, so you
can pet Leon, open the menus and the "Casa" panel, and even steer the games
right from your phone.
| Portal | As a game controller |
|---|---|
![]() |
![]() |
A Voice PE-style audio pipeline (network reader → 1 MB PSRAM ring → decoder) plays FLAC / MP3 / WAV over http — web radio, Home Assistant TTS, Music Assistant tracks, and AirPlay (via Music Assistant's AirPlay receiver). And it's a show:
- 🪩 Party mode when music plays: forced night theme, mirrored disco ball, random laser pulses, a color-shifting dance floor, smoke machines, thumping speaker cabinets — Leon dancing while the RGB LED flashes to the actual beat (live PCM envelope analysis).
- 🔵 Voice rings for the assistant (below).
Just say "Alexa" — always-on wake word, hands-free. The mic streams to Home Assistant where openWakeWord (local, private) listens; on a hit the Assist pipeline answers through the speaker, and follow-up questions reopen the mic by themselves. Hold the button for push-to-talk any time. A quick tap mutes the mic (hard gate at the source, crossed-mic icon), night mode mutes it automatically, and a small cyan mic icon shows end-to-end truth: it only lights when the pipeline is really consuming audio.
| Listening | Thinking | Speaking | Mic muted |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
TV-style pairing: a random 6-digit PIN pops on the screen when an app wants to connect; every WebSocket client must authenticate before anything — state, commands, and especially the microphone. The Security menu lists the connected devices and can revoke everyone with two taps.
| Pairing PIN | Devices + revoke |
|---|---|
![]() |
![]() |
Auto-discovery via zeroconf + PIN pairing; stat/mood/battery sensors, action
buttons, switches (sleep, night mode with configurable sounds, mic
mute, idle clock), brightness sliders, every device setting (name,
timezone, formats), a media_player for TTS and Music Assistant (codec
MP3 or FLAC — not ALAC) and an assist_satellite with the always-on
wake word. And it goes both ways: pull the left edge of the screen for the
"Casa" panel — your chosen HA entities on the device itself, lights and
switches as one-tap toggles, temperature/humidity/presence sensors live.
| Repo | What it is |
|---|---|
| homecritters-firmware | Device firmware (ESP32-S3 / Spotpear Ball V2): the pet, 3 mini-games, web portal, media player |
| homecritters-ha-plugin | Home Assistant integration (HACS): sensors, controls, media player for TTS, Music Assistant & AirPlay |
| homecritters-assets | Public screenshots & art used across the project |
Spotpear/Xiaozhi Ball V2 — ESP32-S3 (16 MB flash, 8 MB PSRAM), GC9A01 round 240×240 touch display, ES8311 audio codec + speaker, WS2812 RGB LED.
🗣️ A custom "Ei Leon" wake word (trained openWakeWord model) · 📦 OTA updates · 🪙 coins & a little shop · 🎵 Sendspin multi-room audio when the protocol stabilizes.
Made with ❤️ (and a lot of reverse-engineering) in Brazil.































