💡 Inspiration

More than half of all flood drownings happen in vehicles, often on roads people didn't know were underwater. Official warnings cover entire counties, usually in only one or two languages, and rarely answer the question a resident actually has:

Is **my* street safe right now, and what should I do?*

Agencies like NOAA, USGS, and the National Weather Service already publish rich, real-time data. The problem isn't missing information; it's that the information never reaches people in a form that is local, understandable, and trustworthy. We built SIREN to close that last mile, for every resident, in their own language.

🚨 What it does

SIREN turns live environmental data into evidence-backed, street-level flood warnings delivered in English or Spanish via text and voice.

  • Live status where you are: Share your location and SIREN pulls nearby NOAA river gauges, active NWS alerts, forecasts, and recent rainfall. A versioned rules engine assigns one of five statuses: Normal, Watch, Warning, Emergency, or Unknown. Missing data never defaults to "safe."
  • "How deep is it?": Snap a photo of floodwater and Gemini estimates its depth from reference objects like tires and curbs, returning a depth range and confidence score. Deterministic guardrails then enforce a strict do-not-drive rule.
  • Ask SIREN: Voice or text questions are answered only from cited NWS and Ready.gov guidance plus current conditions. Anything outside that scope gets a safe refusal pointing to 911.
  • Storm replays: Judges can scan a QR code and receive live alerts on their own phones as five real floods unfold: Hurricane Beryl (Houston), Hurricane Helene (Asheville), the 2023 Vermont flood, the 2022 Eastern Kentucky flood, and the 2024 San Diego flash flood.
  • Total traceability: Every alert shows the exact rule version that fired, source-linked gauge readings with timestamps, the AI execution path, transcripts, and delivery logs (Drafted $\rightarrow$ Generated $\rightarrow$ Delivered $\rightarrow$ Acknowledged). A "Re-run rule" button recomputes any alert instantly.

🛠️ How we built it

Rules decide, AI explains

The core of SIREN is a deterministic, versioned rules engine (rules.yaml). It evaluates official NOAA flood stages, river rise rate, hourly rainfall, active NWS Flash Flood Warnings, verified photo depths, and data freshness. AI never decides a status; it only translates and explains one.

Data freshness. Every reading carries an observation timestamp $t_{\text{obs}}$. If its age exceeds a staleness threshold $\tau$, the reading is discarded rather than trusted:

$$ \text{age} = t_{\text{now}} - t_{\text{obs}}, \qquad \text{age} > \tau \;\Rightarrow\; \text{status} = \textbf{Unknown} $$

River rise rate. Beyond the absolute stage $h(t)$, we track how fast the river is climbing:

$$ r = \frac{h(t) - h(t - \Delta t)}{\Delta t} $$

so a rapidly rising river can trigger a Watch before it crosses an official flood stage.

Hysteresis. Near a threshold, noisy gauge readings could make alerts flap on and off. SIREN uses separate thresholds to enter and exit a level, with $\theta_{\text{exit}} < \theta_{\text{enter}}$:

$$ s_{t} = \begin{cases} \text{escalate} & \text{if } h(t) \ge \theta_{\text{enter}} \ \text{de-escalate} & \text{if } h(t) < \theta_{\text{exit}} \ s_{t-1} & \text{otherwise} \end{cases} $$

Do-not-drive guardrail. For photo-based estimates, we act on the upper end of Gemini's predicted depth range $[d_{\min}, d_{\max}]$, so uncertainty always errs toward caution:

$$ d_{\max} \ge 12\text{ in} \;\Rightarrow\; \textbf{Do not drive} $$

Validated AI with fallbacks

Gemini Flash handles translation, explanations, Q&A, and depth estimation through structured JSON. Code validators check that every number matches the source data, street names stay unchanged, and any phrasing suggesting water is safe to cross is blocked. If Gemini fails, SIREN falls back to Groq, then to deterministic templates, so an alert always goes out:

$$ \text{Gemini} \rightarrow \text{Groq} \rightarrow \text{Templates} $$

Multilingual voice

ElevenLabs generates English and Spanish audio alerts with cached clips, backed by browser speech fallbacks and mandatory text transcripts.

Data sources and stack

  • Data: NOAA National Water Prediction Service, USGS Water Data, NWS observations, Iowa Environmental Mesonet, and OpenStreetMap (with Nominatim, Overpass, and OSRM).
  • Backend: FastAPI (Python) with 57 automated tests in pytest.
  • Frontend: React, TypeScript, and Vite with Leaflet maps and Recharts, plus a complete offline mode for reliable demos.
  • Deployment: Docker, Render, and Vercel.

🧗 Challenges we ran into

  • Messy real data: During Hurricane Helene and the Kentucky floods, river gauges went dark at peak flow. That's exactly when a naive system would show "Normal." This proved why our core rule, "missing data is never safe," matters, and replaying those storms helped us catch bugs that would have stalled alerts mid-storm.
  • Honest timing: We benchmarked SIREN against official NWS radar-based warnings by measuring lead time:

$$ \Delta t_{\text{lead}} = t_{\text{NWS}} - t_{\text{SIREN}} $$

SIREN's gauge-dependent Warnings arrived slightly later than NWS ($\Delta t_{\text{lead}} < 0$). But its early Watches came up to $39$ minutes earlier in Houston and $101$ minutes earlier in Kentucky, and reached residents in their own language within $3$ to $11$ minutes. We chose to report both results rather than only the flattering one.

  • Feed lags and limits: Live gauge readings typically lag 30 to 60 minutes, which forced us to tune staleness thresholds carefully. We also worked within free-tier API and voice character quotas through response caching.

🏆 Accomplishments that we're proud of

  • Reliability: 57 automated tests covering the rules engine, hysteresis, AI validators, and live demo flows.
  • Photo depth validation: On $N = 22$ openly licensed flood photos with known depths $d_i$, we measured how often the true depth fell inside Gemini's predicted range, and the mean absolute error of its estimates $\hat{d}_i$:

$$ \text{Hit rate} = \frac{1}{N}\sum_{i=1}^{N} \mathbb{1}!\left[d_i \in [d_{\min,i},\, d_{\max,i}]\right] \approx 79\%, \qquad \text{MAE} = \frac{1}{N}\sum_{i=1}^{N} \left|\hat{d}_i - d_i\right| = 3.1\text{ in} $$

  • Accessibility: Severity is shown with shapes and words, never color alone, with full keyboard navigation, screen-reader support, and high-contrast modes.
  • Real-storm replays that let anyone experience SIREN's alerts on their own phone.

📚 What we learned

  • In safety-critical tools, AI should explain decisions, not make them. Keeping thresholds in a deterministic, versioned rules engine made every alert auditable, testable, and reproducible.
  • Real-world data fails exactly when you need it most. Designing for missing and stale data from day one was essential, not an edge case.
  • Uncertainty should push toward caution. Acting on the upper bound of a depth estimate, and treating stale data as Unknown, turned AI uncertainty into a safety feature instead of a risk.
  • Honest benchmarks teach more than perfect ones. Measuring against NWS showed where SIREN adds value (early watches, local language, street-level detail) and where it still needs work.
  • Accessibility and multilingual delivery are core features. A warning only works if the person receiving it can understand it.

🚀 What's next for SIREN: Street-Level Flood Intelligence

  • Real SMS and phone-call delivery.
  • More languages and persistent user preferences.
  • Denser rain-gauge networks and radar rainfall analysis.
  • Crowdsourced photo reports that verify each other.
  • Expanding to wildfire and air-quality alerts using the same rules-first architecture.

Built With

Share this project:

Updates

Submission history