Ankündigung

Einklappen
Keine Ankündigung bisher.

CPAN-Modul / Sonnenstand

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [wiregate] CPAN-Modul / Sonnenstand

    Hallo zusammen,

    die aktuelle Hitze durch die Sonneneinstrahlung macht mich noch halb wahnsinnig.

    Ich würde gerne die Rolladen meines Hauses Fassadenweise automatisch fahren sobald die Sonne auch nur in die Nähe kommt.

    Code:
    # 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";
    Jetzt habe ich den Code aber noch nicht ausprobieren können, weil ich das Astro::Coord::ECI und die anderen CPAN-Module nicht habe ...

    @makki:
    gibt es da eine Chance die Module zu bekommen ohne sie selbst zu compilen, oder versuch ich hier wieder mal dem wiregate mehr Logik zu verpassen als eigentlich gewünscht?

    Grüße,
    Julian

    #2
    libastro-satpass-perl ist im Repository aber ungetestet..
    (inkl. depends: libparams-util-perl)
    Also normal über Paket installieren oder apt-get install ..

    Warum nicht, ist ja nichts zeitkritisches oder lastintensives..

    Makki
    EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
    -> Bitte KEINE PNs!

    Kommentar


      #3
      Supi.

      Hab noch ein paar Codeänderungen machen müssen, hatte mich an ein paar Stellen verhauen, und für einen PHP-Entwickler ist das ganze hashes-vs-lists-Konzept von Perl doch etwas verwirrend

      Nicht erschrecken - vieles davon sind nur Kommentare.

      Code:
      # 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";
      Grüße,
      Julian

      Kommentar


        #4
        Schön, gefällt mir auch echt sehr gut, ich glaube das wird morgen mal meine Beschattung im HS ablösen
        Denn da sind 2J nach dem Einzug wegen dem elendigen geklicke im HS nur 2 von 8 Rolläden umgesetzt.. Das finde ich hier wundervoll: 4 Zeilen, 8 Adressen, fertig..

        - Im Kommentar ganz oben sind lat und lon vertauscht (im Code stimmts)
        - Für das deaktivieren der Sperre könnte man vielleicht noch ein plugin_subscribe machen, damit das sofort wirkt, nicht erst im Zyklus, Kosmetik..

        Makki


        Edit: Perl hat seine Vor&Nachteile, ich kotze darüber unterm Tisch ja auch gerne&oft. Hier äussern sich aber die Vorteile: a) es gibt ein (bzw. vermutlich zig) Astro-PMs für sowas und b) ich kann von sowas ausm cpan in 5 Minuten völlig schmerzfrei ein halbwegs anwendertaugliches .deb machen (dh-make-perl wens interessiert), inklusive Abhängigkeiten..
        EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
        -> Bitte KEINE PNs!

        Kommentar


          #5
          Hi,

          Zitat von makki Beitrag anzeigen
          - Im Kommentar ganz oben sind lat und lon vertauscht (im Code stimmts)
          - Für das deaktivieren der Sperre könnte man vielleicht noch ein plugin_subscribe machen, damit das sofort wirkt, nicht erst im Zyklus, Kosmetik..
          stimmt, gute Einwände.
          Ich hab noch für meinen eigenen Anwendungsfall den Bugfix für das kaputte Busch-Jäger-Interface eingebaut (nach jedem Telegramme 20 millisekunden warten) und das per Konfiguration schaltbar gemacht. Und es gab noch ein paar Zeilen überflüssigen Code aus der Entwicklungszeit.

          Worüber ich grade noch nachgedacht habe, mich im Endeffekt aber entscheiden habe daran nichts zu ändern:
          nach einer Sperre der Automatik, bspw. über Nacht oder über den Winter, geht das Plugin von einem falschen "letzten" Sonnenstand aus. Es fährt also möglicherweise eine eigentlich unbeteiligte Fassade in die "offen"-Position.
          Ich gehe aber davon aus, dass das so ok ist, weil man im Zweifelsfall eine sowieso offene Fassade auffährt (= passiert nix), oder falls die Rolläden geschlossen bleiben sollen, hat man diese sowieso gegen fahren gesperrt. Also: code blieb so.

          Code:
          # 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";
          Bei mir wird das noch ergänzt durch ein zweites Plugin, basierend auf https://knx-user-forum.de/wiregate/8...g-userlog.html das mir die Rolläden frühs und abends selbstständig fährt, und auch das "Hitzeschild" für die Nacht deaktiviert:

          Code:
          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;
          Bei Bedarf könnte man das zweite Plugin jetzt auch auf die Astro-Module umschreiben um eine einheitliche Codebasis zu erhalten.

          Grüße,
          Julian

          EDIT:
          Kleinen Codefehler korrigiert der verhinderte dass die Rolläden sich schlossen. Den passenden Wert für den Einfallswinkel sollte jeder für sich selbst experimentell feststellen (bei mir sinds eher 60° als 45°).

          Kommentar


            #6
            Wunderbar, dann muss ich mir ja doch die Wetterstation nicht mehr aufs Dach basteln :-)

            Lbau

            Kommentar


              #7
              Bislang ist es halt ein rein mathematischer Ansatz - komplett ohne Berücksichtigung von Sensorwerten wie Temperatur oder Lichteinfall.

              Ich denke aber das ließe sich noch relativ einfach nachrüsten, dass man gewisse Grenzwerte für die Außentemperatur hinterlegt (die hat man ja meistens) und bei Überschreiten dann den Sonnenschutz walten lässt.

              Grüße,
              Julian

              Kommentar


                #8
                Erst mal - auf so ein Plugin habe ich schon gewartet!

                Was mir allerdings noch nicht ganz klar ist, ist wann und wieso welcher Rolladen wie weiter verfahren wird, d.h. die Strategie dahinter...

                Ein paar Anmerkungen / Verbesserungen hätte ich noch für den Code:
                • Die genauen Koordinaten lassen sich sehr leicht auf der Web-Seite Get Lat Lon - find the latitude and longitude of a point on a map besimmen
                • Das Ergebnis sollte man in Grad dem Plug-In mitteilen, der Umrechnen in Radiant kann das Plugin übernehmen
                • Ich hätte gerne noch die Möglichkeit GAs anzugeben die die Fahrt nach unten individuell sperren, wenn die Terrassen-Türe offen ist
                TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                Kommentar


                  #9
                  Hi Chris,

                  die Strategie ist folgende:
                  - alle Rolläden zusammen haben insgesamt nur zwei mögliche Positionen: offen und "beschattung"/zu
                  - bei jedem Aufruf wird errechnet, in welchem Winkel die Sonne zum Haus steht (nicht die Höhe der Sonne, sondern "Osten", "OstSüdOst" etc.
                  - jede Fassade eines Hauses und die dazugehörigen Rollläden werden als Gruppe hinterlegt, unter Angabe des Winkels den die Fassade zur Himmelsrichtung "Norden" hat (nicht der Winkel der Fassade selbst, sondern die senkrechte auf die Fassade - also wenn man grade aus einem Fenster rausschaut quasi)

                  Bei jedem Aufruf wird also die Position der Sonne mit den Ausrichtungen der Fassaden/Fenster verglichen - und sobald die Sonne "um die Hausecke rum" (bei mir waren es bis eben 60°, werds wohl noch mal mit 75° probieren) ins Fenster strahlt, wird das Fenster dicht gemacht. Ist die Sonne wieder weg (also um die nächste Hausecke rum) wird wieder aufgemacht.

                  Beantwortet das deine Frage nach der "Strategie"?
                  Wie gesagt, Wettereinflüsse sind noch nicht enthalten, halte ich aber noch für relativ dringend - wenns kühl ist brauch ich keinen Hitzeschutz.

                  Deine Anmerkungen hab ich mir bei der Entwicklung auch überlegt:
                  - Angabe in degree - möglich, habs aus Performancegründen vorher umgerechnet um es nicht bei jedem Aufruf on-the-fly umrechnen zu müssen. Nicht dass die Performance schlecht wäre, aber wenn ich mal auf Anhieb was sehe was man optimieren kann, wieso nicht? Wobei das sicherlich nur ein quäntchen ist, und sobald ich mit meinen usleep() komme wirds eh lächerlich. Von daher - kann man klar auch in degree angeben, dann muss man nur folgendes ersetzen:

                  Code:
                  my $loc = Astro::Coord::ECI->geodetic($lat, $lon, $elev);
                  durch
                  Code:
                  my $loc = Astro::Coord::ECI->geodetic(deg2rad($lat), deg2rad($lon), $elev);
                  - Fahrt nach unten sperren: hatte ich drüber nachgedacht, mich dann aber entschieden das seinzulassen; das würde das Plugin unnötig komplex machen; das Sperren der Abwärtsfahrt eines Rolladen würde ich eher im Aktor hinterlegen - und falls der Aktor das nicht selber kann dann ein eigenes "Proxy"-Plugin für den betreffenden Rolladen basteln das die Sperrung annimmt und die Fahrtbefehle in dem Fall dann "verschluckt". KISS

                  - getlatlon ist mir neu - das ist mainstream-praktisch Hatte garnicht nach sowas gesucht sondern mich einfach kurz mit meinem Garmin auf die Terasse gestellt

                  Grüße,
                  Julian
                  der sich jetzt den Bitumen-Voranstrich aus der Haut waschen geht.

                  Kommentar


                    #10
                    Im Detail ist das Thema Rolläden "in smart" natürlich leider dann doch wieder mal etwas komplexer
                    Was noch einfliessen könnte
                    - Handbedienung
                    - Helligkeit(+Temperatur oder Sommer/Winter)
                    - Szenen (was man auch einfach verschiedene Sperren/Freigaben nennen kann)

                    Ich hab das Thema Rolläden bei mir schon 3x komplett umgebaut, weil ich erstmal nicht wusste, was ich eigentlich will.. (zwar im HS, aber sei jetzt mal egal)

                    Fast schon peinlich, die letzten Tage fahre ich die Beschattung von Hand, weil es einfach nicht passt..

                    Deswegen hab ich mir angeregt von dem Thread gestern mal einen möglichst pragmatischen "Neustart" der ganzen Thematik ausgedacht, ich will nur auch gleich dazuschreiben, wo die möglichen Problemstellen liegen:

                    - Sperre/Zwangsführung ("Terassentür") erfolgt per FK->Aktor. Einfach, sicher, zuverlässig. Wenn das Fenster/Tür aufgeht->Rolladen hoch und niemals wieder runter solange offen, basta, egal welche Logik was sagt.
                    Ungeeignet: Wenn man Beschatten und z.B. Fenster kippen will
                    - Beschattung mit diesem Plugin, modifiziert: %Pos anfahren statt 0/1, da ich nicht ganz runter will; muss natürlich der Aktor können und: Geschmacksfrage
                    - Sperre durch Schlafen-Szene (ich habe zwei derer, eine "grosse" für den letzten/ersten und eine kleine für den Mittagsschlaf usw.)
                    - Aktiviert nur bei >30klux+Freigabe+ATemp>22°, damit erübrigt sich auch das nächtliche Sperren
                    - Allerdings: Verhalten genau wie es jetzt ist: bei Sperre/deaktivierung wird nicht mehr automatisch gefahren (ausser vielleicht durch eine zweite morgens/abends "Zeitschaltuhr).
                    Die Rolläden verbleiben in der letzten Position, basta, sonst wirds kompliziert mit Handbedienung und vor allem bei wolkigem/grenzwertigen Wetter usw.

                    Das grosse Problem dabei ist, wenn man das Thema wirklich zuende denkt, wird man schnell bei so einem "Monster" wie den Rolladenbausteinen von Marc Naroska landen, die dann so kompliziert sind das wieder nichts funktioniert wie man will
                    Und an die Grenzen von Plugins stossen, zumindest was die übersichtlichkeit angeht wenn man kein Programmierer ist...

                    Aber deshalb versuche ichs jetzt mal in einfach..


                    @Netzkind: reichen der USB-SS denn diese 20ms ?? Verwegene Idee: dagegen eine globale Telegrammratenbegrenzung von sagen wir 50 tps für alle USB-IFs einzubauen spricht ja nichts (bei 34-38 ist physikalisch eh Schluss bei TP1)
                    Vielleicht geh ich mit dem Thema mal zu mkoegler, der Workaround (oder wie auch immer man es nennt) gehörte ja eigentlich in den eibd..

                    Makki
                    EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                    -> Bitte KEINE PNs!

                    Kommentar


                      #11
                      Zitat von makki Beitrag anzeigen
                      @Netzkind: reichen der USB-SS denn diese 20ms ??
                      Ich darf ich da nochmal nachhaken Eine Telegrammratenbegrenzung für den eibd bei bestimmten Backends ist nämlich gerade recht nahe..

                      Makki
                      EIB/KNX & WireGate & HS3, Russound,mpd,vdr,DM8000, DALI, DMX
                      -> Bitte KEINE PNs!

                      Kommentar


                        #12
                        Hi makki,

                        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

                        Kommentar

                        Lädt...
                        X