Beschattung mit sonnengeführten elektrischen Rollläden

image_pdfimage_print

 

Schön langsam entwickeln sich die Temperaturen auch in Deutschland in Richtung Sommer. Da sich aufgrund von Corona immer noch viele die meiste Zeit zu Hause aufhalten, mag der Wunsch entstehen, seine elektrischen Rollläden zur Beschattung der Wohnung zu verwenden. Die einfachste Möglichkeit ist, alle Rollos auf 80% schließen und den ganzen Tag im Dunkeln sitzen. Da das aber nicht wirklich schön ist, wäre eine Beschattung mit sonnengeführten elektrischen Rollläden wesentlich cooler. Wie das geht, zeige ich hier.

Als erstes braucht man natürlich neben den elektrischen Rollläden, eine bereits funktionierende Haussteuerung. Ich verwende bereits seit vielen Jahren FHEM dafür.

Beschattung

Die Idee ist, sich mit einem notify-device an ein Twilight-modul zu hängen, um damit alle paar Minuten den aktuellen Sonnenstand zu bekommen. Im notify-device wird dann ein Makro aufgerufen, das die neue Position jedes Rollladens anhand des aktuellen Sonnenstandes berechnet und diesen auf die neue Position fährt. Im Ergebnis bewegen sich alle paar Minuten alle Rollläden um einige Millimeter, sodass sie genau richtig abschatten — nicht zu viel (-> nicht zu dunkel) und nicht zu wenig (-> zu viel Sonneneinstrahlung).

Sonnengeführt

Zur Berechnung verwenden wir zwei Vektoren im Raum:

  • Der Sonneneinfallsvektor bestehend aus Azimuth und Elevation (Himmelsrichtung und Höhe der Sonne)
  • Der Rollo-Bewegungsvektor, der den Fahrweg des Rollos beschreibt

Anschließend berechnen wir den Winkel der beiden Vektoren, der dem Winkel der Sonne zur Fensterfläche entspricht. Durch einfache Winkelberechnungen können wir nun die Rolloposition bestimmen, die für eine optimale Abschattung sorgt.

elektrische Rollläden

