Seite 1 von 16

HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 24.02.2014, 13:30
von funkleuchtturm
Auf meiner Homepage gibt´s hierzu eine neue verbesserte Lösung http://www.stall.biz/?project=sonnensta ... sen-lampen

Wenn ich hier von Sonnenstand spreche, dann meine ich die Position der Sonne mit den Kennzeichen Azimut und Elevation.
Der Azimut ist der Winkel des Sonnenstandes in der Horizontalen: wie bei der Kompassrose ist 0° gleich NORD, 90°gleich OST, 180° gleich SUED und 170°gleich WEST.
Die Elevation ist der Winkel des Sonnenstandes in der Vertikalen: 0° ist der Horizont, 90° ist der "Himmel ganz oben".
Mit diesen beiden Größen kann man sehr gut feststellen, ob und wann die Sonne bestimmte Elemente "besonnt" und ggf. ob mit der Homematic bestimmte Aktionen auszulösen sind. Aktionen können das Herunterlassen der Rolladen sein, das Ausfahren der Markisen, das Öffnen von Lüftungsfenstern, das Steuern der Lage von Sonnenkollektoren oder einfach das Schalten von Umwälzpumpen bei thermischen Sonnenkollektoren. Schliesslich kann man sogar mit der Information des Elevationswinkels dämmerungsabhängig bestimmte Aktionen auslösen: Lampen und/oder Rolläden .

Leider ist die Berechnung des Sonnenstandes eine relativ schwierige Rechnung, weil einerseits die lokalen Positionsdaten zu berücksichtigen sind, wie auch die lokale Zeit mit dem ganzen Thema Sommer/Winterzeit. siehe auch Google Sonnenstand und u.a. http://de.wikipedia.org/wiki/Sonnenstand
Zudem erfordert die Berechnung leider mathematische Winkelfunktionen, die in der HM-Skriptsprache nicht enthalten sind; also im Hinblick auf Realisierung auf der Homematic ein schwieriges Thema.

Lösungsansätze:
- Eine Lösung ist die Auslagerung der komplexen Kalkulation in ein kleines TCL oder PHP-Progrämmchen, was dann per HM-Skript gestartet wird. Aber das ist auch nicht so prickelnd, weil ggf. beim Firmware-Update das Progrämmchen wieder an Ort und Stelle gespeichert werden muss.
- Eine andere Lösung ist, die Sonnenstandsdaten aus dem Internet beispielsweise alle 5 Minuten zu holen, ähnlich wie die Wetterdaten mit z.B. Wunderground. Hierfür gibt es mehrere Server, die aber eher semiprofessionell betrieben werden. Wie lange und wie oft man die Daten dort herunterladen kann ist ungewiss. Gerade im Hinblick auf die besondere Bedeutung der häuslichen Elemente, die man damit steuern will, ist das m.E. nicht so zielführend. Aber trotzdem ist das eine mögliche Lösung. http://homematic-forum.de/forum/viewtop ... onnenstand

Mein Lösungsansatz verwendet nur ein HM-Skript, das die Daten Azimut und Elevation für den individuellen Standort mit einem Interpolationsverfahren berechnet, welches nur mit den vier Grundrechenarten arbeitet:
Zuerst dazu hier etwas Theorie oder gleich nach unten zum Kochrezept:
Wichtig bei der Sonnenstandsberechnung ist zuerst die Ermittlung der aktuellen Sonnenzeit. Diese ergibt sich aus der Zeitzonenzeit plus Addon-Zeit , die aus dem Längengrad berechnet wird. Da wir aber auch Winter/Sommerzeit haben, muß das ebenfalls berücksichtigt werden. Ich habe hier ein anderes Verfahren verwendet, bei dem aus den in der Homematic vorhandenen Zeiten für Sonnenaufgang und Untergang einfach der Mittelwert berechnet wird und die Abweichung von 12:00h die Korrekturzeit ist, die zur aktuellen Zeit addiert wird. So erhält man die lokale Sonnenzeit, ohne dass man kompliziert rechnen muss.
In Abhängigkeit von dieser so berechneten Sonnenzeit berechnet sich der Sonnenstand in Abhängigkeit vom Breitengrad über eine komplexe trigonometrische Formel. Zur Berechnung gibt es im Internet schöne Excel-Berechnungsvorlagen. Ich habe diese hier verwendet : http://karena.de/software.htm#Solardiagramm und für meinen Standort ausgedruckt:
sonnenstand0.jpg
Wenn man beispielweise sich den Sonnenstand für 15:00H während des Jahres anschaut, dann verändert sich der Azimut um ca. 25°, was im Rahmen einer Beschattungssteuerung schon wichtig ist. Das zeigt, dass eine rein uhrzeitabhängige Steuerung der Beschattung oder der nachtabhängigen Rolladenbetätigung für die meisten Anwendungen zu ungenau ist.
Für die Berechnung des Sonnenstandes mit einem HM-Skript werden von dem individuellen Chart, nur die mit Kreisen gekennzeichneten Koordinaten abgelesen und in das Skript eingetragen. Das Skript macht dann eine mehrstufige lineare Interpolation und errechnet sich für den aktuellen Tag die rot gekennzeichnete Tagesline . Diese wiederum ergibt mit der Sonnenzeit die gesuchten Werte für Azimut und Elevation.

