3 Seeti:手機替你計算壓力煲鳴笛次數
My phone counts the cooker's whistles so I don't have to
3 Seeti 用手機上的開放音訊模型 YAMNet 偵測壓力煲鳴笛,逐次語音報數,並在最後一次鳴笛後提醒關火。YAMNet 在瀏覽器本機運行,音訊不會錄製或上傳;首次載入後,應用程式可離線使用。19 種日常菜式由應用程式內的資料表提供答案,其他菜式則交由 Groq 免費方案上的開放權重模型 GPT-OSS 20B 處理,這項功能需要連線。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
In an Indian kitchen, recipes aren't measured in minutes. They're measured in whistles. Toor dal is three seeti, rajma is six, rice is two. The pressure cooker goes pssshhhht every few minutes, and someone has to stand near the stove and count.
Or not stand there, get distracted, lose count, and come back to the smell of dal stuck to the bottom of the cooker.
3 Seeti does the counting. Tell it what's in the cooker, put the phone on the counter, and walk away. An open audio model listens on the phone and says each whistle out loud: "Pehli seeti. Do aur." On the last one: "Teesri seeti. Gas band kar do!", with an alarm that keeps going until you tap it. If the dish needs time on a low flame after the whistles, like rajma's ten minutes, the timer takes over from there.
It's the laziest thing I could think of that actually helps: the job is literally "stand there and count to three".
Demo
Try it: three-seeti.onrender.com (free plan, so the first load after a quiet spell takes about half a minute)
Allow the microphone, put the phone near the cooker, and leave. No cooker nearby? Tap "Try a recorded kitchen". It plays three and a half minutes of a kitchen with talking, frying, a TV, a kettle, a mixer and exactly three whistles, and the app counts along. The GIF above is the fast version of that.
Code
3 Seeti
Put the phone on the counter and walk away. 3 Seeti counts the pressure cooker's whistles for you and says "Teesri seeti. Gas band kar do!" when the dal is done.
In an Indian kitchen, the recipe isn't in minutes, it's in whistles: dal is 3, rajma is 6, rice is 2. So someone stands near the stove counting, or wanders off, loses count, and comes back to burnt dal. Here the counting is done by YAMNet, an open audio model from Google, running in the browser on the phone. No sound is recorded or sent anywhere, and after the first visit it works with no internet.
How it works
- Say what's cooking. Tap a dish (dal, rajma, chole, rice, aloo, khichdi) or type anything: "rajma, forgot to soak it", "aadha kilo mutton", "kathal ki sabzi". Nineteen everyday dishes are answered from a table in the app, no…
How I Built It
Next.js 16 and TypeScript. The ears are YAMNet, Google's open audio classification model, running in the browser through MediaPipe. It's 4 MB and knows 521 kinds of sound. Every quarter second it scores the last second of audio from the mic.
A whistle isn't a "Whistle"
YAMNet has a label called Whistle, so I assumed I'd just watch that. Before writing any app, I ran the model over 20 real recordings from freesound.org (all CC0): pressure cookers, plus everything else that happens in a kitchen.
| Recording | Steam / Hiss | Whistle |
|---|---|---|
| Indian cooker, whistle bursts | 0.89 | 0.20 |
| Other pressure cookers | 0.20–0.94 | up to 0.08 |
| Whistling kettles | 0.74–0.92 | 0.80–0.98 |
| Talking, TV, mixer, gas stove, kitchen background | 0.00–0.02 | 0.00 |
| Frying | 0.04–0.08 | 0.01–0.02 |
To the model, a cooker's whistle is steam. Whistle goes to tonal sounds, and the most tonal thing in a kitchen is the kettle. So the rule became: a burst of steam is a whistle, and a burst of tone is a kettle that must never count.
The kettle that steams first
That rule failed straight away on the second kettle recording. It hisses for three and a half seconds before it starts to whistle. My first version counted the moment it heard half a second of steam, so it counted the kettle.
The fix was to be a little slow and steady about it. A burst only counts once it has ended and five more seconds have passed with no tone, or straight away if it's long. "Teesri seeti" now arrives a few seconds after the whistle instead of during it. That's fine for dal, and the kettle is ignored.
Half a whistle
Another early miss: a short 1.3-second whistle scored only 0.26, below the threshold. MediaPipe's classifier works on back-to-back one-second windows, and this whistle fell across the join, half in each. Classifying a sliding one-second window every quarter second fixed it: the same whistle now scores 0.33 to 0.41 across four windows.
Testing it without a cooker
The counter (lib/counter.ts) is plain code with no model inside. I saved YAMNet's real output for all 20 recordings as test fixtures, so the unit tests check the counter on what the model actually hears:
- three whistles in the demo kitchen, at 62, 118 and 176 seconds
- zero in talking, TV, mixer, frying and both kettles
- a warning, instead of a count, for the Western cookers whose valve hisses non-stop
On top of that, the browser tests start real Chrome, load the real model, and run the recorded kitchen through the whole app. They check the count, the kettle and the alarm, the low-flame timer, and "+1" and "−1". Then they do it all again with the network switched off. GitHub Actions runs everything on every push.
The part that needs a model to think
Nineteen everyday dishes (dal, rajma, chole, rice, aloo, khichdi and so on) are answered from a table, with no internet needed. Anything else goes to GPT-OSS 20B, an open-weight model on Groq's free tier: "rajma, forgot to soak it" gets 8 whistles and "soak next time to save gas". Its answer has to be between 1 and 12 whistles or it's thrown out. Every number can be changed with a tap.
At first it lectured me about soaking instead of answering, and said jackfruit sabzi isn't made in a pressure cooker (it very much is). Two lines in the prompt fixed both.
Why Does Open Innovation Matter?
The kitchen stays private. The model runs on the phone. There's no audio upload, no account, and nothing recorded. That matters a lot for a microphone left on in someone's home for twenty minutes.
It works with no internet. The model, its runtime and the app are kept on the phone by a service worker after the first visit. The browser tests switch the network off and count the whistles again. Only asking about an unusual dish needs a connection.
It costs nothing to run, forever. A cloud speech or audio API charges per minute of audio, and a cooker is twenty minutes, twice a day. Here the listening is free, and the one call to an LLM can be pointed at Ollama on a laptop instead of Groq by changing one setting.
I could look inside it. Because YAMNet is open, I could run it over my own test recordings and see its scores before building anything. That's how I found out a cooker's whistle is "steam" to it, which the whole app is built on.
Prize Categories
-
Best Use of Render: the app runs on Render's free tier from a Blueprint (
render.yaml), set to deploy only commits that pass CI. - Best Use of GitHub Copilot, for the GitHub Actions part: every push runs lint, typecheck, the unit tests on real model output, and the real-Chrome tests (online and offline), and gates the Render deploy.
So far it's been tested on recordings of real cookers. A real kitchen, with an exhaust fan and a cooker that has its own personality, is the next test.
來源:DEV Community · dev.to

