This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
My phone says I slept 4 hours 24 minutes a night this week.
I'm job hunting in Ireland, so every email might be the one. I did everything people recommend: notifications off for every social app, every WhatsApp chat archived. Email is the only door I left open, because that's where an interview invite or an offer will arrive.
It's also the door everything else walks through. One notification at 7am and I'm in: the email, then LinkedIn "just in case", then Instagram, then the chats I archived. Forty minutes later the morning is gone, and with it the book, the gym, packing food and catching the bus. At night it's the opposite problem. I can never be sure nothing important came in, so I don't sleep well either.
Here it is in my own voice:
Every shot of the board is real. The night and morning scenes are faceless AI stand-ins, because I couldn't film my own mornings before the deadline.
So I built Morning Sloth: an Arduino UNO Q on my desk that reads my Gmail overnight, lets open-weight Gemma 4 decide on the board whether anything actually needs me, and shows the answer as one face on its LED matrix. In the morning it also counts down to my bus, using the live feed.
Why an UNO Q, and why a sloth. The UNO Q came in the event pack for the Hacktoberfest fest I'm hosting in Galway this Thursday, 29 October. I was too curious to leave it in the box. Then Week 3 dropped with a sloth theme, and it fit: a small board running a model on its own CPU is slow, and that's fine. I had no extra modules, so my first ideas, which needed temperature sensors and the like, were out. I asked a different question instead: what's actually wrong with my week, and how could this board help? The answer was email, my phone, and sleep.
TL;DR. Look at the sloth, not your phone. Asleep: nothing needs you. One eye open: someone you've written to replied, and it can wait. Wide awake: something needs you today. Gemma 4 E2B runs in llama.cpp on the UNO Q's own CPU, so my job search and my bills never leave the room. On email it had never seen, it made the right wake-or-sleep call 98% of the time, with zero false wakes.
What I Built
A sloth with three moods, and nothing to scroll:
- Asleep, breathing slowly: nothing needs you. The phone stays face down.
- One eye open: someone you've written to replied, or a deadline is close. It can wait until the bus.
- Wide awake, blinking: something needs you today: a failed payment, a parcel arriving, a leaked API key, a recruiter asking for something.
- A bus and a number: from 9am to 1pm, the minutes until the next 404 actually reaches Castlegar GAA, delays and cancellations included. A dot in the corner means the time is live.
It never touches your mailbox. Read the email on your phone and the sloth goes back to sleep on its own. From 02:00 to 06:00 the matrix goes dark, so it isn't one more light keeping you up.
Who gets to be lazier? Me first: someone who has to keep email on, but loses mornings to it. Then anyone who keeps their phone out of the bedroom and still worries about what's waiting. The sloth makes the one decision that used to need my phone, and most mornings that decision is "no".
Why not Gmail's Important label? I checked it against my own inbox. Gmail marked a Trustpilot review request and a vendor's "[urgent]" incident notice as Important, and missed both of my failed electricity top-ups. And a label still means unlocking the phone to look at it.
Demo
The raw demo, uncut: 4 minutes 52 seconds, filmed on my Meta Ray-Ban glasses at half past midnight, nothing sped up. I send myself two emails and you watch Gemma read them on the board. The cards beside the footage explain what's happening while it thinks.
- 0:35 I send "Quick question for tomorrow" from an address the sloth counts as someone I've written to.
-
1:43 One eye opens. Gemma said
fyi, and the people-you've-written-to rule raised it tosoon. - 2:08 I send "Webinar starting in 10 minutes".
-
3:24 Wide awake. The starting-soon rule makes it
needs_today, whatever Gemma says. - 4:27 I read it on my phone, and the sloth goes back to sleep on its own.
Code
MuhammadMurtuzaHussain
/
morning-sloth
Look at the sloth, not your phone: Gemma 4 on an Arduino UNO Q sorts your Gmail overnight and shows one face on the LED matrix.
Look at the sloth, not your phone. An Arduino UNO Q reads your Gmail overnight, open-weight Gemma 4 decides on the board whether anything needs you, and one face on an LED matrix tells you
See it live Ā· Demo guide Ā· Setup Ā· Results Ā· Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 3: Slow and Steady
Morning Sloth š¦„
In plain words: you sleep late, you hate waking up to twenty notifications, and only one in four overnight emails actually matters. The sloth reads your inbox for you and shows one of three faces. You only pick up your phone when it's awake.
See it live
Real footage of the board, no editing tricks. The face is the whole interface.
MIT licensed. The README has the full setup: one docker run for Gemma, one adb push for the app, and a one-line command that saves your Gmail app password on the board without it ever showing on screen.
How I Built It
Gmail (read-only IMAP) āāāŗ python on the UNO Q's Linux side āāāŗ Gemma 4 E2B in llama.cpp, on the board
ā ā
Sent mail (who you've written to) āāāāāā needs_today / soon / fyi / noise
ā
TFI live bus feed āāāŗ bus.py countdown floors.py code rules
ā ā
āāāāāāāāāāŗ sketch on the STM32 āāāāāāāāāāāāāāā
ā
13 Ć 8 LED matrix
The UNO Q has two brains: a Qualcomm Linux computer and an STM32 microcontroller, joined by Arduino's Bridge. The Linux side does the slow work. It reads Gmail over IMAP with EXAMINE and BODY.PEEK, so it can never mark anything read or move it. It sends each new email, one at a time, to Gemma 4 E2B running in llama.cpp in a Docker container on the same board, and turns the highest level among unread emails into a face. The STM32 asks for that face over the Bridge and draws it: breathing when asleep, blinking when awake.
Choosing the model on the board, not on a laptop
I labelled 91 of my real emails by hand and ran three open models on the UNO Q itself:
| Model | Exact | Wake vs. quiet | Speed on the board |
|---|---|---|---|
| Gemma 3 270M | 7% | 13% (called all 91 urgent) | 7.6 s/email |
| Gemma 3 1B | 12% | 21% | 39 s/email |
| Gemma 4 E2B | 69% | 86% | 34 s/email |
The first surprise: Gemma 4 E2B "thinks" by default, and it spent its whole answer budget on reasoning, so every first answer came back empty. With thinking off (--reasoning-budget 0 and enable_thinking: false) it answers with one short JSON object.
Gemma judges, code guarantees
Gemma reads the sender, subject and preview, and picks a level. Then plain code applies rules Gemma can't override:
| Rule | Why I added it |
|---|---|
| A bill sender reporting a failure is always needs_today | Gemma called both of my failed PrepayPower top-ups "fyi" |
| A carrier delivering today is needs_today | Gemma called An Post's "delivering today" "fyi" |
| An event "starting in N minutes" is needs_today | Gemma called a webinar going live "noise" |
| Someone you've written to is at least soon | Gemma put a recruiter and a request for slides in "noise" |
| Google's alerts about connecting the sloth are capped at fyi | Setting up an app password sends three security alerts |
Rules can raise a level but never lower it, apart from that one setup cap. I wrote the rules after seeing the first 91 emails, so I also kept 46 held-out emails from three other days, labelled before running anything:
| Wake vs. quiet | False wakes | Needed me that day | |
|---|---|---|---|
| Design set (85 scored) | 88% | 7 | 5 of 6 caught |
| Held-out set (42 scored) | 98% | 0 | 3 of 3 wake it |
One held-out miss changed the prompt: GitHub's "Possible valid secrets detected" alert, which Gemma first called noise. One extra line about security problems with your own accounts fixed it, without turning ordinary sign-in notices into false alarms. Every number, misses included, is in eval/RESULTS.md.
The bus that's actually coming
The timetable said my bus was 24 minutes away. The live feed said the 20:24 was running 48 minutes late, so the next bus was really 12 minutes away. With a free Transport for Ireland key, the board downloads the national GTFS-Realtime feed every two minutes during bus hours. As protobuf it's about 500 KB, against 2.9 MB as JSON, so I decode it with about 70 lines of standard-library code instead of adding a protobuf library to the board. It applies delays, drops cancelled buses and adds extra ones. If the feed is down or more than 10 minutes old, the countdown falls back to the timetable and the live dot goes out.
The repo has 40 tests, run on every push. They cover the rules, the setup cap, the 9am to 1pm bus window, Irish summer time (including Sunday's clock change), the October bank holiday timetable, the protobuf decoder, and late, cancelled and extra buses.
Why Does Open Innovation Matter?
Because this is my job search, my bills and my home address. Triaging it with a cloud model would mean sending all of that to someone else's server every night. Gemma 4 E2B runs on the board's own CPU, so the mail never leaves the room. The only traffic leaving the board is the read-only connection to Gmail and, during bus hours, a download of the public bus feed.
Because a closed API can't live on a small board on my desk. Open weights and llama.cpp let me choose a model by measuring it on the actual hardware: the 270M was fast and useless, the 1B was slow and useless, and E2B was the one that worked. I could turn its thinking off, change its prompt and wrap it in rules, all on the device.
Because it costs nothing to run, ever. No tokens, no subscription, no account. The sloth will work the same in five years even if every AI company changes its pricing tomorrow.
Where a closed model would win: speed. A frontier API would rate an email in a second instead of 34. But the sloth reads while I sleep, and ten emails overnight take about six minutes. Slow and steady is fine when nobody's waiting.
My Agent Session
Four Claude Code sessions, curated into one, from "I have an UNO Q and no sensors" to the live bus feed and the films. It keeps the ideas that died along with the one that lived. Damp Sloth died when the board turned out to have no sensors, and I wouldn't fake readings. Drying Window failed the "do we even need the board?" test. Then the LED grid became a job a phone can't do.
The Lazy Payoff
I've used it since Thursday night, on my real inbox. Here's what it saves, measured honestly:
- The first glance of the day. Over three nights, about 1 in 4 of my overnight emails needed me that morning. The sloth tells me whether one of those is waiting, so on a quiet night I don't unlock the phone at all.
- The forty minutes. The email check was never the real problem; it was the door to LinkedIn, Instagram and the chats. No unlock, no door.
- The bus run. One glance at the matrix tells me when to leave, delays included. No transport app, which would be another unlock.
- What it caught. On its first night it woke up for exactly two things: a failed electricity top-up and a parcel out for delivery. Both were real and needed me that morning. Everything else let it sleep.
What I didn't expect: it's a companion. I've been working too much: hosting a fest, job hunting, posting reels at midnight. A sloth asleep on the desk is a small daily reminder that nothing needs me right now, and that going slow is allowed. It keeps me in check. Fewer unlocks mean less anxiety in the morning, more focus for the book or the gym, and a calmer head. That's the payoff I care about most, and the one I can't put a number on yet.
What it hasn't fixed yet: my sleep. A few nights is too soon to show up in the graph, and I won't pretend otherwise. So tonight the phone sleeps in the hallway and the sloth stays on the desk. I'll post next week's graph either way.
Prize Categories
- Best Use of Arduino: an open-weight model running on the UNO Q, with each half doing what it's best at: Gemma, IMAP and the live bus feed on the Qualcomm Linux side, the faces and breathing on the STM32, joined by the Bridge.
- Best Use of Gemma: Gemma 4 E2B, chosen by measuring three Gemma models on the board, with thinking turned off, a prompt fixed by a held-out miss, and code rules around it. 98% wake-vs-quiet on held-out email.
- Best Use of ElevenLabs: the story film is narrated in my own cloned voice, and ElevenLabs also made the music, the sound effects and the AI stand-in shots for the nights and mornings I couldn't film.
On AI in this post: I drafted it with Claude Code and checked every number against the repo. The raw demo is real footage, uncut. In the story film, the board footage and my sleep data are real, the night and morning scenes are faceless AI stand-ins (ElevenLabs), and the voice is mine, cloned with ElevenLabs. The 3D opener is the board modelled in code (three.js), with the faces drawn from the sketch's own pixel maps.






