Wetterwarnungen vom DWD – Neu: Open Data Server

Am 14.08.17 erreichte mich die Nachricht vom DWD, dass es nun den Open Data Server gibt und dieser bis Ende des Jahres den GDS (FTP-Server) ablösen wird.
Alle Infos zum Open Data Server hier!

Bei näherer Recherche, wie ich denn darüber an die Wetterwarnungen komme, habe ich festgestellt, dass es etwas einfacher wird mit diesem Open Data Server. Die bisherige CAP-Zip-Datei lässt sich über den Server unter immer der gleichen URL abrufen. Hier muss man nun nicht mehr die aktuellste Datei ermitteln:

https://opendata.dwd.de/weather/alerts/cap/COMMUNEUNION_DWD_STAT/ Z_CAP_C_EDZW_LATEST_PVW_STATUS_PREMIUMDWD_COMMUNEUNION_DE.zip

Wenn Ihr Euch jetzt fragt „https?“, kann ich nur sagen „Ja, https!“. Das heißt der ganze FTP-Quatsch fliegt aus dem Script raus und macht es deutlich einfacher. Glücklicherweise lässt sich über die http-header das Änderungsdatum der Zip-Datei ermitteln, damit man auch weiß, ob ein erneuter Download überhaupt nötig ist. Der Server unterstützt zwar auch Directory Listing, aber da das Änderungsdatum aus dem generierten html rauszuparsen wäre schon sehr unglücklich bzw. sch***e gewesen.

<?php
require_once("functions.php");

$url = "https://opendata.dwd.de/weather/alerts/cap/COMMUNEUNION_DWD_STAT/Z_CAP_C_EDZW_LATEST_PVW_STATUS_PREMIUMDWD_COMMUNEUNION_DE.zip";
$headers = get_headers($url, 1);
if (!$headers) exit();
$time = strtotime($headers['Last-Modified']);

if (!is_dir("download_cache")) {
  mkdir("download_cache");
}
if (!is_dir("unzip_cache")) {
  mkdir("unzip_cache");
}

$local_file = "download_cache/".$time.".zip";
$remote_file = "Z_CAP_C_EDZW_LATEST_PVW_STATUS_PREMIUMDWD_COMMUNEUNION_DE.zip";

if (!file_exists($local_file)) {
	echo "updated file '$remote_file' available<br />";
	$files = glob("download_cache/*");
	foreach($files as $file){
		if(is_file($file)) unlink($file);
	}
	if (!file_put_contents($local_file, fopen($url, 'r'))) {
		exit();
	}
	
	$files = glob("unzip_cache/*");
	foreach($files as $file){
		if(is_file($file)) unlink($file);
	}

	if(!Unzip($local_file, "unzip_cache/")) {
		exit();
	}
} else {
	echo "local file '$local_file' still up to date<br />";
}

Das Ganze läuft in meinem Wetterwarnungen Service bereits wie am Schnürchen. Durch die Änderung von FTP auf HTTPS wird mit Sicherheit auch die Scriptlaufzeit etwas verkürzt worden sein. Also bringt die Neuerung meines Erachtens nur Vorteile.

Hier nochmal das komplette Script:

<?php
function Unzip($zipFile, $unzipDir) {
	echo "<br />";
	echo "Unzipping '$zipFile' <br />";
	$zip = new ZipArchive;
	$result = $zip->open($zipFile);
	if($result !== true){
	 echo "Error :- Unable to open the Zip File: $result";
	 return false;
	} 
	/* Extract Zip File */
	$zip->extractTo($unzipDir);
	$zip->close();
	echo "Unzipped to '$unzipDir' <br /><br />";
	return true;
}

function getLevel($info) {
	if ($info->urgency == "Future") return 1;
	switch($info->severity) {
		case "Minor":
			return 2;
			break;
		case "Moderate":
			return 3;
			break;
		case "Severe":
			return 4;
			break;
		case "Extreme":
			return 5;
			break;
	}
}

function getState($area) {
	$stateShort = getGeocode("STATE", $area);
	switch($stateShort) {
		case "NRW":
			return "Nordrhein-Westfalen";
			break;
		case "RP":
			return "Rheinland-Pfalz";
			break;
		case "BY":
			return "Bayern";
			break;
		case "BW":
			return "Baden-Württemberg";
			break;
		case "HE":
			return "Hessen";
			break;
		case "SN":
			return "Sachsen";
			break;
		case "TH":
			return "Thüringen";
			break;
		case "NS":
			return "Niedersachsen";
			break;
		case "HH":
			return "Hamburg";
			break;
		case "HB":
			return "Bremen";
			break;
		case "SH":
			return "Schleswig-Holstein";
			break;
		case "SL":
			return "Saarland";
			break;
		case "SA":
			return "Sachsen-Anhalt";
			break;
		case "BB":
			return "Brandenburg";
			break;
		case "BL":
			return "Berlin";
			break;
		case "MV":
			return "Mecklenburg-Vorpomern";
			break;
	}
}

