Astral – mit Python Sonnenaufgang, Sonnenuntergang, Mondphasen, goldene / blaue Stunde berechnen

Kein Kommentar Autor: Jürgen (jdo)

Bei meinen Experimenten, den Raspberry Pi bei Sonnenaufgang und Sonnenuntergang etwas tun zu lassen, hat ein Kommentator die Python-Bibliothek Astral erwähnt. Damit würde es auch offline funktionieren. Ich bin schon vorher darüber gestolpert, aber es funktionierte nicht so richtig. Allerdings hat mich die Idee auch nicht losgelassen und ich wollte mich genauer mit Astral beschäftigen. Ich programmiere nicht so oft und einfach war das nicht, muss ich zugeben.

Eines meiner größten Probleme war, dass sich die meisten Beispiele für Astral im Web auf Python 2 beziehen und nicht Python 3. Es gibt noch ein paar andere Stolpersteine, über die ich gefallen bin. Der Beitrag hier soll auch als persönlicher Spickzettel dienen. Es ist einfach eine Installationsanleitung mit ein paar Fallbeispielen in Scripten. Die offizielle Dokumentation arbeitet nur mit der Python-Shell und ist meiner Meinung nach nicht sehr anfängerfreundlich. Außerdem hat sich herausgestellt, dass die Dokumentation zu Astral etwas undurchsichtig. Die perfekte Zutat für Frust.

Ein Wort zu offline: Der Raspberry Pi hat per Standard keine RTC (Real Time Clock) und speichert die Uhrzeit deswegen nicht dauerhaft. Willst Du bei Systemstart die korrekte Uhrzeit haben, muss der Pi online sein. Du kannst die Uhrzeit auch manuell stellen oder lötest ein RTC-Modul an*.

Übrigens: Die Berechnungen mit Astral unterscheiden sich nur minimal zu meiner Online-Lösung. Deswegen habe ich mein Script auch angepasst und benutze nun eine Offline-Variante. In der Dokumentation steht, dass die Höhe des Standorts nicht in die Berechnung einfließt, weil es vernachlässigbar ist.

Probleme mit Astral und Raspberry Pi

Ausgangspunkt war eine komplett neue Installation von Raspbian Buster, die auf den neuesten Stand gebracht wurde:

sudo apt update
sudo apt upgrade

Da Astral via Pip installiert wird, müssen wir das entsprechende Paket für Python  3 installieren

sudo apt install python3-pip

Die offizielle Dokumentation beschreibt dann auch noch, wie ich Astral installieren kann:

pip3 install astral

Der Anfang ist gemacht und die Software ist installiert.

Weil bei Raspbian Lite im Gegensatz zur Desktop-Version gpiozero nicht installiert ist, erledige ich das an dieser Stelle auch gleich. Will ich Dinge via Astral schalten, brauche ich das früher oder später.

sudo apt install python3-gpiozero

Nun bin ich mit den Vorbereitungen zufrieden.

Script fällt auf die Nase

Nun habe ich gleich versucht, Astral in einem Script zu benutzen und das ist grandios auf die Nase gefallen. Das war damals auch der Grund, warum ich es nicht weiter benutzt habe. Mein Fehler war, das Test-Script astral.py zu nennen und deswegen ist das Script auf die Nase gefallen. Ich habe diese Fehlermeldung erhalten:

ImportError: cannot import name ‘LocationInfo’ from ‘astral’ (/home/pi/astral.py)

Hier als Screenshot:

Astral kann LocationInfo nicht importieren

Astral kann LocationInfo nicht importieren

Spielst Du mit dem Programm, dann mache einfach nicht den gleichen Fehler wie ich. Benenne ich die Datei in astral_test.py um, funktioniert die Sache. Man lernt nie aus.

Aber genug der Probleme. Sehen wir uns nun ein paar praktische Beispiele an. Das macht auch wesentlich mehr Spaß.

Datenbank von Astral abfragen

Aus der Dokumentation kannst Du entnehmen, dass Standortdaten für diverse Städte in einer Datenbank vorhanden sind. Es sind alle Hauptstädte, plus ein paar zusätzliche Städte aus Großbritannien und den USA enthalten. Die einzige deutsche Stadt mit Standortdaten ist somit Berlin. Du kannst die Datenbank wie folgt abfragen:

