Inspiration

Printed expiration dates assume food stayed cold its whole life. They can't know about the warm car ride home, a fridge door left open, or a fridge that runs a few degrees warm. Spoilage speed depends heavily on temperature, so two identical packs with the same date can have very different real lives. People guess: they throw out food that was fine, or keep food too long. We wanted an estimate based on what actually happened to the food.

What it does

Claudius Maximus tracks every item in your fridge and tells you how many days it has left.

  • A BME688 sensor in the fridge measures temperature, humidity and gas and uploads readings every 20 seconds.
  • Each item accumulates "effective age" from that temperature record. Time spent warm burns more life, using a Q10 model relative to 4 C.
  • A gas-anomaly score and a color-label score can only shorten an estimate or veto it to zero. They can never make food look fresher than the temperature record supports.
  • Scan a food label with your phone and a local vision model fills in the product, dates and size. You review and edit before anything is saved.
  • A voice-capable assistant answers questions and manages items, but it can only act through validated tools and never produces freshness numbers itself.
  • The app shows a fridge dashboard, per-item details, alerts, and Celsius/Fahrenheit and dark-mode settings.

It is a waste-reduction aid, not a food-safety device.

How we built it

  • Engine (Python): pure functions for three tracks: temperature (Q10 budget), gas baseline with temperature/humidity conditioning, and color label. A fusion step combines them, with a confidence value and a status (fresh, check_early, past_budget_quiet, discard_quality_signal).
  • Profiles: shelf-life baselines for five food categories from USDA FSIS cold-storage guidance, with a Q10 of 2.7 fitted by log-linear regression (R^2 = 0.9997) to published chicken shelf-life data.
  • Backend: FastAPI. Every telemetry source (HTTP, ThingSpeak poller, simulator, CSV replay) goes through one ingest path, and alerts are rebuilt from scratch on every change. Optional SQLite persistence.
  • Hardware: an ESP32 running Bosch BSEC2 with a BME688, uploading to ThingSpeak, in a 3D-printed enclosure.
  • AI: Ollama with Qwen, running locally, for label scanning and the assistant. No data leaves the home network.
  • Mobile: Expo SDK 57 / React Native app, built as a standalone iOS release.

Challenges we ran into

  • Sensors that don't transfer. Our available spoilage dataset used MQ-series gas sensors, not a BME688, so absolute gas values don't carry over. We ended up making gas experimental and gave it no influence on estimates by default.
  • Firmware and deep sleep. BSEC needs a monotonic timestamp, but the ESP32's millis() restarts at zero on every deep-sleep wake, so the sketch had to keep time itself.
  • iOS builds. Parallel code signing failed on our machine with errSecInternalComponent and produced apps that built but wouldn't install. We wrote a build script that signs serially and verifies every framework.
  • Label photos. Rotated and HEIC photos broke OCR, so we added EXIF handling and a rotation probe that only rotates when it clearly beats upright.
  • Keeping an LLM honest. We restricted the assistant to validated tools so it can't invent freshness numbers.

Accomplishments that we're proud of

  • A working end-to-end system: sensor to ThingSpeak to API to phone, with per-item days left, alerts and a confidence level.
  • A safety-minded design that is tested: extra signals can only shorten an estimate, never extend it.
  • Estimates that fail visibly (disconnected, unavailable, withheld) rather than confidently wrong.
  • Fully local AI for scanning and the assistant.
  • Clear documentation of what is and isn't validated, including the placeholder profiles and the missing calibration.
  • Using deep sleep mode, the current firmware build can save up to 85% of battery life comparing to running normally.

What we learned

  • Where a model's inputs come from matters as much as the model. The chicken data behind our Q10 is the most important number in the system, so its provenance has to be recorded.
  • Cheap gas sensors need per-device calibration; you can't borrow another sensor's numbers.
  • Constraining an LLM to validated tools is what makes it safe to put next to numbers people rely on.
  • Hardware needs calibration knobs and real-world handling for drift, stale data and sleep cycles.
  • Saying "this is not validated" in the README and the app is part of building responsibly.

What's next for Claudius Maximus

  • Run a real spoilage experiment on our own BME688 hardware to calibrate the gas track.
  • Add a door sensor, so door-open events are detected instead of assumed closed.
  • Multi-fridge and multi-household support with authentication and durable storage.
  • Automated mobile UI tests and an Android release build.

Built With

Share this project:

Updates

Submission history