Aus Linux-Magazin 02/2015

Perl-Skript erkundigt sich nach dem Wetter

© alphaspirit, 123RF

Ein Perl-Skript, das im Morgengrauen die aktuelle Wettervorhersage einholt, hilft bei der Entscheidung, auf Risiko zu spielen oder doch einen Schirm einzupacken.

In der nassen Jahreszeit stellt sich oft die Frage, ob im Laufe des Tages Regen oder Schnee vom Himmel fallen wird und man deswegen gut beraten wäre, auf den Weg zur Arbeit einen Schirm mitzunehmen.

Untergrund-Wetter

Letztlich wären aber sogar gelegentliche Regenschauer um die Mittagszeit irrelevant, solange sich der Weg zur und von der Arbeit trockenen Fußes bewältigen lässt. Zum Glück bietet der Wetterdienst “Weather Underground” [1] kostenlose Vorhersagen für die laufenden Stunden des Tages. Obwohl diese zweifellos nicht immer hundertprozentig zutreffen, schlagen sie doch die menschliche Intuition im Schnitt um Längen.

Auf dem CPAN finden Perl-Programmierer das Modul WWW::Wunderground::API, das die Wetterdaten mit einem eigens von [2] eingeholten API-Key skriptgesteuert vom Server saugt. Das simple Skript in Listing 1 nutzt das Modul, iteriert über die stündlichen Einträge im zurückkommenden Json-Datenwust und gibt pro Stunde die Uhrzeit und die Regenwahrscheinlichkeit im Eintrag »pop« (Probability of precipitation, [3]) aus. Abbildung 1 zeigt, dass es am Nachmittag mit weniger als 50 Prozent Wahrscheinlichkeit regnen wird, ein gläubiger Mathematiker könnte den Schirm zu Hause lassen.

Listing 1

chance-of-rain.pl

01 #!/usr/local/bin/perl -w
02 use strict;
03 use WWW::Wunderground::API;
04 use DateTime;
05
06 my $w = WWW::Wunderground::API->new(
07   location => "Munich, Germany",
08   api_key  => "0123456789abcdef",
09   auto_api => 1,
10 );
11
12 for my $e (@{ $w->hourly }) {
13   my $dt = DateTime->from_epoch(
14     epoch => $e->{ FCTTIME }->{ epoch } );
15
16   print "$dt: $e->{ pop }%\n";
17 }
Abbildung 1: Anfangend bei der aktuellen Stunde gibt Weather Underground die stündliche Regenwahrscheinlichkeit an.

Abbildung 1: Anfangend bei der aktuellen Stunde gibt Weather Underground die stündliche Regenwahrscheinlichkeit an.

Mehr als nur Regen

Dabei kommt vom Underground-Server weit mehr zurück als nur die Regenwahrscheinlichkeit. Die in Zeile 12 von Listing 1 aufgerufene Methode »hourly()« liefert einen Array von stündlichen Wetterelementen des Tages. Wie der Datensalat in Abbildung 2 zeigt, verweist jedes Element auf eine Reihe von Schlüsseln wie »humidity« (Luftfeuchtigkeit) oder »sky« (Bewölkung). Schließlich stehen unter »FCTTIME« das Datum und die Uhrzeit der Vorhersage.

Abbildung 2: Die stündlichen Wettervorhersagen enthalten nicht nur die Regenwahrscheinlichkeit, sondern auch Luftfeuchtigkeit oder Temperatur.

Abbildung 2: Die stündlichen Wettervorhersagen enthalten nicht nur die Regenwahrscheinlichkeit, sondern auch Luftfeuchtigkeit oder Temperatur.

Listing 1 schnappt sich den Eintrag »epoch« aus dem Datum und wandelt die dort stehenden Unix-Sekunden seit 1970 mit dem Perl-Modul »DateTime« in ein lesbares und später leicht maschinell manipulierbares Format um.

API-Key gegen E-Mail-Adresse

Ganz offen ins Internet legt der Wunderground-Server die Daten nicht, aber wer sich auf der Developer-Seite [2] mit einer gültigen E-Mail-Adresse registriert, bekommt einen 16-stelligen hexadezimalen API-Key, mit dem der Service eine beschränkte Anzahl täglicher Abfragen freischaltet. Wer allerdings den kostenlosen “Cumulus”-Plan wählt und außerdem versichert, die Daten nicht zu kommerziellen Zwecken zu verwenden (Abbildung 3), der muss auch keine Zahlungsmodalitäten angeben. In den vorgestellten Listings 1 und 2 ist dann der mit »$api_key« definierte String vor Gebrauch durch den eingeholten API-Key zu ersetzen (Abbildung 4).