from astral import LocationInfo
from astral.geocoder import database, lookup
city = lookup("Berlin", database())
print(city)

Damit bekomme ich folgende Ausgabe:

Astral hat die Standortdaten von Berlin in einer Datenbank gespeichert

Astral hat die Standortdaten von Berlin in einer Datenbank gespeichert

Ich kann die Werte auch einzeln abfragen:

from astral import LocationInfo
from astral.geocoder import database, lookup

city = lookup("Berlin", database())

print(city.name)
print(city.region)
print(city.timezone)
print(city.latitude)
print(city.longitude)

Ich muss die Datenbank aber nicht benutzen, sondern kann meinen eigenen Standort definieren. Dafür muss ich natürlich astral.geocoder nicht mehr importieren. Willst Du die Berechnung so genau wie möglich haben, definierst Du am besten Breitengrad und Längengrad selbst:

from astral import LocationInfo

city = LocationInfo(name="Regensburg", region="Germany", timezone="Europe/Berlin", latitude=49.03451, longitude=12.11923)

print((
    f"Information for {city.name}/{city.region}\n"
    f"Timezone: {city.timezone}\n"
    f"Latitude: {city.latitude:.02f}; Longitude: {city.longitude:.02f}\n" ))

OK, nun haben wir unseren Standort definiert. Schauen wir uns an, was wir damit machen können.

Sonnenaufgang, Sonnenuntergang, Morgendämmerung und Abenddämmerung

Mit dem Standort berechnet uns Astral die gewünschten Zeiten, per Standard in UTC. Das ist relativ einfach und sieht wie folgt aus:

from astral import LocationInfo
from astral.sun import sun

city = LocationInfo(name="Regensburg", region="Germany", timezone="Europe/Berlin", latitude=49.03451, longitude=12.11923)

c_data = sun(city.observer)

print("Sonnenaufgang: " + str(c_data["sunrise"]))
print("Sonnenuntergang: " + str(c_data["sunset"]))
print("Morgendämmerung: " + str(c_data["dawn"]))
print("Abenddämmerung: " + str(c_data["dusk"]))

Die Ausgabe ist wie folgt:

Astral verrät und Sonnenaufgang, Sonnenuntergang, Morgendämmerung und Abenddämmerung für den Standort Regensburg

Astral verrät und Sonnenaufgang, Sonnenuntergang, Morgendämmerung und Abenddämmerung für den Standort Regensburg

Hinweis: Die Zeiten werden berechnet, wenn die Sonne den Horizont bei klarer Sicht durchbricht – Hindernisse im Auge des Betrachters werden nicht beachtet.

Gibst Du kein Datum an, rechnet Astral mit dem aktuellen Datum. Du kannst Dir die Werte aber auch für ein bestimmtes Datum berechnen lassen. Du musst es bei der Definition von c_data nur angeben und datetime importieren. Hier ein Beispiel für den 21. Oktober 2019:

from astral import LocationInfo
from astral.sun import sun
import datetime

city = LocationInfo(name="Regensburg", region="Germany", timezone="Europe/Berlin", latitude=49.03451, longitude=12.11923)

c_data = sun(city.observer, date=datetime.date(2019, 10, 21))

print("Sonnenaufgang: " + str(c_data["sunrise"]))
print("Sonnenuntergang: " + str(c_data["sunset"]))
print("Morgendämmerung: " + str(c_data["dawn"]))
print("Abenddämmerung: " + str(c_data["dusk"]))

Da sind die Tage schon kürzer:

Im Herbst sind die Tage kürzer

Im Herbst sind die Tage kürzer

In der Dokumentation steht, dass man sich auch Informationen zur goldenen Stunde und blauen Stunde anzeigen lassen kann. Vor allen Dingen für Fotografen sind das wichtige Informationen.

Goldene Stunde und blaue Stunde

Die blaue Stunde und die goldene Stunde tauchen zweimal pro Tag auf. Vereinfacht gesagt: bei der blauen Stunde steht die Sonne unterhalb des Horizonts und bei der goldenen knapp drüber. Bei der blauen Stunde dominiert das blaue Lichtspektrum und bei der goldenen Stunde sind die Farben viel weicher und wärmer.

