Servus,
da ich bei weather.com nur kostenpflichtige XML Dienste gefunden habe, hab ich heute mal daran gesetzt und einen kostenfreien Wetterdienst mit XML Daten implementiert.
Warum das Ganze? Hmm, ich betrachte die Wetteranzeige im Webcontrol eher als Gimmick, für das ich nicht auch noch Geld bezahlen will.
Hier erst mal die Hauptfunktionen / Anforderungen:
- Keine Änderung an der CCU notwendig
- Keine CPU Last in der CCU beim Aktualisieren der Daten
- Aktualisierung nur bei Bedarf, kein unnötiger Traffic
- Individuell im Aussehen und Funktion anpassbar
Nachfolgend eine kleine Anleitung zum Einbauen - ein wenig PHP / HTML / CSS Kenntnisse vorausgesetzt. Ich habe bei Freeweatheronline.com einen kostenfreien XML Wetterdienst gefunden, bei dem ihr euch über
http://www.worldweatheronline.com/register.aspx anmelden könnt. Nach der Anmeldung solltet ihr im Besitz eines gültigen API Keys sein. Nun müsst ihr nur noch Änderungen an ein paar Dateien vornehmen.
Als erstes der Stammcode. Aus der Datei includes/php/weather.php einiges habe ich als gegeben übernommen, aber vieles eben auch abgeändert. Speichert dazu nachfolgenden Quellcode als fweather.php im Verzeichnis includes/php/.
Hier mal der Quellcode, denke die Kommentare sagen alles Weitere:
Code: Alles auswählen
<?php
class WeatherXmlFeedForecast {
private $LicenceKey = 'GET-YOUR-OWN'; // Dein kostenloser Licence Key von www.worldweatheronline.com
private $City = 'Leipzig,Germany'; // Standard Stadt. Das Land wird in der Anzeige ausgeblendet. Details siehe: http://www.worldweatheronline.com/weather-api.aspx
private $UpdateIntervall = 4; // Alle wie viele Stunden sollen die Wetter Cache Daten aktualisiert werden? (mind. 3.5 laut AGB!)
private $Forecast = 5; // Anzahl der Tage für die Verhersage, falls keine im Funktionsaufruf angegeben werden
private $WeatherCache = '../../weathercache/'; // Pfad für die XML Cache Dateien (../../ ist das Root Verzeichnis)
public $CurrentConditions = array();
public $DaysForecast = array();
function __construct ($Var_City,$Var_Forecast) {
// Funktionaufruf Fehlerprüfung
if($Var_City!=''){$this->City=$Var_City;}else{$this->City=$DefaultCity;}
if($Var_Forecast!=''&&is_int($Var_Forecast*1)){$this->Forecast=$Var_Forecast;}else{$this->Forecast = $Forecast;}
// URL mit den entsprechenden XML Daten
$this->Url = 'http://free.worldweatheronline.com/feed/weather.ashx?key='.$this->LicenceKey.'&q='.urlencode($this->City).'&num_of_days='.$this->Forecast.'&format=xml';
// URL zur XML Cache Datei
$this->WeatherCache.=$this->City.'.xml';
$xmlCache = 'Cached - ';
//Gibt es zu dem Ort schon eine Cache Datei?
if(file_exists($this->WeatherCache)){
$xmlCity = simplexml_load_string(file_get_contents($this->WeatherCache));
$xmlTime = $this->TimeEngToDeu((string)$xmlCity->current_condition->observation_time);
$xmlParseDate = $this->DateUnix((string)$xmlCity->current_condition->observation_time,(string)$xmlCity->weather->date);
$nowParseDate = mktime(date('H')-$this->UpdateIntervall,date('i'),date('s'),date('m'),date('d'),date('Y'),-1);
// Wenn ja, ist der Inhalt noch aktuell?
if($xmlParseDate < $nowParseDate) {
$xmlCity = simplexml_load_string(file_get_contents($this->Url));
$fh = fopen($this->WeatherCache, 'w') or die('Kann XML Wetterdaten nicht in Datei schreiben: '.$this->WeatherCache);
fwrite($fh, file_get_contents($this->Url));
fclose($fh);
$xmlCache = 'Updated - ';
}
}else{
$xmlCity = simplexml_load_string(file_get_contents($this->Url));
$fh = fopen($this->WeatherCache, 'w') or die('Kann XML Wetterdaten nicht in Datei schreiben: '.$this->WeatherCache);
fwrite($fh, file_get_contents($this->Url));
fclose($fh);
$xmlCache = 'Updated - ';
}
$xmlCity = simplexml_load_string(file_get_contents($this->WeatherCache));
$CityName = explode(",", $xmlCity->request->query); // Hier wird das Land nach dem Komma entfernt...
/* Ab hier werden die aktuellen Wetterdaten ($xmlCity->current_condition) der XML in Variablen ($this->CurrentConditions['???']) geschrieben.
Folgende Daten stehen zur Verfügung:
observation_time Uhrzeit in UTC-Format hhmm tt. Z. B.: - 06.45 Uhr oder 11.34 Uhr
temp_C Temperatur in Grad Celsius
windspeedMiles Windgeschwindigkeit in Meilen pro Stunde
windspeedKmph Windgeschwindigkeit in Kilometer pro Stunde
winddirDegree Windrichtung in Grad
winddir16Point Windrichtung in 16-Punkt-Kompass
weatherCode Wetter Bedingungscode
weatherDesc Wetter Beschreibungstext
weatherIconUrl Wetter Icon URL
precipMM Niederschlag in Millimeter
humidity Luftfeuchtigkeit in Prozent
visibility Sichtweite in Kilometer
pressure Luftdruck in Millibar
cloudcover Bewölkung in Prozent
Da die Werte in englischen Angaben vorliegen, werden sie teilweise noch mit Funktionen eingedeutscht, z.b. TimeEngToDeu()
*/
// Wer den vollen Stadtnamen, IP-Adresse oder Koords haben will, ersetzt $CityName[0] durch $xmlCity->request->query
$this->CurrentConditions['CityName'] = (string)$CityName[0];
// Ich hab den Stand nur als Tooltip, mit der Angabe ob die Daten neu sind oder aus dem Cache. Cache Angabe aus $xmlCache
$this->CurrentConditions['Time'] = 'Stand: '.$xmlCache.$this->TimeEngToDeu((string)$xmlCity->current_condition->observation_time).' Uhr';
$this->CurrentConditions['Temperature'] = ($xmlCity->current_condition->observation_time == "N/A") ? "" : ((string)$xmlCity->current_condition->temp_C).'°C';
$this->CurrentConditions['Humidity'] = ($xmlCity->current_condition->humidity == "N/A") ? "" : ((string)$xmlCity->current_condition->humidity).'%';
$this->CurrentConditions['Airpressure'] = ($xmlCity->current_condition->pressure == "N/A") ? "" : ((string)$xmlCity->current_condition->pressure).'mBar';
$this->CurrentConditions['PrecipMM'] = ($xmlCity->current_condition->precipMM == "N/A") ? "" : ((string)$xmlCity->current_condition->precipMM).'mm';
$this->CurrentConditions['WindSpeed'] = ($xmlCity->current_condition->windspeedKmph == "N/A") ? "" : ((string)$xmlCity->current_condition->windspeedKmph).'km/h';
// Die Angabe der Windrichtung ist in Englisch, daher ist Osten / East als einziger ander und wird mit preg_replace ersetzt.
$this->CurrentConditions['WindDir'] = ($xmlCity->current_condition->winddir16Point == "N/A") ? "" : ((string)preg_replace("/E/","/O/",$xmlCity->current_condition->winddir16Point));
$this->CurrentConditions['CloudCover'] = ($xmlCity->current_condition->cloudcover == "N/A") ? "" : ((string)$xmlCity->current_condition->cloudcover).'%';
$this->CurrentConditions['Description'] = ($xmlCity->current_condition->weatherDesc == "N/A") ? "" : $this->DescEngToDeu((string)$xmlCity->current_condition->weatherDesc);
$this->CurrentConditions['Icon'] = (string)'http://c358489.r89.cf1.rackcdn.com/images/weather/small/'.$xmlCity->current_condition->weatherCode.'_day_sm.png';
/* Ab hier werden die Wetterdaten der Vorhersage (weather) in einen Loop für die Anzahl der Tage (0=heute, 1=morgen, usw.) in Variablen geschrieben.
Folgende Daten stehen zur Verfügung:
date Lokale Vorhersage Zeitpunkt, als "yyyy-MM-DD" formatiert. z.B.: 2012.05.31
tempMaxC Höchsttemperatur des Tages in Grad Celsius.
tempMaxF Höchsttemperatur des Tages in Grad Fahrenheit.
tempMinC Minimale Temperatur des Tages in Grad Celsius.
tempMinF Minimale Temperatur des Tages in Grad Fahrenheit.
windspeedMiles Windgeschwindigkeit in Meilen pro Stunde
windspeedKmph Windgeschwindigkeit in Kilometer pro Stunde
winddirDegree Windrichtung in Grad
winddir16Point Windrichtung in 16-Punkt-Kompass
weatherCode Wetter Bedingungscode
weatherIconUrl Wetter icon URL
weatherDesc Wetter Beschreibungstext
precipMM Niederschlagsmenge in Millimeter
Da die Werte in englischen Angaben vorliegen, werden sie teilweise noch mit Funktionen eingedeutscht, z.b. TimeEngToDeu()
*/
$i = 0;
foreach ($xmlCity->weather as $day){
$MyDat = explode("-", $day->date);
$MyDate = $MyDat[2].'.'.$MyDat[1].'.'.$MyDat[0];
if($MyDate==date('d.m.Y')){$MyDate='Heute';}
if($MyDate==date('d.m.Y',mktime(0,0,0,date("m"),date("d")+1,date("Y")))){$MyDate='Morgen';} // Anstelle Datum 'Morgen' ausgeben...
if($MyDate==date('d.m.Y',mktime(0,0,0,date("m"),date("d")+2,date("Y")))){$MyDate='Übermorgen';}// Anstelle Datum 'Übermorgen' ausgeben...
$this->DaysForecast[$i] = array();
$this->DaysForecast[$i]['Low'] = ($day->tempMinC == "N/A") ? "" : ((string)$day->tempMinC).'°C';
$this->DaysForecast[$i]['Hi'] = ($day->tempMaxC == "N/A") ? "" : ((string)$day->tempMaxC).'°C';
$this->DaysForecast[$i]['Date'] = ($day->date == "N/A") ? "" : ((string)$MyDate);
$this->DaysForecast[$i]['Icon'] = (string)'http://c358489.r89.cf1.rackcdn.com/images/weather/small/'.$day->weatherCode.'_day_sm.png';
$this->DaysForecast[$i]['Desc'] = $this->DescEngToDeu((string)$day->weatherDesc);
$i++;
}
}
function getCurrentConditions() {
return $this->CurrentConditions;
}
function getForecastConditions($var_day) {
return $this->DaysForecast[$var_day];
}
function TimeEngToDeu($var_engTime){ // Hier wird die 11:00 AM Zeit in eine 24h Zeit umgewandelt
$Time24 = "";
$TimeParts = explode(" ", $var_engTime);
$TimePartsHours = explode(":", $TimeParts[0]);
$Time24 = (string)$TimeParts[0];
if ($TimeParts[1] == "PM"){
$Time24 = ((string)(((int)$TimePartsHours[0])+12)).":".(string)$TimePartsHours[1];
}
return $Time24;
}
function DateEngToDeu($var_engDate){ // Hier das Datum umgewandelt
$DateParts = explode("-", $var_engDate);
return $DateParts[2].','.$DateParts[1].','.$DateParts[0];
}
function DateUnix($var_engTime,$var_engDate){ // Hier das Datum umgewandelt 08:28 AM
$Time24 = "";
$TimeParts = explode(" ", $var_engTime);
$TimePartsHours = explode(":", $TimeParts[0]);
$Hour24 = $TimePartsHours[0];
if ($TimeParts[1] == "PM"){
$Hour24 = $TimePartsHours[0]+12;
}
$DateParts = explode("-", $var_engDate);
$UnixDate = mktime((int)$Hour24,(int)$TimePartsHours[1],0,(int)$DateParts[1],(int)$DateParts[2],(int)$DateParts[0],-1);
return $UnixDate;
}
function DescEngToDeu($var_engDesc){ // Hier ersetze ich die Englischen Beschreibungen durch deutsche - kann sicher noch etwas fehlen!
// Bitte alle englischen Beschreibungen klein und ohne Leerzeichen eintragen! Die Angaben im XML kommen mal groß, mal klein. Mal mit Leerzeichen am Ende mal ohne - daher diese Formatierung...
$engDesc = array(
'/cloudy/',
'/partlycloudy/',
'/patchyrainnearby/',
'/lightrainshower/',
'/patchylightdrizzle/',
'/sunny/',
'/LAST ENTRY/');
// Hier die deutsche Übersetzung eintragen. Auf die richtige Reihenfolge und UTF8 Kodierung achten!
$deuDesc = array(
'Bewölkt',
'Teilweise Bewölkt',
'Leichter Regen',
'Leichte Regenfälle',
'Leichter Nieselregen',
'Sonnig',
'LAST ENTRY');
$var_engDesc = strtolower(preg_replace("/ /","",$var_engDesc)); // Hier wird der englische String wie oben benannt umgewandelt...
return preg_replace($engDesc, $deuDesc, $var_engDesc);
}
}
?>
Einstellungen müsst ihr nur in dieser Datei ganz am Anfang vornehmen. Ich denke die Kommentare im PHP Code sind selbsterklärend. Ich habe bewusst auf die Global: WEATHERFILE_SOURCE verzichtet, um eventuell vorhandene Installationen nicht zu behindern.
Im nächsten Schritt, müsst ihr in der Seite, die die Wetterdaten anzeigen soll, die Funktion aufrufen. Das passiert bei mir in meiner sites/webcontrol/index.php wobei das am Ende egal ist, da die reine Wetterfunktion keine Anbindung zur CCU braucht. Hauptsache ist eben, es muss eine *.php sein.
Hier der Code am Anfang der PHP:
Code: Alles auswählen
require_once("../../includes/php/fweather.php");
require_once("../../includes/globals.inc.php");
$gweather = new WeatherXmlFeedForecast('Leipzig,Germany',5);
Mehr ist es nicht. Als erstes werden die benötigten Dateien eingefügt und anschließend die Wetterdaten in ein Array $gweather geladen. Wer mehrere verschiedene Wetterstandorte einbinden möchte, ruft weitere Daten in neue Arrays aka $Mein2Array = new WeatherXmlFeedForecast('Berlin,Germany',5); ab. Wie in der fweather.php beschrieben steht der erste Parameter für die Stadt (IP-Adresse, Koordinaten siehe Doku auf
http://www.worldweatheronline.com/api-usage-api.aspx) und der zweite für die Anzahl der Vorhersagetage.
OK, zum Anzeigen der Daten müssen wir jetzt nur noch die Daten aus dem jeweiligen Array abrufen. Das machen wir im <body> Bereich eurer Anzeigeseite mit folgendem Code:
Code: Alles auswählen
<div class="WeatherButton">
<img src="<?php echo $gweather->CurrentConditions['Icon'] ?>" title="<?php echo $gweather->CurrentConditions['Time'] ?>" class="WeatherButtonIcon" />
</div>
<?php echo $gweather->CurrentConditions['CityName'] ?><br />
<span style="font-size:12px;"><?php echo $gweather->CurrentConditions['Description'] ?></span>
</div>
<div class="Text2Line" id="2" style="text-align:left;">
Temperatur: <?php echo $gweather->CurrentConditions['Temperature'] ?><br />
Luftfeuchtigkeit: <?php echo $gweather->CurrentConditions['Humidity'] ?>
</div>
<div class="Text2Line" id="2" style="text-align:left;">
Luftdruck: <?php echo $gweather->CurrentConditions['Airpressure'] ?><br />
Niederschlag: <?php echo $gweather->CurrentConditions['PrecipMM'] ?>
</div>
<div class="Text2Line" id="2" style="text-align:left;">
Wind: <?php echo $gweather->CurrentConditions['WindSpeed'] ?> aus <?php echo $gweather->CurrentConditions['WindDir'] ?><br />
Bewölkung: <?php echo $gweather->CurrentConditions['CloudCover'] ?>
</div>
<div class="clearfloat"></div><div class="clearfloat"></div>
<?php for($i=1; $i<=4; $i++){
echo '<div class="Text2Line2" id="'.$i.'">';
echo ' <div class="WeatherButton">';
echo ' <img src="'.$gweather->DaysForecast[$i]['Icon'].'" title="'.$gweather->DaysForecast[$i]['Desc'].'" class="WeatherButtonIcon" />';
echo ' </div>';
echo ' '.$gweather->DaysForecast[$i]['Date'].'<br /><span style="font-size:12px;">'.$gweather->DaysForecast[$i]['Hi'].' / '.$gweather->DaysForecast[$i]['Low'].'</span>';
echo '</div>';
} ?>
Wie ihr seht rufe ich in der ersten Zeile die aktuellen Wetterdaten ab und in der zweiten Zeile die Vorhersage für die nächsten 4 Tage - der Einfachheit halber als Loop "for($i=1; $i<=4; $i++)". Eure Designs müsst ihr euch natürlich entsprechend anpassen, da ich diese bei mir natürlich verändert habe.
Im Grunde war es das schon. Ich weiß es ist vieles nicht perfekt, aber nach 14h coden muss ich mal Pause machen und wollte euch das Ergebnis nicht vorenthalten. Gerade an der Übersetzung der englischen Wetterbeschreibungen und einer eigenen Icon Engine arbeite ich noch oder nehme aktualisierte Arrays gern an.
Hier ist ein Screenshoot von meiner Version:
Wenn Fragen dann hier oder gern per Email.