DEV Community

Yuvan Shankar M
Yuvan Shankar M

Posted on

Touch Grass Garden: a plant tracker that only counts the days you went outside

What I Built

Most apps want you to open them every day. I wanted to build one that doesn't care whether you open it at all.

Touch Grass Garden is a plant tracker for beginners. You enter your location and what you sowed, and it works out the season and suggests what to plant this month. Every day it writes a short card with the best time to go out, any weather warnings, and one thing to look for at each plant. After that you close the laptop and go and look at the real plant.

The streak is the part I care about most. It only counts days when you log a check-in at your plants, and opening the app earns nothing. The weekly goal, the badges and the 12-week heatmap all use the same rule, so the only way to make progress is to go outside.

Here's everything it does:

  • It reads your coordinates and the date to find the season (kharif, rabi or zaid in India, four seasons elsewhere), then lists what's good to sow this month with the growing method and what each crop needs (sun, water, soil).
  • Each plant gets stages like sown, germinated, flowering and harvest, with expected dates worked out from the sowing date.
  • Every day Gemma writes a short outdoor card: the best time to go out, weather alerts, and one thing to look for at each plant.
  • For check-ins you pick the stage you actually see, add a note, tick if you watered, and attach a photo. Each plant has a timeline with a chart and the photos.
  • Watering reminders are based on how often each crop needs water, with a warning when heavy rain is forecast.
  • The streak, a weekly target (4 days by default), badges and a 12-week calendar heatmap all come from real check-ins only.
  • The garden recap shows days outside, longest streak and totals for each plant, with a download button.
  • The printable card is a plain-text card with tick boxes and "what I saw" lines, so you can take it outside without a screen.
  • Each crop has two "if you see this" tips for common problems and what to do about each.
  • Anyone can drop a JSON file into a folder to add or change crops for their own region (I call these crop packs).
  • Deleting a plant or a check-in asks for confirmation first.
  • I also added two experimental extras. The card can be written in a few other languages (Hindi, Tamil and others), and the local model can describe a check-in photo. I haven't tested either properly, so I don't know how good the output is. The photo description is labelled as an unverified AI description in the app.
  • Weather alerts use each crop's own temperature limits, so a cold night warns about the plants it would actually hurt. Plants of the same crop are grouped into one alert, and the heat threshold is stricter so it doesn't warn all the time.
  • Saved photos are resized to 1600 px at most and stripped of EXIF location data, and the log is saved atomically so a crash can't corrupt it.

I Took It Outside

It was a good morning for it, and I could hear birds the whole time. I had planted a tomato and a chilli next to my hibiscus plant, so I took the card out there.

This is what it said:

  • Look for moist, not waterlogged soil around the Tomato plants.
  • Examine the timmy for moist, not waterlogged soil.
  • Observe the soil conditions for both plants during the best time.
  • Put the phone away and truly look at your plants.

