sorry - hatte das damals bei mir auf usleep(20000); gestellt gehabt und dann vergessen dass ich das Ergebnis noch beachten sollte

Ja, mit 20ms habe ich in den letzten Wochen keine Probleme mit "nicht-fahrenden Rollläden" gehabt.
Grüße,
Julian

Eine Telegrammratenbegrenzung für den eibd bei bestimmten Backends ist nämlich gerade recht nahe..

my $loc = Astro::Coord::ECI->geodetic($lat, $lon, $elev);
my $loc = Astro::Coord::ECI->geodetic(deg2rad($lat), deg2rad($lon), $elev);

Hatte garnicht nach sowas gesucht sondern mich einfach kurz mit meinem Garmin auf die Terasse gestellt 
# Plugin Hitzeschild
# fährt die Beschattung eines Hauses nach dem Stand der Sonne
# die Automatik kann über eine Gruppenadresse gesperrt werden
# Einstellungen
# die eigenen Koordinaten
#
# Koordinatenformat:
# aktuelle Koordinaten feststellen im Format Grad - also xx,xxxxxx
# Koordinaten entweder mit einfachem GPS, oder bspw. über Google Maps oder Google Earth
# ablesen
# auf google.de gehen und nach "xx.xxxxxx degrees in radians" suchen
# Google verrät einem das Ergebnis, das hier eintragen
#
# Höhe über null: entweder per GPS/Höhenmesser feststellen,
# oder auf wikipedia die nächstgelegene Stadt raussuchen und da in den Daten nachlesen
my ($lat, $lon, $elev) = (
0.914027184, # breitengrad in radians
0.12383111, # längengrad in radians
59 / 1000 # Höhe über normalnull in meter
);
# die Fassaden und deren Rolläden/Beschattungs-Gruppenadressen festlegen
# die Zahl ist der Winkel zwischen Norden und "senkrechte auf die Fassade"
# => echter Osten = 90°, echter Süden = 180°, echter Westen = 270°, echter Norden = 0°
# aber wessen Haus steht schon korrekt nach diesen Himmelsrichtungen.
# Format:
# Fassadenwinkel => ["GA1", "GA2", ...]
my %GAFassaden = (
60 => ["2/2/0"],
150 => ["2/3/0", "2/3/1"],
240 => ["2/2/2", "2/2/4", "2/2/5", "2/2/6", "2/3/2"],
330 => ["2/2/1", "2/3/3"]
);
# ab und bis zu welchem Einfallwinkel auf die Fassade soll die Fassade als beschienen
# betrachtet werden; standard sind 60 Grad
my $einfallwinkel = 60;
# welche Position soll das Beschattungsprodukt (= Rolladen) einnehmen,
# wenn Sonneneinfall gemeldet wird?
# je nach angegebener Gruppenadresse und Fähigkeiten des dahinter hängenden Aktors
# sollte das hier eine Fahrtrichtung, oder eine Position sein (standard: 1, abwärts fahren)
my $beschattungsposition = 1;
# welche Position soll das Beschattungsprodukt (= Rolladen) einnehmen,
# wenn kein Sonneneinfall gemeldet wird?
# Angabe wie Beschattungsposition
my $offenposition = 0;
# eine Gruppenadresse über welche die Automatisierung gesperrt werden kann
# bspw. um nicht nachts die Rolläden rumzufahren
# oder wenn die Hitzewelle nachgelassen hat für den Rest des Jahres
my $GAsperre = "0/0/8";
# 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
my $bugfixSlowInterface = 1;
# ab hier eigentlich nurnoch Programmcode und wahrscheinlich
# keine Notwendigkeit was zu konfigurieren
# festlegen wie oft wir normalerweise laufen
$plugin_info{$plugname.'_cycle'} = 300;
# auf die Adresse der Sperre anmelden
$plugin_subscribe{$GAsperre}{$plugname} = 1;
# feststellen, ob die Automatik abgeschaltet wurde
# dazu wird ausschließlich der Nachrichten-Cache des Wiregate abgefragt
if (knx_read($GAsperre, 0, 1) == 1) {
# wenn gesperrt ist, dann nurnoch stündlich laufen - wir fahren ja eh nix rum
$plugin_info{$plugname.'_cycle'} = 0;
return "Beschattungsautomatik gesperrt durch GA " . $GAsperre;
}
# und finally:
# wenn wir nicht gesperrt sind, weiterlaufen
# Module laden
use Astro::Coord::ECI;
use Astro::Coord::ECI::Sun;
use Astro::Coord::ECI::TLE;
use Astro::Coord::ECI::Utils qw{rad2deg deg2rad};
# aktuelle Zeit
my $time = time ();
# die eigenen Koordinaten
my $loc = Astro::Coord::ECI->geodetic($lat, $lon, $elev);
# Sonne instanziieren :)
my $sun = Astro::Coord::ECI::Sun->universal($time);
# feststellen wo die Sonne grade ist
my ($azimuth, $elevation, $range) = $loc->azel($sun);
# und feststellen wo die Sonne eben noch war
my $lastAzimuth = $plugin_info{$plugname.'_lastAzimuth'};
# den Einfallwinkel in radians umrechnen, brauchen wir so
$einfallwinkel = deg2rad($einfallwinkel);
my $tmpReturn = "";
foreach my $fassadenwinkel (keys %GAFassaden) {
my $GAs = %GAFassaden->{$fassadenwinkel};
# den Winkel noch in radians umrechnen
$fassadenwinkel = deg2rad($fassadenwinkel);
# über alle Fassaden laufen und jeweils schauen ob Sonneneinfall errechnet ist
if ($azimuth > ($fassadenwinkel - $einfallwinkel) && $azimuth < ($fassadenwinkel + $einfallwinkel)) {
if ($lastAzimuth < ($fassadenwinkel + $einfallwinkel) && $lastAzimuth > ($fassadenwinkel - $einfallwinkel)) {
# bereits beim letzten Schritt verfahren
$tmpReturn .= "zu (unverändert): " . rad2deg($fassadenwinkel) . ";";
} else {
# jetzt neu fahren
# diese Fassade gilt es Sonnenbestrahlt
foreach (@$GAs) {
knx_write($_, $beschattungsposition);
if ($bugfixSlowInterface) {
usleep(20000);
}
}
$tmpReturn .= "zu: " . rad2deg($fassadenwinkel) . ";";
}
} elsif ($lastAzimuth < ($fassadenwinkel + $einfallwinkel) && $lastAzimuth > ($fassadenwinkel - $einfallwinkel)) {
# eben war diese Wand noch beschienen - jetzt nicht mehr
# also die Beschattung wieder zurücknehmen
foreach (@$GAs) {
knx_write($_, $offenposition);
if ($bugfixSlowInterface) {
usleep(20000);
}
}
$tmpReturn .= "auf: " . rad2deg($fassadenwinkel) . ";";
}
}
# für die nächste Iteration den aktuellen Sonnenstand merken
# damit wir die Beschattung ggf. wieder zurücknehmen können
$plugin_info{$plugname.'_lastAzimuth'} = $azimuth;
# und fertig
return "Sonnenposition gegen Norden: " . round(rad2deg($azimuth)) . " Grad, geschaltet: $tmpReturn";
use Math::Trig;
$plugin_info{$plugname.'_cycle'} = 300;
# Diese Daten müssen eingepflegt werden; Längengrad und Breitengrad, sowie die Zeitzone
# (localtime)[8] gibt an, ob gerade Sommerzeit ist und addiert entsprechend +1 dazu
# *************************************************************************************
# Breiten und Längengrad in degrees
my $lat = 52.4;
my $lon = 9.9;
my $timezone = (localtime)[8];
# Gruppenadressen der Rollläden für automatisches öffnen morgens
my @autoMorgen = ("2/2/2", "2/2/3", "2/2/4", "2/2/5", "2/2/6", "2/3/0");
# Position die morgens angefahren werden soll
my $directionMorgens = 0;
# Gruppenadressen der Rollläden für automatisches schließen abends
my @autoAbend = ("2/2/0", "2/2/1", "2/2/2", "2/2/4", "2/2/5", "2/2/6", "2/3/0", "2/3/1", "2/3/3");
# Position die abends angefahren werden soll
my $directionAbends = 1;
# Gruppenadresse der Rolläden für den Fall dass das Haus als verlassen gilt
my @autoAll = ("0/0/3");
# Gruppenadresse um festzustellen, ob das Haus verlassen ist
# hier: Riegelschaltkontakt in der Haustür - wenn verschlossen ist, ist niemand da
# dann werden alle Rolläden gefahren, da man so auch niemanden stört
my $GAdoorLocked = "7/0/1";
# Gruppenadresse um abends das Hitzeschild zu sperren und frühs wieder zu aktivieren
my $GAlockHitzeschild = "0/0/8";
# 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
my $bugfixSlowInterface = 1;
# *************************************************************************************
my $h = -0.0145;
my $RAD = pi/180.0;
my $B = $lat * $RAD;
my $DOY = ((localtime)[7]+1); # DOY = Day Of Year
my $timecalc = -0.171 * sin(0.0337 * $DOY + 0.465) - 0.1299 * sin(0.01787 * $DOY - 0.168);
my $declination = 0.4095 * sin(0.016906 * ($DOY - 80.086));
my $tmp = (sin($h) - (sin($B) * sin($declination))) / (cos($B) * cos($declination));
my $timediff = 12* acos($tmp)/pi;
my $timenow = ((localtime)[2] + (localtime)[1]/60);
my $boolIsDark = 0;
if ($plugin_info{$plugname."_status"} !=0 and $timenow > sunrise() and $timenow < sunset() ) {
# aktuelle Zeit > Sonnenaufgangszeit und < Sonnenuntergangszeit
# die Sonne ist also "am Himmel", aufgegangen
$boolIsDark = 0;
} elsif ($plugin_info{$plugname."_status"} !=1 and $timenow > sunset() ) {
# aktuelle Zeit > Sonnenuntergangszeit
# die Sonne ist untergegangen
$boolIsDark = 1;
} else {
# unverändert, also weg
my $sunrise = sunrise();
my $sunset = sunset();
$sunrise = floor($sunrise) . ":" . sprintf("%02d", round(($sunrise - floor($sunrise))*60));
$sunset = floor($sunset) . ":" . sprintf("%02d", round(($sunset - floor($sunset))*60));
return "sunrise: $sunrise, sunset: $sunset";
}
# status ablegen
$plugin_info{$plugname.'_status'} = $boolIsDark;
# festlegen, welche Rolläden und welche Richtung
my @auto;
my $intDirection;
if ($boolIsDark == 0) {
# morgens, Hitzeschild wieder aktivieren
knx_write($GAlockHitzeschild, 0);
# die GA für Morgens raussuchen und "öffnen" anspringen
@auto = @autoMorgen;
$intDirection = $directionMorgens;
} else {
# abends, Hitzeschild deaktivieren
knx_write($GAlockHitzeschild, 1);
# die GA für Abends raussuchen und "schließen" anspringen
@auto = @autoAbend;
$intDirection = $directionAbends;
}
if (knx_read($GAdoorLocked, 0) == 1) {
# das Haus ist verlassen, also alle Rollläden automatisieren
@auto = @autoAll;
}
# und jetzt dann mal Rolläden fahren!
foreach (@auto) {
knx_write($_, $intDirection);
if ($bugfixSlowInterface) {
usleep(20000);
}
}
return "neuer dunkelheits-status: $intDirection";
sub sunrise{
my $sunrise = 12 - $timediff - $timecalc + (15-$lon)*4/60 + $timezone;
return $sunrise;
}
sub sunset{
my $sunset = 12 + $timediff - $timecalc + (15-$lon)*4/60 + $timezone;
return $sunset;
}
return;