Abbildung 3: Den für Weather Underground erforderlichen API-Key rückt der Server gegen eine gültige E-Mail-Adresse heraus.

Abbildung 3: Den für Weather Underground erforderlichen API-Key rückt der Server gegen eine gültige E-Mail-Adresse heraus.

Abbildung 4: Der API-Key auf Weather Underground besteht aus einer 18-stelligen Hexzahl.

Abbildung 4: Der API-Key auf Weather Underground besteht aus einer 18-stelligen Hexzahl.

Schirm oder Risiko?

Um nun zu ermitteln, ob es an einem bestimmten Tag in den kritischen Zeitfenstern auf dem Weg zur und von der Arbeit regnet und ob damit ein Schirm erforderlich ist, läuft das Skript in Listing 2 per Cronjob im Morgengrauen los. Es definiert in Zeile 12 die kritischen Stunden, im Beispiel 8 und 9 Uhr morgens für den Weg zur Arbeit und dann wieder 17, 18 und 19 Uhr abends für den Nachhauseweg nach Feierabend, falls es doch mal wieder später wird.

Listing 2

umbrella

#!/usr/local/bin/perl -w
02 use strict;
03 use WWW::Wunderground::API;
04 use DateTime;
05 use Log::Log4perl qw(:easy);
06 use Getopt::Std;
07
08 getopts "v", \my %opts;
09 Log::Log4perl->easy_init(
10   $opts{ v } ? $DEBUG : $ERROR);
11
12 my @critical_hours = qw(8 9 17 18 19);
13
14 my $w = WWW::Wunderground::API->new(
15   location => "Munich, Germany",
16   api_key  => "0123456789abcdef",
17   auto_api => 1,
18 );
19
20 for my $e (@{ $w->hourly }) {
21   if( !scalar @critical_hours ) {
22     last;
23   }
24
25   my $dt = DateTime->from_epoch(
26     epoch => $e->{ FCTTIME }->{ epoch } );
27
28   if( $dt->hour() == $critical_hours[0] ) {
29     DEBUG "Checking hour ", $dt->hour(),
30       " ($e->{ pop }%)";
31
32     if( $e->{ pop } > 50 ) {
33       printf "Bring your Umbrella! " .
34         "(%d%% rain at %s)\n",
35           $e->{ pop }, $dt->hms();
36     }
37
38     shift @critical_hours;
39   }
40 }

Im Parameter »location« in Zeile 15 ist der Ort des Wettergeschehens anzugeben, unter »api_key« wieder der eingeholte Zugangsschlüssel. Die Option »auto_api« sorgt dafür, dass das CPAN-Modul mit der in Zeile 20 aufgerufenen Methode »hourly()« gleich hinter den Kulissen die REST-Schnittstelle des Wunderground-Servers aufruft und den gewünschten Json-Array zurückliefert.

Ohne Parameter aufgerufen gibt das Skript nur dann eine Meldung aus, falls es festgestellt hat, dass die Regenwahrscheinlichkeit in den kritischen Stunden einmal über 50 Prozent liegt. Dann schreibt die »printf« -Anweisung in Zeile 33 einen String wie

Bring your Umbrella! (52% rain at 19:00:00)

auf die Standardausgabe, und das nachfolgende E-Mail-Skript in Listing 3 schickt die Meldung an den gespannt wartenden User.

Listing 3

mandrill-email

01 #!/usr/local/bin/perl -w
02 use strict;
03 use warnings;
04 use LWP::UserAgent;
05 use JSON qw(to_json);
06
07 my $text = join "", <>;
08
09 if( !length $text ) {
10   exit 0;
11 }
12
13 my $api_key = "abcdefghi0123456789";
14 my $from    = 'from@email-address.com';
15 my $to      = 'to@email-address.com';
16
17 my $ua = LWP::UserAgent->new();
18
19 my $resp = $ua->post(
20   "https://mandrillapp.com/api/1.0/" .
21     "messages/send.json",
22   Content => to_json( {
23     key => $api_key,
24     message => {
25       text    => $text,
26       subject => $text,
27       from_email => $from,
28       to => [ { email => $to } ],
29     } } ),
30 );
31
32 if( $resp->is_error() ) {
33   die "Sending mail failed: ",
34     $resp->message();
35 }

