Ankündigung

Einklappen
Keine Ankündigung bisher.

Auf hörende GA schreiben?

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

    [WireGate-Plugin] Auf hörende GA schreiben?

    Moin zusammen,

    ich sitze gerade vor einem Problem und komme nicht weiter. Hoffe mir kann jemand helfen.

    Hintergrund:
    Ich will eine simple Anwesenheitssteuerung realisieren. Diese wird mittels zweier Taster (Schlafzimmer/Haustür) und Präsenzmelder realisiert (diese steuern nur abwesend und anwesend, schlaf wird ausschließlich über Taster geregelt).
    Wird ein Taster gedrückt, ändert sich der Status sofort (anwesend, abwesend, schlaf). Der andere Taster wird dann entsprechend aktualisiert.
    Wird das Plugin zyklisch aufgerufen, werden die Präsenzmelder abgefragt. Sollte sich jemand im Bereich befinden -> anwesend; ist niemand da und der Taster schlaf nicht gedrückt -> abwesend.

    Jetzt habe ich das Problem, dass ich im Plugin auf die hörenden GAs schreibe und hierdurch sich das Plugin endlos selbst aufrufen würde. Wie löse ich das?

    Hier der Code:
    Code:
    # Logik für Anwesenheit
    # Voraussetzungen:
    #  - Taster sind Master (bei Druck sofort auf Abwesenheit / Schlafen bzw. anders herum)
    #  - Status Schlaf wird nur durch Taster aktiviert
    #  - PM melden Anwesenheit bei Änderung auf je eine eigene GA;
    #     bei mehr als 30 Min (Nachlauf im PM eingestellt) keine Bewegung => Abwesenheit
    
    # Kommentieren, um Plugin zu aktivieren
    return;
    
    # Variablen
    my @PM_GA=("12/0/0", "12/0/10"); # PM, die den Status ändern dürfen, z.B. Küche etc.
    my $anwesenheit_GA="0/0/254"; # (dpt 2, 00: anwesend; 01: schlafen, 10: abwesend, 11: spare)
    my $taster_schlaf_GA="12/1/0";
    my $taster_weg_GA="12/1/12";
    my $status=undef;
    
    # Aufrufzyklus auf 5 Min setzen
    $plugin_info{$plugname.'_cycle'} = 300;
    
    
    # Plugin an Taster GAs anmelden, um bei Änderungen aufgerufen zu werden
    $plugin_subscribe{$taster_schlaf_GA}{$plugname} = 1;
    $plugin_subscribe{$taster_weg_GA}{$plugname} = 1;
    
    
    # Überprüfen, ob Plugin wg. Tastendruck (Schlaf od. Abwesenheit) aufgerufen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write")
    {
     # Taster schlaf gedrückt?
     if ($msg{'dst'} eq ($taster_schlaf_GA))
     {
      # Status abfragen und auf den Bus senden
      if (int ($msg{'data'}) == 1) 
       {
        knx_write($anwesenheit_GA,01,2); # Status Schlaf
        knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
        $status="01";
       }
       else
       {
        knx_write($anwesenheit_GA,00,2); # Status Anwesend
        knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
        $status="00";
       }
     }
    
     # Taster weg gedrückt?
     if ($msg{'dst'} eq ($taster_weg_GA))
     {
      # Statusänderung abfragen und auf den Bus senden
      if (int ($msg{'data'}) == 1) 
       {
        knx_write($anwesenheit_GA,10,2); # Status Abwesend
        knx_write($taster_schlaf_GA,0,1);# Taster Schlaf aktualisieren
        $status="10";
       }
       else 
       {
        knx_write($anwesenheit_GA,00,2); # Status Anwesend
        knx_write($taster_schlaf_GA,0,1); # Taster Schlaf aktualisieren
        $status="00";
       }
     }
    }
    
    if ($status == undef)
     { 
     # Da beide Taster nicht gedrückt wurden, zyklische Abfrage der PM
     # Hierdurch wird sichergestellt, dass der korrekte Status auch ohne Tastendruck gemeldet wird
    
     # Prüfen, ob irgendeine Bewegung im Haus
     my $anwesenheit = 0;
     $anwesenheit+=knx_read(_$,300,1) for (@PM_GA);
    
    
     # Auswertung der PM 
     if ($anwesenheit!=0) # Bewegung im Haus
      {
       knx_write($anwesenheit_GA, 00, 2); # Status Anwesend
       knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
       knx_write($taster_schlaf_GA,0,1); # Taster schlaf aktualisieren
       $status="00";
      }
      elsif (knx_read($taster_schlaf_GA,300,1)==0)# keine Bewegung und Taster schlaf nicht gedrückt
      {
       knx_write($anwesenheit_GA,10,2); # Status abwesend
       knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
       knx_write($taster_schlaf_GA,0,1); # Taster schlaf aktualisieren
       $status="10";
      }
     }
    return $status;

    Danke,
    Grüße!

    EDIT:
    1. Aufrufzyklus angepasst
    2. Syntax Abfrage der PM geändert (@PM_GA)

    #2
    Nachbrenner:
    Kann ich den Status im Wiregate speichern (GA 0/0/254 im obigen Beispiel) oder wo lege ich den Anwesenheitsstatus sinnvoll ab? Habe nur Taster (B.IQ), PM (MDT) und Heizungsaktoren (ebenfalls MDT)...

    Grüße

    Kommentar


      #3
      Hallo

      Wiso beschreibst du die höhrende Adresse? Da ergibt für mich etwas keinen Sinn. Vor allem auch wesshalb du zyklisch die PM abfragst... Du kannst ja auch auf die GA der PM's reagieren. Wenn sich da tagelang nichts tut weil alle in den Ferien sind muss doch nicht alle 30 Sekunde gepollt werden oder?
      Gruss Patrik alias swiss

      Kommentar


        #4
        Zitat von swiss Beitrag anzeigen
        Du kannst ja auch auf die GA der PM's reagieren.
        Das stimmt allerdings. Guter Punkt, werde ich ändern.

        Zitat von swiss Beitrag anzeigen
        Wiso beschreibst du die höhrende Adresse?
        Der Status soll auf dem Bus verfügbar sein, da mehrere Geräte auf diesen zugreifen. Daher wollte ich die Kombination der beiden Taster nutzen (Taster 1 == 1 -> Schlaf, Taster 2 == 1 -> Abwesend, beide == 0 -> Anwesend). Mir ist sonst nichts eingefallen, wie ich den Status sinnvoll ablegen kann. Daher muss ich aber zwangsläufig die Taster ansprechen.
        Bsp:
        Ich verlasse das Haus und drücke den Taster --> Abwesend.
        Bei Rückkehr meldet sich ein PM --> Anwesend, Taster auf Wert 0 ändern.

        Ähnliches Szenario beim Schlafen...

        Wie löst ihr das denn? iButtons haben wir nicht und sind (für uns) auch nicht praktikabel...

        Grüße!

        Kommentar


          #5
          Diese Kombination ist doch völlig kompliziert:

          Wenn ich Schlafe dann ist auch jemand zu Hause. -> Taster Abwesend uninteressant.
          Wenn ich nicht zu Hause bin dann schlafe ich auch nicht dort. -> Taster Schlafen uninteressant.

          Davon ab, man braucht den Status nicht alle 30s auf dem Bus. Ich bin zwar auch ein Freund von zyklischen Telegrammen aber da reicht auch alle 5 Minuten.
          Umgezogen? Ja! ... Fertig? Nein!
          Baustelle 2.0 !

          Kommentar


            #6
            Zitat von JuMi2006 Beitrag anzeigen
            Davon ab, man braucht den Status nicht alle 30s auf dem Bus. Ich bin zwar auch ein Freund von zyklischen Telegrammen aber da reicht auch alle 5 Minuten.
            Das habe ich nur zu Testzwecken gesetzt und vergessen das vorm Posten zu ändern. Bitte da nicht dran stören, wird geändert.

            Zitat von JuMi2006 Beitrag anzeigen
            Diese Kombination ist doch völlig kompliziert:

            Wenn ich Schlafe dann ist auch jemand zu Hause. -> Taster Abwesend uninteressant.
            Wenn ich nicht zu Hause bin dann schlafe ich auch nicht dort. -> Taster Schlafen uninteressant.
            Ok, verstanden. Folgendes Beispiel:
            Gehe zur Arbeit (Notfall, also nicht planbar) und drücke Taste -> Status Abwesend.
            Jetzt komme ich wieder nach Hause und gehe in die Küche (ohne Tastendruck, wie oben erläutert). Die WW-Zirkulation (als Beispiel) soll jetzt natürlich nur laufen, wenn auch jemand zu Hause ist. Wen fragt die Zirkulation nach dem Status? Taster Abwesend meldet 'keiner da', aber ein Präsenzmelder schon. Also muss ich vor jedem Pumpenlauf alle in Frage kommenden Delinquenten rufen.
            Daher kam ich auf die Idee den Status möglichst nur an einer Stelle abzulegen. Keine Bivalenzen, nur zwei Telegramme. Anders rum, wenn der Taster 'weg' meldet, ist auch wirklich keiner zuhause.

            Wahrscheinlich macht es wirklich Sinn den Status im Wiregate als Plugin Variable abzulegen. Andere Plugins können da ohne Bus drauf zugreifen und ein Plugin 'MeldeHausStatus' kann bei Busanfrage eines KNX Gerätes drauf antworten. Dann spare ich mir auch den zyklischen Aufruf...

            Grüße!

            Kommentar


              #7
              Und wiso löst du dies nicht anders?...

              Taster Abwesend sendet eine 1 an die abwesend GA. Das Plugin wird getriggert und sendet die Befehle für abwesend wie(ZentralAUS, Heizung Nacht, WW Zirkulation AUS usw...)

              Taster Abwesend sendet eine 0 an die GA und das Plugin Triggert. Dabei werden diegleichen Befehle ausgeführt wiewennderPM readiert (ODER Schaltung)

              PM erkennt Bewegung und sendet an seine "bewegung" GA. Das Plugin triggert und liest den Zustand des "schlafen" Taster direkt vom BUS/eibd Cache. Ist dieser 0, sendet das Plugin eine 0 an die GA des abwesend Taster und führt die Befehle für anwesend (Heizung auf Komfort, WW Zirkulation EIN usw...) aus. Ansonsten bei "schlafen = 1" wird der Befehl ignoriert.

              Taster "schlafen" sendet eine 1 an die schlafen GA. Das Plugin triggert und führt die Befehle für schlafen aus (ZentralAUS, Heizung Nacht, Zirkulation AUS usw...)

              Taster "schlafen" sendet eine 0 an die schlafen GA. Das Plugin triggert und führt die Befehle für "schlafen = 0" aus.

              Da braucht es keinerlei Zyklus und auch kein zwischenspeichern von Zuständen... Auch braucht es hier keine höhrende Adressen. Oder habe ich da was falsch verstanden?
              Gruss Patrik alias swiss

              Kommentar


                #8
                Auf die Idee das Ganze mit drei getrennten Plugins zu lösen (Abwesend, Schlafen, Bewegung_PM) bin ich in der Tat noch nicht gekommen. Thx!

                Letzte Verständnisfrage:
                Taster Abwesend hat ne 1 gesendet und das Plugin 'Abwesend' die ganzen Befehle ausgeführt. Jetzt komme ich nach Hause und ein PM schreibt ne 1 auf den Bus. Dann prüft das Plugin 'Bewegung_PM', ob die Schlaf Taste gedrückt ist und sendet dann eine 0 (da niemand schläft) auf den Anwesend Taster. Hierdurch wird doch dann wieder das Plugin 'Abwesend' aufgerufen und die ganzen Befehle ausgeführt oder?
                Ergo: Alles was geschaltet werden muss kommt in Abwesend.pl und Schlaf.pl, in Bewegung_PM.pl kommt nur die Prüfung ob Bewegung und ob Schlaf?!

                Grüße

                Kommentar


                  #9
                  Das kann alles in 1 Plugin, dass auf 3 GA's höhrt, gelöst werden. Ist auch einfacher in der Handhabung.

                  Wenn das Plugin auf eine GA sendet, wird es nicht durch sein eigenes schreiben auf eine GA getriggert.

                  Exemplarisch so:

                  Code:
                  $plugin_info{$plugname.'_cycle'} = 86400; #zyklus 1x pro Tag zum anmelden der GA's
                  
                  $plugin_subscribe{$GA_schlafen_taster}{$plugname} = 1;
                  $plugin_subscribe{$GA_abwesend_taster}{$plugname} = 1;
                  $plugin_subscribe{$GA_PM}{$plugname} = 1;
                  
                  If( $msg('acpi') == "A_Groupvalue_Wirte"){
                      if( $msg('dest') == $GA_PM){
                          $status_schlafen = knx_read(GA_schlafen,300,1.001);
                      
                           if( $status_schlafen == 0){
                               if($plugin_info{$plugname.'_zustand_anwesend'} == 0){
                                    knx_write(GA_abwesend_taster,0,1.001);
                                    anwesend;
                                    $plugin_info{$plugname.'_zustand_anwesend'} = 1;
                                }
                           }
                      }elsif( $msg('dest') == $GA_schlafen_taster{
                           if( $msg('value') == 0){
                               knx_write(GA_abwesend_taster,0,1.001);
                               $plugin_info{$plugname.'_zustand_anwesend'} = 1;
                               anwesend;
                           }else{
                               $plugin_info{$plugname.'_zustand_anwesend'} = 0;
                               schlafen;
                           }
                      }elsif( $msg('dest') == $GA_abwesend_taster{
                           if( $msg('value') == 0){
                               knx_write(GA_schlafen_taster,0,1.001);
                               $plugin_info{$plugname.'_zustand_anwesend'} = 0;
                               anwesend;
                           }else{
                               $plugin_info{$plugname.'_zustand_anwesend'} = 1;
                               abwesend; #sub abwesend
                           }
                  }
                  
                  
                  sub anwesend{
                       #befehle für Tag/anwesend
                  }
                  
                  sub abwesend{
                      #befehle für abwesend
                  }
                  
                  sub schlafen{
                      #befehle für schlafen
                  }
                  Ist rein exemplarisch uns so nicht ganz lauffähig. Soll aber das Prinzip zeigenen

                  EDIT: Ok ganz ohne remanenten Zustandspeicher geht es nicht Ist im Beispiel oben eingeflossen
                  Gruss Patrik alias swiss

                  Kommentar


                    #10
                    EDIT:
                    Sobald ich eine GA beschreibe, wird das Plugin aufgerufen. In deinem Beispiel (genau wie bei meinem) werden also ununterbrochen die TasterGAs mit 0 beschrieben...Gerade nochmal getestet. Wenn ich aber den '_zustand_anwesend' zuerst abfrage müsste die Schleife aufhören...Ich probiers kurz aus.

                    Kommentar


                      #11
                      Stimmt. Das senden der 0 könnte man hinter die prüfung des Zustandspeichers verlegen. Die Frage ist wiso du Rekursionen bekommst??? Da ist nochetwas anderes faul. Wie hast du denndas Plugin nun aktuell? Die mein Beispielist ja sonicht lauffähig. Denn manchmal kommt es auf Feineiten an wie das überprüfen ob es wirklich ein Schreibbefehl und nicht ein Lesebefehl ist der das Plugin aufruft usw...

                      Welche GA's beschreibst du denn jetzt genau und welche GA's sind am Plugin angemeldet?
                      Gruss Patrik alias swiss

                      Kommentar


                        #12
                        Im Moment scheint das Ganze einigermaßen zu laufen. Habe aber noch nicht alle Testfälle durch.

                        Ich beschreibe die beiden Taster und den '_Zustand_Anwesend'.
                        Das Plugin lauscht auf eben diesen Tastern und den PMs.

                        Hier die aktuelle Version. Rekursionen habe ich bis jetzt keine mehr, aber mein Gefühl sagt mir, dass da noch nicht alle Fälle korrekt abgebildet sind. Muss morgen weiter prüfen...

                        Code:
                        # Logik für Anwesenheit
                        # Voraussetzungen:
                        #  - Taster sind Master (bei Druck sofort auf Abwesenheit / Schlafen bzw. anders herum)
                        #  - Status Schlaf wird nur durch Taster aktiviert
                        #  - PM melden Anwesenheit bei Änderung auf je eine eigene GA;
                        #     bei mehr als 30 Min (Nachlauf im PM eingestellt) keine Bewegung => Abwesenheit
                        
                        # Kommentieren, um Plugin zu aktivieren
                        # return;
                        
                        # Variablen
                        my @PM_GA=('12/0/0', '12/0/10'); # PM, die den Status ändern dürfen, z.B. Küche etc.
                        my $anwesenheit_GA="0/0/254"; # (dpt 2, 00: anwesend; 01: schlafen, 10: abwesend, 11: spare)
                        my $taster_schlaf_GA="12/1/0";
                        my $taster_weg_GA="12/1/12";
                        my $status=undef;
                        
                        # Aufrufzyklus auf 0 Min setzen, Plugin wird durch GA aufgerufen
                        $plugin_info{$plugname.'_cycle'} = 0;
                        
                        # Plugin an Taster und PM GAs anmelden, um bei Änderungen aufgerufen zu werden
                        $plugin_subscribe{$taster_schlaf_GA}{$plugname} = 1;
                        $plugin_subscribe{$taster_weg_GA}{$plugname} = 1;
                        for $_ (@PM_GA) {$plugin_subscribe{$_}{$plugname} = 1;}
                        
                        # Überprüfen, ob Plugin wg. Schreibtelegramm aufgerufen wurde
                        if ($msg{'apci'} eq "A_GroupValue_Write")
                        {
                         SELECT:
                         {
                         # Taster schlaf gedrückt?
                         if ($msg{'dst'} eq ($taster_schlaf_GA))
                         {
                          # Status abfragen und auf den Bus senden
                          if (int ($msg{'data'}) == 1) 
                           {
                            knx_write($anwesenheit_GA,01,2); # Status Schlaf
                            knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
                            $plugin_info{$plugname.'_Zustand_Anwesend'}=1;
                            $status="01";
                           }
                           elsif ($plugin_info{$plugname.'_Zustand_Anwesend'}==1)
                            {
                             knx_write($anwesenheit_GA,00,2); # Status Anwesend
                             #knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
                             $status="00";
                             #$plugin_info{$plugname.'_Zustand_Anwesend'}=1;
                            }
                          last SELECT;
                         }
                        
                         # Taster weg gedrückt?
                         if ($msg{'dst'} eq ($taster_weg_GA))
                         {
                          # Statusänderung abfragen und auf den Bus senden
                          if (int ($msg{'data'}) == 1)
                          {
                            knx_write($anwesenheit_GA,10,2); # Status Abwesend
                            knx_write($taster_schlaf_GA,0,1);# Taster Schlaf aktualisieren
                            $status="10";
                            $plugin_info{$plugname.'_Zustand_Anwesend'}=0;
                           }
                           elsif (($plugin_info{$plugname.'_Zustand_Anwesend'})==0)
                           {
                            knx_write($anwesenheit_GA,00,2); # Status Anwesend
                            knx_write($taster_schlaf_GA,0,1); # Taster Schlaf aktualisieren
                            $status="00";
                            $plugin_info{$plugname.'_Zustand_Anwesend'}=1;
                           }
                           last SELECT;
                         }
                        
                         # Abfrage der PM
                         if ( grep /^$msg{'dst'}$/, @PM_GA )
                         {
                          my $anwesenheit = 0;
                          for $_ (@PM_GA) {$anwesenheit += knx_read($_,300,1);}
                          if ($anwesenheit!=0) # && ($plugin_info{$plugname.'_Zustand_Anwesend'})!=1 )# Bewegung gemeldet?
                           {
                            knx_write($anwesenheit_GA, 00, 2); # Status Anwesend
                            knx_write($taster_weg_GA,0,1); # Taster weg aktualisieren
                            knx_write($taster_schlaf_GA,0,1); # Taster schlaf aktualisieren
                            #$status="00";
                            #$plugin_info{$plugname.'_Zustand_Anwesend'}=1;
                           }
                          elsif (knx_read($taster_schlaf_GA,300,1)==0) # keine Bewegung und Taster schlaf nicht gedrückt
                           {
                            knx_write($anwesenheit_GA,10,2); # Status abwesend
                            knx_write($taster_weg_GA,1,1); # Taster weg aktualisieren
                            #knx_write($taster_schlaf_GA,0,1); # Taster schlaf aktualisieren
                            #$status="10";
                            #$plugin_info{$plugname.'_Zustand_Anwesend'}=0;
                           }
                          }
                         }
                         return $status;
                        }

                        Kommentar

                        Lädt...
                        X