GHOst-Weather (Informatik-Projekt des 13. Jahrgangs 2016/2017)

Zusammenfassung:

Von Dezember 2016 bis März 2017 haben wir, der Informatik-Grundkurs des 13. Jahrgangs bei Herrn A. Fischer, ein Software-Projekt namens „GHOst-Weather“ durchgeführt. Ziel dieses Projektes war die Erstellung eines Wetter-Programms. Hierbei sollten wetterrelevante Daten wie Temperatur, Luftfeuchtigkeit, Niederschlag und Windstärke angezeigt werden. Die Daten von weltweit über 74.000 Städten konnten wir entgeltfrei von dem Wetterdienst OpenWeatherMap beziehen. Programmiert haben wir das Projekt mit der Programmiersprache Python 2.7, die wir in den letzten vier Semestern im Unterricht „lieben“ gelernt haben. Die Daten werden in einer graphischen Benutzeroberfläche angezeigt. Zur Organisation der Arbeitsfortschritte verwendeten wir das Versionsverwaltungssystem „GitHub“.

Die graphische Benutzeroberfläche:

Das Startfenster:

Oben links werden der gewählte Stadtname und Datum sowie Uhrzeit der Messung angezeigt. Darunter befindet sich ein animiertes Wetter-Symbol, welches anzeigt, ob es z.B. regnet, stürmt oder schneit. Rechts daneben findet man weitere Details zum Wetter wie die Luftfeuchtigkeit, den Niederschlag und die Windstärke.

Über die Menüleiste kommt man zu den weiteren Fenstern.

Die Stadtauswahl:

Wenn man die Stadtauswahl anklickt, öffnet sich ein Suchfenster. Dort gibt man den Namen der Stadt, z. B. „Waldsassen“, ein und kann dann zwischen einem oder mehreren Orten mit dem eingegebenen Namen wählen. Für den gewählten Ort bekommt man dann das aktuelle Wetter angezeigt.

Der Vorhersage-Graph:

Außerdem gibt es den Menü-Button „Graph“, welcher einem die Vorhersage des Temperaturverlaufs der nächsten zwei bis drei Tage in Form eines Graphen für die ausgewählte Stadt zeigt.

Der Graph ist in drei-Stunden-Abständen eingeteilt, da wir die Daten von OpenWeatherMap in einem drei-Stunden-Takt erhalten.

Die Vorschau:

Der Menüeintrag „Vorschau“ liefert die Temperatur, Luftfeuchtigkeit, Niederschlag und Windstärke für Vormittag, Nachmittag und Abend maximal der nächsten drei Tage.

Die Deutschlandkarte:

Beim Klicken auf „Deutschlandkarte“ wird eine Karte von Deutschland angezeigt, auf der die Städte Hamburg, Berlin, München und Köln sowie die zuletzt ausgewählte Stadt mit einem Bild, welches die Wetterlage darstellt, angezeigt werden.

Somit erhält man einen groben Überblick über das Wetter in ganz Deutschland.

Beenden und Version:

Betätigt man den Button „Beenden“, schließen sich automatisch alle geöffneten Fenster.

Der Versionsbutton leitet den Benutzer direkt zu unserer Projektseite auf Github.com.

Technische Details

MVC-Schema:

Unsere Wetter-App ist mithilfe des MVC-Schema umgesetzt. Das bedeutet, dass unsere Software in drei Komponenten unterteilt ist: die Programmsteuerung (Controller), der Datensammler (Model) und die grafische Benutzeroberfläche (View). Dabei können das Model und die View nicht direkt miteinander kommunizieren. Da der Benutzer innerhalb der View Eingaben tätigt, findet die Kommunikation mit sogenannten Callback-Methoden statt, welche der Controller den einzelnen View-Objekten übergibt.
Wird beispielsweise der Button zum Anzeigen des Graphen gedrückt, registriert dies der Controller mit der übergebenen Callback-Methode. Anschließend beauftragt der Controller das Model, die Wetterdaten für die nächsten Stunden zu übergeben. Das Model entscheidet selbst, ob es dazu die Datenbank aktualisieren muss. Nun kann der Controller das Fenster für den Graphen mit den aktuellen Daten öffnen.

 def graphCallback(self):
      """
      Callback method for main window to open temp_graph
      :return: None
      """
    
      # Holt Daten aus der Model-Klasse „Forecast“
      self.__forecast = Forecast.get(self.aktStadt)
      templist = []
    
      # Füllt die Liste „templist“ mit Wetterdaten
      for i in range(0,23):
        templist.append(self.__forecast[i].getWeather().getTemperature())

     # Öffnen des Temperaturverlaufs und Hinzufügen des Objektes in eine Liste     
     # zur Überwachung der offenen Benutzeroberflächen
     self.__graphGUI.append(
        Temperaturverlauf(templist,self.__city.getName()))

