Ankündigung

Einklappen
Keine Ankündigung bisher.

Neues Plugin: Anwesenheitssimulation

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [WireGate-Plugin] Neues Plugin: Anwesenheitssimulation

    Hallo zusammen,
    auf Wunsch (siehe dieser Thread) habe ich mal eine Anwesenheitssimulation als Wiregate-Plugin zusammengehackt. Wie immer "ohne Gewehr" :-)

    Folgender Disclaimer: es handelt sich um einen Quick Hack, auch um zu zeigen, wie schön Perl doch ist, wenn es um Quick Hacks geht :-)

    Ich selbst brauche keine Anwesenheitssimulation, deshalb bittet mich nicht um eure 10.000 Wunschfeatures. Wer das Plugin erweitern will - be my guest, aber beachtet die GPL und postet das verbesserte Plugin hier bzw. im SVN.

    Das Ganze funktioniert so: das Plugin Anwesenheitssimulation abonniert eine einzige GA (im Skript festgelegt, extra dafür wollte ich kein .conf-File schreiben). Diese GA sollte (wie immer) in der eibga.conf hinterlegt sein und DPT-Typ 1 haben (wie ein Schalter: an/aus).

    Wird die Anwesenheitssimulation über die GA angeschaltet (Telegrammwert 1), so erzeugt sie ein neues Plugin aus der eib.log. Das neue Plugin wird danach vom Wiregate-Daemon ausgeführt und wiederholt einfach die Telegramme, die im eib.log gefunden wurden. (Beispielhaft steht im Skript auch drin, wie man bestimmte GAs ausfiltern kann).

    Wird die Anwesenheitssimulation über die GA ausgeschaltet (Telegrammwert 0), so löscht sie das erzeugte Plugin wieder.

    Und hier das Skript, wie immer auch im SVN zu finden:

    Code:
    #!/usr/bin/perl -w                                                                                                                                 
    ##########################                                                                                                                         
    # Anwesenheitssimulation #                                                                                                                         
    ##########################                                                                                                                         
    # Wiregate-Plugin                                                                                                                                  
    # (c) 2012 Fry under the GNU Public License                                                                                                        
    
    #$plugin_info{$plugname.'_cycle'}=0; return 'deaktiviert';                                                                                         
    
    # Aufrufgrund ermitteln                                                                                                                            
    my $event=undef;
    if (!$plugin_initflag)
    { $event='restart'; } # Restart des daemons / Reboot                                                                                               
    elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'})
    { $event='modified'; } # Plugin modifiziert                                                                                                        
    elsif (%msg) { $event='bus'; } # Bustraffic                                                                                                        
    elsif ($fh) { $event='socket'; } # Netzwerktraffic                                                                                                 
    else { $event='cycle'; } # Zyklus                                                                                                                  
    
    # eine Gruppenadresse zum Starten und Stoppen. Diese ist vom Typ DPT 1 (An/Aus)                                                                    
    $plugin_subscribe{'1/2/0'}{$plugname}=1;
    
    # kein regelmaessiger Aufruf                                                                                                                       
    $plugin_info{$plugname.'_cycle'}=0;
    
    # Nur auf Bustraffic reagieren                                                                                                                     
    return unless $event=~/bus/ && $msg{apci} eq "A_GroupValue_Write";
    my $in=int($msg{value});
    
    # Name des Simulationsskriptes                                                                                                                     
    my $simscript="/etc/wiregate/plugin/generic/Anwesenheitssimulationsskript.pl";
    
    unless($in) { system "rm", "-f", $simscript; return "Anwesenheitssimulation gestoppt"; }
    
    # Start Anwesenheitssimulation: einfach ein neues Plugin aus eib.log erzeugen, der wiregate-Daemon fuehrt es dann aus                              
    open SIM, ">$simscript";
    
    my $line=1;
    
    print SIM <<EOF;
    #!/usr/bin/perl -w                                                                                                                                 
    
    \$plugin_info{\$plugname.'_line'}=1 unless defined \$plugin_info{\$plugname.'_line'};
    
    given(\$plugin_info{\$plugname.'_line'}) {
    when($line) {
    EOF
    
    my $time=`/bin/date +%X`; $time=~/^([0-9][0-9])\:([0-9][0-9])\:([0-9][0-9])/; my ($h,$m,$s)=($1,$2,$3);
    my $lastdaynum=undef;
    
    open IN, "</var/log/eib.log";
    
    $/="\n";
    
    while($_=<IN>)
    {
        chomp;
    
        next unless /^([0-9][0-9][0-9][0-9])\-([0-9][0-9])\-([0-9][0-9]) ([0-9][0-9])\:([0-9][0-9])\:([0-9][0-9])[^,]*,[^,]*,[^,]*,([0-9]+\/[0-9]+\/[0\
    -9]+),[^,]*,([^,]*),[^,]*,([^,]*),.*$/;
    
        my ($year, $month, $day, $hour, $min, $sec, $ga, $val, $dpt)=($1, $2, $3, $4, $5, $6, $7, $8, $9);
        $val="'$val'" if $dpt=~/^16/;
    
        # Alle Telegramme auf manchen Hauptgruppen ausfiltern                                                                                        
        next if $ga=~m!^(5|6)/0!;
    
        my $daynum=365*$year; $year-- if $month<=2; $daynum+=int($year/4) - int($year/100) + int($year/400);
    
        my $delta = (defined $lastdaynum) ? $daynum-$lastdaynum : 0;
        $lastdaynum=$daynum;
        $delta=(($delta*24+($hour-$h))*60+($min-$m))*60+($sec-$s);
        next if $delta<0;
        ($h,$m,$s)=($hour,$min,$sec);
    
        if($delta>0)
        {
            $line++;
        print SIM <<EOF;
    \$plugin_info{\$plugname.'_cycle'}=$delta; }
    when($line) {
    EOF
        }
    
        print SIM <<EOF;
    # $_                                                                                                                                               
    knx_write('$ga', $val, $dpt);
    EOF
    
    }
    close IN;
    
    
    print SIM <<EOF;
    }
    
    }
    
    default { \$plugin_info{\$plugname.'_line'}=1; }
    }
    
    \$plugin_info{\$plugname.'_line'}++;
    
    return \$plugin_info{\$plugname.'_line'}-1;
    
    EOF
    
    close SIM;
    
    return "Anwesenheitssimulation gestartet";
    Bitte holt das Plugin aus dem SVN - dort stehen ggf. neuere Versionen.

    Have fun!

    VG, Fry

    #2
    Genial.
    Wie machst du das alles nebenher?
    Und dann noch ohne Eigennutzen!

    Wow
    DANKE!

    Kommentar


      #3
      Zitat von henfri Beitrag anzeigen
      Wie machst du das alles nebenher?
      Und dann noch ohne Eigennutzen!
      Danke henfri!

      War gestern abend eine Sondersituation. Das Plugin ist übrigens zu 80% erstmal auf der Kommandozeile (perl -e) entstanden. Erst als die Simulation lief, hab ich es in ein File kopiert, die GA-subscription usw ergänzt.

      So einfach ist das mit Perl. Macht das mal in Python...

      VG, Fry

      PS. Wofür braucht man nochmal einen Homeserver?

      Kommentar


        #4
        Zitat von Fry Beitrag anzeigen
        PS. Wofür braucht man nochmal einen Homeserver?
        Das Frage ich mich seit dem du hier aktiv bist auch
        Mit freundlichen Grüßen
        Niko Will

        Logiken und Schnittstelle zu anderen Systemen: smarthome.py - Visualisierung: smartVISU
        - Gira TS3 - iPhone & iPad - Mobotix T24 - ekey - Denon 2313 - Russound C5 (RIO over TCP Plugin) -

        Kommentar


          #5
          oh man sowas nennst du nen "Quick Hack". Bei mir wäre das ein "14 Tage Urlaub/24h Hack"
          Steh aber auch erst am Anfang mit Perl.

          Jedenfalls kann ich dem nur bei plichten, das seid dem du ein paar Plug-Ins geschrieben hast, ich meine Kaufentscheidung vom HS zum Wiregate geschwenkt habe. Bzw. ich werd es wohl die Tage auch bestellen.
          Bis jetzt spiel ich mit den Plug-Ins immer im Communitygate.

          Wie genau/ oder welche GA's filterst du denn hier aus.
          Code:
          # Alle Telegramme auf manchen Hauptgruppen ausfiltern                                                                                          
              next if $ga=~m!^(5|6)/0!;

          Kommentar


            #6
            Im genannten Beispiel wären alle GAs "5/0/*" und "6/0/*" ausgefiltert.
            VG, Fry

            Kommentar


              #7
              Alle klar! Danke.
              ...nicht das nachher noch das "Rolladen Rodeo" losgeht

              Kommentar


                #8
                Habe gerade die Zeile mit dem Ausfiltern noch nach oben geschoben - das verbessert die Codequalität des erzeugten Skriptes.
                VG, Fry

                Kommentar


                  #9
                  Zitat von Fry Beitrag anzeigen
                  So einfach ist das mit Perl. Macht das mal in Python...
                  Full Ack
                  <flamewar>da geht es einfacher und schöner lesbar/schreibbar</flamewar>

                  Friedliche Grüße

                  Marcus

                  Kommentar


                    #10
                    Wie kommt es eigentlich, dass die Forumssoftware aus Python einen Link nach Python Programming Language &ndash; Official Website bastelt, aber nicht aus Perl einen Link nach The Perl Programming Language - www.perl.org ?

                    Wäre schön, wenn das mal jemand fixen könnte...

                    (ok, es mag Wichtigeres geben)

                    Fry

                    Kommentar


                      #11
                      Wegen des Homeservers
                      Umgezogen? Ja! ... Fertig? Nein!
                      Baustelle 2.0 !

                      Kommentar


                        #12
                        Irgendjemand hat's gefixt. Perl Perl Perl Perl. Danke!
                        Fry

                        Kommentar


                          #13
                          Neue Version im SVN. Die alte hatte einen Bug, der dazu fuehrte, dass nur ein Tag simuliert wurde und nicht die gesamte eib.log. Jetzt sollte das ok sein.
                          VG, Fry

                          Kommentar


                            #14
                            Hallo zusammen

                            Ich habe gestern das Plugin "Anwesenheitssimulation.pl" komplett neu geschrieben und neu ins SVN eingestellt. Das neue Plugin ist wesentlich robuster gegen Störeinflüsse und ist auch besser getestet (dennoch wie immer "ohne Gewähr").

                            Hier eine kurze Beschreibung der (neuen) Funktionsweise:

                            Voraussetzung: im Webmin (http://wiregateXXX:10000) unter System->Logdatei-Rotation, dort "eib.log" anklicken und einstellen Rotationszeitplan = WÖCHENTLICH und Maximale Größe = 15M oder mehr. Sinn und Zweck ist dabei, eine gesamte Woche des KNX-Busprotokolls einzufangen, aus dem später die Anwesenheitssimulation extrahiert werden kann. Ich _empfehle_ ferner, für eib.log die Komprimierung auszuschalten. Das spart Zyklen im Plugin.

                            Ach ja, mindestens Wiregate-PL32 ist auch erforderlich.

                            Das Plugin Anwesenheitssimulation.pl enthält einen sehr kurzen Abschnitt oben im File, in dem alle konfigurierbaren Parameter enthalten sind.

                            * $source ist entweder eib.log.1, eib.log.2 oder ein anderes eib.log-Archiv... Auch eib.log selbst sollte funktionieren, ich empfehle aber eine der Archivdateien (also bspw eib.log.1), weil die einen gesamten Zyklus (eine Woche) enthalten (natürlich nur falls die o.g. Optionen im Webmin bereits seit entsprechend langer Zeit aktiv sind).

                            * $erzeugen ist eine KNX-Gruppenadresse (GA) vom DPT-Typ 1, die das Plugin Anwesenheitssimulation.pl abonniert. Wird auf diese GA eine 1 gesendet, so erzeugt Anwesenheitssimulation.pl aus dem Sourcefile $source ein zweites Plugin namens "AnwSimSkript.pl", das die erste Woche aus $source nach Licht- und Jalousiekommandos filtert und diese endlos wiederholt abspielt. AnwSimSkript.pl wird dabei in /etc/wiregate/plugin erzeugt, ist also bei Erzeugung noch NICHT aktiv.

                            * $starten ist eine KNX-Gruppenadresse (GA) vom DPT-Typ 1, die das Plugin Anwesenheitssimulation.pl abonniert. Wird auf diese GA eine 1 gesendet, so wird das oben erzeugte AnwSimSkript.pl von /etc/wiregate/plugin nach /etc/wiregate/plugin/generic kopiert, wird also aktiv. Ab dann werden also zyklisch Telegramme für Licht und Jalousien erzeugt. Dabei achtet AnwSimSkript darauf, dass die Telegramme an dem Wochentag und der Uhrzeit gesendet werden, wo sie auch in der Vorlage $source vorkamen. (das ist wesentlich für eine überzeugende Simulation) Wird auf die GA $starten eine 0 gesendet, so wird /etc/wiregate/plugin/generic/AnwSimSkript.pl wieder gelöscht und der Spuk somit beendet.

                            * @gafilter ist schlichtweg eine Liste der GAs, die in die Anwesenheitssimulation aufgenommen werden sollen. Diese Liste erzeugt man am besten durch einen kleinen Trick, zum Beispiel nimmt
                            Code:
                            my @gafilter=grep m!^(6/2/|6/3/)!, keys %eibgaconf;
                            alle GAs der Haupt/Mittelgruppen 6/2 und 6/3 in die Simulation auf. Empfehlenswert ist es übrigens, nur Licht und Jalousien aufzunehmen!

                            * $use_shorts setzt man am besten auf 0, es sei denn, man verwendet das gleiche GA-Namensschema wie ich: bei mir haben alle GA Namen, die im ersten Wort (Zeichen bis zum ersten Space) eine EINDEUTIGE Kennzeichnung enthalten. Weil das bei mir so ist, kann ich den @gafilter oben einfach so definieren:
                            Code:
                            my @gafilter=grep /^(LI|LD|JA|JS|JP)\S*$/, keys %eibgaconf;
                            Damit sind alle Lichtschalt- und -dimmaktionen, alle Jalousie auf/ab, stop und Positionierungsbefehle drin und sonst nichts.

                            Das war's bezüglich der Konfiguration!

                            Anwesenheitssimulation schreibt für jede Aktivität etwas in /var/log/wiregate_plugin.log, damit man sich nicht wundert, wo der Traffic herkommt...

                            Ich freue mich über Erfolgsmeldungen sowie Verbesserungen und auch Bugreports. Hauptsache, jemand findet es nützlich.

                            Have fun!
                            Fry

                            Kommentar


                              #15
                              Edit: da war noch ein kleiner aber kritischer Bug drin. Korrigiert.
                              Fry

                              Kommentar

                              Lädt...
                              X