function getGeocode($geocode, $area) {
	foreach($area->geocode as $code) {
		if ($code->valueName == $geocode){
			return (string) $code->value;
		}
	}
}

function getEventCode($eventCode, $info) {
	foreach($info->eventCode as $code) {
		if ($code->valueName == $eventCode){
			return (string) $code->value;
		}
	}
}

function getAltitudeStart($area) {
	$altCode = getGeocode("ALTITUDE", $area);
	switch($altCode) {
		case "B":
			return 200;
		case "C":
			return 400;
		case "D":
			return 600;
		case "E":
			return 800;
		case "F":
			return 1000;
		case "G":
			return 1500;
		case "H":
			return 2000;
		case "L":
			return 0;
		case "M":
			return 0;
		case "N":
			return 0;
		case "A":
			return 0;
	}
}

function getAltitudeEnd($area) {
	$altCode = getGeocode("ALTITUDE", $area);
	switch($altCode) {
		case "B":
			return 3000;
		case "C":
			return 3000;
		case "D":
			return 3000;
		case "E":
			return 3000;
		case "F":
			return 3000;
		case "G":
			return 3000;
		case "H":
			return 3000;
		case "L":
			return 800;
		case "M":
			return 600;
		case "N":
			return 400;
		case "A":
			return 200;
	}
}

function getAltitudeStartFromAltitude($altitude) {
	$result = round($altitude * 0.3048);
	if ($result == 0) {
		return null;
	} else {
		return $result;
	}
}

function getAltitudeEndFromCeiling($ceiling) {
	$result = round($ceiling * 0.3048);
	if ($result == 3000) {
		return null;
	} else {
		return $result;
	}
}
?>
<?php
require_once("functions.php");

$url = "https://opendata.dwd.de/weather/alerts/cap/COMMUNEUNION_DWD_STAT/Z_CAP_C_EDZW_LATEST_PVW_STATUS_PREMIUMDWD_COMMUNEUNION_DE.zip";
$headers = get_headers($url, 1);
if (!$headers) exit();
$time = strtotime($headers['Last-Modified']);

if (!is_dir("download_cache")) {
  mkdir("download_cache");
}
if (!is_dir("unzip_cache")) {
  mkdir("unzip_cache");
}

$local_file = "download_cache/".$time.".zip";
$remote_file = "Z_CAP_C_EDZW_LATEST_PVW_STATUS_PREMIUMDWD_COMMUNEUNION_DE.zip";

if (!file_exists($local_file)) {
	echo "updated file '$remote_file' available<br />";
	$files = glob("download_cache/*");
	foreach($files as $file){
		if(is_file($file)) unlink($file);
	}
	if (!file_put_contents($local_file, fopen($url, 'r'))) {
		exit();
	}
	
	$files = glob("unzip_cache/*");
	foreach($files as $file){
		if(is_file($file)) unlink($file);
	}

	if(!Unzip($local_file, "unzip_cache/")) {
		exit();
	}
} else {
	echo "local file '$local_file' still up to date<br />";
}

$alerts = array();

$files = glob("unzip_cache/*");
foreach($files as $file){
	if(is_file($file)) {
		$xml = simplexml_load_file($file);

		foreach($xml->info->area as $area) {
			$alert['start'] = (int) strtotime($xml->info->onset) * 1000;
			$alert['end'] = (int) strtotime($xml->info->expires) * 1000;
			$alert['regionName'] = (string) $area->areaDesc;
			$alert['level'] = getLevel($xml->info);
			$alert['type'] = (string) getEventCode("GROUP", $xml->info);
			$alert['altitudeStart'] = getAltitudeStartFromAltitude((float) $area->altitude);
			$alert['event'] = (string) $xml->info->event;
			$alert['headline'] = (string) $xml->info->headline;
			$alert['description'] = (string) $xml->info->description;
			$alert['altitudeEnd'] = getAltitudeEndFromCeiling((float) $area->ceiling);
			$alert['stateShort'] = (string) getGeocode("STATE", $area);
			$alert['instruction'] = (string) $xml->info->instruction;
			$alert['state'] = getState($area);
			
			$alert['ii'] = (int) getEventCode("II", $xml->info);
			$alert['published'] = (int) strtotime($xml->info->effective) * 1000;
			$alerts['time'] = (int) strtotime(date("c")) * 1000;

			if ($alert['regionName'] != "polygonal event area") {
				if((string) $xml->info->urgency == "Immediate") {
					$alerts['warnings'][(string) $area->geocode[0]->value][] = $alert;
				} else {
					$alerts['vorabInformation'][(string) $area->geocode[0]->value][] = $alert;
				}
				
			}
		}
	}
}

echo "found ".count($alerts['warnings'])." warnings<br />";
echo "saving warnings to 'warnings.json'<br />";
$fp = fopen("warnings.json", "w");
fwrite($fp, json_encode($alerts, JSON_PRETTY_PRINT));
fclose($fp);
echo "warnings successfully saved<br /> ";

?>

 

Categories: DWD Unwetter Parser