← Back to Course
Weather Station Dashboard and Alerts
📊 Weather Station Dashboard and Alerts - Real-Time Weather Monitoring
📊 What You'll Learn:
- 🌡️ Set up critical weather alerts for temperature, humidity, wind, and rain
- 🚨 Receive instant notifications when thresholds are crossed
- 🌧️ Take protective action before weather damages your crops
- 📊 Configure a complete weather dashboard with real-time data
A weather station is only useful if you act on the data. Setting up automated alerts ensures you never miss a critical weather event - heat waves, frost, heavy rain, or high winds. This lesson teaches you the essential alert thresholds for farm protection.
📋 Recommended Weather Alert Thresholds
| Condition | Threshold | Urgency | Action Required |
|---|---|---|---|
| 🌡️ High Temperature | > 35°C | 🔴 HIGH | Increase irrigation by 50%, provide shade cloth |
| ❄️ Low Temperature (Frost Risk) | < 5°C | 🔴 HIGH | Cover crops, irrigate before dawn, move potted plants indoors |
| 💧 High Humidity | > 80% | 🟡 MEDIUM | Check for fungal disease, increase ventilation, apply fungicide |
| 💨 High Wind | > 30 km/h | 🟡 MEDIUM | Stop pesticide spraying, secure structures, stake tall crops |
| 🌧️ Heavy Rain | > 10 mm/hour | 🟡 MEDIUM | Skip irrigation, check drainage systems, cover vulnerable plants |
| 📉 Rapid Pressure Drop | > 2 hPa/hour | 🔴 HIGH | ⚠️ Storm approaching within 12-24 hours! Secure equipment |
| 🌞 Extreme Heat | > 40°C | 🚨 CRITICAL | Emergency irrigation, evacuate livestock, stop field work |
| ❄️ Freezing | < 0°C | 🚨 CRITICAL | Harvest sensitive crops, irrigate continuously, use row covers |
| 🌧️ Extreme Rain | > 25 mm/hour | 🚨 CRITICAL | 🚨 Flooding risk! Evacuate low areas |
💡 Alert Priority Levels:
- 🚨 CRITICAL (Red): Immediate action required within minutes - life or crop-threatening
- 🔴 HIGH (Orange): Action required within hours - significant risk to crops
- 🟡 MEDIUM (Yellow): Action within 24-48 hours - monitor closely
- 🔵 LOW (Blue): Informational only - no immediate action needed
📋 Complete Weather Alert Code
/*
* Complete Weather Station Dashboard with Alerts
* Sends SMS/Email/Push notifications when thresholds are crossed
*/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// ========== WIFI CONFIGURATION ==========
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
// ========== ALERT CONFIGURATION ==========
const float HIGH_TEMP_THRESHOLD = 35.0; // °C
const float EXTREME_TEMP_THRESHOLD = 40.0; // °C
const float LOW_TEMP_THRESHOLD = 5.0; // °C
const float FREEZE_THRESHOLD = 0.0; // °C
const float HIGH_HUMIDITY_THRESHOLD = 80.0; // %
const float HIGH_WIND_THRESHOLD = 30.0; // km/h
const float HEAVY_RAIN_THRESHOLD = 10.0; // mm/hour
const float PRESSURE_DROP_THRESHOLD = 2.0; // hPa/hour
// ========== SENSOR DATA ==========
float currentTemp = 0;
float currentHumidity = 0;
float currentPressure = 0;
float windSpeed = 0;
float rainRate = 0;
bool isRaining = false;
// ========== PRESSURE TRACKING ==========
float pressureHistory[24];
int pressureIndex = 0;
int pressureCount = 0;
// ========== ALERT FUNCTIONS ==========
void sendSMS(String message) {
// Integrate with SMS gateway (Twilio, Africa's Talking, etc.)
Serial.println("📱 SMS Alert: " + message);
}
void sendEmail(String message) {
// Integrate with email service
Serial.println("📧 Email Alert: " + message);
}
void sendPushNotification(String message) {
// Integrate with OceanRemote push notifications
Serial.println("📱 Push Alert: " + message);
}
// ========== CHECK TEMPERATURE ALERTS ==========
void checkTemperatureAlerts(float temp) {
if (temp >= EXTREME_TEMP_THRESHOLD) {
sendPushNotification("🚨 CRITICAL: Extreme heat " + String(temp) + "°C! Emergency irrigation needed!");
sendSMS("🔥 Heat emergency: " + String(temp) + "°C");
}
else if (temp >= HIGH_TEMP_THRESHOLD) {
sendPushNotification("⚠️ High temperature alert: " + String(temp) + "°C. Increase irrigation.");
}
else if (temp <= FREEZE_THRESHOLD) {
sendPushNotification("🚨 CRITICAL: Freezing " + String(temp) + "°C! Protect crops immediately!");
sendSMS("❄️ Freeze warning: " + String(temp) + "°C");
}
else if (temp <= LOW_TEMP_THRESHOLD) {
sendPushNotification("⚠️ Frost risk: " + String(temp) + "°C. Cover sensitive crops.");
}
}
// ========== CHECK HUMIDITY ALERTS ==========
void checkHumidityAlerts(float humidity) {
if (humidity > HIGH_HUMIDITY_THRESHOLD) {
sendPushNotification("💧 High humidity: " + String(humidity) + "%. Fungus risk - increase ventilation.");
}
}
// ========== CHECK WIND ALERTS ==========
void checkWindAlerts(float wind) {
if (wind > HIGH_WIND_THRESHOLD) {
sendPushNotification("💨 High wind: " + String(wind) + " km/h. Stop spraying, secure structures.");
}
}
// ========== CHECK RAIN ALERTS ==========
void checkRainAlerts(float rain, bool raining) {
if (raining) {
sendPushNotification("🌧️ Rain detected! Skipping irrigation.");
}
if (rain > HEAVY_RAIN_THRESHOLD) {
sendPushNotification("⚠️ Heavy rain: " + String(rain) + " mm/hour. Check drainage.");
}
if (rain > 25) {
sendSMS("🚨 Extreme rain: " + String(rain) + " mm/hour. Flooding risk!");
}
}
// ========== CHECK PRESSURE TREND ==========
void addPressureReading(float pressure) {
pressureHistory[pressureIndex] = pressure;
pressureIndex = (pressureIndex + 1) % 24;
if (pressureCount < 24) pressureCount++;
}
float getPressureTrend() {
if (pressureCount < 3) return 0;
int current = (pressureIndex - 1 + 24) % 24;
int past = (pressureIndex - 4 + 24) % 24; // 3 hours ago
return (pressureHistory[current] - pressureHistory[past]) / 3;
}
void checkPressureAlerts(float trend) {
if (trend < -PRESSURE_DROP_THRESHOLD) {
sendPushNotification("⚠️ Rapid pressure drop: " + String(trend) + " hPa/hour. Storm approaching!");
sendSMS("🌩️ Storm warning: Pressure dropping rapidly");
}
}
// ========== DISPLAY DASHBOARD ==========
void displayDashboard() {
Serial.println("\n╔══════════════════════════════════════════════════════════════╗");
Serial.println("║ 🌤️ WEATHER DASHBOARD ║");
Serial.println("║ " + String(__TIME__) + " ║");
Serial.println("╚══════════════════════════════════════════════════════════════╝");
Serial.println("\n🌡️ TEMPERATURE:");
if (currentTemp > HIGH_TEMP_THRESHOLD) {
Serial.printf(" 🔴 %.1f°C (HIGH - Action needed)\n", currentTemp);
} else if (currentTemp < LOW_TEMP_THRESHOLD) {
Serial.printf(" 🔵 %.1f°C (LOW - Frost risk)\n", currentTemp);
} else {
Serial.printf(" 🟢 %.1f°C (Normal)\n", currentTemp);
}
Serial.println("\n💧 HUMIDITY:");
if (currentHumidity > HIGH_HUMIDITY_THRESHOLD) {
Serial.printf(" 🟡 %.1f%% (HIGH - Disease risk)\n", currentHumidity);
} else {
Serial.printf(" 🟢 %.1f%% (Normal)\n", currentHumidity);
}
Serial.println("\n💨 WIND:");
if (windSpeed > HIGH_WIND_THRESHOLD) {
Serial.printf(" 🟡 %.1f km/h (HIGH - Caution)\n", windSpeed);
} else {
Serial.printf(" 🟢 %.1f km/h (Normal)\n", windSpeed);
}
Serial.println("\n🌧️ RAIN:");
Serial.printf(" Raining: %s\n", isRaining ? "YES" : "NO");
Serial.printf(" Rate: %.1f mm/hour\n", rainRate);
float trend = getPressureTrend();
Serial.println("\n📊 PRESSURE TREND:");
if (trend < -PRESSURE_DROP_THRESHOLD) {
Serial.printf(" 🔴 %.1f hPa/hour (RAPID DROP - Storm risk)\n", trend);
} else {
Serial.printf(" 🟢 %.1f hPa/hour (Stable)\n", trend);
}
Serial.println("\n══════════════════════════════════════════════════════════════\n");
}
// ========== SEND TO OCEANREMOTE ==========
void sendToOceanRemote() {
if (WiFi.status() != WL_CONNECTED) return;
HTTPClient http;
http.begin("https://api.oceanremote.net/device/state");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String data = "token=YOUR_TOKEN";
data += "&temperature=" + String(currentTemp);
data += "&humidity=" + String(currentHumidity);
data += "&pressure=" + String(currentPressure);
data += "&wind_speed=" + String(windSpeed);
data += "&rain_rate=" + String(rainRate);
data += "&raining=" + String(isRaining ? "YES" : "NO");
http.POST(data);
http.end();
}
// ========== READ SENSORS (Placeholder) ==========
void readSensors() {
// Replace with actual sensor readings
// currentTemp = dht.readTemperature();
// currentHumidity = dht.readHumidity();
// currentPressure = bmp.readPressure() / 100.0F;
// windSpeed = readWindSpeed();
// rainRate = readRainRate();
// isRaining = (digitalRead(RAIN_PIN) == LOW);
// Test values - replace with actual!
currentTemp = 36.5;
currentHumidity = 85.0;
currentPressure = 1008.0;
windSpeed = 25.0;
rainRate = 12.0;
isRaining = true;
}
// ========== SETUP ==========
void setup() {
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("✅ WiFi connected!");
Serial.println("========================================");
Serial.println("🌤️ WEATHER STATION DASHBOARD v2.0");
Serial.println(" Real-time alerts + monitoring");
Serial.println("========================================\n");
}
// ========== LOOP ==========
void loop() {
readSensors();
// Add pressure to history
addPressureReading(currentPressure);
// Check all alerts
checkTemperatureAlerts(currentTemp);
checkHumidityAlerts(currentHumidity);
checkWindAlerts(windSpeed);
checkRainAlerts(rainRate, isRaining);
checkPressureAlerts(getPressureTrend());
// Display dashboard
displayDashboard();
// Send to cloud
sendToOceanRemote();
delay(600000); // Check every 10 minutes
}
📖 Case Study - Frost Alert Saves Citrus Crop:
A citrus farmer in South Africa set up low-temperature alerts:
- ❄️ 2 AM alert: Temperature dropped to 3°C (frost risk)
- 📱 Push notification: Farmer woke up and checked dashboard
- 💧 Action: Started irrigation before dawn (water releases heat when freezing)
- 🌡️ Result: Temperature dropped to -1°C but crops survived
- 💰 Savings: Prevented $10,000 in crop loss
"The frost alert woke me at 2 AM. Without it, I would have lost my entire harvest." - Citrus Farmer, South Africa
💡 Dashboard Best Practices:
- 📱 Mobile-first design: Most farmers check on phones - ensure dashboard is responsive
- 🎨 Color code everything: Red = critical, Yellow = warning, Green = normal
- 🚨 Multiple alert methods: Push notification + SMS (for when internet is down)
- ⏰ Avoid alert fatigue: Use cooldown periods (don't alert every minute)
- 📊 Historical trends: Show 24-hour graphs to visualize patterns
🎯 Key Takeaways:
- ✅ High temp (>35°C): Increase irrigation, provide shade
- ✅ Low temp (<5°C): Frost risk - cover crops, irrigate before dawn
- ✅ High humidity (>80%): Fungus risk - increase ventilation
- ✅ High wind (>30 km/h): Stop spraying, secure structures
- ✅ Heavy rain (>10 mm/h): Skip irrigation, check drainage
- ✅ Rapid pressure drop (>2 hPa/h): Storm approaching in 12-24 hours
Next lesson: Calibration and Maintenance of Weather Station
💡 Key Takeaways:
- Apply these concepts directly to your farm or project.
- Take notes on important details for the quiz.
- Use the button below to track your progress.
×