da ich meine komplette Rollladen-Steuerung vom PC auf die CCU2 verlagern möchte, habe ich mich mit diesem Thema mal wieder beschäftigt.
Zwar gibt es schon einige Threads, die sich mit der Sonnenstandsberechnung beschäftigen, für mich waren die aber teilweise zu kompliziert bzw. ungenau.
Wenn man sowieso schon CuxD hat, und Dateien mittels SSH auf die CCU spielen kann, tut's auch das folgende tcl-Skript:
suninfo.cgi
Code: Alles auswählen
#!/bin/tclsh
load tclrega.so
source [file join $env(DOCUMENT_ROOT) once.tcl]
source [file join $env(DOCUMENT_ROOT) cgi.tcl]
cgi_eval {
##############################################################################
# Himmselsrichtungen: Norden = 0° , Osten = 90° , Süden = 180° , Westen = 270°
# Sonnenhöhenwinkel: Sonnenauf-/untergang = ~0° , Senkrecht von oben = 90°
# Sonnenwinkel auf Fläche: 0° (flach) .. 90° (senkrecht) , < 0° (im Schatten)
# -> Anmerkung: die Sonne kann natürlich nur auf die Fläche scheinen,
# wenn auch Sonnenhöhenwinkel > 0° ist ;-)
##############################################################################
set loglevel 0
set M_PI 3.14159265359
set DachFlaeche(1,SysVarName) "SonnenwinkelOstdach"
set DachFlaeche(1,Dachneigung) 42.0
set DachFlaeche(1,Richtung) 75.0
set DachFlaeche(2,SysVarName) "SonnenwinkelWestdach"
set DachFlaeche(2,Dachneigung) 42.0
set DachFlaeche(2,Richtung) 255.0
##############################################################################
proc log {out} {
global loglevel
if {$loglevel > 0} {puts $out}
}
# Positionseinstellung aus der CCU holen (Breitengrad und Längengrad)
array set res [rega_script {
Write (system.Latitude() # ";" # system.Longitude());
}]
set lst [split $res(STDOUT) ";"]
set lat [lindex $lst 0]
set lon [lindex $lst 1]
#log "lat = $lat"
#log "lon = $lon"
# Sonnenwinkel für JETZT berechnen
set systemTime [clock seconds]
log "systemTime = $systemTime"
# GB: geographische Breite
set GB $lat
log "GB = $GB"
# GBB: geographische Breite im Bogenmaß
set GBB [expr {$GB*$M_PI/180.0}]
log "GBB = $GBB"
# GL: geographische Länge
set GL $lon
log "GL = $GL"
# GM: Meridian (geographische Länge), auf dem die örtliche Standardzeit beruht
set GM 15.0; # //15° für MEZ
# N: Nummer des Tages im Jahr
set N [clock format $systemTime -format %j]
set N [string trimleft $N 0]
set N [expr {$N - 1}]
log "N = $N"
# Standardzeit (Ohne Sommerzeit)!
set SZh [clock format $systemTime -gmt 1 -format %H]
set SZh [string trimleft $SZh 0]
if {$SZh == ""} {set SZh 0}
log "SZh = $SZh"
set SZm [clock format $systemTime -gmt 1 -format %M]
set SZm [string trimleft $SZm 0]
if {$SZm == ""} {set SZm 0}
log "SZm = $SZm"
set SZ [expr {($SZh + 1.0) + ($SZm / 60.0)}]
log "SZ = $SZ"
# B: Jahreskorrekturwinkel
set B [expr {($N - 1.0) * 2.0 * $M_PI / 365.0}]
log "B = $B"
# E: Zeitgleichung (Störungen durch Erdumlauf und Erdrotation)
set E [expr {229.2 * (0.000075 + 0.001868 * cos($B) - 0.032077 * sin($B) - 0.014615 * cos(2*$B) - 0.04089 * sin(2*$B)) / 60.0}]
log "E = $E"
# TS: Sonnenzeit
set TS [expr {$SZ + $E + 4.0*($GL - $GM) / 60.0}]
set ts [expr {12.0 - $TS}]
log "ts = $ts"
# SzW: Stundenwinkel
set SzW [expr {$ts * $M_PI/12.0}]
log "SzW = $SzW"
# Dekl: Deklination
set Dekl [expr {(23.45 * $M_PI/180.0) * sin(2.0*$M_PI * (284.0 + $N) / 365.25)}]
log "Dekl = $Dekl"
# ShW: Sonnen-Höhenwinkel
set ShW [expr {asin(sin($GBB) * sin($Dekl) + cos($GBB) * cos($Dekl) * cos($SzW))}]
log "ShW = $ShW"
# AzW: Azimutwinkel der Horizontale in GRAD
set AzW [expr {acos(((sin($GBB) * sin($ShW)) - sin($Dekl)) / (cos($GBB) * cos($ShW))) * 180.0/$M_PI}]
log "AzW = $AzW"
if {$ts < 0.0} {
set AzW [expr {0.0-$AzW}]
}
log "AzW = $AzW"
log "-----------------------------------------------------------------------------"
# Sonnenhoehenwinkel 0 .. 90 Grad
set Sonnenhoehenwinkel [expr {$ShW * 180.0/$M_PI}]
puts "Sonnenhoehenwinkel = $Sonnenhoehenwinkel"
# Sonnenrichtung 0 .. 360 Grad
set Sonnenrichtung [expr {180.0 - $AzW}]
puts "Sonnenrichtung = $Sonnenrichtung"
log "-----------------------------------------------------------------------------"
proc Ortsvektor {Hoehenwinkel Richtungswinkel} {
global M_PI
set hw [expr {$Hoehenwinkel * $M_PI/180.0}]
set rw [expr {$Richtungswinkel * $M_PI/180.0}]
set v(x) [expr {sin($hw)}]
set v(y) [expr {cos($rw)*cos($hw)}]
set v(z) [expr {sin($rw)*cos($hw)}]
return [array get v]
}
proc VektorWinkel {Vektor1 Vektor2} {
global M_PI
upvar $Vektor1 v1
upvar $Vektor2 v2
return [expr {90.0 - acos($v1(x) * $v2(x) + $v1(y) * $v2(y) + $v1(z) * $v2(z)) * 180/$M_PI}]
}
# Ortsvektor der Sonne aus Hoehenwinkel und Himmelsrichtung bestimmen
array set Ortsvektor_Sonne [Ortsvektor $Sonnenhoehenwinkel $Sonnenrichtung]
log "Ortsvektor_Sonne = $Ortsvektor_Sonne(x) $Ortsvektor_Sonne(y) $Ortsvektor_Sonne(z)"
# Sonnenwinkel Fläche 1
array set Einheitsnormale_Flaeche1 [Ortsvektor [expr {90.0 - $DachFlaeche(1,Dachneigung)}] $DachFlaeche(1,Richtung)]
log "Einheitsnormale_Flaeche1 = $Einheitsnormale_Flaeche1(x) $Einheitsnormale_Flaeche1(y) $Einheitsnormale_Flaeche1(z)"
set SonnenwinkelFlaeche1 [VektorWinkel Einheitsnormale_Flaeche1 Ortsvektor_Sonne]
# Sonnenwinkel Fläche 2
array set Einheitsnormale_Flaeche2 [Ortsvektor [expr {90.0 - $DachFlaeche(2,Dachneigung)}] $DachFlaeche(2,Richtung)]
log "Einheitsnormale_Flaeche2 = $Einheitsnormale_Flaeche2(x) $Einheitsnormale_Flaeche2(y) $Einheitsnormale_Flaeche2(z)"
set SonnenwinkelFlaeche2 [VektorWinkel Einheitsnormale_Flaeche2 Ortsvektor_Sonne]
log "-----------------------------------------------------------------------------"
puts "$DachFlaeche(1,SysVarName) = $SonnenwinkelFlaeche1"
puts "$DachFlaeche(2,SysVarName) = $SonnenwinkelFlaeche2"
array set res [rega_script {
object o_sysvar;
string s_Sonnenhoehenwinkel = "} $Sonnenhoehenwinkel {";
o_sysvar = dom.GetObject("Sonnenhoehenwinkel");
o_sysvar.State(s_Sonnenhoehenwinkel);
string s_Sonnenrichtung = "} $Sonnenrichtung {";
o_sysvar = dom.GetObject("Sonnenrichtung");
o_sysvar.State(s_Sonnenrichtung);
string s_SysVarNameFlaeche1 = "} $DachFlaeche(1,SysVarName) {";
string s_SonnenwinkelFlaeche1 = "} $SonnenwinkelFlaeche1 {";
o_sysvar = dom.GetObject(s_SysVarNameFlaeche1);
o_sysvar.State(s_SonnenwinkelFlaeche1);
string s_SysVarNameFlaeche2 = "} $DachFlaeche(2,SysVarName) {";
string s_SonnenwinkelFlaeche2 = "} $SonnenwinkelFlaeche2 {";
o_sysvar = dom.GetObject(s_SysVarNameFlaeche2);
o_sysvar.State(s_SonnenwinkelFlaeche2);
}]
}
Für die Ausführung benötigt man einen CuxD-Timer mit folgenden Einstellungen: Das vollständige Kommando unter CMD_EXEC, welches bei mir minütlich ausgeführt wird, lautet:
Code: Alles auswählen
wget -O - 'homematic-ccu2/addons/suninfo.cgi'
Für dieses Beispiel liegt die Datei suninfo.cgi unter: "/usr/local/etc/config/addons/www/"
Außerdem benötigt man in diesem Beispiel folgende Systemvariablen: Die beiden Namen für die Dachflächen müssen denen im Script entsprechen.
Nun braucht man nur noch kontrollieren, ob Längen- und Breitengrad in den Einstellungen der WEBUI stimmen.
Viel Spaß damit und Gruß
Thomas