|
From: <kru...@us...> - 2013-09-16 10:14:58
|
Revision: 1889
http://sourceforge.net/p/openautomation/code/1889
Author: krumboeck
Date: 2013-09-16 10:14:56 +0000 (Mon, 16 Sep 2013)
Log Message:
-----------
Updated RollladenAutomatik.pl
- Added templates
- Added various weather functions
- Added configuration file
- Added room temp funktion
Modified Paths:
--------------
wiregate/plugin/generic/RollladenAutomatik.pl
Added Paths:
-----------
wiregate/plugin/generic/conf.d/RollladenAutomatik.conf_sample
Modified: wiregate/plugin/generic/RollladenAutomatik.pl
===================================================================
--- wiregate/plugin/generic/RollladenAutomatik.pl 2013-09-14 05:12:14 UTC (rev 1888)
+++ wiregate/plugin/generic/RollladenAutomatik.pl 2013-09-16 10:14:56 UTC (rev 1889)
@@ -1,28 +1,34 @@
######################################################################################
-#
# Plugin RollladenAutomatik
-# V0.5 2011-06-10
-# Ben\xF6tigt: libastro-satpass-perl -> 'apt-get install libastro-satpass-perl'
+# V0.6 2013-09-15
+# Autoren: kleinklausi (http://knx-user-forum.de/members/kleinklausi.html)
+# krumboeck (http://knx-user-forum.de/members/krumboeck.html)
+# Benötigt: libastro-satpass-perl -> 'apt-get install libastro-satpass-perl'
#
-# Ein Wiregate Plugin zum automatischen Fahren der Rolll\xE4den. Es berechnet unter Anderem
-# den Stand der Sonne und f\xE4hrt je nach Winkel der Sonne zum Fenster, den Rollladen in
-# eine Beschattungsposition. Folgende Funktionen werden unterst\xFCtzt:
+# Ein Wiregate Plugin zum automatischen Fahren der Rollläden. Es berechnet unter Anderem
+# den Stand der Sonne und fährt je nach Winkel der Sonne zum Fenster, den Rollladen in
+# eine Beschattungsposition. Folgende Funktionen werden unterstützt:
# - Sonnenstand (Azimuth)
# - Anfangs- und Endwinkel (Azimuth) ab dem das Fenster beschienen wird
# - Globale Sperre duch eine Gruppenadresse
# - Sperre eines einzelnen Rollladens durch eine Gruppenadresse
# - Fahren des Rollladen zu (1) oder auf (0) oder Positionsfahren mit Prozentwert
# - Zufahren bei Dunkelheit am Abend und Hell am Morgen
-# - Bugfix f\xFCr Busch-J\xE4ger USB Schnittstelle (muss eingeschaltet werden)
+# - Bugfix für Busch-Jäger USB Schnittstelle (muss eingeschaltet werden)
+# - Vorlagen um die Konfiguration zu vereinfachen (krumboeck)
+# - Rolladenschutz vor hohen Windgeschwindigkeiten (krumboeck)
+# - Zufahren bei sehr niedgrigen Außentemperaturen um die Isolationswirkung zu erhöhen (krumboeck)
+# - Öffnen bei sehr starker Bewölkung um die Helligkeit im Raum zu erhöhen (krumboeck)
+# - Seperate Konfigurationsdatei (krumboeck)
+# - Steuerung aufgrund der Raumtemperatur (krumboeck)
+# - Hysteresewerte für Temperatur, Wind und Bewölkung (krumboeck)
+# - Speichern der Rolladenposition und aktuellen Zuständen (krumboeck)
#
# TODO: Was teilweise integriert ist aber noch nicht komplett ist:
-# - Nur zufahren, wenn es im Raum warm genug ist
-# - Wetterstation einbinden: Helligkeit, Sonnenschein, D\xE4mmerung
# - Bei Fensterdefinition auch Elevation oben bzw. unten angeben
-# - Jalousie Lamellenf\xFChrung
+# - Jalousie Lamellenführung
# - Vorwarnpositionsfahrten?
# - Englisch oder Deutsch?
-# - Au\xDFentemperaur
######################################################################################
@@ -30,149 +36,172 @@
### BEGINN DEFINITION ###
#########################
-# Die Koordinaten des Hauses. Sehr einfach \xFCber http://www.getlatlon.com/ zu ermitteln.
-# Und die H\xF6he \xFCber NN
-my ($lat, $lon, $elev) = (
- 49.02917390736781, # Breitengrad in Grad
- 8.570709228515625, # L\xE4ngengrad in Grad
- 180 / 1000 # H\xF6he \xFCber NN in Kilometer (dewegen geteilt durch 1000)
- );
+use constant HIGHER => 1;
+use constant EQUAL => 0;
+use constant LOWER => -1;
+# Die Koordinaten des Hauses. Sehr einfach über http://www.getlatlon.com/ zu ermitteln.
+# Und die Höhe über NN
+my ($lat, $lon, $elev);
+
# Elevation der Sonne, ab der es abends dunkel ist bzw. morgens hell ist.
-# B\xFCrgerliche D\xE4mmerung ist bei -6 Grad.
+# Bürgerliche Dämmerung ist bei -6 Grad.
my $daemmerung = -3;
-# Gruppenadresse, \xFCber welche die komplette Automatik f\xFCr alle Rolll\xE4den gesperrt werden kann
-my $GASperreAlle = "0/0/125";
+# Gruppenadresse, über welche die komplette Automatik für alle Rollläden gesperrt werden kann
+my $GASperreAlle;
-# Bugfix f\xFCr KNX-Schnittstellen die sich bei zu schneller Telegrammabfolge
-# verschlucken, und denen wir deshalb die Geschwindigkeit der Telegramme drosseln m\xFCssen
-# 0 = nicht anschalten (Telegramme mit voller Geschwindigkeit abfeuern)
-# 1 = anschalten (Telegramme um 20 millisekunden verz\xF6gern)
-# nur f\xFCr "Busch-J\xE4ger 6196 USB REG" ist bekannt das dies ben\xF6tigt wird
+# Bugfix für KNX-Schnittstellen die sich bei zu schneller Telegrammabfolge
+# verschlucken, und denen wir deshalb die Geschwindigkeit der Telegramme drosseln müssen
my $bugfixSlowInterface = 0;
# Ein Array von Hashes, wobei jeder Hash ein Rollladen/Fenster/Raum ist.
my @AlleRolllaeden;
-# Name des Rolladen
-# name => "Speisekammer"
-# Winkel zum Norden, ab dem das Fenster beschienen wird.
-# Echter Osten = 90\xB0, echter S\xFCden = 180\xB0, echter Westen = 270\xB0, echter Norden = 0\xB0
-# winkel1 => 66
-# Winkel zum Norden, bis zu dem das Fenster beschienen wird
-# winkel2 => 186
-# Richtung bei Beschattung: wenn 1 wird DPT3 angenommen und ganz zugefahren.
-# Bei ungleich 1, wird DPT5 angenommen und Position angefahren
-# wertZuBesch => 1
-# Richtung bei keiner Beschattung: wenn 0 wird DPT3 angenommen und ganz aufgefahren.
-# Bei ungleich 0, wird DPT5 angenommen und Position angefahren
-# wertAufBesch => 0
-# Richtung bei Nacht: wenn 1 wird DPT3 angenommen und ganz zugefahren.
-# Bei ungleich 1, wird DPT5 angenommen und Position angefahren
-# wertZuNacht => 1
-# Richtung bei keiner Nacht: wenn 0 wird DPT3 angenommen und ganz aufgefahren.
-# Bei ungleich 0, wird DPT5 angenommen und Position angefahren
-# wertAufNacht => 0
-# Ob der Rollladen in die Automatik f\xFCr Sonnenauf- und untergang einbezogen werden soll
-# sonnenAufUnter => 1
-# Raum-Solltemperatur, wenn keine GA angegeben wurde oder kein Wert vom Bus gelesen wurde
-# raumSollTemp => 22
-# GA der Raum-Solltemperatur
-# GAraumsollTemp => "0/0/127"
-# GA der Raum-Isttemperatur
-# GAraumIstTemp => "0/0/128"
-# GA um Rollladen zu fahren TODO:Sollte man hier mehrere GAs angeben k\xF6nnen?
-# GAfahren => "0/0/126"
-# GA um die Automatik dieses einen Rollladen zu sperren
-# GAsperre=> "0/0/129"
-push @AlleRolllaeden, { name => "Speisekammer", winkel1 => 66, winkel2 => 186, wertZuBesch => 1, wertAufBesch => 0,
- wertZuNacht => 1, wertAufNacht => 0, sonnenAufUnter => 1, raumSollTemp => 22, GAraumSollTemp => "0/0/127",
- GAraumIstTemp => "0/0/128", GAfahren => "2/1/11", GAsperre => "0/0/129" };
-push @AlleRolllaeden, { name => "K\xFCche", winkel1 => 194, winkel2 => 294, wertZuBesch => 80, wertAufBesch => 2,
- wertZuNacht => 100, wertAufNacht => 2, sonnenAufUnter => 1, raumSollTemp => 22, GAraumSollTemp => "0/0/127",
- GAraumIstTemp => "0/0/128", GAfahren => "2/2/3", GAsperre => "0/0/129" };
-push @AlleRolllaeden, { name => "Kind Strasse", winkel1 => 182, winkel2 => 294, wertZuBesch => 86, wertAufBesch => 2,
- wertZuNacht => 100, wertAufNacht => 2, sonnenAufUnter => 0, raumSollTemp => 22, GAraumSollTemp => "0/0/127",
- GAraumIstTemp => "0/0/128", GAfahren => "2/3/13", GAsperre => "0/0/129" };
-push @AlleRolllaeden, { name => "Kind Friedhof", winkel1 => 182, winkel2 => 294, wertZuBesch => 86, wertAufBesch => 2,
- wertZuNacht => 100, wertAufNacht => 2, sonnenAufUnter => 0, raumSollTemp => 22, GAraumSollTemp => "0/0/127",
- GAraumIstTemp => "0/0/128", GAfahren => "2/3/23", GAsperre => "0/0/129" };
-push @AlleRolllaeden, { name => "Schlafen", winkel1 => 359, winkel2 => 359, wertZuBesch => 82, wertAufBesch => 2,
- wertZuNacht => 100, wertAufNacht => 2, sonnenAufUnter => 0, raumSollTemp => 22, GAraumSollTemp => "0/0/127",
- GAraumIstTemp => "0/0/128", GAfahren => "2/3/3", GAsperre => "0/0/129" };
-#######################
-### ENDE DEFINITION ###
-#######################
+# Gruppenadresse für die Windgeschwindigkeit
+my $GAWindSpeed;
+# Gruppenadresse für die Windgrichtung
+my $GAWindDirection;
+# Gruppenadresse für die Bewölkung
+my $GACloudiness;
+
+# Gruppenadresse für die Außentemperatur
+my $GATemperature;
+
+
+#################################
+### Lesen der Konfigurationsdatei
+#################################
+
+my ($user, $pass, $name, $lat, $lon, $alt, $GAtemp);
+my @TimeExclusions;
+
+# Read config file in conf.d
+my $confFile = '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
+if (! -f $confFile) {
+ plugin_log($plugname, " no conf file [$confFile] found.");
+ return "no conf file [$confFile] found.";
+} else {
+ open(CONF, $confFile);
+ my @lines = <CONF>;
+ close($confFile);
+ my $result = eval("@lines");
+ if ($@) {
+ plugin_log($plugname, "conf file [$confFile] returned:");
+ my @parts = split(/\n/, $@);
+ plugin_log($plugname, "--> $_") foreach (@parts);
+ }
+}
+
# Festlegen, dass das Plugin alle 5 Minuten laufen soll
$plugin_info{$plugname.'_cycle'} = 300;
-# Auf die GA der globalen Sperre anmelden
-#TODO: muss man sich \xFCberhaupt auf die GA anmelden. Sollte doch reichen wenn man den letzten Stand liest...
-$plugin_subscribe{$GASperreAlle}{$plugname} = 1;
-# Fals global gesperrt, Plugin-Durchgang beenden
-if (knx_read($GASperreAlle, 0, 1) == 1) {
- return "Global gesperrt";
+my $debug = 0;
+
+#######################
+### ENDE DEFINITION ###
+#######################
+
+if (defined $GASperreAlle) {
+ # Auf die GA der globalen Sperre anmelden
+ # TODO: muss man sich überhaupt auf die GA anmelden. Sollte doch reichen wenn man den letzten Stand liest...
+ $plugin_subscribe{$GASperreAlle}{$plugname} = 1;
+ # Fals global gesperrt, Plugin-Durchgang beenden
+ if (knx_read($GASperreAlle, 0, 1) == 1) {
+ return "Global gesperrt";
+ }
}
-# Sonnenstands-Berechnungen durchf\xFChren
+my $weather = {};
+if (defined $GAWindSpeed) {
+ $weather->{windSpeed} = knx_read($GAWindSpeed, 1800, 9.005);
+}
+if (defined $GAWindDirection) {
+ my $windDirection = knx_read($GAWindDirection, 1800, 5.003);
+ if (defined $windDirection) {
+ $weather->{windFromDirection} = ($windDirection + 180) % 360;
+ }
+}
+if (defined $GACloudiness) {
+ $weather->{cloudiness} = knx_read($GACloudiness, 1800, 5.004);
+}
+if (defined $GATemperature) {
+ $weather->{temperature} = knx_read($GATemperature, 1800, 9.001);
+}
+
+# Sonnenstands-Berechnungen durchführen
my ($azimuth, $elevation) = berechneSonnenstand($lat, $lon, $elev);
+
# Auslesen wo die Sonne beim letzten Durchgang war
my $lastAzimuth = $plugin_info{$plugname.'_lastAzimuth'};
my $lastElevation = $plugin_info{$plugname.'_lastElevation'};
-# Teste ob es Nacht ist, oder gerade Abend- oder Morgend\xE4mmerung ist
-my $testAbendDaemmerung = ($elevation < deg2rad($daemmerung) && $lastElevation > deg2rad($daemmerung)) || 0;
-my $testMorgenDaemmerung = ($elevation > deg2rad($daemmerung) && $lastElevation < deg2rad($daemmerung)) || 0;
-my $testNacht = ($elevation < deg2rad($daemmerung)) || 0;
+my %rolllaeden;
+foreach my $element (@AlleRolllaeden) {
+ $rolllaeden{$element->{name}} = $element;
+}
+
# Los gehts. Jeden Rolladen/Fenster/Raum abarbeiten.
foreach my $element (@AlleRolllaeden) {
- # Falls gesperrt, mit n\xE4chstem Rollladen fortfahren
- if (knx_read($element->{GAsperre}, 0, 1) == 1) {
+
+ if (defined $element->{istVorlage} && $element->{istVorlage}) {
next;
}
- # Die Einfallwinkel in Radians umrechnen
- my $winkel1 = deg2rad($element->{winkel1});
- my $winkel2 = deg2rad($element->{winkel2});
- # Teste ob das Fenster beschienen wird
- my $testAktuellBeschienen = ($azimuth > $winkel1 && $azimuth < $winkel2) || 0;
- my $testVoherBeschienen = ($lastAzimuth > $winkel1 && $lastAzimuth < $winkel2) || 0;
-
- # Fenster war nicht beschienen, ist jetzt beschienen, keine Nacht
- if (!$testVoherBeschienen && $testAktuellBeschienen && !$testNacht) {
- fahreRollladen($element->{wertZuBesch}, $element->{GAfahren});
- plugin_log($plugname,"Name: " . $element->{name} . "; Wegen Sonne zufahren bei: " . round(rad2deg($azimuth)));
+ my $rolladen = berechneRolladenParameter($element, 0);
+
+ # Falls gesperrt, mit nächstem Rollladen fortfahren
+ if (defined $rolladen->{GAsperre}
+ && knx_read($rolladen->{GAsperre}, 0, 1) == 1) {
+ next;
}
- # Fenster ist nicht beschienen, war beschienen, keine Nacht
- if ($testVoherBeschienen && !$testAktuellBeschienen && !$testNacht) {
- fahreRollladen($element->{wertAufBesch}, $element->{GAfahren});
- plugin_log($plugname,"Name: " . $element->{name} . "; Wegen Sonne auffahren bei: " . round(rad2deg($azimuth)));
+
+ my ($position, $bemerkung) = berechneRolladenposition($rolladen, $azimuth, $elevation, $lastAzimuth, $lastElevation, $daemmerung, $weather);
+ my $lastPosition = ladeRolladenParameter($rolladen, "position");
+
+ if (defined $position) {
+ if ($position != $lastPosition) {
+ fahreRollladen($rolladen, $position);
+ plugin_log($plugname,"Name: " . $rolladen->{name} . "; " . $bemerkung);
+ }
+ } elsif ($debug) {
+ plugin_log($plugname,"Name: " . $rolladen->{name} . "; Fahren wird fuer diesen Zyklus ausgesetzt");
}
- # AbendDaemmerung
- if ($testAbendDaemmerung && $element->{sonnenAufUnter}) {
- fahreRollladen($element->{wertZuNacht}, $element->{GAfahren});
- plugin_log($plugname,"Name: " . $element->{name} . "; Wegen Abenddaemmerung zufahren bei: " . round(rad2deg($azimuth)));
- }
- # MorgenDaemmerung
- if ($testMorgenDaemmerung && $element->{sonnenAufUnter}) {
- fahreRollladen($element->{wertAufNacht}, $element->{GAfahren});
- plugin_log($plugname,"Name: " . $element->{name} . "; Wegen Morgendaemmerung auffahren bei: " . round(rad2deg($azimuth)));
- }
+
}
-# F\xFCr die n\xE4chste Iteration den aktuellen Sonnenstand merken
-# TODO: M\xFCsste man sich nicht eigentlich f\xFCr jedes Element den Zustand merken, ob es auf- oder zugefahren wurde???
-# lastAzimuth ging noch als nur der Sonnenstand entscheidend war, ob gefahren wird. Jetzt aber auch lokale Sperre,
-# IstTemperatur, Sonnenschein.
+# Für die nächste Iteration den aktuellen Sonnenstand merken
$plugin_info{$plugname.'_lastAzimuth'} = $azimuth;
$plugin_info{$plugname.'_lastElevation'} = $elevation;
-# Ende
+
return "Grad gegen Norden: " . round(rad2deg($azimuth)) . "; Grad ueber Horizont: " . round(rad2deg($elevation));
+####################################
+# Berechne Parameter eines Rolladen
+####################################
+sub berechneRolladenParameter {
+ my ($rolladen, $counter) = @_;
+ if ($counter > 20) {
+ die $plugname . "Name: " . $rolladen->{name} . "; Endlosschleife bei Templates";
+ }
+ if (defined $rolladen->{vorlage}) {
+ my $template = berechneRolladen($rolllaeden{$rolladen->{vorlage}}, $counter + 1);
+ foreach my $key (keys (%$template)) {
+ if (!defined $rolladen->{$key}) {
+ if ($debug) {
+ plugin_log($plugname,"Name: " . $rolladen->{name} . "; Uebernehme Parameter " . $key . " aus Template " . $template->{name});
+ }
+ $rolladen->{$key} = $template->{$key};
+ }
+ }
+ }
+ return $rolladen;
+}
+
+
####################################################
# Aufruf mit berechneSonnenstand($lat, $lon, $elev);
####################################################
@@ -191,11 +220,168 @@
# Feststellen wo die Sonne gerade ist
my ($azimuth, $elevation, $range) = $loc->azel($sun);
return ($azimuth, $elevation);
+}
+##################################
+# Berechne Position eines Rolladen
+##################################
+sub berechneRolladenposition {
+ my ($element, $azimuth, $elevation, $lastAzimuth, $lastElevation, $daemmerung, $weather) = @_;
+
+ # Die Einfallwinkel in Radians umrechnen
+ my $winkel1 = deg2rad($element->{winkel1});
+ my $winkel2 = deg2rad($element->{winkel2});
+
+ # Teste ob das Fenster beschienen wird
+ my $testAktuellBeschienen = ($azimuth > $winkel1 && $azimuth < $winkel2) || 0;
+ my $testVoherBeschienen = ($lastAzimuth > $winkel1 && $lastAzimuth < $winkel2) || 0;
+
+ # Test ob Nach oder Daemmerung
+ my $testAbendDaemmerung = ($elevation < deg2rad($daemmerung) && $lastElevation > deg2rad($daemmerung)) || 0;
+ my $testMorgenDaemmerung = ($elevation > deg2rad($daemmerung) && $lastElevation < deg2rad($daemmerung)) || 0;
+ my $testNacht = ($elevation < deg2rad($daemmerung)) || 0;
+
+ my ($position, $bemerkung);
+
+ if (defined $element->{maxWindGeschw}) {
+ if (defined $weather->{windSpeed}) {
+ my $compare = vergleicheWert($weather->{windSpeed}, $element->{maxWindGeschw}, $element->{windGeschwHysterese});
+ if ($compare == HIGHER) {
+ speichereRolladenParameter($element, "windProtection", 1);
+ }
+ if ($compare == LOWER) {
+ speichereRolladenParameter($element, "windProtection", 0);
+ }
+ }
+ my $windProtection = ladeRolladenParameter($element, "windProtection");
+ if (defined $windProtection && $windProtection) {
+ $position = $element->{wertAufSchutz} || 0;
+ $bemerkung = "Wegen zu hoher Windgeschwindigkeit auffahren bei " + $weather->{windSpeed} . " km/h";
+ return ($position, $bemerkung);
+ }
+ }
+
+ if ($element->{sonnenAufUnter}) {
+ if ($testNacht) {
+ $position = $element->{wertZuNacht};
+ $bemerkung = "Wegen Abenddaemmerung zufahren bei: " . round(rad2deg($azimuth));
+ return ($position, $bemerkung);
+ } elsif ($testMorgenDaemmerung) {
+ $position = $element->{wertAufNacht};
+ $bemerkung = "Wegen Morgendaemmerung auffahren bei: " . round(rad2deg($azimuth));
+ }
+ }
+
+ # Fenster wird von der Sonne beschienen
+ if (!$testVoherBeschienen && $testAktuellBeschienen) {
+ $position = $element->{wertZuBesch};
+ $bemerkung = "Wegen Sonne zufahren bei: " . round(rad2deg($azimuth));
+ } elsif ($testVoherBeschienen && !$testAktuellBeschienen) {
+ $position = $element->{wertAufBesch};
+ $bemerkung = "Wegen Sonne auffahren bei: " . round(rad2deg($azimuth));
+ }
+
+ my $testTempNiedrig = 0;
+ my $testTempHoch = 0;
+ if (!$testNacht && $testAktuellBeschienen && $element->{tempGesteuert}) {
+ # Solltemperatur für den Raum feststellen
+ my $sollTemp;
+ if (defined $element->{GAraumSollTemp}) {
+ $sollTemp = knx_read($element->{GAraumSollTemp}, 300, 9);
+ }
+ if (!defined $sollTemp) {
+ $sollTemp = $element->{raumSollTemp};
+ }
+
+ # Aktuelle Temperatur für den Raum feststellen
+ my $istTemp = knx_read($element->{GAraumIstTemp}, 300, 9);
+
+ if (defined $sollTemp && defined $istTemp) {
+ my $tempHysterese = $element->{tempHysterese};
+ if (!defined $tempHysterese) {
+ $tempHysterese = 1;
+ }
+ $testTempNiedrig = ($istTemp < ($sollTemp - $tempHysterese));
+ $testTempHoch = ($istTemp > ($sollTemp + $tempHysterese));
+
+ # Fenster ist beschienen, Rolladen ist zu und Temperatur ist zu niedrig
+ if ($testTempNiedrig) {
+ $position = $element->{wertAufBesch};
+ $bemerkung = "Wegen Temperatur auffahren bei: " . $istTemp . ' °C';
+ }
+
+ # Fenster ist beschienen, Rolladen ist offen und Temperatur ist zu hoch
+ if ($testTempHoch) {
+ $position = $element->{wertZuBesch};
+ $bemerkung = "Wegen Temperatur zufahren bei: " . $istTemp . ' °C';
+ }
+ } else {
+ plugin_log($plugname,"Name: " . $element->{name} . "; Temperatur konnte nicht festgestellt werden");
+ return (undef, undef);
+ }
+ }
+
+ if (!$testNacht
+ && $testAktuellBeschienen
+ && defined $element->{maxBewoelkung}) {
+ if (defined $weather->{cloudiness}) {
+ my $compare = vergleicheWert($weather->{cloudiness}, $element->{maxBewoelkung}, $element->{bewoelkungHysterese});
+ if ($compare == HIGHER) {
+ speichereRolladenParameter($element, "overclouded", 1);
+ }
+ if ($compare == LOWER) {
+ speichereRolladenParameter($element, "overclouded", 0);
+ }
+ }
+ my $overclouded = ladeRolladenParameter($element, "overclouded");
+ if (defined $overclouded && $overclouded) {
+ $position = $element->{wertAufBesch};
+ $bemerkung = "Wegen Bewoelkung auffahren bei: " . $weather->{cloudiness} . ' %';
+ }
+ }
+
+ if (defined $element->{minAussenTemp}) {
+ if (defined $weather->{temperature}) {
+ my $compare = vergleicheWert($weather->{temperature}, $element->{minAussenTemp}, $element->{aussenTempHysterese});
+ if ($compare == LOWER) {
+ speichereRolladenParameter($element, "tempProtection", 1);
+ }
+ if ($compare == HIGHER) {
+ speichereRolladenParameter($element, "tempProtection", 0);
+ }
+ }
+ my $tempProtection = ladeRolladenParameter($element, "tempProtection");
+ if (defined $tempProtection && $tempProtection) {
+ $position = $element->{wertZuSchutz} || 1;
+ $bemerkung = "Wegen zu niedriger Temperatur zufahren bei " + $weather->{temperature} . ' °C';
+ }
+ }
+
+ return ($position, $bemerkung);
}
+######################################################################
+# Prüfen ob der aktuelle Wert eine Grenze über bzw. unterschritten hat
+######################################################################
+sub vergleicheWert {
+ my ($currentValue, $reference, $hysterese) = @_;
+ my $current = EQUAL;
+ my $last = EQUAL;
+ if (!defined $hysterese) {
+ $hysterese = 0;
+ }
+ if ($currentValue < ($reference - $hysterese)) {
+ $current = LOWER;
+ }
+ if ($currentValue > ($reference + $hysterese)) {
+ $current = HIGHER;
+ }
+ return $current;
+}
+
+
####################################################
# Aufruf mit fahreRollladen($richtung, $GA);
####################################################
@@ -203,11 +389,13 @@
# Falls $richtung 0 oder 1 ist, wird angenommen, dass der Rollladen
# komplett zu- bzw. aufgefahren werden soll (DPT3).
# Bei $richtung>1 wird angenommen, dass eine Positionsfahrt
- # durchgef\xFChrt werden soll (DPT5).
- # TODO: man muss bei Positionsfahrt f\xFCr den Offen-Zustand mindestens 2% angeben...
- # hm, wenn man die GAs ins Wiregate importiert hat, br\xE4uchte man keinerlei
+ # durchgeführt werden soll (DPT5).
+ # TODO: man muss bei Positionsfahrt für den Offen-Zustand mindestens 2% angeben...
+ # hm, wenn man die GAs ins Wiregate importiert hat, bräuchte man keinerlei
# Unterscheidung mehr! Und man kann auch 0% bzw 1% benutzen
- my ($richtung, $GA) = @_;
+ my ($rolladen, $richtung) = @_;
+ my $GA = $rolladen->{GAfahren};
+
if ($richtung == 0 || $richtung == 1) {
# Auf/Zu fahren
knx_write($GA,$richtung,3);
@@ -216,9 +404,31 @@
# Position anfahren
knx_write($GA,$richtung,5);
}
+
+ # Position speichern
+ speichereRolladenParameter($rolladen, "position", $richtung);
+
# kurze Pause, falls das benutzte Interface das braucht...
if ($bugfixSlowInterface) {
usleep(20000);
}
}
+
+########################################
+# Parameter für einen Rolladen speichern
+########################################
+sub speichereRolladenParameter {
+ my ($rolladen, $parameter, $value) = @_;
+ $plugin_info{$plugname . '_Rolladen_' . $rolladen->{GAfahren} . "_" . $parameter} = $value;
+}
+
+
+####################################
+# Parameter für einen Rolladen laden
+####################################
+sub ladeRolladenParameter {
+ my ($rolladen, $parameter) = @_;
+ return $plugin_info{$plugname . '_Rolladen_' . $rolladen->{GAfahren} . "_" . $parameter};
+}
+
Added: wiregate/plugin/generic/conf.d/RollladenAutomatik.conf_sample
===================================================================
--- wiregate/plugin/generic/conf.d/RollladenAutomatik.conf_sample (rev 0)
+++ wiregate/plugin/generic/conf.d/RollladenAutomatik.conf_sample 2013-09-16 10:14:56 UTC (rev 1889)
@@ -0,0 +1,104 @@
+# Die Koordinaten des Hauses. Sehr einfach über http://www.latlong.net/ zu ermitteln.
+# Und die Höhe über Normalnull (NN)
+$lat = 48.225073; # Breitengrad in Grad
+$lon = 15.643443; # Längengrad in Grad
+$elev = 267 / 1000; # Höhe über NN in Kilometer (dewegen geteilt durch 1000)
+
+# Elevation der Sonne, ab der es abends dunkel ist bzw. morgens hell ist.
+# Bürgerliche Dämmerung ist bei -6 Grad.
+# Defaultwert ist -3
+$daemmerung = -3;
+
+# Gruppenadresse, über welche die komplette Automatik für alle Rollläden gesperrt werden kann
+# $GASperreAlle = "0/1/2";
+
+# Gruppenadresse für die Außentemperatur
+# $GATemperature = "1/2/0";
+
+# Gruppenadresse für die Windgeschwindigkeit
+# $GAWindSpeed = "1/2/3";
+
+# Gruppenadresse für die Windrichtung (hat derzeit noch keine Funktion)
+# $GAWindDirection = "1/2/4";
+
+# Gruppenadresse für die Bewölkung
+# $GACloudiness = "1/2/5";
+
+# Bugfix für KNX-Schnittstellen die sich bei zu schneller Telegrammabfolge
+# verschlucken, und denen wir deshalb die Geschwindigkeit der Telegramme drosseln müssen
+# 0 = nicht anschalten (Telegramme mit voller Geschwindigkeit abfeuern)
+# 1 = anschalten (Telegramme um 20 millisekunden verzögern)
+# nur für "Busch-Jäger 6196 USB REG" ist bekannt das dies benötigt wird
+# $bugfixSlowInterface = 1;
+
+# Ein Array von Hashes, wobei jeder Hash ein Rollladen/Fenster/Raum ist.
+# Name des Rolladen
+# name => "Speisekammer"
+# Definition ist ausschließlich eine Vorlage und wird daher nicht gesteuert
+# istVorlage => 1
+# Name des Rollladen oder der Definition, welche als Vorlage dienen soll (Rekursionen sind möglich)
+# vorlage => "default"
+# Winkel zum Norden, ab dem das Fenster beschienen wird.
+# Echter Osten = 90°, echter Süden = 180°, echter Westen = 270°, echter Norden = 0°
+# winkel1 => 66
+# Winkel zum Norden, bis zu dem das Fenster beschienen wird
+# winkel2 => 186
+# Richtung bei Beschattung: wenn 1 wird DPT3 angenommen und ganz zugefahren.
+# Bei ungleich 1, wird DPT5 angenommen und Position angefahren
+# wertZuBesch => 1
+# Richtung bei keiner Beschattung: wenn 0 wird DPT3 angenommen und ganz aufgefahren.
+# Bei ungleich 0, wird DPT5 angenommen und Position angefahren
+# wertAufBesch => 0
+# Richtung bei Nacht: wenn 1 wird DPT3 angenommen und ganz zugefahren.
+# Bei ungleich 1, wird DPT5 angenommen und Position angefahren
+# wertZuNacht => 1
+# Richtung bei keiner Nacht: wenn 0 wird DPT3 angenommen und ganz aufgefahren.
+# Bei ungleich 0, wird DPT5 angenommen und Position angefahren
+# wertAufNacht => 0
+# Schließen für Schutzfunktion (z.B.: zu niedrige Temp): wenn 1 wird DPT3 angenommen und ganz zugefahren.
+# Bei ungleich 1, wird DPT5 angenommen und Position angefahren
+# wertZuSchutz => 1
+# Öffnen für Schutzfunktion (z.B.: zu hoher Wind): wenn 0 wird DPT3 angenommen und ganz aufgefahren.
+# Bei ungleich 0, wird DPT5 angenommen und Position angefahren
+# wertAufSchutz => 0
+# Ob der Rollladen in die Automatik für Sonnenauf- und untergang einbezogen werden soll
+# sonnenAufUnter => 1
+# Raum-Solltemperatur, wenn keine GA angegeben wurde oder kein Wert vom Bus gelesen wurde
+# raumSollTemp => 22
+# GA der Raum-Solltemperatur
+# GAraumsollTemp => "0/0/127"
+# GA der Raum-Isttemperatur
+# GAraumIstTemp => "0/0/128"
+# GA um Rollladen zu fahren
+# GAfahren => "0/0/126"
+# GA um die Automatik dieses einen Rollladen zu sperren
+# GAsperre=> "0/0/129"
+# Rolladen soll aufgrund der Raumtemperatur gesteuert werden
+# tempGesteuert => 1
+# Hysterese für Regelung aufgrund der Raumtemperatur (in °C)
+# tempHysterese => 0.5
+# Rolladenschutz für zu hohe Windgeschwindigkeiten (max. Geschwindigkeit in km/h)
+# maxWindGeschw => 50
+# Hysterese für Regelung aufgrund der Windgeschwindigkeit (in km/h)
+# windGeschwHysterese => 5
+# Rolladen wird ab einer maximalen Bewölkung (in %) nicht mehr runtergefahren
+# maxBewoelkung => 75
+# Hysterese für Regelung aufgrund der Bewölkung (in %-Punkten)
+# bewoelkungHysterese => 5
+# Rolladen wird runtergefahren wenn die Temperatur unterschritten wird (in °C)
+# minAussenTemp => -15
+# Hysterese für Regelung aufgrund der Außentemperatur (in °C)
+# aussenTempHysterese => 2
+push @AlleRolllaeden, { name => "default", istVorlage => 1, wertZuBesch => 1, wertAufBesch => 0,
+ wertZuNacht => 1, wertAufNacht => 0, sonnenAufUnter => 1, raumSollTemp => 23,
+ tempGesteuert => 1, tempHysterese => 0.5, maxWindGeschw => 80,
+ windGeschwHysterese => 5, maxBewoelkung => 75, bewoelkungHysterese => 5,
+ minAussenTemp => -15, aussenTempHysterese => 2, wertAufSchutz => 0, wertZuSchutz => 1 };
+
+push @AlleRolllaeden, { name => "Wohnzimmer", vorlage => "default", winkel1 => 66, winkel2 => 180,
+ GAraumIstTemp => "2/3/0", GAfahren => "3/1/0" };
+push @AlleRolllaeden, { name => "Küche", vorlage => "default", winkel1 => 152, winkel2 => 252,
+ GAraumIstTemp => "2/3/1", GAfahren => "3/1/2" };
+push @AlleRolllaeden, { name => "Schlafzimmer", vorlage => "default", winkel1 => 93, winkel2 => 186,
+ wertZuNacht => 80, sonnenAufUnter => 0, GAraumIstTemp => "2/3/3", GAfahren => "3/1/3" };
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|