DEV Community

Cover image for Ventana seca: finding the dry hour to get outside in Panama's rainy season, with Gemma on my laptop
Arnulfo
Arnulfo

Posted on

Ventana seca: finding the dry hour to get outside in Panama's rainy season, with Gemma on my laptop

Hacktoberfest: Maintainer Spotlight

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass

What I Built

October is the heart of the rainy season in Panama City. Most afternoons, the sky opens up somewhere between 1 and 5 p.m. A weather app gives me a percentage for every hour and leaves the decision to me, so I end up checking the screen over and over, or I just stay inside.

Ventana seca ("dry window") answers one question: when today can I be outside without getting soaked or cooked?

I don't have a free weekday morning for a trail. My chance to be outside is my daily route: on foot near Plaza 5 de Mayo at 7:30 a.m., arriving in Costa del Este at 8:00, lunch at noon, heading out at 4:00. So the main mode takes that route, checks the forecast for each stop, and tells me which stop is worth spending time outdoors, plus what to carry for the whole day. On weekends, a second mode looks for the best window at a park like the Parque Natural Metropolitano or the Cinta Costera.

You run one command in the morning, read one card, and optionally save a calendar event that alerts you 30 minutes before. Then the phone goes back in your pocket. The screen should be the shortest part of the experience.

Demo

This is my real route for Tuesday, October 6, with the real forecast and Gemma choosing on my laptop:

Ventana seca route card: Plaza 5 de Mayo at 7:30 a.m., Costa del Este at 8:00 a.m., 12:00 p.m. and 4:00 p.m.; Gemma picks 8:00 a.m.

The 7:30 and 8:00 stops look dry (20% and 18%). Noon brings a 66% chance of rain with a 39 °C heat index, and 4:00 p.m. is at 88%. Gemma picks 8:00 a.m. in Costa del Este, and the raincoat goes on the list from the morning because of the afternoon.

Here is the same route when I write, in my own words, that I want to walk during lunch:

Same route with a lunch preference: Gemma picks 12:00 p.m. and warns about rain and heat; the code adds an

Gemma respects the time I asked for and warns me about the rain and heat. The red Ojo ("heads up") line is not written by the model. The code adds it whenever the chosen window scores poorly. I'll explain why below.

Watch the 31-second demo video. It has no narration and shows the command and the resulting card for three scenes. The interface is in Spanish, because the people I built it for speak Spanish.

Code

GitHub logo yosef7 / ventana-seca

Find the rain-free window to go outside in Panama City, chosen by Gemma running locally. DEV Hacktoberfest 2026 · Week 1: Touch Grass

Ventana seca

En octubre llueve en Ciudad de Panamá casi todas las tardes. Ventana seca mira el pronóstico por hora de los próximos días, calcula los tramos de luz con menos lluvia, calor y sol fuerte para salir a caminar o correr, y deja que Gemma, un modelo de pesos abiertos que corre en tu propio equipo con Ollama, escoja uno según lo que tú le pidas. El resultado es una tarjeta de un vistazo y un recordatorio en el calendario que avisa media hora antes, para que guardes el teléfono y salgas.

In English. Ventana seca ("dry window") finds the best rain-free window to go outside in Panama City during the rainy season. It scores hourly forecasts from Open-Meteo, lets Google's open-weight Gemma model, running locally through Ollama, pick one of those windows based on what you ask for in plain words, and writes a one-glance card plus…

MIT license, Python standard library only (plus pytest for the 25 tests). Setup:

git clone https://github.com/yosef7/ventana-seca.git
cd ventana-seca
uv sync
ollama pull gemma4:e2b
uv run python -m ventana_seca --ruta "7:30 5 de mayo, 8:00 costa del este, 12 pm costa del este, 4 pm costa del este"
Enter fullscreen mode Exit fullscreen mode

The route is saved, so the next mornings it's just uv run python -m ventana_seca --mi-ruta.

How I Built It

The split: code calculates, the model interprets. Numbers are where a small model is most likely to slip, so the code handles all of them:

  1. Forecast. Ventana seca asks Open-Meteo for hourly rain probability, millimeters, heat index, UV and daylight. It asks for the coordinates of the place (a park, a plaza), never mine, and keeps a local copy so it still works without signal.
  2. Scoring, no AI. Each window starts at 100 points and loses points for rain probability, expected millimeters, heat index above 32 °C and UV above 7. The code keeps up to five daylight windows, at most two per day and at least three hours apart, so there are real alternatives (morning vs. late afternoon). In route mode, each stop of my day is a candidate.
  3. Choice, with Gemma. Gemma 4 E2B runs locally through Ollama (the 4.6 GB Q4_K_M build, on a MacBook with 8 GB of RAM). It receives the candidates with their forecast and whatever I wrote: "quiero caminar en la hora del almuerzo", "voy con mi hija de 6 años, que no aguanta el calor". Its reply is constrained with Ollama's structured output: a JSON Schema whose ventana field only accepts the labels of the computed windows, and whose llevar (things to carry) field only accepts items from a closed list.
  4. Validation and fallback. If Ollama isn't running, or the answer is invalid, a fixed rule picks the highest score. The tool always answers.
  5. Non-negotiables in code. Water always; raincoat at 30% rain or more; cap and sunscreen at UV 6+; repellent on forest trails; a flashlight if the window touches darkness. In route mode they're computed for the whole day.

