Point it at any island on Earth

AquaGrid

An AI that forecasts an island’s water demand, schedules desalination against the solar forecast, harvests the rain, and catches failures nobody would notice until they were expensive.

Desalination is the largest electrical load on a small island, and it is usually run on a wall timer set to overnight hours — a habit inherited from mainland off-peak grid pricing. On a solar island that is exactly backwards. The water tank is a battery nobody schedules.

The island is a parameter, not a constant. Search any place by name and AquaGrid fetches its real weather, forecasts its demand on-device, sizes a plant to its population and re-runs everything. The figures below are one worked example — Funafuti, Tuvalu — and every one of them moves when you change the island.

78%less diesel than
a fixed timer
45.3L/h forecast error
R² 0.987
24%of water supplied
by rainfall
2 hto detect a
450 L/h burst
anyisland on Earth,
computed on-device
0servers, and it runs
with no signal

The problem

Water and energy are the same problem on an island

On a small isolated island, water and energy are the same problem. Fresh water comes from rain when it falls and from a desalination plant when it does not, and that plant is usually the single largest electrical load on the island. The electricity comes from solar when the sun is up and from a diesel generator when it is not — and the diesel arrives by barge, every few weeks, whether or not you are running low.

So every hour there is a real decision: make water now, or wait. Making it at noon on a clear day is nearly free. Making it at 02:00 costs imported fuel. And the tank is a battery — it will hold a day or two of demand — which means the decision can be deferred, if you know what tomorrow looks like.

Almost nowhere is that decision actually made. It is delegated to a timer set decades ago.

How this is solved today

Eight approaches in common use. None is stupid; all are blind the same way.

Wall timer / fixed schedule

The pump runs the same hours every day, typically overnight, inherited from mainland off-peak electricity tariffs.

On a diesel-and-solar island there is no off-peak. Those hours are the ones with no sun, so the timer systematically picks the most expensive water of the day.

Float switch / level control

A level sensor starts the pump below a set point and stops it above another.

Purely reactive. It responds to the tank after it has already drained, never anticipates, and is equally happy to run at midnight as at noon.

Operator judgement with SCADA

A skilled operator watches gauges and decides by experience when to run.

Works, and often works well — but it does not scale, does not survive staff turnover, and no human runs a 12-hour lookahead over a weather forecast every hour.

Commercial microgrid controllers

Hybrid energy-management systems that dispatch generators, batteries and PV.

They optimise the electrical side, treating the desalination plant as a fixed load to be served. The water tank's value as storage is invisible to them. They also assume connectivity and a budget neither of which a village of 1,200 has.

Rainwater, managed separately

Household and community tanks collect rain independently of the plant.

The plant makes water on days the sky is about to fill the tank for free, and the rain overflows while diesel burns.

Threshold alarms for leaks

Alert when pressure or level crosses a fixed bound.

A threshold cannot distinguish a burst pipe from a busy evening. By the time the level is visibly wrong, the water is gone. Large utilities use district-metered minimum-night-flow analysis; that infrastructure does not exist on a small island.

Calendar or run-to-failure maintenance

Membranes cleaned on a schedule, or when performance becomes obviously bad.

Too early wastes a clean; too late means months of quietly elevated energy per cubic metre, paid for in diesel.

Fuel tracked by dipstick

Litres remaining checked manually against a barge schedule on a whiteboard.

Nobody projects the current burn rate forward against the delivery date until it is close, and the barge does not come early because you ran out.

Each of these is reasonable on its own. The failure is that none of them share a demand forecast, so none can defer a decision. The timer cannot know that tomorrow is sunny; the float switch cannot know that rain is coming in four hours; the leak alarm cannot know what the tank *should* be doing at 03:00 on a Tuesday; the maintenance calendar cannot see that specific energy has been climbing for six weeks.

Predict demand once, and every one of those problems becomes tractable with arithmetic. That is the whole thesis of AquaGrid: one forecast, shared by the scheduler and every detector.

Predict, decide, explain, detect

Four stages. Each one feeds the next.

STAGE 1

Predict

A random forest forecasts water demand 48 hours ahead from hour, weekday, temperature and tourist season — trained on two years of history, tested on the 60 days that came after.

ml/train_model.py
STAGE 2

Decide