Und jetzt für diejenigen ohne Interesse für die Theorie hier
das Kochrezept:

1. Anlegen der Systemvariablen:
- sonne_azimut Zahl grad -360 bis +360
- sonne_elevation Zahl grad -90 bis +90

2. Eintragen der lokalen Koordinatenwerte in das Skript. Für Köln sind die Werte bereits eingetragen. Wer einen anderen Breitengrad hat, kann aus folgender Tabelle sich die Werte direkt oder interpoliert herausholen:
stuetzstellen_sonnenstand.jpg
3. Folgendes Skript etwa alle 5 Minuten aufrufen, damit die Systemvariablen aktualisiert werden

Code: Alles auswählen

!############################################################################################
!Daten aus lokalem Sonnenbahndiagramm in gerundeten Werten einsetzen: 
!(diese  Werte hier sind für  Breitengrad 51grad ,Köln!)
integer a12max = 180; integer a11max = 152; integer a10max = 129; integer a9max = 111;
integer e12max = 63;   integer e11max = 60;   integer e10max = 55;   integer e9max = 46;  
integer  a12min = 180; integer a11min  = 166; integer a10min  = 152; integer a9min = 140; 
integer e12min = 15;    integer e11min  = 14;   integer e10min = 11;    integer  e9min = 5;    
!############################################################################################
!Konstantwerte für alle mitteleuropäischen Breitengerade von 48grad(Wien) bis 54grad(Kiel)
integer a5max = 63;  integer e5max = 7;integer a5min = 95;  integer e5min = -28;

