Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ sketches/secrets.h

.env
.vscode
.kiro
.kiro

stitch/
249 changes: 190 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,237 @@
# 🌱 TerraDetect – A Smart Agriculture Solution

[![Live](https://img.shields.io/badge/Live-Demo-00C853?style=flat-square&logo=vercel&logoColor=white)](https://terradetect.onrender.com)
[![Built with Flask](https://img.shields.io/badge/Built%20with-Flask-000?style=flat-square&logo=flask)](https://flask.palletsprojects.com/)
[![Made with Python](https://img.shields.io/badge/Made%20with-Python-FFD43B?style=flat-square&logo=python&logoColor=blue)](https://python.org)
[![Go Backend](https://img.shields.io/badge/Backend-Go-00ADD8?style=flat-square&logo=go)](https://go.dev)
[![React Native](https://img.shields.io/badge/Mobile-React%20Native-61DAFB?style=flat-square&logo=react)](https://reactnative.dev)
[![ESP32](https://img.shields.io/badge/Hardware-ESP32-3C873A?style=flat-square&logo=esphome)](https://www.espressif.com/en/products/socs/esp32)

> πŸ”— **Live Demo**: [https://terradetect.onrender.com](https://terradetect.onrender.com)

---

TerraDetect is a smart farming assistant that combines real-time **soil monitoring**, **sensor-based data collection**, and **ML-powered crop & fertilizer recommendations**. It uses ESP32 microcontrollers to gather environmental data and a Flask web app to display and analyze this information.
TerraDetect is a comprehensive smart farming platform that combines real-time **soil monitoring**, **IoT sensor integration**, and **ML-powered crop & fertilizer recommendations**. The system features a Go backend with ONNX inference, React Native mobile app with Expo, and ESP32 microcontrollers for environmental data collection.

---

## πŸ”§ Key Features

### 🌐 Web Dashboard (Flask)
- πŸ“Š Visualize real-time & historical soil data
- 🌾 Crop and fertilizer prediction using ML
- πŸŒ“ Dark mode UI with mobile responsiveness
- πŸ”’ Secure API endpoints with JWT authentication
### πŸ“± Mobile App (React Native + Expo)
- οΏ½ Modern Material Design 3 UI with dark mode support
- πŸ“Š Real-time sensor data visualization with telemetry cards
- 🌾 ML-powered crop, fertilizer, and suitability predictions
- πŸ“ˆ Historical data tracking and analysis
- οΏ½ User authentication with JWT tokens
- 🎭 **Guest Mode** - Try predictions without registration
- οΏ½ Offline support with request queuing
- οΏ½ Cross-platform (iOS & Android)

### �️ Backend (Go + MongoDB)
- ⚑ High-performance REST API with Gin framework
- 🧠 ONNX Runtime for ML inference (crop & fertilizer models)
- πŸ” JWT authentication with refresh tokens
- πŸ‘₯ User and device management
- πŸ“Š Sensor data storage and retrieval
- 🎭 Guest token system for anonymous predictions
- πŸ”’ Rate limiting and security middleware
- πŸ“‘ CORS support for cross-origin requests

### πŸ”Œ IoT Integration (ESP32)
- πŸ“‘ WiFiManager for dynamic setup
- πŸ” User-entered 6-character Device ID (stored in EEPROM)
- πŸ“‘ WiFi connectivity with dynamic configuration
- πŸ” Device ID authentication (format: AB1234)
- πŸ“ˆ HTTPS sensor data uploads with API key validation
- 🌿 Sensor support:
- 🌿 Multi-sensor support:
- Soil pH
- Moisture
- Temperature
- Temperature & Humidity
- EC (Electrical Conductivity)
- NPK (via RS485 Modbus)
- NPK (Nitrogen, Phosphorus, Potassium)

### πŸ€– Machine Learning
- 🌾 Crop recommendation (23 crop types)
- πŸ§ͺ Fertilizer suggestion (7 fertilizer types)
- πŸ“Š Crop suitability analysis
- ⚑ ONNX models for fast inference
- 🎯 Confidence scores for predictions

---

## πŸ“ Folder Structure
## πŸ“ Project Structure

```
TerraDetect/
β”œβ”€β”€ esp32/ # ESP32 firmware & sensor integration
β”œβ”€β”€ static/ # CSS, JS, images
β”œβ”€β”€ templates/ # Jinja2 HTML templates
β”œβ”€β”€ models/ # Crop & fertilizer ML models
β”œβ”€β”€ utils/ # Utility scripts (auth, helpers)
β”œβ”€β”€ app.py # Flask backend
└── requirements.txt # Python dependencies
β”œβ”€β”€ backend/ # Go backend server
β”‚ β”œβ”€β”€ handlers/ # API route handlers
β”‚ β”œβ”€β”€ middleware/ # Auth, rate limiting, CORS
β”‚ β”œβ”€β”€ models/ # Data models (User, Device, Sensor)
β”‚ β”œβ”€β”€ inference/ # ONNX ML inference engine
β”‚ β”œβ”€β”€ db/ # MongoDB connection
β”‚ └── main.go # Server entry point
β”œβ”€β”€ mobile/ # React Native mobile app
β”‚ β”œβ”€β”€ app/ # Expo Router pages
β”‚ β”‚ β”œβ”€β”€ (app)/ # Authenticated screens
β”‚ β”‚ └── (auth)/ # Auth screens (login, register, guest)
β”‚ β”œβ”€β”€ components/ # Reusable UI components
β”‚ β”œβ”€β”€ store/ # Zustand state management
β”‚ β”œβ”€β”€ lib/ # API client & utilities
β”‚ └── assets/ # Images, icons, fonts
β”œβ”€β”€ ml/ # Machine learning models
β”‚ β”œβ”€β”€ crop-model.onnx # Crop recommendation model
β”‚ β”œβ”€β”€ fertilizer-model.onnx # Fertilizer suggestion model
β”‚ └── *.py # Model training & conversion scripts
β”œβ”€β”€ sketches/ # ESP32 Arduino firmware
β”‚ └── esp32_terradetect.ino
└── docs/ # API documentation
```

---

## πŸš€ Getting Started

### 🧰 Requirements
- Python 3.9+
- Flask, scikit-learn, pandas
- ESP32-WROOM-32 (30-pin or 38-pin)
- Arduino IDE / PlatformIO for flashing ESP32
### 🧰 Prerequisites
- **Backend**: Go 1.21+, MongoDB 4.4+
- **Mobile**: Node.js 18+, npm/yarn, Expo CLI
- **IoT**: ESP32-WROOM-32, Arduino IDE or PlatformIO
- **ML**: Python 3.9+ (for model training/conversion)

### βš™οΈ Backend Setup

```bash
# Navigate to backend directory
cd backend

# Install Go dependencies
go mod download

# Set up environment variables
cp .env.example .env
# Edit .env with your MongoDB URI and JWT secret

# Run the server
go run .
```

The backend will start on `http://localhost:8080`

### βš™οΈ Setup
### πŸ“± Mobile App Setup

```bash
# Clone the repo
git clone https://github.com/gagan-ahlawat-0/TerraDetect---A-Smart-Agriculture-Solution.git
cd TerraDetect---A-Smart-Agriculture-Solution
# Navigate to mobile directory
cd mobile

# Install dependencies
pip install -r requirements.txt
npm install

# Set up environment variables
cp .env.example .env
# Edit .env with your API URL

# Start Expo development server
npx expo start

# Run the Flask app
python app.py
# Scan QR code with Expo Go app (iOS/Android)
# Or press 'a' for Android emulator, 'i' for iOS simulator
```

### πŸ“‘ Flashing ESP32
### πŸ“‘ ESP32 Setup

- Open `esp32/` code in Arduino IDE
- Upload to ESP32 board
- On first boot:
- Connect to ESP32 AP
- Enter WiFi credentials + Device ID
1. Open `sketches/esp32_terradetect.ino` in Arduino IDE
2. Install required libraries:
- WiFiManager
- HTTPClient
- ArduinoJson
3. Copy `secrets.h.template` to `secrets.h` and configure:
- API endpoint URL
- Device ID
- API key
4. Upload to ESP32 board
5. On first boot, connect to ESP32 AP to configure WiFi

---
### πŸ€– ML Model Training (Optional)

```bash
# Navigate to ml directory
cd ml

## πŸ” Security
# Train models (if needed)
python train_crop_model.py
python train_fertilizer_model.py

- πŸ”‘ HTTPS requests from ESP32 with API key
- 🧠 Device identity stored in EEPROM
- πŸ”’ JWT tokens for secure API access
# Convert to ONNX format
python export_onnx.py

# Validate ONNX models
python validate_onnx.py
```

---

## πŸ“Š ML Prediction Modules
## πŸ” API Endpoints

### Authentication
- `POST /api/v1/auth/register` - Register new user
- `POST /api/v1/auth/login` - User login
- `POST /api/v1/auth/guest` - Get guest token (30 min)
- `POST /api/v1/auth/refresh` - Refresh access token
- `POST /api/v1/auth/logout` - Logout user

### Sensor Data (Authenticated)
- `GET /api/v1/sensor/latest` - Get latest sensor reading
- `GET /api/v1/sensor/history` - Get historical data (paginated)

### Predictions (Authenticated)
- `POST /api/v1/predict/crop` - Crop recommendation
- `POST /api/v1/predict/fertilizer` - Fertilizer suggestion
- `POST /api/v1/predict/suitability` - Crop suitability analysis

### Guest Predictions (No Auth Required)
- `POST /api/v1/guest/predict/crop` - Guest crop prediction
- `POST /api/v1/guest/predict/fertilizer` - Guest fertilizer prediction
- `POST /api/v1/guest/predict/suitability` - Guest suitability analysis

### Device Management
- `POST /api/v1/device/check` - Check device availability
- `POST /api/esp32` - ESP32 sensor data upload (API key required)

- **Crop Recommendation**
Based on NPK, pH, and other sensor values
See [docs/api.md](docs/api.md) for detailed API documentation.

- **Fertilizer Suggestion**
Trained on real-world datasets to identify soil deficiencies
---

## πŸ”’ Security Features

- πŸ”‘ JWT-based authentication with access & refresh tokens
- 🎭 Guest tokens with limited permissions (30-minute expiry)
- πŸ” API key validation for ESP32 devices
- πŸ›‘οΈ Rate limiting on all endpoints
- 🚫 CORS protection with configurable origins
- πŸ”’ Password hashing with bcrypt
- πŸ“Š User-specific data isolation
- 🧠 Device identity validation (format: AB1234)

---

## πŸ§‘β€πŸŒΎ Use Cases

- Farmers optimizing fertilizer use
- Students building Agri-IoT projects
- Researchers monitoring field soil health
- 🌾 **Farmers**: Real-time soil monitoring and crop recommendations
- πŸŽ“ **Students**: Learning platform for Agri-IoT and ML applications
- πŸ”¬ **Researchers**: Field data collection and analysis
- 🏒 **Agribusinesses**: Precision agriculture and resource optimization
- 🌱 **Home Gardeners**: Smart gardening with data-driven insights
- πŸ‘₯ **Consultants**: Try predictions as guest without registration

---

## 🎯 Key Improvements in v2.0

- βœ… **Complete rewrite** from Flask to Go for better performance
- βœ… **Native mobile app** with React Native + Expo
- βœ… **Guest mode** for trying predictions without registration
- βœ… **ONNX inference** for faster ML predictions
- βœ… **Real-time telemetry** dashboard with live sensor data
- βœ… **Offline support** with request queuing
- βœ… **Material Design 3** UI with dark mode
- βœ… **Enhanced security** with JWT refresh tokens
- βœ… **Better error handling** and user feedback
- βœ… **Comprehensive API** documentation

---

Expand All @@ -115,13 +243,16 @@ python app.py

## βš™οΈ Tech Stack

| Layer | Tech Used |
|---------------|----------------------------------|
| Frontend | HTML, CSS, JS, FontAwesome |
| Backend | Python, Flask, REST APIs |
| ML | Scikit-learn, Pandas, NumPy |
| IoT Hardware | ESP32, RS485 NPK, analog sensors |
| Auth & Security | JWT, API keys, EEPROM, HTTPS |
| Layer | Technologies |
|------------------|-------------------------------------------------|
| **Mobile App** | React Native, Expo, TypeScript, NativeWind |
| **Backend** | Go, Gin, MongoDB, ONNX Runtime |
| **ML Models** | Python, Scikit-learn, ONNX |
| **IoT Hardware** | ESP32, RS485 NPK sensor, analog sensors |
| **Auth** | JWT, bcrypt, guest tokens |
| **State Mgmt** | Zustand (mobile) |
| **Styling** | TailwindCSS (NativeWind), Material Design 3 |
| **API** | REST, JSON, CORS |

---

Expand Down
35 changes: 35 additions & 0 deletions backend/handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,27 @@ func (h *AuthHandler) Logout(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Logged out successfully."})
}

func (h *AuthHandler) GuestToken(c *gin.Context) {
// Generate a guest token valid for 30 minutes
guestToken, err := h.generateGuestToken(30 * time.Minute)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": gin.H{
"code": "INTERNAL_ERROR",
"message": "Failed to generate guest token.",
},
})
return
}

c.JSON(http.StatusOK, gin.H{
"access_token": guestToken,
"expires_in": 1800, // 30 minutes in seconds
"token_type": "Bearer",
"user_type": "guest",
})
}

func (h *AuthHandler) generateToken(username, deviceID, tokenType string, duration time.Duration) (string, error) {
claims := jwt.MapClaims{
"username": username,
Expand All @@ -372,3 +393,17 @@ func (h *AuthHandler) generateToken(username, deviceID, tokenType string, durati

return token.SignedString([]byte(h.cfg.SecretKey))
}

func (h *AuthHandler) generateGuestToken(duration time.Duration) (string, error) {
claims := jwt.MapClaims{
"username": "guest",
"device_id": "",
"token_type": "guest",
"exp": time.Now().Add(duration).Unix(),
"iat": time.Now().Unix(),
}

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

return token.SignedString([]byte(h.cfg.SecretKey))
}
Loading
Loading