Eight rules and a 12-hour lookahead dispatch the pump across solar, battery, rainfall and diesel, holding the reserve floor without wasting fuel.

logic/scheduler.js
STAGE 3

Explain

Every hour carries a plain-language reason. An open-weight model writes the shift briefing, answers the operator’s questions, and drafts the public notice.

lib/ai.js
STAGE 4

Detect

Residual analysis against the forecast finds a burst pipe in hours, dirty panels in a day, and fouling membranes six weeks before they cost anything.

logic/leak.js · assets.js

Any island on Earth

Because we ship the model, not only its predictions

Every feature the forecaster uses is categorical except temperature. So the trained forest is evaluated exhaustively over its entire input grid and exported as a 15,120-cell lookup table — 2 seasons × 7 days × 24 hours × 45 temperature buckets.

That is the model, not an approximation of it. The only loss is temperature discretised to 0.5 °C, costing a mean 5.5 L/h — 12% of the model’s own error. A real forecaster running on the phone, with no ML runtime, no server and no inference API.

Same code, live forecasts, four islands

IslandPopulationDiesel savedWhy
Apia, Samoa40,40780%abundant sun
Malé, Maldives103,69370%equatorial, steady
Santorini, Greece15,45364%strong but seasonal
Reykjavík, Iceland118,91823%barely any sun to schedule

Reykjavík is the honest answer, not a bug. Where there is little sun there is little for a scheduler to win, and the app says so.

Every feature, and what it does

Fourteen features across five roles · predict, decide, supply, detect, explain

01PREDICT

Demand forecasting

Predicts how many litres the island will use, every hour, 48 hours ahead.

How A RandomForestRegressor trained on two years of hourly history using five features: hour of day, day of week, weekend flag, temperature and tourist season. Evaluated on a chronological split so it is tested on the future.

Why Everything else depends on this. Without a demand curve you cannot know whether the tank will hold, so you cannot decide anything except reactively.

MAE 45.3 L/h · R² 0.987 · 89% better than predicting the average

02DECIDE

Pump scheduling

Decides each hour whether to run the desalination pump, and on what power.

How Eight rules in strict priority order with a 12-hour lookahead that projects tank level against forecast demand, full-solar hours and expected rainfall. First matching rule wins.

Why This is the product. A wall timer runs the pump when power is most expensive; this runs it when power is free, and spends a little diesel early to avoid spending a lot later.

78% less diesel than a fixed timer, zero shortage hours

03SUPPLY

Rainwater harvesting

Captures rainfall into the tank and holds the pump when a shower is coming.

How Precipitation comes from the same Open-Meteo call as solar. harvest = rain_mm × catchment_m² × runoff. Rule 2 suppresses pumping when forecast rain exceeds forecast demand over the next six hours.

Why Funafuti is in reality almost entirely rainwater-fed, with desalination as the backup. A scheduler that ignores rain is optimising the wrong variable, and makes water it is about to spill.

11.3 m³ harvested — 24% of all water supplied

04SUPPLY

Battery storage

Stores surplus midday solar and spends it running the pump after dark.

How Solar serves the pump first; surplus charges the battery at round-trip efficiency. When pumping without enough sun, the battery discharges before any diesel is burned. Energy that arrives with the battery full is counted as curtailed.

Why The demand peak is 18:00–20:00 and the solar peak is midday. Without storage those never meet and the evening runs on diesel.

66 kWh discharged to the pump · 304 kWh curtailed

05DECIDE

Storm preparation

Abandons fuel economy and fills the tank to 100% before a cyclone lands.

How Scans the 24-hour wind outlook. Above the storm threshold, Rule 0 overrides every cost rule until the tank is full.

Why After landfall the array is down, the pump may be offline and the resupply barge will not sail. Whatever is in the tank is what the island has. Optimising for fuel at that moment is the wrong objective.

Simulate cyclone control, since the live forecast has none

06DETECT

Leak detection

Finds a burst pipe from the pattern of the loss, hours before the tank looks low.

How Each hour, compare the drop the sensor reports against the drop the forecast predicts (demand − pumped − harvested). σ is calibrated on the first twelve hours as a known-good baseline. Alert on 3σ for three consecutive hours.