Besteht keine Gefahr, dass Niederschlag den Arbeitnehmer durchnässt, gibt das Skript auch nichts aus und der nachsetzende E-Mailer bricht ab, ohne eine Nachricht abzusenden.

Wer genau wissen will, was das Skript treibt, ruft es mit der Option »-v« auf, wie in Abbildung 5 gezeigt, und erhält die Regenwahrscheinlichkeit in den kritischen Stunden mittels Log4perl-Meldungen angezeigt. Der Cronjob muss das Skript allerdings ohne »-v« , also zum Beispiel um 7 Uhr morgens mit

Abbildung 5: Im Verbose-Modus verrät das Skript, welche Meldungen des Wetterberichts es prüft.

Abbildung 5: Im Verbose-Modus verrät das Skript, welche Meldungen des Wetterberichts es prüft.

0 7 * * * umbrella | mandrill-email

aufrufen, damit der nachfolgende E-Mailer keine Nachricht schickt, falls es gar nicht regnet. Zu beachten ist auch, dass die Skripte entweder in einem Verzeichnis stehen müssen, das der Cronjob findet, oder der Croneintrag muss den absoluten Pfad zu den Skripten explizit festlegen.

Mailprovider gesucht

Im Spam-Zeitalter ist es gar nicht mehr so einfach, automatisch E-Mails zu verschicken. In der Firma oder zu Hause geht es noch, da kann der ISP verifizieren, wer da was treibt. Um flexibel zu sein, wendet man sich am besten an Drittanbieter. So erlaubt zum Beispiel die Firma Mandrill gegen einen Obolus die Nutzung ihrer Mailschleudern, aber Testaccounts dürfen auch ein paar E-Mails für lau schicken.

E-Mail mit REST

Auf [4] kann sich der interessierte Nutzer mit einer gültigen E-Mail registrieren und erhält dann einen 22-stelligen API-Key im Base64-Format, den Skripte später nutzen können, um mit Mandrills REST-Server E-Mails zu versenden. Allerdings ist an dieser Stelle zu beachten, dass die From-Adresse immer die bei der Registrierung angegebene gültige E-Mail-Adresse sein muss. Ist das nicht der Fall, dann verweigert Mandrill den Dienst, zumindest für die kostenlosen Testaccounts.

Zeile 7 in Listing 3 schnappt sich die auf der Standardeingabe eintrudelnden Textdaten und legt sie in »$text« ab. Bleibt dieser String leer, weil das vorhergehende Skript in der Unix-Pipeline nichts ausgab, bricht Zeile 10 ohne Fehlermeldung ab. In diesem Fall wäre nichts zu senden. In Zeile 13 ist der »$api_key« durch den Mandrill-Testkey zu ersetzen und die Absenderadresse in »$from« (Zeile 14) durch die dort verwendete Registrations-E-Mail. Die Empfängeradresse darf der Anwender nach Belieben festlegen.

Das Skript kodiert die E-Mail-Daten mittels der Funktion »to_json« des Json-Moduls als Blob und schickt sie per POST-Request an den Mandrill-Server. Falls Zeile 32 keinen Fehler entdeckt, wurde die E-Mail versandt und der zur Arbeit hetzende Arbeitnehmer kann auf seinem Smartphone sehen, ob der Wetterdienst zu einem Schirm rät.

Online PLUS

In einem Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/2015/02/plus

Infos

  1. Weather Underground: http://wunderground.com
  2. Weather Underground, Developer-API: http://www.wunderground.com/weather/api
  3. Probability of precipitation: http://en.wikipedia.org/wiki/Probability_of_precipitation
  4. E-Mail-Service Mandrill: http://mandrillapp.com
  5. Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2015/02/Perl

Der Autor

Michael Schilli arbeitet als Software-Engineer bei Yahoo in Sunnyvale, Kalifornien. In seiner seit 1997 erscheinenden Kolumne forscht er jeden Monat nach praktischen Anwendungen der Skriptsprache Perl. Unter mailto:mschilli@perlmeister.com beantwortet er gerne Fragen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben