Berechnung des Sonnenstandes

01.09.2016

Bereits seit einiger Zeit entwickelt sich bei mir ein Plan, die Rollläden im Haus automatisch zu steuern, in Abhängigkeit von der Sonneneinstrahlung und dem Wetter. Dabei spielt der Sonnenstand eine wichtige Rolle. Den Stand der Sonne gibt man in zwei Winkeln an: Azimut und Zenit. Die beiden Größen verändern sich kontinuierlich über den Tag (und auch in der Nacht). Hier beschreibe ich, mit welcher einfachen Formal man diese Zahlen berechnen kann und wie ich es in mein vernetztes Zuhause integriere.

Bildquelle: www.zum.de/portal/

Azimut und Zenit

Mit diesen beiden Winkeln kann man den aktueleln Stand der Sonne von überall auf der Welt beschreiben:

  • Azimut nennt man den Winkel der Sonnen zur Nord/Süd-Achse. Durch die Bestimmung des Azimut kann man also feststellen, von welcher Himmelsrichtugn die Sonne gerade scheint und z.B. prüfen, welches Fenster dadurch gerade bescheint wird und welches der Sonne gerade abgewandt ist.
  • Der Zenit ist der Winkel der Sonne zur Senkrechten zum Erdmittelpunkt. Mithilfe der Zenit-Angabe kann man sehen, wie "hoch" die Sonne gerade steht. Im Sonner erreicht der Zenit erwartungsgemäß seht hohe Werte und im Winter steht die Sonne niedrig.

Diese beiden Zahlen kann man nach verschiedenen Methoden berechnen, die mehr oder weniger Präzise sind. Für die Anforderungen hier im hundhome sind aber alle Methoden gleichwertig genau. Alle Methoden erfordern darüber hinaus die Kenntnis der aktuellen Position auf dem Globus - also die Angabe des Längengrads und des Breitengrads. Schließlich ist der Stand der Sonne immer abhängig vom Ort an dem man sich befindet.
Zunächst habe ich im Internet nach Online Diensten gesucht, die eine API anbieten zur Berechnung. Am ende fand ich eine Formel und habe mich entschieden den Wert selbst zu berechnen und keine Online API zu nutzen. Ich erwarte, dass das am ende weniger zeitintensiv und systembelastend ist.
Die folgende LUA Funktion verwende ich:

moduleobj.calc = function(self, timestamp)
        timestamp = timestamp or os.date("*t")
        local dayofyear =   (timestamp.month - 1) * 30.3 + timestamp.day
        local declination = -23.45 * math.cos(sc.kbypi * 360 *(dayofyear + 10) / 365)
        local timestate =   60 * (-0.171 * math.sin(0.0337 * dayofyear + 0.465) - 0.1299 * math.sin(0.01787 * dayofyear - 0.168))
        local hourangle =   15 * ((timestamp.hour + timestamp.min / 60) - (15 - self.lon) / 15 - 12 + timestate / 60)
        local sincenit =    math.sin(sc.kbypi*self.lat)*math.sin(sc.kbypi * declination) + math.cos(sc.kbypi * self.lat) * math.cos(sc.kbypi * declination) * math.cos(sc.kbypi * hourangle)
        local cenit =       math.asin(sincenit) / sc.kbypi
        local cosazimut =   -(math.sin(sc.kbypi * self.lat) * sincenit - math.sin(sc.kbypi * declination)) / (math.cos(sc.kbypi * self.lat) * math.sin(math.acos(sincenit)))
        local azimut =      math.acos(cosazimut) / sc.kbypi
        --if ((timestamp.hour + timestamp.min / 60) > (12 + (15 - self.lon) / 15 - timestate / 60)) then azimut = 360 - azimut end
        return cenit, azimut
    end

Die konstanten Zahlen in der Formel sind Vereinfachungen der Zahl Pi bzw. der Umrechnung vom Gradmaß zum Bogenmaß. Die Ungenauigkeit, die dadurch entsteht, ist für den hier gezeigten Anwendungsfall nicht kritisch. Die Werte des Längengrads und Breitengrads verbergen sich hinter den Variablen "self.lat" und "self.lon". Der Timestamp-Wert erlaubt es den Sonnenstand für eine bestimmte Tageszeit zu berechnen.

Die Integration in girder

Weil ich in girder die Veränderungen des Azimut und des Zenit Winkels als Event für Automatismen nutzen möchte, habe ich mich entschieden, die Berechnungsformel in einen virtuellen Sensor zu packen. Dieser Sensor liefert alle 5 Minuten den aktuellen Sonnenstand als eine JSON-Stuktur mit den beiden werten Azimut und Zenit.

Ein einzelnes item Manager Module Objekt bezieht sich dabei auf eine Lokation mit einem festen Längengrad und einem festen Breitengrad. Dazu wird ein einzelnes Item erstellt welches den virtuellen Sensor abbildet. Dieser Sensor gibt nun alle 5 Minuten einen JSON-String ab der im Rahmen von Regeln und Automatismen als Auslöser und Vergleichsoperator verwendet werden kann. In einem zukünftigen Beitrag erkläre ich, wie ich daraus eine Rollladensteuerung baue.

Zurück