DEV Community

Manan Sharma
Manan Sharma

Posted on AI-assisted

Grass Forecast - Turning Bike-Share and Weather Data into a Reason to Touch Grass

What I Built

Grass Forecast helps people find a reason to step outside—even when the latest activity data is delayed.

The project uses public Chicago Divvy bike-share data and weather information to forecast outdoor activity. When activity data is fresh, it predicts whether tomorrow is likely to be a high-activity day and identifies a likely busy time window. When Divvy’s published data is stale, it switches to a separate ride-count estimate, labels it clearly as an estimate, and shows how old the source data is. If an activity estimate isn’t available, the dashboard can still suggest an outing based on the weather.

The idea is to make the forecast useful without pretending an estimate is an observation. Grass Forecast also generates a short, weather-aware nudge to make going outside feel more approachable.

Demo

Video Demo:

Code

Grass Forecast

Grass Forecast is a tiny outdoor-day forecaster built for the Touch Grass challenge. It learns from public outdoor activity data and historical weather to estimate whether tomorrow will be a high-activity day, which window is likely busiest, and then writes a short spoken nudge.

What this does

  • Pulls Chicago Divvy bike-share activity data from the public Divvy bucket
  • Fetches historical daily weather for the training period and tomorrow's forecast from Open-Meteo for Chicago
  • Builds a daily feature table with leakage-safe history and weather features
  • Evaluates with expanding, time-ordered walk-forward folds and compares against three baselines
  • Uses TabPFN when its token is configured and available; otherwise labels the scikit-learn fallback explicitly
  • Generates a short, conversational nudge with Gemma through the Gemini API or a local fallback message, including a weather-aware estimate-based nudge when activity data is stale
  • Converts fresh-data and stale-estimate nudges to short audio files with ElevenLabs when…

How I Built It

Grass Forecast has a Python and FastAPI backend with a React dashboard. It collects public Divvy trip data and weather data from Open-Meteo, then prepares daily and hourly activity features for forecasting.

The project uses two distinct approaches rather than treating missing recent data as if it were current:

  • With fresh activity data, it uses a high-activity classifier and estimates the busiest window.
  • With stale data, it uses a separate ride-count estimator for targets up to 30 days beyond the latest observation. The dashboard shows the activity-through date, data age, forecast lead, and estimated count.

The stale estimate is directional, not measured activity. Its displayed model range is not a calibrated prediction interval, and the historical weather evaluation uses observed weather rather than archived day-ahead forecasts—so those results may be optimistic.

For AI, I use the open-weight Gemma 3 4B model through the Gemini API to generate a concise, conversational nudge. The project also supports TabPFN for classification when configured, with a clearly labeled scikit-learn fallback.

Why Does Open Innovation Matter?

This project depends on being able to combine and inspect tools from different parts of the ecosystem: public activity data, open weather data, open-weight models, and open-source application frameworks.

That flexibility helped me build a system that can adapt when one source is delayed. Instead of hiding the gap or returning nothing, Grass Forecast can switch to a clearly labeled estimate or offer a weather-based idea. Open tools also make it easier to see where the data comes from, what is processed locally, and where hosted AI services are involved. That transparency matters when a forecast could otherwise look more certain than it really is.

Prize Categories

Best Use of TabPFN
Best Use of GitHub Copilotx
Best Use of ElevenLabs
Best Use of Gemma

Published by -

Top comments (0)