Farm intelligence dashboard for East African smallholder farmers.
FarmPulse combines real-time weather forecasting with AI-powered tree canopy analysis to deliver actionable, context-aware insights — not just data. Instead of showing a farmer "rain is coming" and "12 trees need care" separately, FarmPulse cross-references both to surface recommendations like "rain expected Thursday — ideal conditions to replant the 4 flagged trees."
Built as a technical assessment integrating the WeatherAI API.
Live demo: farmpulse-1.onrender.com
Backend: farmpulse-l2c0.onrender.com
- Current conditions — temperature, humidity, wind, UV index, with Gemini AI summary
- 7-day forecast — daily breakdown with precipitation probability
- Auto-detect location — uses WeatherAI's IP geo-detection to find the user's farm region automatically
- Farm tree analysis — upload a drone or satellite image to get tree count, canopy coverage, health breakdown (healthy / needs care / needs replacement), and agronomic recommendations powered by OpenCV + Gemini
- Insight Banner — cross-references weather forecast and tree health to generate combined, actionable farm recommendations
- Annotated overlay — visual output showing detected tree crowns on the uploaded image
| Layer | Technology |
|---|---|
| Frontend | React, Vite |
| Backend | Node.js, Express |
| Image handling | Multer (memory storage) |
| HTTP client | Axios |
| API | WeatherAI (/v1/weather, /v1/weather-geo, /v1/trees/analyze) |
| Frontend deploy | Netlify |
| Backend deploy | Render |
Client (React + Vite)
│
│ GET /api/weather?lat=&lon=
│ GET /api/weather/current
│ POST /api/trees/analyze (multipart/form-data)
▼
Express Proxy (Node.js) ← API key lives here only
│
│ Authorization: Bearer wai_...
▼
WeatherAI API (api.weather-ai.co)
The backend is a deliberate thin proxy — its only responsibility is keeping the API key server-side and forwarding requests to WeatherAI. All UI logic and data composition lives in the frontend.
- Node.js 18+
- A WeatherAI API key — sign up at weather-ai.co
git clone https://github.com/kiki-glow/FarmPulse.git
cd farmpulsecd server
npm installCreate server/.env:
WEATHER_AI_API_KEY=wai_your_key_here
PORT=3001Start the server:
npm run devBackend runs at http://localhost:3001. Verify with:
curl http://localhost:3001/healthcd client
npm installCreate client/.env:
VITE_API_URL=http://localhost:3001Start the dev server:
npm run devFrontend runs at http://localhost:5173.
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Server health check |
GET |
/api/weather?lat=&lon=&days= |
7-day forecast + current conditions |
GET |
/api/weather/current |
Auto-detect location via IP + current weather |
POST |
/api/trees/analyze |
Upload farm image for tree analysis |
curl -X POST http://localhost:3001/api/trees/analyze \
-F "image=@/path/to/farm.jpg" \
-F "location=-1.2921, 36.8219"{
"total_tree_count": 84,
"canopy_coverage_pct": 41.2,
"confidence_score": 0.87,
"tree_health": {
"healthy": 68,
"needs_care": 12,
"needs_replacement": 4
},
"recommendations": [
"Consider thinning northern section to improve light penetration",
"Improve drainage around water source trees"
],
"overlay_image_url": "https://storage.googleapis.com/..."
}farmpulse/
├── server/
│ ├── routes/
│ │ ├── weather.js # Weather + geo-detection proxy
│ │ └── trees.js # Image upload + tree analysis proxy
│ ├── middleware/
│ │ └── errorHandler.js # Centralised error handling
│ ├── .env.example
│ └── index.js
│
└── client/
├── src/
│ ├── api/
│ │ └── farmpulse.js # All fetch calls to Express backend
│ ├── components/
│ │ ├── Layout.jsx
│ │ ├── Header.jsx
│ │ ├── LocationSearch.jsx
│ │ ├── WeatherPanel.jsx
│ │ ├── ForecastStrip.jsx
│ │ ├── TreeAnalysisPanel.jsx
│ │ └── InsightBanner.jsx
│ ├── utils/
│ │ └── weatherIcon.js
│ └── App.jsx
├── .env.example
└── vite.config.js
GET /v1/weather — current conditions and 7-day forecast by coordinates, with Gemini AI summary.
GET /v1/weather-geo — auto-detects caller location from IP, returns weather + geo metadata. Used for the one-click location detection feature.
POST /v1/trees/analyze — accepts a farm image as multipart/form-data. Returns tree count, density per acre, canopy coverage, health breakdown, annotated overlay image, and Gemini-powered agronomic observations.
| Variable | Description |
|---|---|
WEATHER_AI_API_KEY |
WeatherAI API key (prefixed wai_) |
PORT |
Port to run Express on (default: 3001) |
| Variable | Description |
|---|---|
VITE_API_URL |
Base URL of the Express backend |
- Push
server/to GitHub - Create a new Web Service on Render, point to the repo
- Set build command:
npm install - Set start command:
node index.js - Add environment variable:
WEATHER_AI_API_KEY
- Push
client/to GitHub - Create a new site on Netlify, point to the repo
- Set build command:
npm run build - Set publish directory:
dist - Add environment variable:
VITE_API_URLpointing to your Render backend URL
Kinya — github.com/kiki-glow