Inspiration

Corpus Christi's Coastal Bend is packed with petrochemical plants, port traffic, and a stormwater network that drains to the bay and its estuaries. When it storms, runoff can push sediment and other contaminants through outfalls in short-lived pulses — and those pulses often pass between the scheduled visits when crews actually collect samples. Continuous monitoring exists, but it is usually expensive and power-hungry. We wanted a cheap, low-power way to notice when conditions change and tell a team where to look first.

What it does

OutfallWatch is a low-power coastal runoff sentinel. A cheap ESP32-S3 node reads a DIY optical turbidity sensor (and an optional temperature probe), decides at the edge when readings deviate enough from a learned baseline to matter, and streams explainable early-warning alerts to a live dashboard. It runs a transparent state machine — NORMAL -> ELEVATED -> ALERT -> RECOVERING — with persistence and hysteresis so brief spikes do not raise false alarms. Every alert is explained with the actual index change and duration, and it recommends inspection and sampling.

Crucially, it flags change, not chemistry: turbidity, temperature and conductivity cannot identify pollutants, bacteria, or safety, and the UI never claims otherwise. The whole system is demoable offline with a deterministic storm simulator, and official NOAA and GCOOS observations are shown alongside, clearly separated from the prototype's own readings.

How we built it

  • Firmware: ESP32-S3 (Arduino / PlatformIO) reads the sensor, runs a rolling-median filter and the same detection logic as the backend, drives local indicators even with Wi-Fi down, and buffers readings in a bounded offline queue that flushes on reconnect. Adaptive sampling: 10 s in NORMAL, 2 s during an event; it transmits on state change plus a heartbeat.
  • Backend: Python + FastAPI, Pydantic v2, SQLAlchemy + SQLite, with Server-Sent Events for live push. One canonical telemetry schema and one deterministic detection engine are shared by the hardware and the simulator.
  • Frontend: React 18 + TypeScript, Vite, Tailwind, Apache ECharts, and MapLibre GL with an offline SVG fallback — a 7-page mission-control dashboard.
  • Green AI: a reproducible fixed-vs-adaptive comparison on the same seeded replay, plus a CodeCarbon host benchmark.
  • Data: live NOAA Tides & Currents (station 8775296) and GCOOS ERDDAP (station CBI_042), each with labelled offline fixtures.
  • Infra: Docker, Render, and Cloudflare Tunnel.

Challenges we ran into

  • A reading_id collision across reboots silently dropped readings while the device still looked "online" — fixed with a per-boot nonce in the ID.
  • A heartbeat slower than the backend's stale timeout made a healthy board flap ONLINE/STALE; we retuned the heartbeat.
  • The ESP32-S3 is 2.4 GHz-only, which failed silently on 5 GHz access points.
  • Keeping the Green AI story honest: fewer messages is not automatically less energy, so we report both counts and label all energy figures ESTIMATED.

Accomplishments that we're proud of

  • A real end-to-end pipeline: a Freenove ESP32-S3 flashed, booted, and streaming live HARDWARE telemetry to the backend over Wi-Fi.
  • One deterministic engine shared by firmware and simulator, so the offline demo behaves exactly like the hardware path.
  • A transparent Green AI result — adaptive sends about 89% fewer messages with 0 missed anomalies on the same seed — with an explicit, documented energy model.
  • 19 backend tests passing, a clean frontend build, and a demo that runs fully offline.

What we learned

  • Edge-first design keeps a cheap node useful when the network is not.
  • "Green AI" is most credible as measured, energy-aware processing — not a buzzword — and being honest about estimated vs. measured matters.
  • Low-cost sensors detect change; the responsible product tells people where to investigate rather than overclaiming.

What's next for OutfallWatch

  • Wire and calibrate the turbidity sensor (set V_clear / V_cloudy) and verify the indicators on hardware.
  • Field-validate against accredited lab sampling; add a waterproof enclosure and a real power budget measured with a meter.
  • Harden the ingestion / admin endpoints and move the SSE broker to a shared bus to scale.
  • Explore a small on-device TinyML model (TFLM / ESP-NN) benchmarked against the rule engine.

Built With

Share this project:

Updates

Submission history