Goldene Stunde

Goldene Stunde

Das Problem an dieser Stelle ist, dass nicht offensichtlich in der Dokumentation steht, wie ich an diese Werte komme. Nun könnte ich an dieser Stelle raten oder besser einen Blick in die entsprechende Datei werfen, die zum Glück auf GitHub frei verfügbar ist.

Mögliche Werte für Astral

Mögliche Werte für Astral

Du findest es auch in der Dokumentation, wenn Du auf Package klickst. Das ist etwas versteckt und ich mag Dokumentationen nicht, bei denen man Ostereier suchen muss.

Im Gegensatz zum Sonnenaufgang oder Sonnenuntergang haben blaue Stunde und goldene Stunde zwei Werte: Anfang und Ende. Gibst Du keinen zusätzlichen Wert an, rechnet Astral per Standard zur aufgehenden Sonne. Lassen wir uns die Daten ausgeben:

from astral import LocationInfo
from astral.sun import golden_hour
from astral.sun import blue_hour

city = LocationInfo(name="Regensburg", region="Germany", timezone="Europe/Berlin", latitude=49.03451, longitude=12.11923)

gh = golden_hour(city.observer)
bh = blue_hour(city.observer)

print("Goldene Stunde Start: " + str(gh[0]))
print("Goldene Stunde Ende: " + str(gh[1]))
print("Blaue Stunde Start: " + str(bh[0]))
print("Blaue Stunde Ende: " + str(bh[1]))

Die Berechnung für den Morgen sieht dann so aus:

Goldene Stunde und blaue Stunde beim Sonnenaufgang

Goldene Stunde und blaue Stunde beim Sonnenaufgang

Möchte ich die goldene Stunde und die blaue Stunde für den Abend berechnen, muss ich die Richtung der Sonne auf SETTING setzen. RISING gibt es auch, aber das ist der Standard, wie schon angesprochen. Möchte ich das berechnen, sieht der Code zum Beispiel wie folgt aus (goldene Stunde am Abend und blaue Stunde am Morgen).

from astral import LocationInfo
from astral.sun import SunDirection
from astral.sun import golden_hour
from astral.sun import blue_hour
from datetime import datetime

city = LocationInfo(name="Regensburg", region="Germany", timezone="Europe/Berlin", latitude=49.03451, longitude=12.11923)

gh = golden_hour(city.observer, datetime.now().date(), SunDirection.SETTING)
bh = blue_hour(city.observer)

print("Goldene Stunde Start: " + str(gh[0]))
print("Goldene Stunde Ende: " + str(gh[1]))
print("Blaue Stunde Start: " + str(bh[0]))
print("Blaue Stunde Ende: " + str(bh[1]))

Das Ergebnis liest sich wie folgt:

Goldene Stunde und blaue Stunde beim Sonnenuntergang

Goldene Stunde und blaue Stunde beim Sonnenuntergang

Du siehst an den Zahlen auch, dass die goldene Stunde und die blaue Stunde nicht wirklich 60 Minuten sind. Es kommt hier sehr auf Standort und Jahreszeit an. Deswegen ist es gut zu wissen, wann Du mit Deiner Kamera auf Zack sein musst.

Blaue Stunde an der Weichsel

Blaue Stunde an der Weichsel

Wir können uns mit Astral übrigens auch Informationen zum Mond ausgeben lassen.

Mit Astral Mondphasen berechnen

Das Tool kann auch die Mondphasen ausgeben. Anhand des Datums spuckt das Python-Programm eine Zahl zwischen 0 und 28 aus. In der Dokumentation finden wir, wie die Zahlen der Mondphasen zu deuten sind:

  • 0 – 6,99 – Neumond
  • 7 – 7,99 – zunehmender Mond
  • 14 – 20,99 – Vollmond
  • 21 – 27,99 – abnehmender Mond

Damit die Sache etwas spannender wird, lassen wir uns die Mondphase von gestern, heute und morgen anzeigen. Vor allen Dingen der folgende Tag ist sinnvoll, wenn Du zum Beispiel wissen willst, wann der Mond am vollsten ist:

from astral.moon import phase
import datetime