The soil was moist because it had rained the day before, but it wasn't waterlogged. The ground had soaked up the extra water. The card got the one useful thing right, which was to check soil moisture. It had no idea it had rained, so that was partly luck. The rest wasn't great: three of the four bullets say almost the same thing, and "Examine the timmy"(The card calls my chilli "timmy" because that's the nickname I gave it.) is just clumsy. A 4B model does that. With wifi off, the first card took about 30 seconds because the model had to load. After that, each card took about 6 seconds, online or offline.

Demo

The app runs on my laptop, so there's no live link. Here's a walkthrough:

Where I planted

My hibiscus plant

Code

GitHub logo yuvanshankarm007 / touch-grass-garden

A plant tracker that rewards you for going outside, not for opening the app. Local AI (Gemma via Ollama), works offline.

Touch Grass Garden (v3.0)

A plant milestone tracker that rewards you for going outside, not for opening the app.

  • Detects the local season from your coordinates and the date
  • Suggests what to sow this month, with the growing method and requirements for each crop
  • Tracks each plant through growth milestones (sown -> germinated -> ... -> harvest)
  • Builds a short "today's outdoor card" with a local open-weight model (Gemma via Ollama)
  • Weather alerts and a best-time-outside window (rule-based, forecast cached for offline use)
  • The streak counts days you logged a check-in at your plants - opening the app earns nothing
  • Weekly outdoor goal (default 4 days) with a progress bar - only real check-ins count
  • Photo log: attach a photo to each outdoor check-in and see it in the plant's timeline
  • Growth timeline: chart and history of every check-in per plant
  • Care reminders: watering due dates from crops.json…

To run it, install Ollama, run ollama pull gemma3:4b, then pip install -r requirements.txt and streamlit run app.py.

How I Built It

I used Gemma 3 (4B) through Ollama, so everything runs on my own laptop. The app is Python and Streamlit. The logic lives in one file and the UI in another, and plants and check-ins are stored in a plain JSON file.

A few choices I made:

  • All the crop info lives in one crops.json file, and the model is only allowed to use what I hand it. I didn't want a small model inventing planting advice.
  • The season comes from a simple lookup on location and date, with the Indian calendar (kharif, rabi, zaid) inside India and four seasons elsewhere.
  • The forecast comes from Open-Meteo and gets saved to a file, so the app still has the last forecast when it's offline and shows how old it is. The alerts and the "best time outside" window are plain rules. The window is the longest stretch of daylight hours that are cool enough, dry enough and not too windy. The model never decides an alert, it only words things.
  • For the prompt, I told the model to output only the card, use each plant's exact name, combine advice that repeats across plants, keep it under about 70 words, never mention watering unless it's due, and end by telling you to put the phone away.
  • If Ollama isn't running, the app shows a rule-based card instead, so it never breaks in the garden.
  • Unit tests cover seasons, streaks, the weekly goal, alerts, watering, the timeline, crop packs and the fallback card. There's also a smoke test that loads the whole app without opening a browser. GitHub Actions runs all of it on every push, on Python 3.11 and 3.12, with a Ruff lint check and a check that every crop pack loads.

The first version of the card told me to water a plant that wasn't due for two days. I had passed in "next watering in about 2 days" and the model took it as an instruction. With two plants it also repeated the same bullet. I fixed it by only sending watering info when it's actually due, and by telling the model not to repeat itself. Even then it looked broken for a while, because my Generate button was showing a cached card. The card is still a bit repetitive, as you can see above, but the bigger lesson was that a small model does better with less context and stricter rules.

I built most of the app with Claude and used GitHub's Copilot coding agent for some follow-up features. The voiceover in the demo is from ElevenLabs.

Why Does Open Innovation Matter?

A planting guide is most useful in a garden or on a farm, and those are the places with the worst signal. An app that needs a connection to work is a bad fit.

Running Gemma locally fixes that. The advice, the milestones and the daily card all work on the laptop. Only the forecast needs internet, and the last one is saved, so it's mostly offline rather than fully offline.

A few other things it made possible:

  • Your location and plant notes never leave your device. With a hosted API, all of it would go to a server I don't control.
  • Nothing is charged per request, which matters for something meant for people growing food on a budget.
  • I can swap in a smaller model on a weaker machine, and I can change how it behaves just by editing the prompt.
  • Crop packs are just JSON files, so someone who actually grows things in their region can fix my data without touching any code. I'd want that, because my crop data is a starter set and no expert has checked it. The README tells people to confirm it locally.

The limits: a 4B model makes mistakes, which is why alerts are rules and not model output. I've also only tested the app for two days, so I can't show real growth over time yet.

My Agent Session

I didn't record a DevRelay session. The Copilot agent's work is public on GitHub, so here are the issues and pull requests it worked on:

  • Issues: #1, #3, #5, #7, #9, #11
  • Pull requests: #2, #4, #6, #8, #10, #12

Prize Categories

  • Best Use of Gemma: the daily card is written by gemma3:4b running locally through Ollama.
  • Best Use of GitHub Copilot: I wrote .github/copilot-instructions.md with the project's rules (logic in garden.py with no UI code, alerts are rules and never the model, crop facts only from crops.json, a test for every change). Then I gave the coding agent six real issues and reviewed every pull request before merging. It built the crop-specific temperature alerts (#2), atomic saves and privacy-safe photos (#4), plant and check-in deletion (#6), quieter weather alerts (#8), the calendar heatmap (#10) and a stronger CI workflow (#12). All six are merged. CI runs on GitHub Actions on every push. On #8 I left review feedback, but the agent ran out of monthly credits before it could act on it, so I merged it as it was.
  • Best Use of ElevenLabs: the narration in my demo video was generated with ElevenLabs text-to-speech using the Eleven v4 model and the "Dev Shah - Smooth and Engaging" voice. Here's the script and the generation I used:

I'm a solo participant.

Top comments (0)