Why A level threshold cannot tell a leak from a busy evening — by the time the tank is visibly low, thousands of litres are gone. A forecast knows what normal looks like at 03:00 on a Tuesday.

450 L/h burst caught in 2 hours · estimated 452 L/h at 99% confidence

07DETECT

Panel soiling detection

Notices the solar array is producing less than the sunlight falling on it warrants.

How Compares metered array output against the irradiance-derived prediction across daylight hours only, and reports the shortfall and the kWh not collected.

Why Salt spray and dust cost an island real diesel silently, for months. Nobody climbs up to check panels that are still producing something.

13% below predicted across 20 daylight hours — 90 kWh lost

08DETECT

Membrane fouling prediction

Predicts the date the reverse-osmosis membranes will need cleaning.

How Specific energy — kWh per m³ of fresh water — rises as membranes foul, because the pump must push harder for the same flow. Least-squares fit on 90 days of daily readings, projected forward to the clean-in-place threshold.

Why Maintenance on an island is scheduled around a barge, not around a fault. Six weeks of warning is the difference between a planned clean and an emergency one.

+11.1% from design · threshold reached in 40 days

09DETECT

Diesel inventory

Warns when the fuel will run out before the next resupply barge.

How Projects the schedule's burn rate against litres remaining and days until the barge, and runs the same projection for both baseline strategies.

Why Burning too much diesel and running out of diesel are different failures. The barge does not come early because you ran out.

AquaGrid 39 days; fixed timer dry 3.4 days early, reactive 4.4 days early

10EXPLAIN

Demand-side advisory

Tells residents the hours when using water costs the island nothing.

How Finds runs of consecutive hours where the pump is already running on sun or stored sun, and turns them into a public notice — drafted by the LLM, or by a deterministic template offline.

Why Everything else schedules supply. The cheapest litre of diesel is the one nobody needed because the laundry ran at noon.

Free windows surfaced as tappable chips with litres available

11EXPLAIN

Rationing outlook

Measures supply per person per day against the WHO minimum, and drafts the notice if it falls short.

How Divides available supply over the horizon by population and days, and compares it to 15 L per person per day — the WHO floor for drinking, cooking and basic hygiene.

Why When shortfall is unavoidable, the question stops being about fuel and becomes about whether people have enough to drink. That deserves a number, not a vibe.

18.2 L per person per day — 1.2× the WHO minimum

12PREDICT

Any-island operation

Points the whole system at any location on Earth, with no retraining.

How The trained forest is evaluated exhaustively over its entire input grid and exported as a 15,120-cell lookup table. Open-Meteo geocoding resolves a typed name; the forecast endpoint supplies that island's real weather; the plant is scaled to its population.

Why A demo tied to one island is a demo. This is the difference between a case study and a system.

Table reproduces the model to a mean 5.5 L/h — 12% of its own error

13EXPLAIN

Operator briefing and Q&A

Writes the shift briefing in plain language and answers questions about the decisions.

How A compact state object — never the whole forecast — goes to an open-weight model on Groq, raced against a six-second timeout. Three preset questions let a judge interrogate the scheduler in one tap.

Why A decision nobody can interrogate is not one an operator will trust. Every hour already carries a machine-written reason; this turns the set of them into something a person reads.

~620 ms round trip · falls back to a deterministic template

14PLATFORM

Offline operation

Runs completely with no network — scheduling, detection, charts and briefing.

How The model's predictions and the weather forecast are bundled as a static asset at build time. The only two network calls, Groq and Open-Meteo geocoding, are optional enhancements that degrade to a deterministic path.

Why This is the actual operating condition on an isolated island. It is also why there is no backend to fail.

Airplane mode: every screen renders, only the briefing degrades

One day, as the scheduler sees it

Funafuti, Tuvalu · live Open-Meteo forecast · next 24 hours

Solar output, predicted demand and rainfall

50 kW pump draw 000408121620
Solar output Predicted demand Rainfall

Solar above the dashed line runs the pump for free. Below it, every pump hour spends either the battery or diesel — which is the whole decision.

What the pump actually did

Solar Stored solar Partial solar Diesel Held

The result

Funafuti, Tuvalu · 48-hour horizon · identical forecast and physics, only the rule differs

Fuel, cost and carbon

