Crop Advisory System
An ESP32 field node that texts a paddy farmer when the field needs attention.







A field that stays dry shouldn't text the farmer every 15 seconds. So an alert only goes out when the state changes, with hysteresis and a cooldown so it doesn't flicker.
Overview
An ESP32 field node and a FastAPI backend that turn soil, weather and crop-calendar data into SMS advice for paddy farmers, in English, Hindi or Kannada. It measures, decides with fixed, versioned rules, and texts only when something is new or due.
Problem
A paddy farmer near Bhatkal should hear about a problem in the field by plain SMS, in their own language, without needing a smartphone or an app.
System
An ESP32 reads a DHT22, a soil probe, a rain plate and a light sensor as calibrated raw ADC values and posts every 15 s. A FastAPI backend authenticates, validates and stores the reading in SQLite and answers 202 in milliseconds. A fixed, versioned set of rules decides what to say, so the SMS text never goes through an AI model, and a background outbox worker sends the SMS with retry and backoff, in English, Hindi or Kannada. A failed sensor is reported as a fault, never as a plausible made-up number.
How it works
- The ESP32 reads air temperature and humidity, soil moisture, rain and light, and posts a reading every 15 s.
- The backend checks the device key, validates and de-duplicates the reading and stores it in one transaction, answering 202 straight away.
- A rule engine decides: soil-moisture bands with hysteresis, sensor faults, the fertilizer schedule, harvest checks and a rain warning near harvest. Every result carries its rule version.
- A cooldown gate lets a condition through only when it is new or its cooldown has run out: 6 h for sensor conditions, 24 h for calendar reminders.
- A background worker adds weather and market context, writes the message from templates and sends the SMS with retry and backoff, one job per recipient.
Hardware
| Part | What it does |
|---|---|
| ESP32-WROOM-32 | Microcontroller, Wi-Fi, HTTP client |
| DHT22 | Air temperature and humidity |
| FC-28 soil probe | Soil moisture, raw ADC |
| MH-RD rain plate | Rain detected now |
| LDR module | Ambient light |
Software
- FastAPI, SQLAlchemy and SQLite, with tables for readings, alert events and delivery jobs.
- A database-backed outbox with atomic job claiming and crash recovery, so a reading never waits on an SMS.
- SMS through Twilio or textbee, weather from Open-Meteo, market prices from data.gov.in.
- A dashboard with no JavaScript, and demo scenarios marked [TEST] that never touch real device state.
- About 290 pytest tests that run offline: the rules, the API, the dashboard, the delivery queue and the providers.
My part
Built with Mohammed Iyad, who carried the larger share. We worked across the hardware, firmware, backend, dashboard and SMS together, and I can take apart any layer of it.
Challenges
No spam
A dry field shouldn't text every 15 seconds. Moisture bands with hysteresis (LOW below 28, cleared above 35) and the cooldown gate mean one message per real change.
Honest faults
A failed DHT22 or soil reading becomes a sensor-fault code, never a plausible made-up number.
Delivery that survives a crash
Messages go through an outbox in the database with their own worker, so a slow provider never blocks a reading and a restart carries on where it stopped.
Result
Runs end to end on real hardware: dry the probe and an SMS arrives seconds later. Alerts and history survive a server restart, and every alert can be triggered on demand for a live demo. The agronomic thresholds are illustrative, not yet validated in the field.
What's next
- Validate the thresholds against local KVK values; today they are illustrative.
- Database migrations, rate limiting and an SMS when a node goes silent.
- Certificate checking on the ESP32, and a capacitive soil probe in place of the FC-28, which corrodes.