Displaying local weather with Open-Meteo and PHP

One thing I’ve wanted to investigate doing for a while is changing the colors of the site based on the weather where I live. While I haven’t got that far yet, I did manage to write some code to fetch my current weather using the Open Meteo API.

The first thing I did was set up a cron job to run every 15 minutes and hit their current weather endpoint with wget and save the output to a JSON file (in my case, weather.json). I could’ve also done this directly in PHP with cURL, but cron and wget were easier and less code to maintain so I went that route. Open Meteo’s API Docs has a bunch of options you can choose to build a custom URL for your needs. I’m using the current weather endpoint and limiting the number of days to 1 since I only care about the current forecast.

Here’s what the cron job looks like:

*/15 * * * * /usr/bin/wget -O /some/file/path/weather.json "https://api.open-meteo.com/v1/forecast?latitude=XX.XXXX&longitude=-XX.XXXX&current=temperature_2m,relative_humidity_2m,is_day,rain,showers,snowfall,weather_code,wind_speed_10m,wind_direction_10m,wind_gusts_10m&temperature_unit=fahrenheit&wind_speed_unit=mph&precipitation_unit=inch&forecast_days=1" >/dev/null 2>&1

Once the weather data is saved to our local weather.json file, it’s really easy to process with PHP. This is my template-parts/part-weather.php in my theme:

// Read the weather.json file
$weather_json = file_get_contents( '/path/to/weather.json' );
$weather = json_decode( $weather_json );

// Daytime? 1 = yes, 0 = no
$is_day = $weather->current->is_day;

// Weather code
$weather_code = $weather->current->weather_code;

if ( ( $weather_code == 0 || $weather_code == 1 ) && $is_day == 1 ) {
    $weather_icon = '<i class="fa-solid fa-sun" title="Clear"></i>';
} elseif ( ( $weather_code == 0 || $weather_code == 1 ) && $is_day == 0 ) {
    $weather_icon = '<i class="fa-solid fa-moon" title="Clear"></i>';
} elseif ( $weather_code == 2 && $is_day == 1 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-sun" title="Partly Cloudy"></i>';
} elseif ( $weather_code == 2 && $is_day == 0 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-moon" title="Partly Cloudy"></i>';
} elseif ( $weather_code == 3 ) {
    $weather_icon = '<i class="fa-solid fa-cloud" title="Cloudy"></i>';
} elseif ( $weather_code == 45 || $weather_code == 48 ) {
    $weather_icon = '<i class="fa-solid fa-smog" title="Fog"></i>';
} elseif ( $weather_code == 51 || $weather_code == 53 || $weather_code == 55 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-rain" title="Drizzle"></i>';
} elseif ( $weather_code == 56 || $weather_code == 57 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-showers-water" title="Freezing Drizzle"></i>';
} elseif ( $weather_code == 61 || $weather_code == 80 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-rain" title="Light Rain"></i>';
} elseif ( $weather_code == 63 || $weather_code == 81 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-showers-heavy" title="Rain"></i>';
} elseif ( $weather_code == 65 || $weather_code == 82 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-showers-heavy" title="Heavy Rain"></i>';
} elseif ( $weather_code == 66 || $weather_code == 67 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-showers-water" title="Freezing Rain"></i>';
} elseif ( $weather_code == 71 || $weather_code == 73 || $weather_code == 75 || $weather_code == 77 || $weather_code == 85 || $weather_code == 86 ) {
    $weather_icon = '<i class="fa-solid fa-snowflake" title="Snow"></i>';
} elseif ( $weather_code == 95 ) {
    $weather_icon = '<i class="fa-solid fa-cloud-bolt" title="Thunderstorms"></i>';
} elseif ( $weather_code == 96 || $weather_code == 99 ) {
    $weather_icon = '<i class="fa-solid fa-poo-storm" title="Thunderstorm with hail"></i>';
}

// Current temperature
$current_temp = round( $weather->current->temperature_2m ) . $weather->current_units->temperature_2m;

// Output the icon and temperature
echo $weather_icon . ' ' . $current_temp;

This code is what outputs the little icon and temperature that you see in the footer of the site.

Local weather

Here’s what the code does:

  1. Grabs the weather.json file and reads it
  2. Decodes the JSON
  3. Checks for daytime
  4. Checks the weather code and outputs a Font Awesome icon. A list of the weather codes and what they mean is available at the bottom of the API docs page.
  5. Gets the current temperature
  6. Outputs the icon and temperature

It’s definitely nothing fancy and there’s a bunch more that could be done with it, but this was a really quick and easy way to get my local weather conditions and temperature on the site. If you decide to use any of this on your site, let me know on Mastodon!

0
0