StrategyDieselCostCO₂Pump hoursShortage
AquaGrid15.3 L$2541 kg60 h
Fixed timer 01:00–05:0070.0 L$112188 kg80 h
Reactive, top up below 80%79.2 L$127212 kg110 h

78% less diesel than the fixed timer these plants run today. The tank starts at 32% — the level yesterday’s weather actually left it at, replayed through the scheduler — and never drops below 27% against a 25% reserve floor.

The number that matters more than the percentage

The fuel tank holds 300 L. The next barge is 12 days away.

StrategyBurn rateFuel lastsOutcome
AquaGrid8 L/day39 daysHOLDS
Fixed timer35 L/day8.6 daysDRY −3.4 d
Reactive40 L/day7.6 daysDRY −4.4 d

Burning too much diesel and running out of diesel are different failures. The barge does not come early because you ran out.

Eight rules, in strict order

First match wins · 12-hour lookahead over sun and rain

  1. Storm preparation
    Cyclone-force wind within 24 h → fill to 100% regardless of cost. After landfall the array is down and the barge will not sail.
  2. Emergency
    Below the 25% reserve floor → top up whatever it takes.
  3. Rain hold
    More rain than demand forecast in the next six hours → hold the pump, the tank fills for free.
  4. Free solar
    Sun alone clears the full 50 kW pump draw.
  5. Stored solar
    Shortfall ahead and the battery can carry the pump → spend this morning’s surplus.
  6. Pre-emptive hybrid
    Shortfall ahead with partial sun → spend a little diesel now to avoid a lot tonight.
  7. Reluctant diesel
    Shortfall ahead, no sun, empty battery.
  8. Hold
    Reserves healthy → wait for the sun.

Rules 2, 4 and 5 are where the forecast earns its keep — they are the only ones that act on information the plant does not yet have.

Rain is the point

Funafuti, Tuvalu · rainwater-fed, with desalination as the backup

Any system that ignores the rain forecast is planning against the wrong problem. Precipitation comes from the same Open-Meteo call as the solar forecast, and rain_mm × catchment × runoff flows straight into the tank balance.

Over this horizon, 15.7 mm across 900 m² of public roof delivered 11.3 m³ — 24% of all water supplied. Catchment is sized so rain matters without dominating; raise it and the reserve floor stops binding, and the scheduler has nothing left to decide.

A 150 kWh battery carries surplus midday sun into the evening demand peak. Over the horizon 180 kWh went straight from panel to pump, 66 kWh came back out of the battery, and 304 kWh was curtailed — sun that arrived with the battery full and the pump already running. That last figure is the honest ceiling on what a bigger battery could buy.

One idea, four failures

Compare what the plant does against what the forecast says it should

A threshold alarm sees none of these until they are expensive. A forecast sees all four, because it knows what normal looks like this hour.

FailureSignalCaught
Burst pipeTank falling faster than demand minus supply explains2 h
Dirty panelsMetered array output against irradiance13% · 90 kWh
Fouling membranesSpecific energy trending up over 90 days40 days out
Fuel exhaustionBurn rate against barge lead time39 d margin

Reverse-osmosis specific energy · 90 days

clean-in-place threshold 9.58 kWh/m³ design 8.33

The pump pushes harder for the same flow as membranes foul. Least-squares on 90 days of daily readings puts the clean-in-place date 40 days out — schedule it now, not after it starts costing diesel.

The model

Chronological split — tested on the future, never on shuffled rows

MetricValue
Mean absolute error45.3 L/h
Root mean squared error57.0 L/h
R²0.987
Naive “predict the mean”409.7 L/h
Improvement over naive89%
Train / test rows16,080 / 1,440

Feature importance

Hour of day
0.897
Tourist season
0.032
Weekend
0.031
Day of week
0.028
Temperature
0.012

Hour of day dominates, which is exactly what a village water profile should look like: a morning wash peak and an evening cooking peak, every day.

How it is built

The laptop trains once · the phone does everything else

The laptop trains; the phone does everything else.

Python runs once, to generate the history, train the forest and export it. After that the laptop is not in the loop: it is not needed at runtime, not needed to change island, and not needed for fresh weather. The phone fetches its own forecast, runs the model, schedules the pump, detects the failures and draws the charts.

What ships in `forecast.json` is therefore two different things: the model — a 15,120-cell lookup table that works anywhere — and a seed forecast for the bundled island, so the app has something to show before it ever reaches the network.

Technology stack

LayerTechnologyVersionWhy this one
MLscikit-learn1.9.0RandomForest is interpretable, gives feature importances, needs no GPU
pandas / numpy3.0.5 / 2.5.2Feature frames and the synthetic history
Python3.14.4
AppExpo SDK57.0.18Runs on a real phone with no native build or signing
React Native0.86.3
React19.2.3
react-native-svg15.15.4The only native module for charts — all hand-drawn
expo-location57.0.14GPS for “use my current location”
AsyncStorage2.2.0Offline cache of visited islands
Node25.6.1Also runs the logic tests directly, via ESM auto-detection
ServicesOpen-Meteo Forecast—Solar, temperature, rain, wind. No key
Open-Meteo Geocoding—Name → coordinates + population. No key
Groq—Open-weight LLM, free tier, ~500 ms. Optional
HostingGitHub Pages—This site. The app itself has no host

Deliberately absent: no backend, database, auth, navigation library, charting library, state-management library or CSS framework. Each is a dependency that can break at hour four, and none earn their place.

APIs and data sources

Three network APIs, two device APIs · two of the three need no key at all

Open-Meteo Forecast

NETWORK
https://api.open-meteo.com/v1/forecast

None — no API key, no account

Returns Hourly arrays of shortwave radiation (W/m²), temperature (°C), cloud cover (%), precipitation (mm) and wind speed (km/h).

Feeds Solar output (radiation × panel area × efficiency), the demand model's temperature feature, rainwater harvest, and the cyclone check.

timezone=auto is load-bearing. Funafuti is UTC+12, so UTC timestamps would put peak solar at local midnight and invert every pump decision. past_days=1 supplies the warm-up window used to derive the starting tank level.

Open-Meteo Geocoding

NETWORK
https://geocoding-api.open-meteo.com/v1/search

None — no API key, no account

Returns Candidate places with name, country, admin region, latitude, longitude, population and timezone.

Feeds Turns a typed island name into coordinates for the forecast call, and a population for plant sizing.

Matches settlement names only, so "Malé Maldives" returns nothing on a literal query. We retry on the first token and prefer results whose country or region matches the rest. Population is missing for many small settlements; 3,000 is assumed and labelled as an estimate.

Groq Chat Completions

NETWORK · OPTIONAL
https://api.groq.com/openai/v1/chat/completions

Bearer token, free tier, no credit card

Returns The operator briefing, answers to the preset questions, and the public water notice.

Feeds Narration only. It decides nothing — remove it and every number in the app is unchanged.

OpenAI-compatible shape. gpt-oss is a reasoning model: without reasoning_effort=low it spends the whole token budget thinking and returns empty content. Raced against a 6-second timeout; any failure falls back to a deterministic on-device template. Measured round trip ~500-620 ms.

expo-location

DEVICE
requestForegroundPermissionsAsync · getCurrentPositionAsync · reverseGeocodeAsync

Foreground permission prompt

Returns Device latitude and longitude, and a nearby place name.

Feeds The 'Use my current location' button. The name is resolved back through geocoding so the plant is sized against a real population rather than bare coordinates.

A refused permission is a normal outcome, not an error — the picker says so and search by name still works.

AsyncStorage

DEVICE
@react-native-async-storage/async-storage

None

Returns Previously fetched forecasts and the last island viewed.

Feeds Restores the operator's island on launch and keeps every island already visited working with no signal.

A full or unavailable store never breaks the app — the bundled island always works and everything recomputes from it.

Nothing else talks to the network. No weather key, no maps SDK, no analytics, no crash reporter, and no backend of our own.

No backend, on purpose

The app works with zero connectivity

Python trains and evaluates the model on a laptop and exports everything the app needs to one JSON file, bundled as a static asset. Scheduling, harvesting, battery dispatch, detection and charting all run on the phone.

A laptop-hosted API reached from a phone means LAN addresses, tunnels, CORS and cold starts. Removing the server removes all four — and leaves an app that keeps working on an island whose uplink is a satellite dish, which is the actual requirement.

┌───────────────────┐         ┌────────────────────────────┐
│  Python (laptop)    │         │  Expo app (phone)            │
│  synthetic history  │         │  forecast.json (bundled)     │
│         ↓           │         │         ↓                    │
│  RandomForest ──────┼────────►│  scheduler.js  (decisions)   │
│         ↓           │ writes  │  leak.js       (burst pipe)  │
│  Open-Meteo         │ JSON    │  assets.js     (slow decay)  │
│  solar/rain/wind    │         │  fuel.js       (barge risk)  │
│         ↓           │         │  advisory.js   (the village) │
│  forecast.json      │         │  Groq LLM (optional)         │
└───────────────────┘         └────────────────────────────┘

Why we built this

The case for the project, in the words we would use out loud

Tuvalu is one of the most climate-vulnerable countries on Earth. Nine low-lying atolls, a highest point of around four metres, and a freshwater lens so thin and so easily contaminated by saltwater intrusion that groundwater is largely undrinkable. The island runs on rain. When the rain stops, it runs on desalination, and desalination runs on diesel that arrives by barge.

This is not hypothetical. In 2011 a prolonged drought left Funafuti with days of fresh water remaining. A state of emergency was declared and neighbouring countries flew in portable desalination units and shipped in water. The vulnerability was never really about the plant being too small. It was that nobody could see far enough ahead to act early.

What struck us, reading about how these plants are actually operated, is that the hard parts are already solved. The panels are on the roof. The tank is in the ground. The desalination unit works. The weather forecast is free and public. What is missing is the thin layer in between — the part that looks at tomorrow and decides what to do tonight. That layer is software, and software is the cheapest thing you can add to an island.

So AquaGrid is deliberately not a hardware proposal. It does not ask anyone to buy anything. It takes the equipment an island already has and schedules it against a forecast, which is the difference between making water when it is free and making water when it is expensive. On our test case that is 78% less diesel — and, more importantly, the difference between fuel lasting until the next barge and not.

We also made a decision early that shaped everything else: it had to work with no signal. An app that needs a server to decide whether to run a pump is an app that fails exactly when an island is cut off, which is exactly when it matters. So the model is trained offline and runs on the phone. You can put the device in airplane mode in the middle of the demo and nothing stops working. That is not a limitation we worked around. It is the requirement.

Every number in this project is computed, not asserted. The savings come from running three schedulers over the same forecast and the same physics. The model is tested on the 60 days that came after the ones it learned from. The leak detector is given a real injected fault and has to find it. We would rather show a smaller honest number than a larger one we cannot defend — which is why Reykjavík, where there is barely any sun to schedule against, is in the results table at 23% alongside Apia at 80%.

None of this makes anyone's water secure on its own. It is a scheduler, built in a hackathon, on synthetic demand data and simulated sensors, and we have said so plainly wherever it applies. But the underlying idea — that a forecast shared between the pump, the tank and the fuel log turns four separate blind spots into one solved problem — is real, and it does not need any new hardware to be true.

The team — BitHeads

Rishik

The problem

Why an island's water and energy are the same problem, and how these plants are run today.

Neekin

The solution

One forecast, shared by the scheduler and every detector. What that buys.

Srihan

The architecture

Four layers, no backend, and shipping the model rather than its predictions.

Ednit

The features

The eight rules, rainwater, the battery, and the four detectors.

Gowtham

The code and the site

Repository walkthrough, the live test run, the website and the handbook.

BitHeads · DreamHacks 2026 · Track 2 — AI, Automation & Logic

What we are assuming

A system you cannot audit is not one to trust with an island’s water

  • Demand history is synthetic. Generated from published domestic-usage profiles, not measured at a real plant. The model genuinely learns those patterns; the patterns are our construction.
  • All sensors are simulated — tank float, array power meter, and the specific-energy log. No hardware is connected.
  • Demand patterns are assumed universal. New locations scale the reference village’s profile by population. A real deployment would retrain on that island’s meter data.
  • Plant sizing scales linearly with population, holding specific energy, days of storage and solar-hours-versus-pump-draw constant. That is why savings vary by weather rather than by size.
  • Diesel is assumed at $1.60/L delivered. Real island prices move with barge schedules.
  • 48-hour horizon. The lookahead cannot see past the end of the weather forecast.