Scenario
The Challenge
Modern farms need real-time weather insights to optimize irrigation, protect crops from stress, and maximize yields. Traditional weather apps lack the precision and agricultural-specific metrics needed for data-driven farming decisions.
The Solution
This implementation demonstrates how to build a responsive dashboard that monitors temperature trends, humidity levels, and evapotranspiration rates to guide irrigation scheduling and crop management decisions.
Implementation Benefits
Water Conservation
Data-driven irrigation scheduling reduces waste
Potential water savings (varies by crop/climate)Crop Monitoring
Temperature alerts help prevent heat stress
Improved crop health monitoring capabilityDecision Support
Real-time data for irrigation timing decisions
Enhanced decision-making toolsAutomation Foundation
Base system for IoT integration and alerts
Platform for expanding farm automationAPI Request
API Request
Request Parameters
| Parameter | Value | Type |
|---|---|---|
| location | "42.3601,-71.0589" | string |
| apikey | "YOUR_API_KEY" | string |
Request URL
https://api.tomorrow.io/v4/weather/forecast?location=42.3601%2C-71.0589&apikey=YOUR_API_KEYcURL
curl -X GET "https://api.tomorrow.io/v4/weather/forecast?location=42.3601%2C-71.0589&apikey=YOUR_API_KEY"JavaScript
const response = await fetch('https://api.tomorrow.io/v4/weather/forecast?location=42.3601%2C-71.0589&apikey=YOUR_API_KEY', {
method: 'GET',
});
const data = await response.json();API Response
🌾 Agricultural Significance of Key Fields
API Response
Key Response Fields
Complete Response
{
"timelines": [
{
"timestep": "1h",
"intervals": [
{
"time": "2024-12-21T18:00:00Z",
"values": {
"temperature": 18.6,
"humidity": 75,
"precipitationProbability": 0,
"rainIntensity": 0,
"evapotranspiration": 0.214,
"windSpeed": 4.4,
"windDirection": 70,
"dewPoint": 14.3,
"pressureSeaLevel": 1013.38
}
},
{
"time": "2024-12-21T19:00:00Z",
"values": {
"temperature": 19.7,
"humidity": 69,
"precipitationProbability": 0,
"rainIntensity": 0,
"evapotranspiration": 0.361,
"windSpeed": 3.5,
"windDirection": 68,
"dewPoint": 13.8,
"pressureSeaLevel": 1014
}
},
{
"time": "2024-12-21T20:00:00Z",
"values": {
"temperature": 20,
"humidity": 68,
"precipitationProbability": 0,
"rainIntensity": 0,
"evapotranspiration": 0.355,
"windSpeed": 3.4,
"windDirection": 76,
"dewPoint": 13.9,
"pressureSeaLevel": 1014
}
}
]
}
],
"location": {
"lat": 42.3601,
"lon": -71.0589
}
}Response Structure
Live Implementation
This interactive chart displays real weather data using Chart.js, demonstrating how to build an agricultural monitoring dashboard with Tomorrow.io API data.
Data Processing Flow
temperature, humidity, evapotranspiration from intervals[].valuesImplementation Code
// Transform weather data for Chart.js
const hourlyData = response.data.timelines[0].intervals;
const chartData = {
labels: hourlyData.map(interval =>
new Date(interval.time).toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit'
})
),
datasets: [
{
label: 'Temperature (°C)',
data: hourlyData.map(interval => interval.values.temperature),
borderColor: 'rgb(34, 197, 94)',
backgroundColor: 'rgba(34, 197, 94, 0.1)',
tension: 0.4
},
{
label: 'Heat Stress Threshold (25°C)',
data: Array(hourlyData.length).fill(25),
borderColor: 'rgb(239, 68, 68)',
borderDash: [5, 5],
pointRadius: 0
}
]
};
// Create agricultural monitoring chart
new Chart(ctx, {
type: 'line',
data: chartData,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Farm Temperature Monitoring - Next 24 Hours'
},
legend: {
display: true,
position: 'top'
}
},
scales: {
y: {
title: {
display: true,
text: 'Temperature (°C)'
},
min: 10,
max: 30
}
}
}
});
// Irrigation logic
const currentHumidity = hourlyData[0].values.humidity;
const evapotranspirationRate = hourlyData[0].values.evapotranspiration;
if (currentHumidity < 40 && evapotranspirationRate > 0.3) {
console.log('⚠️ Irrigation recommended - Low humidity & high ET rate');
} else if (currentHumidity > 80) {
console.log('✅ Adequate moisture - Monitor for fungal risk');
} else {
console.log('📊 Moisture levels normal - Continue monitoring');
}Error Handling & Data Validation
// Validate API response structure
function validateWeatherData(response) {
if (!response?.data?.timelines?.[0]?.intervals) {
throw new Error('Invalid API response structure');
}
const intervals = response.data.timelines[0].intervals;
if (intervals.length === 0) {
throw new Error('No weather data intervals found');
}
// Validate required agricultural fields
const firstInterval = intervals[0];
const requiredFields = ['temperature', 'humidity', 'evapotranspiration'];
for (const field of requiredFields) {
if (typeof firstInterval.values[field] !== 'number') {
console.warn(`Missing or invalid ${field} data`);
}
}
return true;
}
// Handle API errors gracefully
async function fetchFarmWeatherData(coordinates, apiKey) {
try {
const response = await fetch(`https://api.tomorrow.io/v4/weather/forecast?location=${coordinates}&apikey=${apiKey}`);
if (!response.ok) {
if (response.status === 401) {
throw new Error('Invalid API key');
} else if (response.status === 429) {
throw new Error('API rate limit exceeded');
} else {
throw new Error(`API error: ${response.status}`);
}
}
const data = await response.json();
validateWeatherData(data);
return data;
} catch (error) {
console.error('Weather data fetch failed:', error);
// Return fallback data or show user-friendly error
return null;
}
}