← Back to the dashboard

How the AI on this dashboard works

Two features here are LLM-generated: the trend summary and the swim/heater advisor. Both run on a local model on the same Mac that fetches the pool data โ€” here's exactly what each one sees, what model answers it, and what happens if the model isn't available. The chlorine outlook is documented here too, precisely because it isn't AI and shouldn't be mistaken for it.

๐Ÿ”’ Runs locally

Both AI features call Ollama, a local LLM runtime, at localhost:11434 on the same Mac that runs the twice-daily fetch. The prompts (pool readings, weather forecast, today's date) never leave that machine, and neither model has internet access or tool use โ€” they just read the numbers they're given and write text back. The only things that do leave the machine each run are the calls to WaterGuru, the National Weather Service, and โ€” if you've enabled push alerts โ€” ntfy.sh.

Trend summary llama3.2:3b

The 2-3 sentence readout at the top of the dashboard on whether chlorine, pH, and water temp are trending up, down, or holding steady.

1
Input: the last 14 days of readings for the pool โ€” timestamp, status, free chlorine, pH, water temp, and skimmer flow for each one.
2
Prompt: asks the model to say, in plain prose (not a list), whether each of those three readings is trending up, down, or steady, and whether things look solid or need attention โ€” with real numbers, not vague language.
3
Fallback: if Ollama isn't reachable, a rule-based sentence is generated instead by comparing the first and last reading in the window โ€” same idea, just not written by a model. The dashboard shows which one you're looking at.

Swim & heater advisor qwen2.5:32b

The great/good/marginal/poor verdict on each of the next 5 days, plus the heater lead-time advice paragraph.

1
Input: today's date, the pool's most recent water-temperature reading, and the 5-day National Weather Service forecast (high temp, rain chance, wind, and conditions for each day).
2
Prompt: asks the model to weigh each day's air temperature against the water temp and against what's normal for the season, factor in rain/wind/storms, and โ€” since this is a heated pool that takes a couple of days to visibly move in temperature โ€” call out any day that's notably cooler or warmer than the rest of the stretch, with a concrete suggestion to adjust the heater setpoint roughly 2-3 days ahead of it.
3
Output contract: the model must return strict JSON โ€” a verdict (great/good/marginal/poor) and a one-phrase note per day, plus the heater-advice paragraph. The response is validated (right dates, right verdict values) before the dashboard trusts it.
4
Fallback: if Ollama is unreachable, or the model's output fails validation, the dashboard falls back to a fixed point formula instead (temperature, rain chance, and wind each subtract points; any mention of storms is an automatic fail) โ€” cruder, but it never leaves the forecast card blank.

Why these two models

Three local models were compared for the swim advisor specifically, since it has to weigh several factors into a judgment call and return valid JSON โ€” that's a meaningfully harder ask than the trend summary.

ModelResult
llama3.2:3bFast, valid JSON, but inconsistent or illogical verdicts โ€” e.g. once rated a sunny 78ยฐF day worse than a stormy one.
gpt-oss:20bIgnored the JSON output constraint entirely and returned rambling chain-of-thought prose instead of the requested structure.
qwen2.5:32bReliable JSON every time, and verdicts that were internally consistent (worse weather reliably scored worse) โ€” this is what's actually running. Takes roughly 30-45 seconds per run, which is a non-issue for something that runs twice a day in the background.

The trend summary's ask is simpler (summarize a table of numbers in a few sentences), so the smaller, much faster llama3.2:3b handles it fine.

Chlorine outlook no AI involved

The "estimated now" number and the projection chart. This one is worth being explicit about, because it sits next to two features that are LLM-generated: it's ordinary arithmetic, fully deterministic, and would produce the same answer with Ollama uninstalled.

1
Measure the burn rate: between consecutive measurements, chlorine only falls on its own โ€” so any increase means someone added some, and those stretches are thrown out rather than averaged in. What's left gives a ppm-per-day loss rate, and the median is taken so one odd reading can't drag the whole model.
2
Scale it for heat and stabilizer: chlorine burns faster in hot, sunny weather, and far faster still without cyanuric acid to shield it from UV. Each rate is normalized against both before averaging, then re-scaled per day using the National Weather Service forecast and the current stabilizer level. Normalizing first is what stops the model double-counting โ€” a rate measured during a hot, unstabilized week already has that fast burn baked into it.
3
Walk it forward: starting from the last real measurement โ€” often a day or two old, since the cassette measures roughly daily โ€” chlorine is stepped forward a day at a time to find when it returns to range or drops through the target. Days already elapsed are used for the arithmetic but not shown; projecting into the past isn't a forecast.
4
Fallback: with fewer than three usable declines on record it uses a generic outdoor-pool loss rate instead, and the card says so and marks itself low-confidence rather than quietly presenting a guess as a measurement.

"In range" means what the device means. WaterGuru ships the band it actually judges chlorine against โ€” green from 1.6 to 5.4 ppm around a 3.0 target โ€” so that's what the card uses, rather than a tolerance invented at this end.

What it deliberately doesn't model: UV index, bather load, or anything else this sensor doesn't report. Both the heat and stabilizer adjustments are coarse approximations. It's a trend projection to tell you whether to reach for the chlorine this week โ€” not a chemistry calculator.

Nothing here is a substitute for judgment

These are convenience reads, not safety systems. The chemistry alerts (RED/YELLOW/GREEN, cassette replacement) are WaterGuru's own thresholds, not AI-generated โ€” the LLMs only touch the trend summary and the swim/heater advice. The chlorine outlook and the sensor-health checks are plain arithmetic. Treat all of them as a second opinion worth a glance, not a replacement for checking the water yourself.