Für jeden Rollladen sollten eine Reihe von Werten berücksichtigt werden, die Einfluß auf die Beschattung haben:

  • Breite und Höhe des Fensters
  • Tiefe der Fensterlaibung (bzw. wie weit die Sonne “rein” scheinen darf)
  • Dachwinkel (90 ° bei senkrechten Fenstern)
  • Höhe der Auf-/Vorbauten (z.b. außen liegender Rollokasten, oder ein Mauervorsprung
  • Fensterausrichtung (Himmelsrichtung)
  • Min-/Max Azimuth und Min-/Max Elevation für die Beschattung
  • Min-/Max schattenrelevante Position

Umsetzung

Die Logik des Makros läßt sich sicherlich in fast jeder Haussteuerung umsetzen, aber ich beschreibe hier wie es mit FHEM geht.

Als erstes das Twilight-Modul. Gemäß der Dokumentation, hier die allgemeine Definition:

 

define <name> Twilight <latitude> <longitude> [<indoor_horizon> [<Weather_Position>]]

Die Parameter dürften selbstredend sein, latitude und longitude ist die eigene geographische Position, der indoor_horizon beschreibt, bei wieviel Grad Sonnenstand das Event indoor Sunset ausgelöst werden soll. Für die Beschattung brauchen wir ihn nicht. Eine fertige Definition wäre somit:

define MyTwilight 49.123456 8.123456 -3

Das notify-device (Dokumentation) ist einfach definiert:

MyTwilight:azimuth:.* {
}

Somit wird es immer dann ausgelöst, wenn das Twilight-Device die Eigenschaft azimuth aktualisiert. Dies geschieht alle paar Minuten. Innerhalb der geschweiften Klammern kommt das eigentliche Steuerungsmakro zur sonnengeführten Beschattung mit elektrischen Rollläden:

MyTwilight:azimuth:.* {
	######### Rolladensteuerung
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	my $Elev = ReadingsVal('MyTwilight', 'elevation', '0');
	my $Azim = ReadingsVal('MyTwilight', 'azimuth', '0');
	Log 1, "Elev: $Elev";
	Log 1, "Azim: $Azim";
	# finales hochfahren, nach Sonnenuntergang, Deaktivierung (Aktivierung erfolgt ausserhalb kurz vor Sonnenaufgang)
	if ($Elev < 22 && $Azim > 180) {
		fhem("set BU_RolloS up");
		fhem("set BU_RolloN up");
		fhem("set KU_Rollo up");
		fhem("set WC_Rollo up");
		if ($Elev < 15) {
			fhem("set GZ_RolloW up");
			fhem("set notRolloSteuerung inactive");
			fhem("set Rollos up");
		}
	}
	# Fensterdefinitionen (DevName, Breite, Höhe, Tiefe, Dachwinkel, Aufbauhöhe, Fensterausrichtung, Aktiv)
		# 0, DeviceName des Rollos
		# 1, 2: Breit, Höhe (cm) = sichtbare Breite, Höhe des Fensters (Glas innerhalb des Rahmens)
		# 3: Tiefe (cm) = Wie weit darf die Sonne "ins Fenster" scheinen (vom Fensteraussenscheibe messen!)
		# 4: Dachwinkel (Grad) = native Neigung der Fensterscheibe (=Dach), bzw. 90° bei "normalen" Wandfenstern
		# 5: Aufbauhöhe (cm) = Wieviel cm tragen Rollläden, Wandvorsprünge, etc. zur Fensterscheibe auf?
		# 6: Fensterausrichtung (Grad) = In welche Himmelsrichtung "schaut" das Fenster? -> Senkrechte auf die Scheibe, Nord = 0°, Süd = 180°
		# 7: Min Azim. (Grad) = ab welchem Azimut wird beschattet?
		# 8: Max Azim. (Grad) = bis welchem Azimut wird beschattet?
		# 9: Min Elev. (Grad) = ab welcher Elevation wird beschattet?
		# 10: Max Elev. (Grad) = bis welcher Elevation wird beschattet?
		# 11: Min Schatten (%) = minimale schattenrelevante Rollo-Position (z.B. 12%)
		# 12: Max Schatten (%) = maximale schattenrelevante Rollo-Position (z.B. 98%)
		# 13: Aktiv = 0 -> Deaktiviert, 1 -> Aktiv
	my @BU_S = ("BU_RolloS", 77, 98, 15, 43, 0, 276, 90, 360, 29, 90, 16, 100, 1);
	my @BU_N = ("BU_RolloN", 77, 98, 15, 43, 0, 276, 90, 360, 22, 90, 16, 100, 1);
	my @KU = ("KU_Rollo", 77, 100, 15, 43, 0, 276, 90, 360, 21, 90, 16, 100, 1);
	my @WC = ("WC_Rollo", 60, 90, 15, 43, 0, 276, 90, 360, 20, 90, 16, 100, 1);
	my @SZ = ("SZ_Rollo", 300, 200, 35, 90, 15, 96, 0, 186, -10, 90, 14, 100, 1);
	my @WZ = ("WZ_Rollo", 300, 200, 35, 90, 15, 96, 0, 186, 0, 90, 14, 100, 1);
	my @GA = ("GA_Rollo", 105, 130, 15, 43, 0, 96, 0, 270, -10, 90, 13, 100, 1);
	my @GZ_O = ("GZ_RolloO", 105, 130, 15, 43, 0, 96, 0, 270, 0, 90, 13, 100, 1);
	my @GZ_W = ("GZ_RolloW", 125, 130, 15, 43, 0, 276, 90, 360, 15, 90, 14, 100, 1);
	my @ArrFenster = (@BU_S, @BU_N, @KU, @WC, @SZ, @WZ, @GA, @GZ_O, @GZ_W);
	# Array-Zugriffskonstanten
	my $C_DEVNAME = 0;
	my $C_BREITE = 1;
	my $C_HOEHE = 2;
	my $C_TIEFE = 3;
	my $C_DACHWINKEL = 4;
	my $C_AUFBAU = 5;
	my $C_F_AUSRICHTUNG = 6;
	my $C_MINAZIM = 7;
	my $C_MAXAZIM = 8;
	my $C_MINELEV = 9;
	my $C_MAXELEV = 10;
	my $C_MINPOS = 11;
	my $C_MAXPOS = 12;
	my $C_AKTIV = 13;
	# allgemeine Variablen/Konstanten
	my $pi = 3.1415926535897932;
	my @V_Rollo = (0, 0, 0);	# Vektor Rollo
	my @V_Sonne = (0, 0, 0);	# Vektor Sonne
	my $Aufbauwinkel = 0;
	my $Gesamtneigung = 0;
	my $Theta = 0;
	my $Phi = 0;
	my $Winkel = 0;
	my $RolloPos = 0;
	# rad = grad * pi / 180; 		grad = rad * 180 / pi
	# Sonnenvektor berechnen
	$Theta = (90 + $Elev) * ($pi / 180);
	$Phi = $Azim * ($pi / 180);
	$V_Sonne[0] = sin($Theta) * sin($Phi);
	$V_Sonne[1] = cos($Theta);
	$V_Sonne[2] = sin($Theta) * cos($Phi);
	foreach (@ArrFenster) {
		my @Fenster = @$_;
		# Gesamtneigung berechnen
		$Aufbauwinkel = atan($Fenster[$C_AUFBAU] / $Fenster[$C_HOEHE]) * (180 / $pi);
		$Gesamtneigung = $Fenster[$C_DACHWINKEL] + $Aufbauwinkel;
		# Rollo-Vektor berechnen
		$Theta = (90 + $Gesamtneigung) * ($pi / 180);
		$Phi = $Fenster[$C_F_AUSRICHTUNG] * ($pi / 180);
		$V_Rollo[0] = sin($Theta) * sin($Phi) * -1;
		$V_Rollo[1] = cos($Theta);
		$V_Rollo[2] = sin($Theta) * cos($Phi) * -1;
		# Sonnenwinkel auf Fensterfläche berechnen (=Winkel der beiden Vektoren)
		$Winkel = acos(($V_Rollo[0] * $V_Sonne[0] + $V_Rollo[1] * $V_Sonne[1] + $V_Rollo[2] * $V_Sonne[2]) /
				  (sqrt($V_Rollo[0] ** 2 + $V_Rollo[1] ** 2 + $V_Rollo[2] ** 2) * 
				  sqrt($V_Sonne[0] ** 2 + $V_Sonne[1] ** 2 + $V_Sonne[2] ** 2)));
		# Rollo-Position bestimmen
		if ($Fenster[$C_MINAZIM] < $Azim && $Azim < $Fenster[$C_MAXAZIM] && 
			$Fenster[$C_MINELEV] < $Elev && $Elev < $Fenster[$C_MAXELEV]) {
			$RolloPos = ((($Fenster[$C_TIEFE] + $Fenster[$C_AUFBAU]) / tan($Winkel)) / $Fenster[$C_HOEHE]) * 100;
		} else {
			$RolloPos = 100;
		}
		if ($RolloPos < 0) {$RolloPos = 0};
		if ($RolloPos > 100) {$RolloPos = 100};
		# Rollo-Pos auf schattenrelevanten Bereich skalieren
		$RolloPos = ($Fenster[$C_MAXPOS] - $Fenster[$C_MINPOS]) * ($RolloPos / 100) + $Fenster[$C_MINPOS];
		# Rollo auf Position fahren
		if ($Fenster[$C_AKTIV] == 1) {
			fhem("sleep 1; set ".$Fenster[$C_DEVNAME]." pct ".sprintf("%.0f", $RolloPos));
			Log 1, "Rollo ".$Fenster[$C_DEVNAME]." auf ".sprintf("%.0f", $RolloPos);
			#Log 1, "Rollo ".$Fenster[$C_DEVNAME].": Winkel ".($Winkel * 180 / $pi)." Theta ".($Theta*(180/$pi))." Phi ".($Phi*(180/$pi));
			#Log 1, "Rollo ".$Fenster[$C_DEVNAME].": V_Sonne ".$V_Sonne[0]."; ".$V_Sonne[1]."; ".$V_Sonne[2];
			#Log 1, "Rollo ".$Fenster[$C_DEVNAME].": V_Rollo ".$V_Rollo[0]."; ".$V_Rollo[1]."; ".$V_Rollo[2];
			#Log 1, "Rollo ".$Fenster[$C_DEVNAME].": Tiefe ".$Fenster[$C_TIEFE]." Höhe ".$Fenster[$C_HOEHE];
		}
	}
}

[print-me]

Schreibe einen Kommentar