Was Anfang des Jahres als kleine Idee begonnen hatte, ist inzwischen in einem einigermaßen komplexen Projekt gemündet: Ich wollte das Wetter in meinem Lieblings-Flugsimulator Aerofly FS2 verbessern.

Aerofly FS2 ist noch weit entfernt von der Tiefe und Komplexität von X-Plane oder auch Prepar3D. Darum hatte ich mir zwischenzeitlich X-Plane angeschaut, war aber inzwischen bereits sehr verwöhnt von der Performance und Unkompliziertheit von Aerofly FS2. Gerade die Unterstützung für Virtual Reality gefiel mir in AFS2 einfach besser, so dass ich X-Plane inzwischen wieder in den Hangar gerollt hatte.

Nach meiner Rückkehr zu AFS2 vermisste ich nun aber doch ein paar Features:

  1. Air Traffic Control, d.h. die korrekte Verwendung des Funkgerätes,
  2. eine lebendig wirkende Umwelt,
  3. und den realen Bedingungen entsprechendes Wetter.

Während die lebendig wirkende Umwelt (in Form von Autos und Schiffen) gerade durch das Aerofly Life Project angegangen wird, habe ich mir also das Wetter vorgenommen.

Tatsächlich existiert in X-Plane eine Idee, die in Aerofly FS2 ebenfalls funktioniert: Jeder größere Flughafen auf diesem Planeten veröffentlicht in relativ kurzen Abständen seinen aktuellen Wetterbericht in Form eines METAR. Dieser Wetterbericht ist nicht nur sehr verdichtet, sondern auch mit etwas Geschick maschinenlesbar.

KEYW 261153Z 36005KT 10SM FEW012 23/22 A3004 RMK AO2 SLP172 T02330217 10233 20222 53012

Darüber hinaus gibt es viele Anlaufstellen, die METARs über eine HTTP-Schnittstelle zur Verfügung stellen. Die Quelle war also gefunden.

Gleichzeitig hatte ich in der Hauptkonfigurationsdatei main.mcf von AFS2 entdeckt, dass die Wetterdaten darin gespeichert wurden. Zu meiner Überraschung fanden sich dort sogar Schalter, die in der Simulation selber gar nicht konfigurierbar waren. Mit ein paar wenigen Experimenten konnte ich nachweisen, dass Veränderungen in der main.mcf tatsächlich in AFS2 übernommen wurden – hier war also mein Ziel.

Die Aufgabe

Die Aufgabe war jetzt also klar erkennbar:

  1. Einen METAR für einen definierbaren Flughafen per HTTP-API abholen,
  2. den METAR-Bericht in ein strukturiertes METAR-Objekt umwandeln,
  3. das METAR-Objekt wiederum in ein Aerofly-kompatibles Objekt umwandeln,
  4. und diese Daten dann in die Simulation schreiben – hier also in die main.mcf.

Phase 1: Kommandozeile

Als Webprogrammierer habe ich mich für das Projekt an eine Sprache gehalten, die ich gut kannte: JavaScript, bzw. NodeJS.

Hier zahlte sich vor allen Dingen aus, dass ich privat sehr gerne test-getrieben entwickele, da das Format von METARs doch einige Überraschungen parat hatte. Unzählige Tests später hatte ich dann aber einen METAR-Parser, der mit vielen Fallstricken der METAR-Angaben umgehen konnte.

Schon nach einem Monat kopierte das Kommandozeilen-Tool fröhlich METAR-Daten in Aerofly FS2. Das ganze Projekt veröffentliche ich als „Aerofly-Weather“ bzw. „AeroWX“ bei NPM.

Schon bald fiel mir aber auf, dass ich zu kurz gesprungen war: Einerseits erforderte mein Programm die Installation von NodeJS – andererseits war es ein Kommandozeilenprogramm, mit entsprechend wenig ansprechender Präsentation.

Phase 2: Electron

Es musste also eine bedienbare Desktop-Applikation her. Da ich als Webprogrammierer mit dieser Welt bisher nur sehr wenig Erfahrung hatte, fand ich zum Glück eine Lösung genau nach meinem Geschmack: Electron.

Mit Electron konnte ich nicht nur meine NodeJS-Programmierung direkt weiterverwenden, das GUI meiner Applikation konnte mit HTML, CSS und JavaScript gebaut werden – Sprachen, mit denen ich jeden Tag arbeite. So konnte mit relativ moderatem Aufwand nach einem Monat eine Desktop-Applikation gebaut werden. Diese wurden mit dem Electron-Builder zu einer eigenständigen EXE-Datei kompiliert und ließ sich dann als „Aerofly-Weather“ bzw. „AeroWX“ bei Github herunterladen.

