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_KEY
cURL
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[].values
Implementation 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;
}
}