moon_today = phase()
moon_yesterday = phase(datetime.datetime.now() - datetime.timedelta(days=1))
moon_tomorrow = phase(datetime.datetime.now() + datetime.timedelta(days=1))

print("Mond gestern", end=": ")
print(moon_yesterday)
print("Mond heute", end=": ")
print(moon_today)
print("Mond morgen", end=": ")
print(moon_tomorrow)

Astral würde nun folgendes ausgeben:

Wie voll ist der Mond? Gestern, heute und morgen ...

Wie voll ist der Mond? Gestern, heute und morgen …

Nun kann man damit lustige Spielchen machen. Willst Du zum Beispiel Sterne fotografieren, willst Du so wenig Mond wie möglich haben.

Sternenspur (Star Trail) und Palmen

Sternenspur (Star Trail) und Palmen

Mit nachfolgendem Script finden wir zum Beispiel heraus, wann der Mond in den nächsten 365 Tagen am vollsten und am wenigsten sichtbar ist:

from astral.moon import phase
import datetime

moon_dic = {}

for var in list(range(365)):
    date_temp = datetime.datetime.now().date() + datetime.timedelta(days=(var))
    moon_phase = phase(date_temp)
    moon_dic[moon_phase] = date_temp

darkest = min(moon_dic)
print(moon_dic.get(darkest), end=": ")
print(darkest)

darkest2 = max(moon_dic)
print(moon_dic.get(darkest2), end=": ")
print(darkest2)

Nun weiß ich, dass in den nächsten 365 Tagen der Mond am 17. September 2020 und am 11. Mai 2021 am sehr wenig sichtbar ist.

Astral ist ein nützliches Tool für die Mondphasen

Astral ist ein nützliches Tool für die Mondphasen

Wann er am vollsten ist, kann ich nicht genau sagen. Das Tool sagt mir, dass zwischen 14 – 20,99 Vollmond ist – aber nicht genau, wann der Mond am vollsten ist. Ist das genau bei der Hälfte, also 14? Ich werde in den Himmel starren und versuchen, das beim nächsten Vollmond selbst herauszufinden.

Update: Der vollste Vollmond ist bei 14. Das war der Vollmond gestern Nacht (5. Juni 2020) bei 13,6.

Der Mond bei 13,6 (Astral)

Der Mond bei 13,6 (Astral)

Hier die Astral-Ausgabe zum Screenshot oben. Nun bin ich schlauer und meine anfängliche Vermutung hat sich bestätigt.

Die Astral-Werte zum Bild oben

Die Astral-Werte zum Bild oben

Das Tool kann noch ein paar andere Daten berechnen, aber mehr brauche ich im Moment nicht. Ich kann ausrechnen, was ich will und mir die Daten auch auf mein Smartphone schicken lassen (mit Pushover).

Nun hab ich einen eigenen Bitcoin Ticker, einen Coronavirus Ticker und ein Tool für Sonnenaufgang, Sonnenuntergang, blaue Stunde, goldene Stunde und Mondphasen. Ich weiß, dass es dafür verschiedene Apps gibt, aber ich muss weniger Zeug auf meinem Smartphone installieren und kann mir die Tools außerdem so anpassen, wie ich das gerne hätte. Nun kann ich mir aber sehr gezielt Informationen schicken lassen.

Ich hoffe, das war verständlich

Den Beitrag habe ich geschrieben, um Astral auch selbst ein bisschen besser zu verstehen. Ein paar Dinge sind mir noch nicht ganz klar, aber im Großen und Ganzen verstehe ich, wie Astral einzusetzen ist.

Vielleicht hilft Dir der Beitrag auch, etwas Sinnvolles mit dem Tool anzufangen. Nachdem ich kapiert habe, wie ich es benutze, finde ich es richtig gut. Auf jeden Fall gibt es jede Menge Möglichkeiten, wie sich die von Astral berechneten Daten einsetzen lassen.

Nette Pi-Konstellation

Suchst Du ein VPN für den Raspberry Pi? NordVPN* bietet einen Client, der mit Raspberry Pi OS (32-Bit / 64-Bit) und Ubuntu für Raspberry Pi (64-Bit) funktioniert.




 Alle Kommentare als Feed abonnieren

Kommentare sind geschlossen.