# Einstellungen
# die eigenen Koordinaten
#
# Koordinatenformat:
# aktuelle Koordinaten feststellen im Format Grad - also xx,xxxxxx
# Koordinaten entweder mit einfachem GPS, oder bspw. über Google Maps oder Google Earth
# ablesen
# auf google.de gehen und nach "xx.xxxxxx degrees in radians" suchen
# Google verrät einem das Ergebnis, das hier eintragen
#
# Höhe über null: entweder per GPS/Höhenmesser feststellen,
# oder auf wikipedia die nächstgelegene Stadt raussuchen und da in den Daten nachlesen
my ($lat, $lon, $elev) = (
0.914027184, # längengrad in radians
0.12383111, # breitengrad in radians
59 / 1000 # Höhe über normalnull in meter
);
# die Fassaden und deren Rolläden/Beschattungs-Gruppenadressen festlegen
# die Zahl ist der Winkel zwischen Norden und "senkrechte auf die Fassade"
# => echter Osten = 90°, echter Süden = 180°, echter Westen = 270°, echter Norden = 0°
# aber wessen Haus steht schon korrekt nach diesen Himmelsrichtungen.
# Format:
# Fassadenwinkel => ["GA1", "GA2", ...]
my %GAFassaden = (
60 => ["2/2/0"],
150 => ["2/3/0", "2/3/1"],
240 => ["2/2/2", "2/2/4", "2/2/5", "2/2/6", "2/3/2"],
330 => ["2/2/1", "2/3/3"]
);
# ab und bis zu welchem Einfallwinkel auf die Fassade soll die Fassade als beschienen
# betrachtet werden; standard sind 45 Grad
my $einfallwinkel = 45;
# welche Position soll das Beschattungsprodukt (= Rolladen) einnehmen,
# wenn Sonneneinfall gemeldet wird?
# je nach angegebener Gruppenadresse und Fähigkeiten des dahinter hängenden Aktors
# sollte das hier eine Fahrtrichtung, oder eine Position sein (standard: 1, abwärts fahren)
my $beschattungsposition = 1;
# welche Position soll das Beschattungsprodukt (= Rolladen einnehmen),
# wenn kein Sonneneinfall gemeldet wird?
# Angabe wie Beschattungsposition
my $offenposition = 0;
# eine Gruppenadresse über welche die Automatisierung gesperrt werden kann
# bspw. um nicht nachts die Rolläden rumzufahren
# oder wenn die Hitzewelle nachgelassen hat für den Rest des Jahres
my $GAsperre = "0/0/8";
# ab hier eigentlich nurnoch Programmcode und wahrscheinlich
# keine Notwendigkeit was zu konfigurieren
# festlegen wie oft wir normalerweise laufen
$plugin_info{$plugname.'_cycle'} = 300;
# feststellen, ob die Automatik abgeschaltet wurde
# dazu wird ausschließlich der Nachrichten-Cache des Wiregate abgefragt
if (knx_read($GAsperre, 0, 1) == 1) {
# wenn gesperrt ist, dann nurnoch stündlich laufen - wir fahren ja eh nix rum
$plugin_info{$plugname.'_cycle'} = 3600;
return "Beschattungsautomatik gesperrt durch GA " . $GAsperre;
}
# und finally:
# wenn wir nicht gesperrt sind, weiterlaufen
# Module laden
use Astro::Coord::ECI;
use Astro::Coord::ECI::Sun;
use Astro::Coord::ECI::TLE;
use Astro::Coord::ECI::Utils qw{rad2deg deg2rad};
# aktuelle Zeit
my $time = time ();
# die eigenen Koordinaten
my $loc = Astro::Coord::ECI->geodetic($lat, $lon, $elev);
# Sonne instanziieren :)
my $sun = Astro::Coord::ECI::Sun->universal($time);
# feststellen wo die Sonne grade ist
my ($azimuth, $elevation, $range) = $loc->azel($sun);
# und feststellen wo die Sonne eben noch war
my $lastAzimuth = $plugin_info{$plugname.'_lastAzimuth'};
# den Einfallwinkel in radians umrechnen, brauchen wir so
$einfallwinkel = deg2rad($einfallwinkel);
my $tmpReturn = "";
use Data::Dumper;
#while ((my $fassadenwinkel, my @GAs) = each ($GAFassaden)) {
foreach my $fassadenwinkel (keys %GAFassaden) {
my $GAs = %GAFassaden->{$fassadenwinkel};
# den Winkel noch in radians umrechnen
$fassadenwinkel = deg2rad($fassadenwinkel);
# über alle Fassaden laufen und jeweils schauen ob Sonneneinfall errechnet ist
if ($azimuth > ($fassadenwinkel - $einfallwinkel) && $azimuth < ($fassadenwinkel + $einfallwinkel)) {
if ($lastAzimuth < ($fassadenwinkel + $einfallwinkel) && $lastAzimuth > ($fassadenwinkel - $einfallwinkel)) {
# bereits beim letzten Schritt verfahren
$tmpReturn .= "zu (unverändert): " . rad2deg($fassadenwinkel) . ";";
} else {
# jetzt neu fahren
# diese Fassade gilt als Sonnenbestrahlt
for my $GA (@$GAs) {
knx_write($_, $beschattungsposition);
}
$tmpReturn .= "zu: " . rad2deg($fassadenwinkel) . ";";
}
} elsif ($lastAzimuth < ($fassadenwinkel + $einfallwinkel) && $lastAzimuth > ($fassadenwinkel - $einfallwinkel)) {
# eben war diese Wand noch beschienen - jetzt nicht mehr
# also die Beschattung wieder zurücknehmen
foreach (@$GAs) {
knx_write($_, $offenposition);
}
$tmpReturn .= "auf: " . rad2deg($fassadenwinkel) . ";";
}
}
# für die nächste Iteration den aktuellen Sonnenstand merken
# damit wir die Beschattung ggf. wieder zurücknehmen können
$plugin_info{$plugname.'_lastAzimuth'} = $azimuth;
# und fertig
return "Sonnenposition gegen Norden: " . round(rad2deg($azimuth)) . " Grad, geschaltet: $tmpReturn";
# Einstellungen
# die eigenen Koordinaten
#
# Koordinatenformat:
# aktuelle Koordinaten feststellen im Format Grad - also xx,xxxxxx
# Koordinaten entweder mit einfachem GPS, oder bspw. über Google Maps oder Google Earth
# ablesen
# auf google.de gehen und nach "xx.xxxxxx degrees in radians" suchen
# Google verrät einem das Ergebnis, das hier eintragen
#
# Höhe über null: entweder per GPS/Höhenmesser feststellen,
# oder auf wikipedia die nächstgelegene Stadt raussuchen und da in den Daten nachlesen
my ($lat, $lon, $elev) = (
0.914027184, # längengrad in radians
0.12383111, # breitengrad in radians
59 / 1000 # Höhe über normalnull in meter
);
# die Fassaden und deren Rolläden/Beschattungs-Gruppenadressen festlegen
# die Zahl ist der Winkel zwischen Norden und "senkrechte auf die Fassade"
# => echter Osten = 90°, echter Süden = 180°, echter Westen = 270°, echter Norden = 0°
# aber wessen Haus steht schon korrekt nach diesen Himmelsrichtungen.
my %GAFassaden = (
60 => ("2/2/0"),
150 => ("2/3/0", "2/3/1"),
240 => ("2/2/2", "2/2/3", "2/2/4", "2/2/5", "2/2/6", "2/3/2"),
330 => ("2/2/1", "2/3/3")
);
# ab und bis zu welchem Einfallwinkel auf die Fassade soll die Fassade als beschienen
# betrachtet werden; standard sind 45 Grad
my $einfallwinkel = 45;
# welche Position soll das Beschattungsprodukt (= Rolladen) einnehmen,
# wenn Sonneneinfall gemeldet wird?
# je nach angegebener Gruppenadresse und Fähigkeiten des dahinter hängenden Aktors
# sollte das hier eine Fahrtrichtung, oder eine Position sein (standard: 1, abwärts fahren)
my $beschattungsposition = 1;
# welche Position soll das Beschattungsprodukt (= Rolladen einnehmen),
# wenn kein Sonneneinfall gemeldet wird?
# Angabe wie Beschattungsposition
my $offenposition = 0;
# eine Gruppenadresse über welche die Automatisierung gesperrt werden kann
# bspw. um nicht nachts die Rolläden rumzufahren
# oder wenn die Hitzewelle nachgelassen hat für den Rest des Jahres
my $GAsperre = "0/0/8";
# ab hier eigentlich nurnoch Programmcode und wahrscheinlich
# keine Notwendigkeit was zu konfigurieren
# festlegen wie oft wir normalerweise laufen
$plugin_info{$plugname.'_cycle'} = 300;
# feststellen, ob die Automatik abgeschaltet wurde
# dazu wird ausschließlich der Nachrichten-Cache des Wiregate abgefragt
if (knx_read($GAsperre, 0, 1) == 1) {
# wenn gesperrt ist, dann nurnoch stündlich laufen - wir fahren ja eh nix rum
$plugin_info{$plugname.'_cycle'} = 3600;
return "Beschattungsautomatik gesperrt durch GA ", $GAsperre;
}
# und finally:
# wenn wir nicht gesperrt sind, weiterlaufen
# Module laden
use Astro::Coord::ECI;
use Astro::Coord::ECI::Sun;
use Astro::Coord::ECI::TLE;
use Astro::Coord::ECI::Utils qw{rad2deg deg2rad};
# aktuelle Zeit
my $time = time ();
# die eigenen Koordinaten
my $loc = Astro::Coord::ECI->geodetic($lat, $lon, $elev);
# Sonne instanziieren :)
my $sun = Astro::Coord::ECI::Sun->universal($time);
# feststellen wo die Sonne grade ist
my ($azimuth, $elevation, $range) = $loc->azel($sun);
# und feststellen wo die Sonne eben noch war
my $lastAzimuth = $plugin_info{$plugname.'_lastAzimuth'};
# den Einfallwinkel in radians umrechnen, brauchen wir so
$einfallwinkel = deg2rad($einfallwinkel);
while (($fassadenwinkel, @GAs) = each(%GAFassaden) {
# den Winkel noch in radians umrechnen
$fassadenwinkel = deg2rad($fassadenwinkel);
# über alle Fassaden laufen und jeweils schauen ob Sonneneinfall errechnet ist
if ($azimuth > ($fassadenwinkel - $einfallwinkel)
&& $azimuth < ($fassadenwinkel + $einfallwinkel)) {
# diese Fassade gilt es Sonnenbestrahlt
foreach (@GAs) {
knx_write($_, $beschattungsposition);
}
} elsif ($lastAzimuth < ($fassadenwinkel + $einfallwinkel)
&& $lastAzimuth > ($fassadenwinkel - $einfallwinkel)) {
# eben war diese Wand noch beschienen - jetzt nicht mehr
# also die Beschattung wieder zurücknehmen
foreach (@GAs) {
knx_write($_, $offenposition);
}
}
}
# für die nächste Iteration den aktuellen Sonnenstand merken
# damit wir die Beschattung ggf. wieder zurücknehmen können
$plugin_info{$plugname.'_lastAzimuth'} = $azimuth;
# und fertig
return "aktuelle Sonnenposition gegen Norden: ", rad2deg($azimuth), " Grad";
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.


Einen Kommentar schreiben: