HOWTO: Usare le API di Wunderground – esempio pratico | Flavio's blog


HOWTO: Usare le API di Wunderground – esempio pratico

weather_underground_logo

(last update del Dicembre 2014: aggiunta la possibilità di mostrare anche le previsioni del giorno, con tanto di riassunto ed icona delle condizioni meteo.)

Weather Underground è un utilissimo sito di meteorologia, che consulto da una decina di anni, che rileva in tempo reale le condizioni atmosferiche e ne trae delle previsioni.

La affidabilità è garantita dalle tante stazioni meteo degli appassionati che inviano i loro dati al sito, e che sono installate proprio in zona.

La particolarità, molto comoda per chi possiede un sito, è che mette anche a disposizione delle comode API per poter interagire con i dati e poter, per esempio, riportare in tempo reale la temperatura di una stazione meteo, direttamente sul proprio sito, o magari le previsioni per una determinata località.

Per prima cosa, andiamo su http://www.wunderground.com/weather/api/ e registriamoci (utilizzando l’opzione free, che permette 500 chiamate al giorno e 10 al minuto) per ottenere la nostra API KEY.

A questo punto, mettiamo di voler mostrare, proprio come nella mia pagina dedicata alla città di Napoli, la temperatura di due stazioni meteo, farne la media, e mostrare quanto tempo è passato dall’ultimo aggiornamento. Inoltre, mostrare le previsioni per il giorno e la notte.

Qualcosa del tipo:

wunderground widget

Copiamo questo script in una pagina:

<?
//The script shows the latest temperature value from various selected personal Wunderground stations. Also, if desired, it shows today's forecast for the selected city. If you want to use Fahrenheit degrees, please change every occurrence of 'temp_c' to 'temp_f' in the code. Be careful to avoid excessive API calls: you have about 120 calls per day before breaking Wunderground Terms!
//Script by flapane.com - Latest rev. 30-Dec-14
$expiretime=30;     //cache expire time in minutes
$apikey="YOUR_API_KEY"; //your wunderground api key - 500 calls per day maximum!
$cachename="/home/yourusername/domains/yourwebsite.com/public_html/wunder_temp.txt"; //name of the cachefile
$forecastlang="IT"; //select forecasts language using uppercase letters
$forecastcity="Italy/Naples"; //in form of State/City in english. Leave it EMPTY if you don't want any forecasts
$number_stations="2"; //total number of PWS stations.
$station[0]="INAPLESN1"; //wunderground station name (just click on one of the personal weather stations and it will show you their name, ie. KNYBROOK40 for Williamsburg, NYC)
$station[1]="INAPOLIP2";
//Add another station using: $station[2]="wunderground station name";

//do not mess with the next lines!!!
if (!file_exists($cachename)) {    //create the cachefile if it doesn't exist
     $create = fopen($cachename, 'w');
      chmod ("$cachename", 0644); //set chmod 644
     fclose($create);
}

// Is the file older than $expiretime, or is the file new/empty?
$FileAge = time() - filemtime($cachename);    // Calculate file age in seconds
if ($FileAge > ($expiretime * 60) || 0 == filesize($cachename))
{
    $handle = fopen($cachename, 'wb');    // Now refresh the cachefile with newer content    
        for($i=0; $i<$number_stations; $i++){
            $parsed_json[$i] = json_decode(file_get_contents("http://api.wunderground.com/api/{$apikey}/conditions/q/pws:{$station[$i]}.json"));
            
            $pws_freshness = (($parsed_json[$i]->{'current_observation'}->{'local_epoch'})-($parsed_json[$i]->{'current_observation'}->{'observation_epoch'})); //elapsed time since PWS sent updated data
            $pws_freshness_human_time = round($pws_freshness/3600, 0)." hour(s)";
            if (preg_replace("/[^0-9,.]/", "", $pws_freshness_human_time) > 24) 
                {
                $pws_freshness_human_time = round($pws_freshness/86400, 1)." day(s)";
                }
                
            if ($pws_freshness < 3600) //the PWS has been sending fresh data in the last hour
                {
                $temp_c[$i] = $parsed_json[$i]->{'current_observation'}->{'temp_c'}."\n";    //add a new line \n (a capo) to every value
                }
            else
                {
                $temp_c[$i] = "<span style='font-weight:normal; font-style: italic;'>(station not reporting in the last $pws_freshness_human_time)</span> ".$parsed_json[$i]->{'current_observation'}->{'temp_c'}."\n";    //add a new line \n (a capo) to every value
                }
            $location_wunder[$i] = $parsed_json[$i]->{'current_observation'}->{'observation_location'}->{'city'}."\n";
            fwrite($handle,$temp_c[$i]);    //write temps
            fwrite($handle,$location_wunder[$i]);    //write locations
        }
        
        if(!empty ($forecastcity)){    //do you want to show the forecast for today?
            $parsed_json_forecast = json_decode(file_get_contents("http://api.wunderground.com/api/{$apikey}/forecast/lang:{$forecastlang}/q/{$forecastcity}.json"));
            for($j=0; $j<2; $j++) {
                $icon_url[$j] = $parsed_json_forecast->forecast->txt_forecast->forecastday[$j]->icon_url."\n";
                $part_of_day[$j] = $parsed_json_forecast->forecast->txt_forecast->forecastday[$j]->title.": ".$parsed_json_forecast->forecast->txt_forecast->forecastday[$j]->fcttext_metric."\n";
                fwrite($handle,$icon_url[$j]);    //write url of the daily forecast
                fwrite($handle,$part_of_day[$j]);    //write the forecasts for both parts of the day
            }
        }
}

// seconds to minutes - from http://forums.digitalpoint.com
$minutes = floor($FileAge/60)."m";
$secondsleft = $FileAge%60;
$ago = "ago";
if($secondsleft<10)
    $secondsleft = "0" . $secondsleft ."s";
if($secondsleft>10)
    $secondsleft = $secondsleft ."s";
if($minutes>$expiretime){    //avoid weird $FileAge values if cachefile has just been refreshed
    $minutes = "now";
    $secondsleft = "";
    $ago = "";
    }
    
// Display most recent temperatures and their average value
$display = file($cachename, FILE_IGNORE_NEW_LINES); //ignore \n for non-reporting stations
foreach ($display as $key=>$value){
    if($key % 2 == 0){  
         $temperature[] = $value; // EVEN (righe del file cache pari)
    }else{
         $location_wunder[] = $value;  // ODD
    }
}

for($i=0; $i<$number_stations; $i++){
       $temperature_stripped[$i] = preg_replace("/[^0-9,.-]/", "", $temperature[$i]);
    }    

$temp_avg = (array_sum($temperature_stripped)/$number_stations); //average temperature
for($i=0; $i<$number_stations; $i++){
    if($temperature[$i] == null){ //if weather station is not reporting data
       $temperature[$i] = "N/A";
       $temp_avg = "N/A";
    }    
echo "<b>".$temperature[$i]."</b>°C (".$location_wunder[$i].") | ";    
}
echo "<b>".$temp_avg."</b>°C (media) | updated $minutes$secondsleft $ago<br /><br />";

// Display the forecasts ONLY if $forecastcity is not empty
if(!empty ($forecastcity)){    //do you want to show the forecast for today?
$lines = array_slice($display, -4);
echo "<p><b>Previsioni per oggi:</b><br /><img src='$lines[0]' width='50' height='50' border='0' /> $lines[1]</p>";
echo "<p><img src='$lines[2]' width='50' height='50' border='0' /> $lines[3]</p>";
}

echo "<img src='/img/wundergroundlogo.png' />";    //showing WU logo is compulsory
?>

Sostituiamo a YOUR_API_KEY la nostra API KEY ottenuta registrandosi a Wunderground, e seguiamo le istruzioni per modificare gli altri valori (es. il corretto formato City/State per le previsioni) di configurazione a nostro piacimento.

Le API ci forniranno una risposta in formato json.

Visto il limite di chiamate giornaliere, e per evitare di appesantire troppo il sito, lo sciprt creerà un file di cache chiamato wunder_temp.txt, che si aggiornerà ogni $expiretime minuti.

Personalmente credo che 30 minuti fra un aggiornamento e l’altro, siano più che sufficienti.

Per trovare le stazioni meteo da inserire al posto di $station[0] e $station[1], dobbiamo selezionare una città in Wunderground, e cliccare su una qualsiasi stazione fra quelle presenti in STAZIONI METEO, a fine pagina.
Nella pagina che si aprirà, troveremo il codice della stazione proprio nel titolo, vicino a “Storico per: NOMESTAZIONE“.

Se non volete mostrare anche le previsioni meteo, è sufficiente lasciare VUOTO il campo $forecastcity.

Ricordo che, per usare le API di Weather Underground, è necessario mostrar,e vicino ai dati, uno dei loro loghi ufficiali, disponibili a questo indirizzo.

Avete utilizzato questo script, o lo avete modificato per recuperare informazioni che non fossero la temperatura ma, per esempio, la pressione atmosferica? Lasciate pure un commento!



2 Commenti »

Per piacere accetta i cookie di terze parti per poter commentare il post! Il pulsante CAMBIA LE SCELTE DEI COOKIE si trova nel footer del sito. / In order to comment this post, please accept the third party cookies! The button CAMBIA LE SCELTE DEI COOKIE is in the footer of the website.