跳到正文
DEV Community· Matias Silveira·· 4 小時前AI 評分35

Drowzy:毋須再伸手關掉鬧鐘

Drowzy: no need to cancel the wake up alarm anymore

AI 導讀

Drowzy 是一款可用語音控制的鬧鐘,用戶可要求延後響鬧或關閉鬧鐘,毋須伸手拿手機。它以 whisper.cpp 和透過 Ollama 執行的開放權重 LLM 在本機處理語音,毋須連接網絡;鬧鐘響 5 秒後錄音 4 秒,並在語意不清時繼續響鬧。作者以合成西班牙語語音測試完整流程,尚未驗證實際麥克風及 Android/Termux。

正文

Matias Silveira

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

Drowzy is an alarm clock you can argue with from under the blanket. When it rings, you don't reach for your phone: you just say "cinco minutitos más" (or "snooze for ten", or "ya estoy despierto, apágala") and it does the right thing. It rings for 5 seconds, goes quiet, listens for 4, understands you, and then snoozes for the time you asked or turns off.

It's for anyone whose worst daily movement is the arm stretch to the nightstand. It's built around the one thing a lazy person actually wants: that being awake is optional until they decide otherwise, and that the alarm can't be fooled into shutting up for good.

Safety guards, because a lazy alarm that makes you late is worse than none:

  • It never dismisses by itself. Silence, mumbling or an unclear sentence keeps it ringing.
  • After 3 snoozes, the first "turn it off" only buys 2 more minutes; the next one works.
  • If the language model is unreachable, a keyword fallback takes over.
  • It gives up (and stays quiet) after 30 minutes instead of pretending you woke up.

Demo

Code

Drowzy

An alarm you snooze or dismiss by talking, without moving. Fully local: whisper.cpp for speech-to-text and an open-weight LLM through Ollama to understand what you mean. Nothing leaves the device, and it works in airplane mode.

alarm rings 5 s -> silence -> records 4 s -> whisper.cpp -> Ollama (JSON) -> snooze N min | dismiss | keep ringing

Say "cinco minutitos más" and it snoozes 5 minutes. Say "ya estoy despierto, apágala" and it stops. Mumbling or noise keeps it ringing.

Safety guards (so it can't make you late)

  • It never dismisses by itself: empty audio, noise or an unclear phrase keeps the alarm ringing.
  • After max_snoozes (default 3) the first "dismiss" only buys a short forced_snooze_minutes, and long snoozes are capped. The next "dismiss" works.
  • If Ollama is down or too slow, a keyword fallback takes over.
  • It gives up after max_ring_minutes and returns…

How I Built It

alarm rings 5 s -> silence -> record 4 s -> whisper.cpp -> Ollama (JSON) -> snooze N min | dismiss | keep ringing
  • Speech-to-text: whisper.cpp with the multilingual ggml-base model, called as a subprocess. Roughly 2 s per phrase on my laptop's CPU.
  • Understanding: an open-weight model served by Ollama (qwen3:4b-instruct on my PC; qwen2.5:1.5b is the default for phones). The prompt asks for strict JSON using Ollama's structured output (format=<JSON schema>, temperature 0) with a few Spanish and English examples: {"action": "snooze|dismiss|ignore", "minutes": 5, "reply": "..."}. When in doubt, the model is told to pick ignore.
  • Glue: Python with Typer, Pydantic and sounddevice. On Android it runs in Termux through Termux:API for audio, with scripts/setup_termux.sh doing the setup.
  • Why it rings and listens in turns: if it recorded while ringing, the microphone would just hear the alarm. Alternating sound and silence avoids needing echo cancellation.
  • Cold start: the first LLM call after boot took 37–47 s on CPU. So Drowzy preloads the model 3 minutes before the alarm and keeps it loaded (keep_alive).

The core is covered by 25 unit tests (intent parsing, the ring loop's guards, scheduling) and 11 integration tests that hit a real Ollama model with no fallback allowed.

What I verified, and what I didn't

  • Verified: the full chain with real sound output, real whisper.cpp and a real Ollama model, using synthetic Spanish voice clips fed in place of the microphone: "cinco minutitos más" → 5-minute snooze, "ya estoy despierto, apágala" → dismissed, and the same phrase after 3 snoozes → a forced 2-minute snooze.
  • Not verified yet: my laptop's microphone only recorded silence in my test, so I haven't yet shouted a phrase into it. And I haven't run the Android/Termux path on a phone.
  • Latency is not great yet: about 2 s of Whisper plus about 6 s of LLM once the model is warm (4B parameters on CPU). A smaller model should cut that, but I haven't measured it.

Why Does Open Innovation Matter?

  • It works in airplane mode. You can put the phone in airplane mode overnight and the alarm still understands you.
  • Your bedroom audio stays on your device. An always-listening alarm that streams your voice to a cloud API is not something I'd want next to my bed. Here, audio goes from the microphone to whisper.cpp and nowhere else.
  • No per-snooze bill. I can say "five more minutes" as many times as I like without paying per call.
  • I can swap and tune the model. Changing the model is a one-line config edit, and the prompt and examples are mine to adjust to my own way of mumbling.

來源:DEV Community · dev.to