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 capability

Decision Support

Real-time data for irrigation timing decisions

Enhanced decision-making tools

Automation Foundation

Base system for IoT integration and alerts

Platform for expanding farm automation

API Request

API Request

Request Parameters

ParameterValueType
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

temperature: Crop heat stress monitoring (°C)
humidity: Moisture levels for disease prevention (%)
evapotranspiration: Plant water loss rate (mm/hour)
precipitationProbability: Natural irrigation forecast (%)
lat/lon: Precise farm location for micro-climate data
intervals: Hourly data points for trend analysis

API Response

Status: 2007/15/2025, 12:40:44 PM

Key Response Fields

temperature
timelines.0.intervals.0.values.temperature
18.6
humidity
timelines.0.intervals.0.values.humidity
75
evapotranspiration
timelines.0.intervals.0.values.evapotranspiration
0.214
precipitationProbability
timelines.0.intervals.0.values.precipitationProbability
0
lat
location.lat
42.3601
lon
location.lon
-71.0589

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

Data Type: object
Top-level Keys: timelines, location
Response Size: ~1KB

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

1API Request: Fetch hourly weather forecast for farm coordinates
2Data Extraction: Extract temperature, humidity, evapotranspiration from intervals[].values
3Chart Transformation: Map time strings to chart labels, values to datasets
4Decision Logic: Apply irrigation thresholds based on humidity + ET rates
5Visualization: Render dual-axis chart with temperature trends and irrigation status
Current Temperature
18.6°C
✅ Optimal range
Humidity
75%
📊 Normal
Irrigation Status
Optimal Conditions
Moisture levels are within normal range
Data from Tomorrow.io Weather API • Farm Location: 42.3601, -71.0589

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;
  }
}