Tags: Skript, Script, Sonnenposition, Elevation, Azimut, Rolladensteuerung, Jalousiensteuerung, Markisensteuerung, Lampensteuerung, Dämmerung, Dämmerungsskript,
Die Sonnenposition wird beschrieben mit der Sonnen_Elevation (Winkel zur Horizontalen) und dem Sonnen_Azimut (Winkel in der Horizontalen, von Norden aus gemessen wie bei der Kompassrose). Beide Grössen sind unentbehrlich für eine jahreszeitabhängige Betätigung von Rolladen für die Nacht, Rolladen für die Beschattung , Jalousien mit variablem Lamellenwinkel, Markisen und letztlich auch für die dämmerungsabhängige Beleuchtung. Professionelle Systeme zur Hausautomation stellen diese Funktion oft nur optional mit Aufpreis zur Verfügung !
Zur Sonnenstandsberechnung hatte ich bereits ein Skript erstellt, das mit mehreren linearen Interpolationsverfahren die Sonnenposition mehr oder weniger genau berechnet. http://homematic-forum.de/forum/viewtop ... 00#p140282 Theorie dazu gibt´s hier: http://de.wikipedia.org/wiki/Sonnenstand
Im Hinblick auf die weitere Verbesserung der Berechnung wird hier nun ein umfangreicheres HM-Skript beschrieben, das die Sonnenposition relativ genau für die gesamten 24h eines Tages berechnet. Durch die Verfügbarkeit brauchbarer Daten der Sonnenposition auch in der Nacht (wenn die Sonne bereits unter dem Horizont ist, Elevation negativ), können auch nachtabhängige Steuerungsaufgaben stufenlos und dämmerungsabhängig einfach gelöst werden. Zeitsprünge durch Umstellung von Sommer- auf Winterzeit entfallen durch diese Steuerungsart vollständig.
Hier also erst mal das Kochrezept:
1.) Sicherstellen, dass in der HM-Zeit- und Positionseinstellung auch der richtige Breitengrad des eigenen Standortes (hier hilft Google Earth !) und die richtige Zeitzoneneinstellung für Deutschland "CET/CEST (UTC +1/+2)" eingetragen sind.
2.) Zwei Systemvariablen anlegen_
- sonne_elevation Zahl -180 bis +180 grad
- sonne_azimut Zahl -360 bis +360 grad
3.) Ein WebUI-Programm anlegen, in dem man beispielsweise all 3 Minuten das folgende Skript aufruft:
Code: Alles auswählen
!berechg sonne_elevation, sonne_azimut; stand 14.03.2014
!Verfasser: funkleuchtturm
real phi = system.Latitude(); !Breitengrad holen
phi = 0.017453292 * phi; !umwandeln in bogenmass
!####### sin_phi und cos_phi mit taylorreihe berechnen
real temp = phi * phi;
real sin_phi =phi * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667)); !sinus-naeherung
real cos_phi = (temp *temp *0.0416667) + 1.0 - (temp * 0.5); !cosinus-naeherung
!### berechnung sonnenzeit, alle zeiten in minuten ########
integer zeit_min = system.Date("%M").ToInteger() + 60*system.Date("%H").ToInteger();
integer tagesbeginn_min = system.SunriseTime("%M").ToInteger() + 60*system.SunriseTime("%H").ToInteger();
integer tagesende_min = system.SunsetTime("%M").ToInteger() + 60* system.SunsetTime("%H").ToInteger();
integer sonnenzeit =zeit_min + 720 - 0.5 *(tagesbeginn_min +tagesende_min);
if (sonnenzeit > 1440) {sonnenzeit = sonnenzeit -1440;}
if (sonnenzeit < 1) {sonnenzeit = 1440 + sonnenzeit;}
boolean nachmittag =false;
if (sonnenzeit > 720) {sonnenzeit =sonnenzeit - 720; nachmittag = true; }
else {sonnenzeit =720 -sonnenzeit;}
!##### berechnung sin_tau und cos_tau ############
real tau = 0.00436332313 * sonnenzeit; ! 15/60 * pi /180 * sonnenzeit [0 < tau < pi ]
if (tau < 1.570796327)
{temp = tau * tau;
real sin_tau =tau * ((temp * temp * 0.0083334) +1.0 - (temp *0.1666667));
tau= 1.570796327 - tau;
temp = tau * tau;
real cos_tau =tau * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));}
else
{real tau1 =3.141592654 - tau;
temp = tau1 * tau1;
real sin_tau =tau1 * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));
tau = tau - 1.570796327;
temp = tau * tau;
real cos_tau = (tau) *(-1.0)* ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667));}
!##### berechnung delta #######################
integer tageszahl = system.Date("%j").ToInteger();
tageszahl = tageszahl +10;
if (tageszahl > 365) {tageszahl = tageszahl - 365;}
if (tageszahl < 92) {real tag = 0.0172142 *tageszahl;temp = tag * tag;
real delta = (-0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));}
if ((tageszahl >91) && (tageszahl < 184)) {tageszahl = 183 - tageszahl; real tag = 0.0172142 *tageszahl;
temp = tag * tag; real delta = (0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));}
if ((tageszahl >183) && (tageszahl < 275)) {tageszahl = tageszahl - 183; real tag = 0.0172142 *tageszahl;
temp = tag * tag; real delta = (0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));}
if ((tageszahl >274) && (tageszahl < 366)) {tageszahl = 365 - tageszahl; real tag = 0.0172142 *tageszahl;
temp = tag * tag; real delta = (-0.410152) *((temp *temp *0.041666) + 1.0 - (temp * 0.5));}
!##### berechnung sin_delta, cos_delta #######################
temp = delta * delta;
real sin_delta =delta * ((temp * temp * 0.0083334) +1.0 - (temp * 0.1666667)); !sinus-naeherung
real cos_delta = (temp *temp *0.0416667) + 1.0 - (temp * 0.5); !cosinus-naeherung
!##### berechnung tan_delta mit stueckweiser linearisierung des tan #######################
boolean vvorzeichen = true;
if (delta< 0.0) {vvorzeichen = false; delta = (-1.0) *delta;}
real tan_delta = 1.0233 * delta;
if (delta >=0.2618) {tan_delta = (1.1822*delta) - 0.0416;}
if (vvorzeichen == false) {tan_delta = (-1.0) * tan_delta;}
!##### berechnung sin_elevation und tan_azimut #######################
real sin_elevation = (sin_phi * sin_delta) +( cos_phi * cos_delta * cos_tau);
temp = sin_elevation * sin_elevation;
real sonne_elevation = sin_elevation * (1.0 + (0.1666667 * temp) + (0.075 * temp * temp));
sonne_elevation = 57.29577951 * sonne_elevation;
real nenner = (sin_phi*cos_tau) - (cos_phi * tan_delta);
if (nenner < 0.0) {boolean plus180 = true;}
real tan_azimut = sin_tau / nenner;
!##### berechnung sonne_azimut mit stueckweiser linearisierung des arctan ############
boolean vorzeichen = true;
if (tan_azimut < 0.0) {vorzeichen = false; tan_azimut = (-1.0)*tan_azimut;}
real sonne_azimut = 0.97723 * tan_azimut;
if ((tan_azimut >=0.2679)&&(tan_azimut < 0.5774)) {sonne_azimut = (0.84588* tan_azimut) + 0.035189;}
if ((tan_azimut >= 0.5774)&&(tan_azimut < 1.0)) {sonne_azimut = (0.6195* tan_azimut) + 0.1659;}
if ((tan_azimut >= 1.0)&&(tan_azimut < 1.3032)) {sonne_azimut = (0.43173* tan_azimut) + 0.3537;}
if ((tan_azimut >= 1.3032)&&(tan_azimut < 1.7321)) {sonne_azimut = (0.3052* tan_azimut) + 0.51856;}
if ((tan_azimut >= 1.7321)&&(tan_azimut < 2.4142)) {sonne_azimut = (0.1919* tan_azimut) + 0.7148;}
if ((tan_azimut >= 2.4142)&&(tan_azimut < 2.9459)) {sonne_azimut = (0.123* tan_azimut) + 0.88115;}
if ((tan_azimut >= 2.9459)&&(tan_azimut < 3.7321)) {sonne_azimut = (0.083312* tan_azimut) + 0.9981;}
if ((tan_azimut >= 3.7321)&&(tan_azimut < 5.0)) {sonne_azimut = (0.050792* tan_azimut) + 1.1194;}
if ((tan_azimut >= 5.0)&&(tan_azimut <7.0)) {sonne_azimut = (0.02775* tan_azimut) + 1.23465;}
if ((tan_azimut >= 7.0)&&(tan_azimut <12.0)) {sonne_azimut = (0.01175117* tan_azimut) + 1.346641;}
if ((tan_azimut >= 12.0)&&(tan_azimut <20.0)) {sonne_azimut = (0.004147854* tan_azimut) + 1.437881;}
if ((tan_azimut >= 20.0)&&(tan_azimut <50.0)) {sonne_azimut = (0.0009987* tan_azimut) + 1.5008639;}
if (tan_azimut >= 50.0) {sonne_azimut = (0.000099983* tan_azimut) + 1.54579974;}
if (sonne_azimut> 1.5707963278) {sonne_azimut = 1.5707963278;}
if (vorzeichen == false) {sonne_azimut = (-1.0) * sonne_azimut;}
sonne_azimut = 57.29577951 * sonne_azimut;
if (plus180 == true) {sonne_azimut = sonne_azimut + 180.0;}
!##### tageszeitliche korrektur und werte auf systemvariablen speichern ######
if (nachmittag == false)
{sonne_azimut = 180.0 - sonne_azimut; sonnenzeit = 720 - sonnenzeit;}
else
{sonne_azimut = sonne_azimut + 180.0;sonnenzeit = 720 + sonnenzeit;}
sonne_azimut = 0.1 *((sonne_azimut*10.0) .ToInteger());
sonne_elevation = 0.1 *((sonne_elevation*10.0) .ToInteger());
dom.GetObject("sonne_elevation").State(sonne_elevation);
dom.GetObject("sonne_azimut").State(sonne_azimut);
11.03.2014: Offset-Fehler bei Azimutwinkel behoben. verschiedene Optimierungen bei der Rechenzeit
12.03.2014: Genauigkeit der Approximaton von sin, cos und arctan weiter verbessert
14.03.2014: Genauigkeit im Nulldurchgang der Elevation verbessert
18.04.2016 Auf meiner Homepage gibt´s ein Update des Sonnenstandsskripts mit Verwendung von weniger Variablen. Das kann der CCU Stabilität vielleicht nützen !
http://www.stall.biz/project/sonnenstan ... sen-lampen
... und nun mit den berechneten Systemvariablen sonne_elevation und sonne_azimut sehr einfach die Rolladen, Markisen und Lampen im Haus steuern.
Wie man das genau machen kann, werde ich bei Gelegenheit an Beispielen vielleicht nochmal darstellen, aber ich denke für den Homematiker ist das kein Problem!
Ach ja, zum Vergleich kann man die Daten mit einem "genauen" Sonnenstandsrechner vergleichen: http://www.volker-quaschning.de/datserv ... /index.php
Breiten und Längengrad eingeben und Berechnungsart "SUNAE" wählen. Die Abweichungen sind bei mir meist unter einem Grad, was bei den verwendeten Näherungsverfahren für die trigonometrischen Funktionen ganz ordentlich ist. Für die Heimautomation ist das jedenfalls mehr als genau!
Ergänzung 14.03.2014:
Wie man an den verwendeten Zahlenkolonnen im Skript erkennt, wurde bewusst weniger auf programmiertechnische "Schönheit" ausgelegt, sondern vielmehr wurde auf möglichst wenig Rechenoperationen und damit Laufzeit optimiert. Dies ist deshalb wichtig, weil das Skript zyklisch häufig aufgerufen wird!
Geringe Unstetigkeiten im Verlauf des Elevations- und Azimutwinkels bedingt durch die verwendeten Näherungsverfahren wurden weiter optimiert, so dass jetzt für die Heimautomation mehr als ausreichende Genauigkeit der Sonnenkoordinaten erreicht wird. Insbesondere im Bereich des Nulldurchgangs der Elevation ist ein möglichst stetiger Winkelverlauf deshalb wichtig, weil die meisten Steuerungsaufgaben im Bereich der Dämmerung erfolgen und hier ein möglichst gleichmässiger stufenloser Verlauf von grossem Vorteil ist.
Das folgende Bild zeigt sehr schön den Azimut und die Elevation, aufgezeichnet mit Historian über 24h. Diese Kurve verschieben sich täglich um einen geringen Betrag, wie man an dem geringen Sprung in der Elevationskurve um ca 00:00h erkennt: Genauigkeit:
Der Vergleich mit Winkelergebnissen der Internet-Sonnenpositionsrechner ist abhängig von dem dort verwendeten Berechnungsverfahren:
Bei dem Berechnungsverfahren SUNAE war der Unterschied bei der Elevation meist weniger als ein halbes Grad. Der Azimutwinkel hatte Abweichungen bis zu etwa 2 Grad. Letztlich ist aber nicht die Genauigkeit entscheidend, sondern dass man im Bereich des Sonnenauf- und -untergangs mit dem Elevationswinkel eine gur aufgelöste stufenlose Zahl hat, von der man Schaltvorgänge reproduzierbar abhängig machen kann. Mit dem Azimut steuert man in der Regel sowieso nur Beschattungseinrichtungen, bei denen eine Winkelgenauigkeit von 2Grad mehr als genau sind.