Aber auch hier nagte die Unzufriedenheit an mir: Diese Applikation hatte als ZIP gepackt eine Größe von über 60MB, und auch die Ausführung dieses Programms verschlang Unmengen an RAM. Für eine so kleine Applikation war dies kaum zu rechtfertigen.

Phase 3: Kommandozeile, aber in C++

Durch einen Tipp aus der Aerofly-Community hatte man mir einen neuen Floh ins Ohr gesetzt: Mit C++ könnte ich mein Projekt so umbauen, dass es auch in der Simulation live das Wetter umstellen könnte. Nach ein bisschen Recherche und Interviews mit befreundeten Programmierern stürzte ich mich erneut ins Unterholz, um das Projekt nochmals zu bauen – nur diesmal in C++.

Praktischer Nebeneffekt war, dass ich alle funktionalen Überlegungen bereits in NodeJS gelöst hatte. In meiner Vorstellung konnte ich mich also ganz auf das Umschreiben meines Projekts von JavaScript auf C++ konzentrieren. Tatsächlich waren ein Großteil der Ideen in C++ reproduzierbar, wenn auch die strenge Typisierung (als PHP- und JavaScript-Programmierer eine ganz neue Erfahrung) und die nun notwendige IDE (Microsoft Visual Studio) doch zuerst eine erhebliche Hürde darstellte.

Nichtsdestotrotz konnte nach knapp zwei Wochen das ursprüngliche Projekt als eigenständig ausführbare Applikation umgesetzt werden. Die Ausgabe auf der Kommandozeile war beinahe identisch – die Größe der eigentlichen Applikation aber deutlich kompakter, und vor allen Dingen die Installation von NodeJS nicht mehr erforderlich. Mit einem einfachen Deployment-Workflow konnte die Applikation als „Aerofly Wettergerät“ bei Github bereitgestellt werden.

Phase 4: Eine echte Desktop-Applikation

Das Aerofly Wettergerät brauchte nun ebenfalls einen feschen Desktop-Aufsatz. Hier hatte ich zuerst Sciter ausprobiert – ähnlich wie Electron hätte man HTML und CSS für die Gestaltung des Frontends verwenden können. Nach einigen Tests erwies sich aber Sciter für meine Belange als wenig geeignet. Stattdessen war der Tipp eines Kollegen goldrichtig: WxWidgets erlaubte mit überschaubarem Aufwand von zwei weiteren Wochen, eine native Applikation im Look & Feel des Betriebssystems zu erstellen.

Die so entstandene Desktop-Applikation wurde ebenfalls im Paket vom „Aerofly Wettergerät“ bei Github bereitgestellt, so dass sowohl die Kommandozeilen- als auch die Desktop-Version nicht nur die selben Sourcen haben, sondern auch im selben Installationspaket geliefert werden. Die Download-Größe liegt unter einem Zehntel des ursprünglichen NodeJS-Paketes, und auch der Fußabdruck im RAM ist um Größenordnungen kleiner – wenn auch die Ausgabe nun etwas schlichter wirkt.

Die nächste Phase?

Bis jetzt verbleibt ein Wehrmutstropfen bei dem Projekt: Das Wetter kann nur außerhalb der Simulation heruntergeladen und eingestellt werden. Damit bleiben folgende Fälle außen vor:

  • Nach dem Starten der Simulation unternimmt man einen längeren Flug, bei dem sich sowohl aufgrund der geografischen Position als auch der voranschreitenden Zeit das Wetter verändert hätte.
  • Nach dem Starten des Simulators entscheidet man sich spontan für einen ganz anderen Start- bzw. Zielflughafen.

Inzwischen habe ich eine kleine DLL zum Leben erwecken können, die im laufenden Aerofly FS2 Nachrichten lesen und schreiben kann. Unter anderem emittiert der Simulator Nachrichten über den nächstgelegenen Flughafen – was das Aerofly Wettergerät wiederum nutzen könnte, um alle 10 Minuten das Wetter für den nächstgelegenen Flughafen aus dem Internet abzufragen und in die Simulation zu übertragen.

Wie bei jeder anderen Projektphase ist auch zu Beginn dieser Phase unklar, wann und ob diese Phase erfolgreich abgeschlossen werden kann.