Inspiration

On the night of 30 June 2025, cloudbursts hit Mandi district in Himachal Pradesh. In Syathi village, no report says any warning arrived. A family's dog woke them around midnight, and more than 60 people got out before the slope came down (The Tribune). Across the district, early official figures counted at least 10 dead and 34 missing (Down To Earth).

We live in Himachal, and this is not rare here. In the 2023 monsoon more than 500 people died in the state (HP Govt PDNA). Yet in December 2023, Himachal had just 1 of India's 338 Central Water Commission flood-forecasting stations (CWC).

The forecasts that do exist are numbers on a website, not a warning a villager hears. And sending a warning is not the same as being heard. In Nepal's September 2024 floods, more than 4 million alert SMS went out and 250 people still died (DHM, UN Nepal). We wanted to build the missing last mile: from a forecast to a family that heard the warning and knows where to go.

What it does

Pukaar (पुकार, "the call") turns a flood forecast into a spoken Hindi warning on every phone in a village, and shows who actually heard it. It watches five villages in Mandi district:

  1. Watch. Every 15 minutes it reads rain and river forecasts for each village. Code sets the danger level, never an AI model, using official rain bands and each village's own 1984-2024 river record.
  2. Approve. A district officer approves the alert in one tap. If they don't answer, the next officer is asked. A critical alert with no answer goes out anyway and is flagged.
  3. Call. The alert is spoken in Hindi (Amazon Polly) and sent to every registered phone on Telegram with one button: "मिल गया" (got it). Anyone who hasn't tapped it gets the alert again.
  4. Where to go. The alert names the nearest open safe place above the river, with a walking route. The village head can mark a shelter full or a road blocked, and the alert switches to the next option.
  5. Report back. Villagers send voice, photo or text from any phone, even offline. A verified report can raise the level on its own.
  6. After. Everyone is asked "Are you safe?", the officer sees who needs help first, and an after-action report is written automatically in Hindi and English.

What makes it different

We checked the public sources of the systems India already has. "Not stated" means the source doesn't mention it.

Spoken alert Each person confirms Officer approves each alert Villagers report back
SACHET (NDMA) not stated not stated not stated not stated
IMD warnings not stated not stated not stated not stated
CWC flood forecasts not stated not stated not stated not stated
Google Flood Hub not stated not stated not stated not stated
Pukaar yes, Hindi voice yes, "मिल गया" yes, one tap yes, voice/photo/text

Pukaar is built to sit beside these systems, not replace them: their forecasts are its inputs, and it carries the warning the last mile to a phone and back. Every alert is also published as a CAP 1.2 feed, the standard SACHET uses.

Try it in 2 minutes

  • Live site: https://main.d15r7ktz99l46x.amplifyapp.com (no account needed)
  • Officer console: sign in at /login as judge, password Judge-E5FCkUl3uY-2026. Press Start replay to replay the July 2023 floods, open the pending alert, press Listen to hear the Hindi warning, then Approve.
  • See access control refuse: sign in as judge_pradhan (same password) and try to approve. It's refused, and the audit trail records why.
  • Telegram: message @PukaarRescuebot with /start gohar.

How we built it

Architecture. The backend is Python and FastAPI, deployed on AWS as one SAM stack. EventBridge Scheduler runs the 15-minute sweep, Lambda runs the logic, Step Functions runs one approval workflow per alert, and DynamoDB stores state with conditional writes so no alert is ever sent twice. Polly speaks the alert, Transcribe reads villagers' Hindi voice notes, AWS IoT Core takes river-gauge readings, AppSync Events pushes live updates, and Cognito signs officers in. The frontend is React, TypeScript and Vite: an offline-capable PWA with a MapLibre/three.js 3D map built on real terrain from AWS Open Data.

AI on a short leash. An agent (Strands Agents on Amazon Bedrock) may only fill in a fixed Hindi template, and a checker rejects any number or place name that isn't in the decision trace. If the model is down, the template goes out anyway, so the warning never depends on the model. Bedrock Guardrails screen every villager report. Cedar policies check every action (only district officers can approve), and every allow and deny goes into an append-only audit log.

The math: how a village's level is decided

No black box. Levels are \(\text{Normal}=0,\ \text{Watch}=1,\ \text{Warning}=2,\ \text{Critical}=3\).

Rain. \(R\) is the forecast rain over the next 24 h in mm, checked against the India Meteorological Department's heavy, very heavy and extremely heavy bands:

$$ L^{\text{rain}} = \mathbf{1}(R \geq 64.5) + \mathbf{1}(R \geq 115.6) + \mathbf{1}(R \geq 204.5) $$

River. Each village's thresholds are the 90th, 97th and 99.5th percentiles of its own daily discharge record (1984-2024), so a small stream and a big river each get limits that fit their own history. With \(Q\) as the forecast peak discharge:

$$ L^{\text{river}} = \mathbf{1}(Q \geq Q^{(90)}) + \mathbf{1}(Q \geq Q^{(97)}) + \mathbf{1}(Q \geq Q^{(99.5)}) $$

Combine. Take the strongest of four sources. If at least two independent sources are at Watch or above, go up one level:

$$ L = \max\left(L^{\text{rain}},\ L^{\text{river}},\ L^{\text{gauge}},\ L^{\text{reports}}\right) $$

$$ L \leftarrow \min\left(L + 1,\ 3\right) \quad \text{if two or more sources are at least Watch} $$

Reports fade. A verified villager report that is \(t\) hours old has this weight. Below 0.5, it counts one level lower:

$$ w(t) = \min\left(1,\ \max\left(0,\ \frac{3 - t}{2}\right)\right) $$

No flickering. \(c\) is the number of calm sweeps in a row. A level rises at once, but drops only one step after 45 calm minutes:

$$ L(t+1) = \max\left(L^{\text{raw}},\ L(t) - \mathbf{1}(c \geq 3)\right) $$

Gauges learn their own limits. \(b\) is the gauge's median daily low water level, in cm. The gauge proposes these thresholds, and an officer must accept them:

$$ h^{\text{watch}} = \max\left(h^{(90)},\ b + 30\right) $$

$$ h^{\text{warning}} = \max\left(h^{(97)},\ h^{\text{watch}} + 15\right) $$

$$ h^{\text{critical}} = \max\left(h^{(99.5)},\ h^{\text{warning}} + 15\right) $$

Quality. 561 automated tests, a 77-check live smoke test against the deployed stack, zero axe accessibility violations, and a villager report page that is ready in 4.6 s on slow 3G.

Challenges we ran into

  • Testing a flood system without a flood. We replay real archived forecasts from the July 2023 and June 2025 floods through the same live code on AWS. Replays are labelled REPLAY everywhere and never sent to real phones.
  • No AI model access. Bedrock model access on our account was still pending during the build. Instead of waiting, we made the system work fully without it, and that became a core safety rule.
  • Global models miss cloudbursts. In our back-test they missed the 2025 Mandi cloudburst entirely. We didn't tune thresholds to fake a hit. Instead, we changed the design so a verified villager report or a river gauge can raise a level on its own.
  • Cheap phones and weak networks. This meant offline queueing, small pages, and voice instead of long text.
  • Ideas that didn't work. A soil-saturation modifier changed no outcome in the back-test, so it's off by default. We report it instead of hiding it.

Accomplishments that we're proud of

  • It's live, not a mockup. Pukaar has been deployed on AWS since 11 Oct 2026. A labelled drill alert went from officer approval to a real phone, and Bedrock Guardrails caught a prompt-injection attempt on the live stack.
  • Early warning that would have worked. Replaying the July 2023 Beas floods, Gohar, Pandoh and Sujanpur all reached Critical, and Gohar's first Watch came 72 hours before the river's peak day. At Pandoh, the river record gave at least 48 hours of lead time, where rain alone gave about 19.
  • Honest about limits. Only 4 village-events could be verified from published reports, so we call this a method, not a verdict. The app labels what is real, what is replayed and what is simulated.
  • 561 tests passing and zero accessibility violations.

What we learned

  • Sending is not hearing. That's why Pukaar measures acknowledgement, not just delivery.
  • Voice beats text for warnings in low-literacy, flood-prone communities (Cumiskey et al., 2015, doi:10.1108/IJDRBE-08-2014-0062).
  • Early warning pays. Countries with limited early-warning coverage have nearly six times the disaster mortality ratio (WMO 2024), and 24 hours of warning can cut damage by 30% (Global Commission on Adaptation, 2019).
  • Let code decide and AI only phrase. A model that writes a warning should never be the thing that decides a warning is needed.

What's next for Pukaar (पुकार)

  • A voice call with "press 1 to confirm" (Amazon Connect) for basic phones and people who can't read, plus an SMS copy of every alert.
  • A real river gauge at a bridge. The low-cost ESP32 design and its AWS IoT Core path are ready. Live readings stay simulated until hardware is installed.
  • Measure what matters: Hindi speech-recognition accuracy on Himachali voices, real delivery and acknowledgement rates, and the false-alarm rate over a full monsoon.

Built With

Share this project:

Updates

Submission history