← Home

ESP32 · camera · MCP server

Stove Watch

A sensor on the side of the fridge that notices when a burner is left on with nobody around, pushes a photo to my phone, and gives Claude a way to check on it.

Hardware
ESP32, OV2640 camera, PIR motion sensor, buzzer
Firmware
C++ on PlatformIO
Server
Bun and TypeScript, SQLite
Status
Mounted and running. Source is private.

The stove says when it is on: its control panel lights a red COOKTOP ON indicator at any burner setting. A camera watches that light, a motion sensor says whether anyone is in the kitchen, and a small state machine turns the two into an alarm.

Four states in order. Cold: light off. Cooking: light on and someone moving. Unattended: no motion for 10 minutes, a push with a photo. Alarm: no motion for 20 minutes, a push every 5 minutes and the buzzer. COLDlight offphoto every 30 minCOOKINGlight on, someone movingphoto every 5 minUNATTENDEDno motion for 10 minpush with a photoALARMno motion for 20 minpush every 5 min, buzzer
Any motion while the light is on drops it back to cooking.

The alarm lives on the board

The ESP32 owns the decision. It needs no network, no computer and no Claude to conclude that the stove is unattended, and it joins Wi-Fi for at most 15 seconds at boot before carrying on without it. A watchdog reboots the board if its main loop ever hangs, because a frozen alarm is worse than a restart. The home computer only stores history, and Claude is a second layer that checks, explains and adjusts.

Reading one small light with a microcontroller

The camera hands out JPEG frames, and decoding a whole 1600 by 1200 frame into RGB would take about 5.8 MB, which the board cannot spare. So the firmware uses the decoder in the ESP32's ROM, which hands out one small block of pixels at a time. It counts only the pixels inside a small region around the indicator and stops decoding once the blocks are past it.

A pixel counts as red when its red channel is high and clearly beats green and blue. The blown-out white centre of a lit light does not count, but its red halo does, so the thresholds are modest, with a gap between them so a flickering reading cannot flap the alarm.

Share of red pixels in the region. Under 4 percent reads as off, 10 percent or more reads as on, and in between the board keeps its last answer. offkeeps its last answeron0%4%10%red pixels in the region

Logic that can be tested without a stove

The state machine and the red-light math are plain C++ with no board code in them. They never touch a pin or the network, so the tests run on a PC with a fake clock and play out a whole evening, a pot left on low at 6 PM, in milliseconds. The server side has a fake ESP32 for the same reason.

The state machine only ever sees on, off or in between, so a different detector, a thermal camera or a current clamp, could feed it later without touching the alarm rules.

A second opinion

A motion sensor misses someone standing still at the counter. Before a text goes out, the collector takes the board's photo and asks a vision model two questions: is a person in view, and is a pot on a burner. If it is confident someone is there, the alert says so.

The same model guards against a bumped camera. Once an hour it finds the control panel in the photo and uses the lit clock digits as an anchor, so if the camera has moved, the region the board watches moves with it.

What Claude does with it

Through an MCP server, Claude can read the current state, look at a photo when the reading leaves doubt, go back through a week of history, and tune the thresholds after the camera is remounted. Silencing the alarm is something it only does when asked, and it repeats back for how long.

← All projects