DEV Community

pulkitgovrani
pulkitgovrani Subscriber

Posted on

FrostLine: A Garden Planner Powered by a Local Open-Source LLM

What I Built

FrostLine tells you what to do in the garden this week. You type your town. It pulls 15 years of nightly lows, works out your median and 1-in-10 "safe" last spring frost and first fall frost, and lists what to sow, start indoors or transplant right now, plus tonight's frost risk.

A local LLM then turns the plan into a short field note that always ends the same way: put the phone down and go outside.

It is for anyone with a patch of soil, a balcony or an allotment who is tired of generic "plant in spring" advice. It also works in places that never freeze: I tested Pune and Sydney, where it switches to the local cool/warm cycle instead of frost dates.

Demo

Live: frostline-h8z9.onrender.com. It runs on Render's free tier, so the first load can take about 50 seconds to wake up. The hosted version has no Ollama, so its field note comes from a template; the local LLM version is the one in the video.

Code

GitHub logo pulkitgovrani / frostline

Garden jobs from your town's frost history, narrated by a local open-weight LLM

FrostLine

Live demo: https://frostline-h8z9.onrender.com (free tier, first load may take ~50s; no local LLM there, so the note is templated)

This week's garden jobs, computed from your own town's frost history, with a local open-weight LLM writing the field note Weather history is fetched once (Open-Meteo, no key) and cached in data/, so afterwards it works without signal.

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
ollama pull gemma4:e4b            # any Ollama model works: FROSTLINE_MODEL=llama3.2 ...
.venv/bin/python -m frostline.cli "Minneapolis"          # CLI
.venv/bin/python -m frostline 8765                       # web UI on http://localhost:8765
.venv/bin/python -m pytest -q
Enter fullscreen mode Exit fullscreen mode

How it works

  • climate.py: 15 years of daily minimum temperature -> median and 1-in-10 safe last-spring / first-fall frost dates (hemisphere-aware).
  • planner.py: transparent rules for ~17 crops anchored on those dates. Tender crops wait for the safe date. Frost-free climates use the local cool/warm cycle instead.
  • model.py: tonight's…

How I Built It

  • Open-weight LLM, running locally: Gemma (gemma4:e4b) through Ollama. The LLM only narrates. Planting dates come from code, because small models invent dates. I caught mine inventing chores (compost, gloves) when the plan was empty, so empty weeks now skip the LLM and use a template.
  • Rules, not vibes: planner.py anchors about 17 crops on the frost dates. Tender crops wait for the 1-in-10 safe date; hardy ones use the median.
  • Frost model: a gradient-boosting classifier predicts tonight's frost from day of year, latitude and recent lows. On two held-out years it scored a Brier of 0.054 against 0.068 for a plain day-of-year baseline (Minneapolis), so it does beat climatology. If you set a TABPFN_TOKEN, it can use TabPFN instead; I have not run that path.
  • Data: Open-Meteo history is fetched once and cached on disk, so after the first run for a town it works with no signal.
  • Stack: plain Python, pandas, scikit-learn and the standard-library HTTP server, with a single static page for the UI. Tests cover the planner and the frost model.

Why Does Open Innovation Matter?

  • It works where gardens are: the garden has no wifi. The weights and the cached data live on the device, which a closed API cannot offer.
  • Your location stays yours: your town and your garden never reach a server I don't control.
  • Swappable: FROSTLINE_MODEL=llama3.2 changes the narrator with no code change, and the frost model can swap sklearn for TabPFN.
  • Free to run: no API bill for a weekend hobby.

Prize Categories

  • Best Use of Render: the web UI is hosted on Render as a free web service, deployed from a render.yaml Blueprint in the repo.

Top comments (0)