!Alle Zeiten in Minuten
integer c_zeit = system.Date("%M").ToInteger() + 60*system.Date("%H").ToInteger(); 
integer c_tagesbeginn = system.SunriseTime("%M").ToInteger() + 60*system.SunriseTime("%H").ToInteger();
integer c_tagesende = system.SunsetTime("%M").ToInteger() + 60* system.SunsetTime("%H").ToInteger();
integer sonnenzeit =c_zeit + 720 - 0.5 *(c_tagesbeginn +c_tagesende);
boolean nachmittag = false;
if (sonnenzeit > 720) {sonnenzeit =1440 - sonnenzeit; nachmittag = true; } 
integer jahrestag = system.Date("%j").ToInteger();
if (jahrestag > 355) {jahrestag =jahrestag -355;} else {jahrestag =jahrestag +10;}
if (jahrestag  > 182) {jahrestag =365 - jahrestag;} 
real jahresfortschritt =0.005464 * jahrestag;  ! entspricht /183
!WriteLine("jahresfortschritt" #jahresfortschritt);   !wert läuft zwischen 0 (dec ) und 1 (jun) und zurück
!WriteLine("sonnenzeit" #sonnenzeit);

!Stuetzwerte der heutigen Tageslinie berechnen
real a12 = 180;
real e12 =  e12min + jahresfortschritt * (e12max - e12min);

real a11 = a11min + jahresfortschritt * (a11max - a11min);
real e11 =  e11min + jahresfortschritt * (e11max - e11min);

real a10 = a10min + jahresfortschritt * (a10max - a10min);
real e10 =  e10min + jahresfortschritt * (e10max - e10min);

real a9 = a9min + jahresfortschritt * (a9max - a9min);
real e9 =  e9min + jahresfortschritt * (e9max - e9min);

real a5 = a5min + jahresfortschritt * (a5max - a5min);
real e5 =  e5min + jahresfortschritt * (e5max - e5min);

real a0 = a5; real e0 =e5; real a1= a9; real e1= e9;
real a =  a0 + (0.00417 * (sonnenzeit -300) * (a1 - a0));
real e =  e0 + (0.00417 * (sonnenzeit -300) * (e1 - e0));
!WriteLine("a    e   " #a #e);

if (sonnenzeit >539)	
  {a0 = a9; e0 =e9; a1= a10; e1= e10; 
   real a = a0 +  (0.0167* (sonnenzeit - 540) *(a1 - a0)); 
    real e = e0 +  (0.0167* (sonnenzeit - 540) *(e1 - e0)); }

if (sonnenzeit >599)  
    {a0 = a10; e0 =e10; a1= a11; e1= e11; 
    real a = a0 +  (0.0167* (sonnenzeit - 600) *(a1 - a0)); 
    real e = e0 +  (0.0167* (sonnenzeit - 600) *(e1 - e0)); }

if (sonnenzeit >659)   
  {a0 = a11; e0 =e11; a1= a12; e1= e12; 
    real a = a0 +  (0.0167* (sonnenzeit - 660) *(a1 - a0)); 
    real e = e0 +  (0.0167* (sonnenzeit - 660) *(e1 - e0)); }

if (nachmittag == true) {a = 360 - a;  sonnenzeit = 1440 - sonnenzeit;}
dom.GetObject("sonne_elevation").State(e);
dom.GetObject("sonne_azimut").State(a);

!Wer noch was mit der lokalen Sonnenzeit anfangen will, der muss zusaetzlich die folgenden Systemvariablen anlegen:
!"sonnen_zeit"  Zahl   min    und    "sonnen_zeit_hh_mm"     Zahl
!und die Rufzeichen in den folgenden Skriptzeilen entfernen
!dom.GetObject("sonnen_zeit").State(sonnenzeit);
sonnenzeit =0.0166 * sonnenzeit;
integer sonnenzeit_h = sonnenzeit.ToInteger();
real sonnenzeit_min = (sonnenzeit - sonnenzeit_h) *0.6;
real sonnenzeit_hhmm = sonnenzeit_min + sonnenzeit_h;
!dom.GetObject("sonnen_zeit_hh_mm").State(sonnenzeit_hhmm);
Fertig!

Wie schon gesagt kann man mit den Werten sonnen_azimut und sonnen_elevation tolle Sachen veranstalten, um zu jeder Jahreszeit die richtigen Aktionen der Rolladen- und Jalousiensteuerung auszulösen. Oder man kann sogar das altbekannte Skript für die Berechnung der Tageszeiten durch ein besseres Tool ersetzen, bei dem man die verschiedenen Dämmerungswerte viel felexibler durch den Elevationswinkel ersetzt. Wenn man erst mal verstanden hat, welch wichtige Göße der absolute Sonnestand bei der Hausautomation ist, möchte man auf diese Information nicht mehr verzichten. Ich glaube sogar, dass professionelle Systeme wie KNX auch diese Grössen berechnen.
Vielleicht werde ich hierzu bei Gelegenheit mal meine aktuelle Rolladen- und Jalousiensteuerung vorstellen, die wesentlich von sonnen_azimut und sonnen_elevation gesteuert wird.

Changelog 28.02.2014: Die notwendigen Systemvariablen wurden weiter reduziert, entsprechende Änderungen im Skript eingetragen. Kennwerte für Köln korrigiert.

Re: HM-Skript zur einfachen Sonnenstandsberechnung

Verfasst: 28.02.2014, 09:03
von Spaßbremse
Das klingt sehr interessant, vielen Dank.

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 11:46
von joe.oster
funkleuchtturm hat geschrieben:Für Köln sind die Werte bereits eingetragen.
Hallo Eugen,

sind das wirklich die Werte für Köln ???

Wenn ich die Zahlen im Skript mit der Tabelle vergleiche würde ich sagen, das sind die Werte für München :shock:

Oder liege ich da falsch ??? :wink:

Ansonsten sehr gute Arbeit, ich werde das Skript nun auch mal testen, Danke :wink:

Joe

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 13:41
von funkleuchtturm
joe.oster hat geschrieben:Wenn ich die Zahlen im Skript mit der Tabelle vergleiche würde ich sagen, das sind die Werte für München :shock:
Hallo Joe,
Du hast völlig recht. Ich hab im Skript jetzt die Werte für Köln eingetragen.
Danke für den Hinweis!

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 20:34
von VVogt
Hallo funkleuchtturm,

interessanter Ansatz. Leider bekomme ich beim Versuch das Script einzustellung eine Fehlermeldung.... :(

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 20:46
von funkleuchtturm
Hallo VVogt,
ich habe gerade sicherheitshalber das Skript aus dem Blog kopiert und im Fenster "Skript bearbeiten" die Fehlerprüfung durchgeführt. Bei mir "keine Fehler!"

Hast Du auch die Systemvariablen am besten mit Copy&Paste aus dem Skript angelegt, damit keine Schreibfehler da sind ?

Das Skript wird bei mir alle 10 Minuten oder auf Tastendruck (virtuelle Taste) ausgelöst und läuft fehlerfrei.

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 21:09
von VVogt
Hallo funkleutturm,

Ich bekommen folgende Fehlermeldung. Kann aber leider "bewußt" keinen Fehler entdecken... :?

Error 1 at row 43 col 56 near ^ - a0));
real e = e0 + (0.00417 * (sonnenzeit -300) * (e1 - e0));
!Writ
Parse following code failed:

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 21:23
von funkleuchtturm
Hast Du das Skript wirklich unverändert über die Copy-Funktion übernommen oder hast Du vielleicht irgendwelche Werte ganz am Anfang geändert ?
... ggf. schick doch mal Dein original verwendetes Skript!

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 21:47
von VVogt
Hallo funkleuchtturm,

eins zu eins kopiert. Bei der Prüfung erhalte ich dann die Meldung.... :(

Re: HM-Skript zur einfachen Sonnenstandsberechnung Script

Verfasst: 28.02.2014, 22:01
von funkleuchtturm
Ich versteh´s einfach nicht!
Heissen Deine Systemvariablen auch wirklich genau wie vorgegeben und sind die auch für negative Zahlenwerte freigegeben , beispielsweise von -360 bis +360?