What testing with the real forecast taught me. The first version worked, and then the real runs showed me five problems. Each one changed the design:

What I saw What I changed
With Gemma 4's thinking mode on, a choice took 38 to 114 seconds Picking among five options doesn't need long reasoning: think: false brought it down to 7–9 seconds
Gemma called a 53% chance of rain "poca probabilidad" (low probability) The code now adds the Ojo line for any window scoring under 60, whatever the model says
Gemma wrote "la opción B" in its explanation, a letter the card never shows Gemma now chooses among readable labels like "mar 6 oct, 12:00 p. m. en Costa del Este", so there's no internal code to leak
Asked for lunch, it picked 8:00 a.m. without saying why it rejected noon New instruction: if the requested time exists, honor it and warn clearly
It offered 7:00–8:00 and 8:00–9:00 as different options Windows on the same day must be three hours apart

The pattern I ended up with: the model is good at understanding what I want, and the code is in charge of the facts and the safety warnings. Every number on the card comes from the forecast, never from the model.

The full list of decisions is in docs/arquitectura.md, and every test run is in docs/validacion.md.

Taking It Outside

On Tuesday, October 6, I followed my usual route with the card from the demo above. Here is the forecast next to what actually happened:

Stop Forecast What happened
7:30 a.m. · Plaza 5 de Mayo 20% · 31 °C · dry Dry
8:00 a.m. · Costa del Este 18% · 31 °C · dry Dry under a gray sky
12:00 p.m. · Costa del Este 66% · 39 °C · rain and heat It rained
4:00 p.m. · Costa del Este 88% · 31 °C · rain It rained

The day went the way the card said it would. The stop Gemma picked, 8:00 a.m. in Costa del Este, was dry. I took this photo at 8:15:

Costa del Este at 8:15 a.m. on October 6: overcast sky, palm trees and dry pavement

Then noon arrived as forecast. At 12:43 p.m., through a window in Costa del Este, the rain was streaking the glass and the hills in the distance had disappeared:

Costa del Este at 12:43 p.m. on October 6, seen through a window: rain on the glass and a hazy horizon

The raincoat, which the card put on the list in the morning because of the afternoon, was needed twice. At 5:52 p.m. the pavement was still wet:

Costa del Este at 5:52 p.m. on October 6: wet pavement, traffic and a heavy gray sky

One honest detail: when I checked Open-Meteo's hourly record for the same coordinates that night, it showed the storm between 11 a.m. and 1 p.m. (8.3 mm at noon) and 0 mm at 4 p.m., even though I saw rain in the afternoon. The record is a model estimate for a grid cell several kilometers wide, and a local afternoon shower can fall outside it. The full comparison is in docs/validacion.md.

Why Does Open Innovation Matter?

What I write about my day stays on my laptop. The preference text can be personal: when you leave work, who you're going out with. The saved route is literally my daily location pattern. With Gemma running locally, none of that goes to a server. The only request that leaves the computer is the forecast, and it carries the coordinates of a public place, not my GPS, with no account and no API key.

It costs nothing to run every morning. No per-request fee, no quota, no subscription. That matters for a tool you're supposed to use daily.

I could see and change how the model behaves. Because the model and the runtime are open, I measured the thinking mode, turned it off, and constrained the output with a schema. When the model softened a 53% rain chance, I could build a guardrail around its exact behavior instead of hoping a hosted API wouldn't change under me. The model is also swappable with --modelo, for example gemma4:e4b on a machine with more memory.

It works where the signal doesn't. Gemma doesn't need the internet, and the forecast is cached. On a trail with no coverage, the card still comes from the last forecast and says when it was saved.

To be honest about the trade-off: a large hosted model would probably write nicer explanations. But this job needed control and privacy more than eloquence, and the small model's mistakes are exactly the kind the code can catch.

Prize Categories

  • Best Use of Gemma. Gemma 4 E2B, running locally with Ollama, is the decision-maker at the core of Ventana seca. It interprets a free-text preference, chooses among computed windows through a constrained JSON Schema, and writes the explanation on the card. Its behavior shaped the design: thinking mode off for speed, readable labels instead of letters, and a code-side warning when it understates risk.

AI assistance disclosure: I built Ventana seca with Claude Code (Claude Opus 5.5) as my coding agent: it implemented the code, tests and documentation, generated the demo, and drafted this post from my route and the recorded test results. I picked the idea, supplied my real route, reviewed the results and tested it on my own commute.

Top comments (0)