Desweiteren hat der Controller die Aufgabe, die geöffneten Fenster zu überwachen, um alle Fenster zu schließen, wenn das Hauptfenster geschlossen wird.

Datensammlung:

Insbesondere bei Programmen wie dem GHOst-Weather ist es vonnöten Daten zur Auswertung in einer Datenbank zu besitzen. Die benötigten Daten über das Wetter werden von dem Online-Dienst OpenWeatherMap zur Verfügung gestellt. Dort muss man sich mit einem kostenlosen Konto anmelden und kann dann über das Application Interface (API) Anfragen über das Wetter einer ausgewählten Stadt stellen. Bei Open-Weather-Map sind weltweit insgesamt über 74.000 Ortschaften erfasst, wobei jeder Ort seine eigene ID besitzt.

Der Crawler ist ein von uns geschriebenes Programm, welches nach bestimmten Kriterien solche Anfragen stellt und die Ergebnisse verarbeitet. Das Ergebnis wird in JSON (JavaScript Object Notation) formatiert zurückgegeben. Da JSON Gemeinsamkeiten mit Python Dictionaries besitzt, interpretieren wir die Rückgabe von der API als Python-Code, aus dem wir dann alle nötigen Informationen extrahieren und in einer Datenbank (hier eine SQLite Datenbank) abspeichern.
Die API Schnittstelle von OpenWeatherMap, die wir verwenden, gibt uns eine Vorhersage für 5 Tage in einem Intervall von 3 Stunden. Deshalb müssen wir alle 3 Stunden den Crawler starten, um stets aktuelle Daten zu besitzen. Dafür kann man die Aufgabenplanung unter Windows oder Cronjobs unter Unix verwenden.

Der Temperatur-Graph:

Der Temperatur-Graph wird mit der in Python integrierten Grafikbibliothek „Tkinter“ auf einem Canvas gezeichnet. Diesem Canvas wird eine feste Größe gegeben.

Auf dem Canvas werden feste x- und y-Werte genommen, um die beiden Achsen darzustellen. Von diesen Achsen gehen alle weiteren Punkte aus und werden nur in x-Richtung verschoben. Dann wird zwischen dem letzten und dem aktuell betrachteten y-Wert eine Linie gezogen, wodurch dann ein Graph erzeugt wird. Die Fläche zwischen der Temperaturlinie und der Abszisse wird hellgrau ausgemalt.

Animierte Bilder:

Für die animierten Bilder haben wir das GIF-Format (Graphics Interchange Format) benutzt. Dieses Format kann mehrere Einzelbilder in einer Datei abspeichern und von vielen Betrachtungsprogrammen als Animation abgespielt werden.

Eine Animation entsteht, wenn die Einzelbilder in einem bestimmten Zeitintervall gewechselt werden.

         

Um eine Animation mit einer Bildwiederholrate von 30 Bildern in der Sekunde abspielen zu können, muss das Bild jede 0,033 Sekunden bzw. ungefähr jede 33 ms gewechselt werden.

Auch Python kann animierte GIFs abspielen, jedoch nur mit einer bestimmten Library, der PIL (Python Imaging Library). Da unser Projekt ohne zusätzliche Libraries auskommen musste, musste ein Workaround programmiert werden. Dieses klappte für unsere Zwecke wunderbar und war mit etwas Hilfe dann auch recht schnell implementiert.

Es mussten mehrere Wetterbilder kreiert und anschließend auch animiert werden, wie z. B. ein Symbol für leichten Regen oder für einen wolkenfreien Himmel. Wann welches Symbol verwendet wird, hängt von den Daten, die wir von der API (der Schnittstelle) bekommen, ab.

Resümee

Das Projekt hat uns allen riesigen Spaß gemacht und wir haben als Gruppe GHrOßartig performt.

Natürlich verlief die Zusammenarbeit nicht immer reibungslos, da wurden schon mal Quellen des einen durch ein unbedachtes commit eines anderen Projektteilnehmers überschrieben. Glücklicherweise sichert GitHub aber alle Zwischenstände, so dass nie etwas verloren ging.

Besonders gefallen hat uns das Tüfteln und Herausfinden von neuen Lösungen zu den nie enden wollenden kleinen und großen Problemen.

Autoren

Johanna Rieper, Julian Michael Czekanski, Sascha Andreas Harry Großmann, Jan-Niklas Jänsch, Philip Stefan Lindner, Michael Marco Malcherek, Ruslan Valentinovic Novikov, Leon Noel Pluskat, Vincent Frank Post, Tim Rademacher