english English

Weather.com API PHP Class

In navolging op mijn blogpost over de Weather API, de verschillende reacties hierop en de reply's op twitter zal ik via deze blogpost wat verder ingaan op de class die we gebruiken binnen Inventis om de Weather API aan te spreken.

De Class

Je kunt de broncode van de class terugvinden op http://code.google.com/p/weathercomforecast/source/browse/trunk/Inventis/Weathercomforecast.php. Opmerkingen zijn steeds welkom in de comments en bugs mag je steeds rapporteren op de bug tracker van Google Code .

Hoe de Class aanroepen

try
{
	$weatherForecast = new Inventis_Weathercomforecast('BEXX0028', 5);
	$weatherDataCity = $weatherForecast->fetchForecast();		
}	
catch (Exception $e)
{
	die($e->getMessage());
}
			
		

Hierboven kun je een voorbeeld vinden van hoe je de class moet aanroepen. Dit stukje code zal via een Try ... Catch statement proberen de weerscondities en voorspellingen voor 5 dagen op te halen voor Kleine Brogel (BEXX0028).

De class uitvergroot

Ik zal kort even functie per functie omschrijven wat er juist gedaan wordt.

Variabelen

Wanneer je deze class gaat gebruiken, vergeet dan zeker niet de variabelen correct in te stellen. Vergeet zeker niet het cachePath op te geven omdat anders bij iedere aanroep van de class een request gedaan wordt naar de Weather.com API.

fetchForecast

public function fetchForecast()
{            
	$this->xmlLocation = "http://xoap.weather.com/weather/local/"
		.$this->cityId."?cc=*&dayf=".$this->dayLength
		."&link=xoap∏=xoap&par=".$this->partnerId
		."&key=".$this->licenseKey."&unit=".$this->units;
		
	$this->xmlUrl = md5($this->xmlLocation);
	
	//check for cachefile
	$this->xmlString = $this->_fetchCache();
	
	//make new simple XML element from string
	$this->xmlData = new SimpleXMLElement($this->xmlString);
	
	//prepare array                    
	$weatherForeCast = array();
	
	//fetch location data
	if(isset($this->xmlData->loc))
		$weatherForeCast['location'] = $this->_fetchLocationData();
	
	//fetch current conditions
	if(isset($this->xmlData->cc))        
		$weatherForeCast['current_conditions'] = $this->_fetchCurrentConditionsData();
	
	
	//fetch day forecasts        
	if(isset($this->xmlData->dayf))
	{
		$weatherForeCast['last_update_dayforecasts'] = $this->xmlData->dayf->lsup;
		$weatherForeCast['day_forecasts'] = $this->_fetchDayForecastsData();
	}
	
	//return weather forecast
	return $weatherForeCast;
}		
		

Deze functie zal de uiteindelijke voorspellingen gaan teruggeven.

$this->_fetchCache() kijkt of er nog een up to date voorspelling gecached werd of niet, deze functie ga ik later bespreken.

De XML string die wordt teruggeven wordt dan via $this->xmlData = new SimpleXMLElement($this->xmlString); in een nieuw SimpleXML object gestoken. Mocht er hier iets foutlopen, dan kun je dit steeds opvangen met een Try ... Catch statement.

_fetchCache

private function _fetchCache()
{
	$data = false;
	
	//check if cachedir exists
	//if doesn't exist do API-request and fetch XML
	//this will lead to huge overhead so make sure the cachedir exists
	if(!is_dir($this->cachePath))
		return $this->_fetchXML($this->xmlLocation);
	
	$cachefilename = $this->cachePath . $this->xmlUrl;
	//check if cache is still up to date
	if (file_exists($cachefilename) && (time() - $this->cacheLifetime < filemtime($cachefilename)))
	{
		$url = $cachefilename;
		$fp = fopen($url,"r");
		while (!feof ($fp))$data .= fgets($fp, 4096);
		fclose ($fp);
	}
	else
	{        
		//make cache
		$data = $this->_fetchXML($this->xmlLocation);    
		$fw = fopen($cachefilename, 'w');
		fwrite($fw, $data);
		fclose($fw);
	}
	
	return $data;        
}  		
		

Binnen deze functie wordt er gekeken of er nog een cache beschikbaar is, zoniet wordt er een nieuwe aangemaakt. Deze functie zal de XML response terugsturen.

_fetchXML

private function _fetchXML($url)
{
	$curl = curl_init();
	curl_setopt ($curl, CURLOPT_URL, $url);
	curl_setopt ($curl, CURLOPT_TIMEOUT, 30);
	curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);

	$html = curl_exec ($curl);
	if (!$html)        
		throw new Exception('Could not load URL');        
	
	curl_close ($curl);
	return $html;
} 		
		
		

Via cURL halen we de XML response binnen en sturen we deze als string door.

_fetchLocationData

private function _fetchLocationData()
{
	$location = $this->xmlData->loc;
	return array(        
		'name'          => $location->dnam,
		'locale_time'	=> date("H:i", strtotime($location->tm)),
		'latitude'      => $location->lat,
		'longitude'     => $location->lon,
		'sunrise'       => date("H:i", strtotime($location->sunr)),
		'sunset'        => date("H:i", strtotime($location->suns)),
		'timezone'      => $location->zone
	);
} 
			
		

Via deze functie worden de gegevens opgehaald met betrekking tot de locatie waaronder de lokale tijd, tijdzone, lengtebreedte, hoogtebreedte, zonsopgang en zonsondergang.

_fetchCurrentConditionsData

private function _fetchCurrentConditionsData()
{
	$currentConditions    = $this->xmlData->cc;
	return array(
		'last_update'       => date("Y-m-d H:i:s", strtotime(str_replace('Local Time', '', $currentConditions->lsup))),
		'observation_tower' => $currentConditions->obst,
		'temperature'       => $currentConditions->tmp,
		'feels_like'        => $currentConditions->flik,
		'text'              => $currentConditions->t,
		'icon'              => $currentConditions->icon,        
		'bar_value'         => $currentConditions->bar->r,
		'bar_text'          => $currentConditions->bar->d,            
		'wind_speed'        => $currentConditions->wind->s,
		'wind_gust'         => $currentConditions->wind->gust,
		'wind_direction'    => $currentConditions->wind->d,
		'wind_text'         => $currentConditions->wind->t,
		'humidity'          => $currentConditions->hmid,
		'visibility'        => $currentConditions->vis,        
		'uv_index'          => $currentConditions->uv->i,
		'uv_text'           => $currentConditions->uv->t,
		'dew_point'         => $currentConditions->dewp,
		'moon_icon'         => $currentConditions->moon->icon,
		'moon_text'         => $currentConditions->moon->t
	);
}			
			
		

Wanneer je de huidige weercondities wilt ophalen worden er via deze functie gegevens zoals de gevoelstemperatuur, luchtdruk, UV-index en vochtigheidsgraad opgehaald.

_fetchDayForecastsData

private function _fetchDayForecastsData()
{
	$days = array();
	$dayForecasts = $this->xmlData->dayf;
	foreach($dayForecasts->day as $child)
	{    
		$day = array(
			'index'     => $child->attributes()->d,
			'text'      => $child->attributes()->t,
			'date'      => $child->attributes()->dt,
			'high'      => $child->hi,
			'low'       => $child->low,
			'sunrise'   => date("H:i", strtotime($child->suns)),
			'sunset'    => date("H:i", strtotime($child->sunr))
		);
		foreach($child->part as $part)
		{
			//check if day or night
			$dayNight = ($part->attributes()->p == 'd' ? 'day' : 'night');
			$day[$dayNight] = array(
				'icon'           => $part->icon,
				'text'           => $part->t,
				'wind_speed'     => $part->wind->s,
				'wind_gust'      => $part->wind->gust,
				'wind_direction' => $part->wind->d,
				'wind_text'      => $part->wind->t,
				'bt'             => $part->bt,
				'ppcp'           => $part->ppcp,
				'humidity'       => $part->hmid,
			);                    

		}
		
		$days[] = $day;                
	}
	return $days;
} 
			
		

Afhankelijk van het aantal opgegeven dagen zal hier per dag de voorspelling voor overdag en 's nachts opgehaald worden. Via de attributen van het child-element kun je achterhalen voor welke dag de voorspellingen gedaan werden.

Wil je deze class gebruiken, geen probleem. Je kunt de broncode van de class terugvinden op http://code.google.com/p/weathercomforecast/source/browse/trunk/Inventis/Weathercomforecast.php. Opmerkingen zijn steeds welkom in de comments en bugs mag je steeds rapporteren op de bug tracker van Google Code .

RSS reacties feed

8 reacties tot nu toe

Serge Peeters

Serge Peeters zei 2 jaar geleden:

Zeer handig en nuttig, bedankt om dit te delen. Dit ga ik in één van mijn volgende projecten zeker gebruiken.
Zomerbrochure

Zomerbrochure zei 2 jaar geleden:

Ik ga nog steeds iemand nodig hebben vrees ik ondanks de heel goede post en uitleg. :)
Tom Hermans

Tom Hermans zei 2 jaar geleden:

Is er iemand die weet waar je data over sneeuwhoogtes kan vinden ? Eén of ander xml-feed oid .. niet gewoon een website

Grtz,
Tom.
Dieter

Dieter zei 2 jaar geleden:

@Tom Hermans, er zijn verschillende diensten die dit aanbieden zoals bv: http://www.weatheronyoursite.nl/
Cedric Vandendriessche

Cedric Vandendriessche zei 2 jaar geleden:

Is er ook ergens een API te vinden die overweg kan met de meeste Belgische steden? Weather.com heeft er namelijk maar enkele..
Dieter

Dieter zei 2 jaar geleden:

@Cedric Vandendriessche, je kunt hier bijvoorbeeld de weather API van Google voor gebruiken.
Deze is wel niet zo uitgebreid als deze van Weather.Com, maar bied wel meer steden aan.

Je kunt deze als volgt aanroepen:
http://www.google.com/ig/api?weather=Houthalen-Helchteren

Je krijgt dan XML-data terug met de voorspellingen.

Ik hoop dat dit je wat verder helpt.
Mike

Mike zei 2 jaar geleden:

Voor hoeveel dagen kan je de voorspellingen ophalen?

Ik gaf namelijk in de classe aan voor 6 dagen de voorspellingen te willen hebben:

$weatherForecast = new Inventis_Weathercomforecast('NLXX0017', 6);

Maar ik krijg er maar 5 te zien.

Verder super handige classe! Goed werk.
Dieter

Dieter zei 2 jaar geleden:

@Mike toen deze blogpost werd geschreven was het mogelijk om een voorspelling op te halen van 10 dagen (dag zelf + 9 volgende dagen). Enkele maanden geleden is er een update gebeurd door Weather.com zodat je nu nog maar een voorspelling kunt ophalen van 5 dagen (dag zelf + 4 volgende dagen)

Reageer op dit artikel

Toegelaten tags: <a href="" title=""> <code> <em> <strong>

RSS Feed

Bekijk alle tags

Laatste reacties

  • Fabio Maggio: @Tom Claus: bedankt!
  • Tom Claus: @Filip Bedankt voor de tip, CouchDB gaan we zeker even mee bekijken. @Fabio Deze...
  • Fabio Maggio: Is die presentatie van Masterizing PHP Data Structure ook nog ergens te bekijken?
  • Tom Hermans: Thx Tom, schone samenvatting en een massa interessante links, ideaal voor mensen die die dag...
  • Filip Stas: Als MongoDb je al boeit zeker ook eens kijken naar couchbase ook zeker de moeite!