Update 10.08.2015:
– Änderungen im Programm roll_nacht_anders, roll_schatten_pgm, roll_nacht_pgm
– Systemvariable roll_zeit_hh_mm hinzugefügt
– Alternative kompaktere Rolladen-Programme , Methode 2 in Schritt 9
Update 25.10.2015:
– Umschaltung manuell/auto-Betrieb in allen Programmen geändert
– Änderungen in roll_schatten_pgm
Diskussionen zu diesem Thema im Homematic-Forum: https://homematic-forum.de/forum/viewforum.php?f=31
Einleitung
Die Theorie mit der Homematic ist toll: Man kaufe sich eine CCU, einige Sensoren und Aktoren schon kann man (oder Frau) die lästige Bedienung der Rolladen, Jalousien und Markisen einfach automatisieren. Hab ich auch so gedacht, aber nach kurzer Zeit stellte sich Enttäuschung ein. Es war doch nicht so einfach mit der Programmierung! Zwar waren einfache zeitgesteuerte Betätigungen schnell realisiert und sogar eine Astro-Funktion mit Sonnenauf- und untergang war schnell implementiert, aber bald erkennt man, daß mit diesen „Bordmitteln“ keine überzeugende Steuerung der Rolladen, Jalousien und Markisen möglich ist. Auch eine Hilfestellung seitens des Herstellers mit entsprechenden Beispielen ist zu diesem wichtigen Thema nicht vorhanden.
So entstanden über die Jahre eigene mehr oder weniger komplexe Lösungen, welche die Geduld der Hausbewohner mit anhaltenden Fehlbedienungen der Rolladen doch arg strapazierten!
Mittlerweile ist alles gut und mit viel Aufwand ist eine (für mich!) überzeugende Lösung einer Rolladensteuerung entstanden, die fast ohne eigenes Zutun die Bedürfnisse der Hausbewohner an Licht und Schatten gut abbildet.
Mit diesem Tutorial möchte ich die Struktur meiner aktuellen automatischen Steuerung erläutern, um Interessierten einen einfachen Nachbau zu erlauben.
Das Konzept
Wichtig sind anfangs die Überlegungen, was mit der Steuerung der Rolladen, Jalousien und Markisen eigentlich erreicht werden soll:
Ist es nur eine „Nachtfunktion“, bei der abends die Rolladen runter und morgens wieder hoch gehen soll ?
… oder möchte man im Sommer mit den Rolladen auch eine Beschattung realisieren ?
… oder möchte man bei Regenwetter die Rolladen gezielt runterfahren, um eine Verschmutzung der Fenster zu vermeiden?
… oder möchte man bei Einbruchalarm alle Rolladen runterfahren ?
… oder möchte man beim Fernsehen und starker Sonnenstrahlung automatisch die wichtigen Rolladen nicht ganz runter fahren aber doch zumindest in eine Beschattungsposition fahren ?
oder, oder, oder …
Man merkt schnell, daß eine Rolladensteuerung nicht trivial ist, sondern wenn sie gut gemacht ist, eine recht komplexe Angelegenheit sein kann!
Das hier erläuterte Konzept ist schematisch im nächsten Bild dargestellt.
Die verwendeten Begriffe sind gleichzeitig die Bezeichnung der Sensoren, Systemvariablen und Programme. Links im Bild ist die verwendete Sensorik. Dabei gibt es einige unverzichtbare Sensoren und andere optionale Sensoren, die mit einem Stern gekennzeichnet sind.
Kernstück der Steuerung ist der sog. Sonnensensor, der die Sonnenstrahlung mit einem kleinen thermischen Sonnenkollektor erkennt. Die häufig verwendeten Helligkeitssensoren sind für diese Aufgabe viel weniger geeignet, weil die Sonneneinstrahlung einen sehr großen Signalbereich hat , der mit den herkömmlichen Photowiderständen kaum meßbar ist. Zudem benötigt man eine „Tiefpassfunktion“ damit das Signal zeitlich geglättet wird und nicht bei jeder Wolke ein- und ausgeschaltet wird. Wie man einen solchen thermischen Sonnensensor baut ist hier beschrieben: https://www.stall.biz/project/sonnensensor-fur-jalousien-und-rolladensteuerung oder als einfachere Lösung: https://www.stall.biz/project/robuster-sonnensensor-ganz-einfach
Von dem Temperatursignal temp_sonne kann man mit der Aussentemperatur temp_aussen eine Differenztemperatur temp_sonne_diff ableiten, die ein Maß für die Sonneneinstrahlung ist. Als Temperaturfühler kann man auch einen sog. Differenztemperaturfühler verwenden und muß dann nicht mehr die Meßgröße temp_sonne_diff berechnen, sondern der Sensor liefert die Differenzgröße gleich mit. Allerdings muß man dann den zweiten Temperaturfühler so platzieren, daß er auch die Aussentemperatur (Nordseite!) unverfälscht messen kann.
Weitere für die Rolladensteuerung sinnvolle verwendbare Sensorik sind eine optionale Wetterstation für Windgeschwindigkeit W-Windgeschwindigkeit und W_Windrichtung für Windrichtung. Falls man in der Nähe einer Wunderground-Wetterstation wohnt, kann man diese Sensorsignale kostengünstig auch übers Internet mit meinem Skript wunderground_pgm holen. https://www.stall.biz/project/wunderground-wetter-mit-einfachem-hm-skript-holen
Ein optionaler Regenmelder ist hilfreich, wenn beispielsweise Markisen und Dachfenster gesteuert werden sollen. Und natürlich müssen einige Fensterkontakte bei Rolladen an Fenstertüren vorhanden sein, um zu verhindern, daß die Rolladen runter gehen, wenn man gerade draussen ist.
Damit man die Steuerung ein- und ausschalten kann, sind sog. virtuelle Taster oder auch Fernbedienungen sinnvoll. In der hier vorgestellten Grundausbaustufe sind zwei virtuelle vorhanden. Der eine (roll_auto_manuell) schaltet den Automatikmodus ein und aus. Der andere (roll_alle_hochrunter) erlaubt alle Rolladen gleichzeitig hoch- und runterzufahren. Das kann auch als Paniktaster o.ä. verwendet werden. Darüber hinaus hat natürlich jeder Rolladenaktor eigene Funktionstaster, mit denen manuell jede Rollade bedient werden kann.
Die Programme
Im Folgenden werden kochrezeptartig alle verwendeten WebUI-Programme und Skripte beschrieben. Das ist dann der Grundstein für eigene Anpassungswünsche, die sicher individuell und reichlich bereits nach kurzer Nutzungszeit entstehen.
Schritt 1: Aktoren und Sensoren installieren und benamen
Ideal ist die Benamung der verwendeten Sensoren nach dem Schemabild oben, ansonsten müssen entsprechende Anpasssungen in den einzelnen Programmen gemacht werden. Der Sonnensensor muß ebenfalls vorhanden sein. Dann noch mindestens zwei virtuelle Taster neu benamen:
– roll_auto_manuell (ich habe dafür den „ccu-wired-taster 19 verwendet)
– roll_alle_hochrunter (ich habe dafür den „ccu-wired-taster 18 verwendet)
Schritt 2: Systemvariablen anlegen
Folgende Systemvariable müssen angelegt werden: (bitte Schreibweise genaustens einhalten !!)
– temp_sonne_diff Typ:Zahl Werte: -80 bis 80 Maßeinheit: °C
– sonne_elevation Typ:Zahl Werte: -180 bis 180 Maßeinheit: grad
– sonne_azimut Typ: Zahl Werte: 0 bis 360 Maßeinheit: grad
– roll_schatten Typ: Logikwert
– roll_nacht Typ: Logikwert
– roll_AutoManuell Typ: Logikwert
– roll_zeit_hh_mm Typ: Zahl Werte 0,00 bis 23,59 Maßeinheit Stunden, Minuten (nur für Programm roll_nacht_anders)
Schritt 3: Programm sonnensensor_pgm installieren
Wenn zwei unabhängige Temperatursensoren für die Temperatur im Sonnensensor und für die Aussentemperatur verwendet werden, dann ist ein kleines Skript notwendig zur Berechnung der Differenztemperatur. Dazu wird erst ein WebUI-Programnm angelegt, mit dem das Skript aufgerufen wird.
Das implementierte Skript verwendet die Seriennummern meiner verwendeten Temperatursensoren. Diese Nummern sind vom Anwender auf seine individuellen Seriennummern zu ändern!
[codesyntax lang=“text“ title=“HM-Skript“]
!Berechnet Differenztemperatur Sonnensensor real Aussen_Temperatur = dom.GetObject("BidCos-RF.HEQ0237327:1.TEMPERATURE").Value(); real Sonnen_Temperatur = dom.GetObject("BidCos-RF.IEQ0405570:1.TEMPERATURE").Value(); real deltat = Sonnen_Temperatur - Aussen_Temperatur; dom.GetObject("temp_sonne_diff").State(deltat);
[/codesyntax]
Einzelheiten zum verwendeten Sonnensensor nochmal hier: https://www.stall.biz/project/sonnensensor-fur-jalousien-und-rolladensteuerung
und hier: https://www.stall.biz/project/robuster-sonnensensor-ganz-einfach
Schritt 4: Programm sonnenstand_pgm installieren
Das Programm für die Berechnung der Sonnenposition am Himmel ist ein besonders wichtiger Teil der Rolladensteuerung. Informationen hierzu in der genauen Funktionsbeschreibung dieses HM-Skriptes findet man hier: https://www.stall.biz/project/sonnenstandsberechnung-2-0-fur-rolladen-markisen-lampen
Mit dem Skript werden die Systemvariable sonne_elevation und sonne_azimut berechnet. Die Elevation ist der Positionswinkel der Sonne gegenüber dem Horizont. Er variiert in unseren Breiten so zwischen 40° im Sommer mittags und fällt nachts (auch wenn man die Sonne nicht sieht !) auf etwa -40°. Die Sonne geht unter bei einem Elevationswinkel von 0°.
Der Azimut ist der Positionswinkel in der Horizontalen. Ost sind 90°, Süd sind 180° und dementsprechend ist West 270°.
Die Verwendung dieser Einflußgrößen läßt sich am folgenden Schemabild erklären:
Mit dem Azimutwinkel kann man festlegen, in welchem Winkelbereich der Sonnenposition in der Horizontalen eine Besonnung des jeweiligen Fensters möglich ist. Bei dem hier verwendeten Beispiel eines nach Süden ausgerichteten Fensters ist eine Besonnung nur möglich bei einem Azimutwinkel von 110° bis 230°. Man kann diesen Winkel theoretisch aus der Bauzeichnung ermitteln oder einfach über den Tag das Fenster beobachten, bei welchem Winkelbereich eine Besonnung entsteht bzw. eine Beschattung notwendig ist.
Die Bestimmung des Elevationswinkelbereiches erfolgt analog. Hier sind Dachüberhänge oder Abschattungen durch vorliegende Häuser, Hecken und Mauern zu berücksichtigen. Wenn keine Hindernisse vorhanden sind, wird der Elevationswinkel für das Beschattungsprogramm gar nicht benötigt.
Und so geht die Installation:
Erst das folgende WebUI-Programm installieren:
Und hier das Skript dazu, das ganztägig alle 5 Minuten aufgerufen wird:
[codesyntax lang=“text“ title=“HM-Skript Sonnenstandsberechnung“]
!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);
[/codesyntax]
Schritt 5: Programm wunderground_pgm installieren
Wetterinformationen zu Wind und Regen sind für die Betätigung von Rolladen, Jalousien und Markisen schon wichtig. Wenn man für die Beschaffung der entsprechenden Sensorsignale eine Wetterstation hat ist das schön, man kann aber auch preiswert die Wetterdaten einer möglichst nah gelegenen Wetterstation aus dem Internet holen. Dazu ist mein HM-Skript sehr gut geeignet:
https://www.stall.biz/project/wunderground-wetter-mit-einfachem-hm-skript-holen
Die Installationsschritte für das Wunderground-Skript sind hier auch nochmal in Kürze:
Dieses WebUI-Programm ruft periodisch ganztägig alle 30min das folgende Skript auf:
[codesyntax lang=“text“ title=“HM-Skript Wunderground Wetter“]
!Stand 03.04.2014 http://homematic-forum.de/forum/viewtopic.php?f=31&t=17209 !zuerst folgende Systemvariablen anlegen !Achtung: keine vergessen und exakte Schreibweise mit Drag&Drop !W_Station Zeichenkette !W_Aktualisierung Zeichenkette !W_Bedingungen Zeichenkette !W_Temperatur Zahl °C !W_Luftfeuchte Zahl % !W_Windbedingungen Zeichenkette !W_Windrichtung Zeichenkette !W_Windrichtg Zahl ° !W_Windgeschwindigkeit Zahl km/h !W_Windboeen Zahl km/h !W_Luftdruck Zahl mb !W_Luftdrucktrend Zeichenkette !W_Taupunkt Zahl °C !W_UV Zeichenkette var url = "http://api.wunderground.com/api/xxxxxxxxxxxxx/conditions/lang:DL/q/Germany/Neuwied.xml"; !hier ist die Abfrage mit CUxD dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("wget -q -O - '"#url#"'"); dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1); string wetter_xml = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State(); !hier ist die Abfrage mit system.Exec !string stdout; !string stderr; !system.Exec("wget -q -O - '"#url#"'", &stdout, &stderr); !WriteLine(stdout); !string wetter_xml = stdout; !WriteLine(wetter_xml); !Beim XML-File den ueberfluessigen Header entfernen integer laenge = wetter_xml.Length(); integer wort_position = wetter_xml.Find("display_location"); wetter_xml = wetter_xml.Substr(wort_position, (laenge - wort_position)); !WriteLine(wetter_xml); !Daten mit Suchworten aus XML-File ausfiltern: !string word = "full"; string word = "city"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); dom.GetObject("W_Station").State(daten); !string word = "observation_time"; string word = "observation_time_rfc822"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); !daten = daten.Substr(0, (word_position -2)); daten = daten.Substr(0, (word_position -11)); dom.GetObject("W_Aktualisierung").State(daten); string word = "weather"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); dom.GetObject("W_Bedingungen").State(daten); string word = "temp_c"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); real zahl = daten.ToFloat(); dom.GetObject("W_Temperatur").State(zahl); string word = "relative_humidity"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); integer zahl = daten.ToFloat(); dom.GetObject("W_Luftfeuchte").State(zahl); string word = "wind_string"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); dom.GetObject("W_Windbedingungen").State(daten); string word = "wind_dir"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); word_laenge =daten.Length(); string anfangsbuchstabe = daten.Substr(0,1); ! Umlaute korrigieren ! ! N # Nord *** if (anfangsbuchstabe == "N") { ! if (daten == "Nordwest") {daten = "Nord-West" ;} } ! S # Süd *** if (anfangsbuchstabe == "S") { ! 4 # Süd if (word_laenge == 4) {daten = "Süd";} ! 8 # Südwest if (word_laenge == 8) {daten = "Süd-West";} ! 12 # Süd-Südost if (word_laenge == 12) {daten = "Süd-Süd-Ost" ;} ! 13 if (word_laenge == 13) {daten = "Süd-Süd-West" ;} } ! W # Westen if (anfangsbuchstabe == "W") { ! 13 # West-Südwest if (word_laenge == 13) {daten = "West-Süd-West" ;} } ! O # Osten if (anfangsbuchstabe == "O") { ! 11 # Ost-Südost if (word_laenge == 11) {daten = "Ost-Süd-Ost" ;} } dom.GetObject("W_Windrichtung").State(daten); !WriteLine(daten); string word = "wind_degrees"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); integer zahl = daten.ToFloat(); dom.GetObject("W_Windrichtg").State(zahl); string word = "wind_kph"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); integer zahl = daten.ToFloat(); dom.GetObject("W_Windgeschwindigkeit").State(zahl); string word = "wind_gust_kph"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); integer zahl = daten.ToFloat(); dom.GetObject("W_Windboeen").State(zahl); string word = "pressure_mb"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); integer zahl = daten.ToFloat(); dom.GetObject("W_Luftdruck").State(zahl); string word = "pressure_trend"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); dom.GetObject("W_Luftdrucktrend").State(daten); string word = "dewpoint_c"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); real zahl = daten.ToFloat(); dom.GetObject("W_Taupunkt").State(zahl); string word = "UV"; integer word_laenge = word.Length(); integer word_position = wetter_xml.Find(word); string daten = wetter_xml.Substr((word_position + word_laenge +1), 100); integer word_position = daten.Find(word); daten = daten.Substr(0, (word_position -2)); real zahl = daten.ToFloat(); dom.GetObject("W_UV").State(zahl);
[/codesyntax]
… und aktualiert dementsprechend alle 30 Minuten die evtl. verwendeten Systemvariablen W_Windgeschwindigkeit und W_Windrichtg .
Schritt 6: Programm roll_schatten_pgm installieren
Für die Berechnung der logischen Systemvariablen roll_schatten , die den „Schattenbedarf“ signalisiert, ist das folgende WebUI-Programme zu installieren:
Dabei kann man mit der Veränderung der Werte für temp_sonne_diff festlegen, wie sensibel die Beschattung auf Sonneneinstrahlung reagieren soll. Bei großen Temperaturwerten reagiert die Beschattung nur auf starke Sonneneinstrahlung, bei kleinen Werten dementsprechend feinfühliger. Wichtig ist die zeitliche Hysterese (hier 20min) im Programm roll_schatten_pgm, damit bei wolkigem Aprilwetter die Rolladen nicht alle 5 Minuten hoch- und runterfahren.
Schritt 7: Programm roll_nacht_pgm installieren
Die Systemvariable roll_nacht wird mit dem folgenden WebUI-Programm berechnet. Diese logische Systemvariable signalisiert, ob die Rolladen zur Nacht herunter gefahren werden sollen:
Mit der Zeitsteuerung von 19h00 bis zum maximal spätesten Sonnenuntergang 22h30 und dem Elevationswinkel kleiner als 3° wird die Systemvariable (roll_nacht =wahr) aktiviert. Morgens ist die Nacht zu Ende (roll_nacht = falsch) wenn Der Elevationswinkel -2° überschreitet, aber nicht vor 6h45.
Diese Werte müssen individell angepasst werden, je nach Lebenswandel !
Schritt 7a: Programm roll_nacht_anders installieren
Alternativ zum Programm roll_nacht_pgm kann man zur Berechnung der Systemvariablen roll_nacht auch ein anderes Programm roll_nacht_anders installieren. Hier wird die Nacht im Winter anders als im Sommer berechnet. Dadurch wird u.a. berücksichtigt, daß die Dämmerungsphase im Winter länger dauert als im Sommer. Mehr zu dieser etwas anderen „Philosophie“ hier: https://www.stall.biz/project/jede-nacht-ist-anders-dynamische-rolladenbetatigung .Mir persönlich gefällt diese Betätigungsstrategie besser, aber das ist Geschmackssache.
Zuerst richtet man ein WebUI-Programm ein, das alle 5 Minuten (periodisch, ganztägig) von 16h bis 23h55 ein Skript aufruft:
Das zugehörige HM-Skript ist sehr einfach:
[codesyntax lang=“text“ title=“HM Skript „]
!setzt abends Systemvariable "roll_nacht" auf "wahr" !www.stall.biz 10.08.2015 !Berechnung Sonnenuntergangszeit. Zeitberechnung immer im Minutenschema, integer SU = system.SunsetTime("%M").ToInteger() + 60* system.SunsetTime("%H").ToInteger(); !Berechnung aktuelle Zeit integer zeit = system.Date("%M").ToInteger() + 60*system.Date("%H").ToInteger(); !Rolladen-Schliesszeit ROLL berechnet sich aus der aktuellen Sonnenuntergangszeit SU real ROLL = 595.0 + 0.58* SU; !frühere Alternative: real ROLL = 433.0 + 0.68* SU; if (zeit > ROLL) {dom.GetObject("roll_nacht").State(1);} !Umformen von der Minutendarstellung von ROLL in Stundendarstellung hh,mm !und abspeichern auf Systemvariable "roll_zeit_hh_mm" real su_zeit = 0.0166 *ROLL; real su_zeit_h = su_zeit.ToInteger(); real su_zeit_m = (su_zeit - su_zeit_h) *60.0; su_zeit_m =0.01 * su_zeit_m.ToInteger(); real su_zeit= su_zeit_m + su_zeit_h; dom.GetObject("roll_zeit_hh_mm").State(su_zeit);
[/codesyntax]
Morgens wird die Systemvariable roll_nacht im Sommer frühestens um 6h45 auf falsch gesetzt (von 6h45 bis 9h00) . Im Winter erfolgt das später, wenn die Elevation der Sonne größer als -2° ist.
Schritt 8: Programm roll_auto_pgm installieren
Die Rolladenautomatik kann man mit dem virtuellen Taster roll_auto_manuell ein und ausschalten. Das ist wichtig, wenn man eine atypische Lebenssituation hat und dann nicht den normalen Rolladenrhytmus haben möchte. Mit dem folgenden WebUI-Programm erfolgt die Umschaltung der logischen Systemvariablen roll_AutoManuell:
Bei Verwendung von Fernbedienungen ist es u. U. sinnvoll, daß die Fernbedienungen nicht direkt in die Rolladensteuerung eingreifen, sondern über die virtuellen Taster.
Schritt 9 (Methode 1): Programme für die verwendeten Rolladenaktoren installieren
Jetzt kommen wir zu den wichtigen WebUI-Programmen, die die einzelnen Rolladen, Jalousien oder Markisen steuern. Für jede Aktor-Einheit werden jeweils drei kleine WebUI-Programme angelegt.
Das erste WebUI-Programm, am Ende der Programmbezeichnung immer mit der Ziffer 0 gekennzeichnet, steuert die Rollade in die heruntergefahrene Position (hier im Beispiel 14%).
Das zweite Programm, am Ende der Programmbezeichnung immer mit der Ziffer 1 gekennzeichnet, steuert die Rollade in die Beschattungsposition(hier im Beispiel 20%).
Das dritte WebUI-Programm, am Ende der Programmbezeichnung immer mit der Ziffer 2 gekennzeichnet, steuert die Rollade in die hochgefahrene Position (100%).
Für jede Rollade muß man sich nun überlegen, welche Betätigungsstrategie diese Rollade haben soll. Zur Betätigung stehen entsprechend dem Schemabild oben eine ganze Reihe von Sensorsignalen oder Systemvariablen zur Verfügung, die nun für diese Rollade logisch verschaltet werden können. An folgenden Beispielen soll das Vorgehen erläutert werden:
1. Beispiel Westfenster
Zuerst wird am Beispiel eines einfach zu betätigendes Fensters rollade_kinder_west die grundsätzliche Funktion aufgezeigt. Hierbei handelt es sich um zwei nach Westen ausgerichtete Fenster, welche zur Nachtzeit und und zur Beschattung betätigt werden. Bei Regen und bei einer bestimmeten Windgeschwindigkeit und Windrichtung werden die Fenster automatisch in die Beschattungsfunktion (20% runtergefahren) gesetzt. Die weiteren Funktionen sind eigentlich selbst erklärend.
Bitte Fehler korrigieren: bei den folgenden 6 Bildern ist roll_AutoManuell nicht nur prüfen sondern auf bei Änderung auslösen einzustellen!!
Hier das erste Programm dazu, Damit werden die Rolladen zur Nacht runtergefahren :
Im folgenden zweiten Programm werden bei der Systemvariablen sonne_azimut die Grenzwerte einzeln abgefragt.
Und mit dem dritten Programm werden die Rolladen wieder hochgefahren:
2. Beispiel Ost-Fenstertür
Beim zweiten Beispiel handelt es sich um eine nach Osten ausgerichtete Fenstertür mit einem Fensterkontakt zur Öffnungserkennung. Ähnlich wie beim ersten Beispiel werden die Rolladen mit drei WebUI-Programmen ausgelöst:
In diesem Beispiel wird neben dem Fensterkontakt auch noch ein Signal von einem Geräuschmelder verwendet, um die Beschattung der Küchentür nur dann auszulösen, wenn die Hausbewohner nicht da sind (keine Geräusche!). So kann man ganz individuell jeden einzelnen Rolladen „verdrahten“ und seinen Wünschen anpassen. Ich verwende beispielsweise im Wohnzimmer ein logisches Signal, das wahr ist, wenn der Fernseher an ist. In diesem Fall gehen dann nur einige bestimmte Rolladen bei Sonnenwetter runter, um die Helligkeit für das Fernsehen zu reduzieren.
Die Sache mit dem Häkchen:
Der aufmerksame Leser hat sicher schon bemerkt, daß die normalerweise selbsttätig gesetzten Häkchen für den Retrigger deaktiviert wurden. Der Grund ist, daß beim Rolladenprogramm aus Gründen der „Funkhygiene“ alle Rolladen mit Zeitverzögerung betätigt werden. Und zudem werden alle Rolladen jeweils mit in diesem Fall drei unabhängigen Programmen betätigt. Da die einzelnen Programme aber nicht exakt gleichzeitig abgearbeitet werden, kann dies dazu führen, das manchmal einige schon mit Zeitverzögerung laufende Aktivitäten „verschluckt“ werden. Dies führt praktisch dazu, daß manchmal einige Rolladen „vergessen“ werden. Auf solche Effekte führe ich viele seltsame Fehler zurück, die in der Vergangenheit manchmal völlig unerklärlich auftraten. Also Vorsicht und Bedacht bei Verwendung des Häkchens, wenn an mehreren Stellen der gleiche Aktor betätigt wird!
Hier eine Diskussion des Problems: http://homematic-forum.de/forum/viewtopic.php?f=19&t=17864&p=146468&hilit=h%C3%A4kchen+retrigger#p146433
Schritt 9 (Methode 2) : Programme für die verwendeten Rolladenaktoren installieren
Insbesondere wenn man viele Rolladen hat ist eine kompaktere Gestaltung der Software sinnvoll, um eine übersichtlichere Darstellung zu bekommen. Bei dieser Methode werden für jede Rollade nur zwei WebUI-Programme erstellt. Meine persönliche Empfehlung ist die Methode 2 !
Das erste Programm ist für den Nachtbetrieb der Rollade sowohl für HOCH als auch RUNTER verantwortlich.
Das zweite Programm ist für die Beschattung verantwortlich, auch in diesem Fall für die Funktionen HOCH und RUNTER.
Will man noch eine Abdunkelung des Raumes bei TV-Betrieb, dann fügt man eine entsprechendes drittes Programm hinzu.
1. Beispiel Westfenster
Hier die beiden Programme rollade_kinder_nacht für den Nachtbetrieb und rollade_kinder_schatten für die Beschattung:
Den „Regen“-Teil des Programmes kann man weglassen, wenn kein Regenschutz der Rolladen gewünscht ist.
2. Beispiel Ost-Fenstertür
Die folgenden beiden Programme rollade_kueche_nacht und rollade_kueche_schatten steuern die Rolläden einer Fenstertür. Mit einem Fensterkontakt man sicher, daß man sich nicht draußen ausschließt.
3. Beispiel Südfenster
Der Vollständigkeit halber werden nachfolgend die Programme für ein Südfenster dargestellt:
Wichtig ist immer, daß man sich überlegt, wann und wie oft die Programme durchlaufen werden. Denn oft ist die Ursache dafür, daß die Rolladen unerwartet in der Nacht hochgehen nicht das zuerst vermutete Nachtprogramm sondern das Schatten-Programm, welches nachts wegen einer Variablen mit „bei Änderung auslösen“ unerwartet durchläuft und im SONST-Zweig dann die Rolladen hochfahren läßt. Die Auslöselogik bzw. die ereignisgesteuerte Funktion des WebUI ist manchmal nicht einfach zu verstehen, eigene Programmierfehler sind aber in fast allen Fällen die Ursache für ein „seltsames“ Verhalten der Rolladen!
Ausblick
Wichtig ist auch, daß bei Verwendung von Funk-Rolladenaktoren die verschiedenen Rolladen und Markisen nicht alle gleichzeitig hoch- oder runtergehen, wenn die die entsprechenden Systemvariablen roll_nacht oder roll_schatten umschalten. Dabei kann so ein reger Funkverkehr entstehen, daß die eine oder andere Rollade nicht richtig betätigt wird. Die Lösung ist für jede Rollade eine unterschiedliche Zeitverzögerung von etwa 1 bis 2sec. Dabei sollte man den Rolladen mit Fenster- oder Türkontakt die kürzeren Zeiten geben, weil bei Türöffnung eine möglichst schnelle Reaktion erfolgen sollte. Ach ja, die Fenster- und Türkontakte funktionieren auch zuverlässiger, wenn in den Geräte-Einstellungen eine Meldeverzögerung von 1 bis 2sec eingestellt wird.
Und hier noch ein paar Anregungen für eigene Erweiterungen:
– Integration in die Alarmanlage: z.B. Rollen alle hoch oder runter wenn Alarm
– Verbesserung des „Fernsehvergnügens“: Rolladen machen aktive Beschattungsscenarios, wenn TV an
– Besuchs- oder Partymodus: dann bleiben die Rolladen hoch!
– im Winter den Beschattungsmodus teilweise abschalten, damit die wenige Sonnenstrahlung nutzbringend ins Haus gelangt.
– Markisen nach Wind und Wetter betätigen
– Dachfenster automatisch öffnen und schließen
– Beleuchtung im und am Haus mit den verwendeten Rolladenscenarien steuern und koordinieren
– …
Wenn man erst mal das Grundkonzept mit den verschiedenen Sensorsignalen und Systemvariablen installiert hat, dann ist die kreative Gestaltung nach den verschiedensten Wünschen an die Rolladenautomation kein Problem mehr.
Viel Spaß für mehr Licht und Schatten im Haus!