Ankündigung

Einklappen
Keine Ankündigung bisher.

GAs abonnieren und an die Shell übergeben

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

    [wiregate] GAs abonnieren und an die Shell übergeben

    Hallo,

    ich habe ein Plugin geschrieben, das auf den KNX-Bus lauscht und immer, wenn bestimmte GAs über den Draht schwirren, diese GAs an ein anderes Programm weiter gibt, in diesem Beispiel an 'echo'.

    Es ist als allgemeines Plugin für alle Fälle gedacht, in denen Daten aus dem Bus an die Shell resp. ein Programm resp. ein Script übergeben werden sollen.

    Könntet ihr mal drauf schauen, ob das so passt, auch mit mehreren (>50) GAs einigermaßen performant ist und ob ich sonst was übersehen habe? Das Script scheint zu funktionieren, aber ich habe kaum Perl-Kenntnisse und hab das so gut wie es ging (dieser Thread hier war eine große Hilfe!) zusammen gefrickelt.

    Code:
    $plugin_info{$plugname.'_cycle'} = 86400;
    
    #####################################################################
    # Definitions
    #####################################################################
    my $GA_Data;
    
    # List all GAs here
    my @GA_Array;
    push @GA_Array, { GA => "0/5/201" };
    push @GA_Array, { GA => "0/5/203" };
    push @GA_Array, { GA => "0/5/205" };
    push @GA_Array, { GA => "0/5/207" };
    
    
    #####################################################################
    # Read GAs
    #####################################################################
    
    foreach my $element (@GA_Array) {
        my $GA_Variable = ($element->{GA});
        
        # Subscribe this GA = actively listen for messages from this GA
        $plugin_subscribe{$GA_Variable}{$plugname} = 1;
    
        # If this GA is coming in then...
        if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $GA_Variable) {
        
            # ...decode the supplied data from this GA
            $GA_Data = decode_dpt14($msg{'data'});
            
            # Hand over this data to the shell
            system("echo $GA_Variable - $GA_Data >> /root/test.log");
        }
    }
    
    return 0;
    Zuletzt geändert von wuestenfuchs; 29.10.2015, 15:36.
    "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

    #2
    Ungetestet weil ich lange kein Perl mehr in der Hand hatte und auch kein WireGate mehr habe:

    - Wozu das Array - Liste reicht.
    - DPT wird aus der eibga.conf ausgelesen, bei Dir ist er festprogrammiert.

    Wenn man will bekommt man den Code sicherlich noch kürzer, aber so sieht man noch ganz gut was er macht.
    Code:
    $plugin_info{$plugname.'_cycle'} = 86400;
    
    #####################################################################
    # Definitions
    #####################################################################
    my $GA_Data;
    my $dpt;
    
    # List all GAs here
    my @GA_Liste = ("0/5/201","0/5/203","0/5/205","0/5/207");
    
    #####################################################################
    # Read GAs
    #####################################################################
    
    foreach my $element (@GA_Liste) {
        # Subscribe this GA = actively listen for messages from this GA
        $plugin_subscribe{$element}{$plugname} = 1;
    
        # If this GA is coming in then...
        if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $element) {
            
            #dpt bestimmen:
            $dpt = $eibgaconf{$element}{'DPTSubId'};
            
            # ...decode the supplied data from this GA
            $GA_Data = decode_dpt($msg{'data'},$dpt);
            
            # Hand over this data to the shell
            system("echo $element - $GA_Data >> /root/test.log");
        }
    }
    
    return 0;

    EDIT:
    Ganz so fein ist das aber auch nicht ... da sollte man noch geschickter mit if/else umgehen um nicht jedes mal zu subscriben...macht aber nix.

    Zuletzt geändert von JuMi2006; 30.10.2015, 15:24.
    Umgezogen? Ja! ... Fertig? Nein!
    Baustelle 2.0 !

    Kommentar


      #3
      Was wäre denn ressourcenschonender... die DPT automatisch bestimmen zu lassen, oder fest vorzugeben - oder macht das keinen großen Unterschied?

      Beispiel für eine feste Vorgabe:

      Code:
      $plugin_info{$plugname.'_cycle'} = 86400;
      
      #####################################################################
      # Definitions
      #####################################################################
      my $GA_Data;
      
      my @GA_Array;
      push @GA_Array, { GA => "0/7/1", DPT => "dpt1" };    # Status Licht
      push @GA_Array, { GA => "0/5/201", DPT => "dpt14" };    # Stromaufnahme Gesamt
      #[...]
      
      
      #####################################################################
      # Read GAs
      #####################################################################
      
      foreach my $element (@GA_Array) {
          my $GA_Variable = ($element->{GA});
          my $DPT_Variable = ($element->{DPT});
          
          # Subscribe this GA = actively listen for messages from this GA
          $plugin_subscribe{$GA_Variable}{$plugname} = 1;
      
          # If this GA is coming in then...
          if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $GA_Variable) {
          
              # ...decode the supplied data from this GA
              if ($DPT_Variable eq 'dpt1') {
                  $GA_Data = $msg{'data'}+0;
              }
              elsif ($DPT_Variable eq 'dpt14') {
                  $GA_Data = decode_dpt14($msg{'data'});
              }
              else {
                  $GA_Data = $msg{'data'}+0;
              }
              
              # Hand over this data to the shell
              system("echo $GA_Variable - $GA_Data >> /root/test.log");
          }
      }
      
      return 0;
      "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

      Kommentar


        #4
        "Automatisch" ist besser weil Du dann auf die zusätzliche Speichervariable verzichten kannst.

        Selbst wenn nicht ... es ist bequemer
        Und dann willst Du für jeden DPT noch das decoding ins Plugin holen ?


        "Automatisch":
        Die Daten lese ich ja nicht wirklich irgendwo aus ... die stehen mir im Ram immer zur Verfügung. Das macht der wiregated.pl.
        Zuletzt geändert von JuMi2006; 31.10.2015, 22:14.
        Umgezogen? Ja! ... Fertig? Nein!
        Baustelle 2.0 !

        Kommentar


          #5
          Hallo
          Wenn man mit "System" ein Shell startet, dann werden die nachfolgenden Befehle erst ausgeführt wenn das Shell-Script beendet ist.
          Braucht das Shell-Script länger so kommt es zu Problemen mit den Plugins.
          Man kann aber auch das Shell im Hintergrund aufrufen wenn man am Ende des Aufrufs ein & einfügt. "System('find /*.txt &')"
          Dann kann es aber wenn das im Hintergrund aufgerufene Script nicht beendet wird zu Zombis kommen.
          Dieses kann man vermeiden wenn vor den Scriptaufruf die PID des Scriptes abgefragt wird.
          Gruß NetFritz
          KNX & Wago 750-849 ,Wiregate u. Cometvisu, iPad 3G 64GB.
          WP Alpha-Innotec WWC130HX (RS232-Moxa-LAN),Solaranlage für Brauchwasser und Heizung.
          PV-Anlage = SMA Webbox2.0 , SunnyBoy 4000TL, Sharp 4kWP

          Kommentar


            #6
            Ihr habt recht, es geht einfacher. @JuMi, habe nun deinen Code "in production", allerdings mit einer kleinen Korrektur:

            Zitat von JuMi2006 Beitrag anzeigen
            Code:
            $plugin_info{$plugname.'_cycle'} = 86400;
            
            #####################################################################
            # Definitions
            #####################################################################
            my $GA_Data;
            my $dpt;
            
            # List all GAs here
            my @GA_Liste = ("0/5/201","0/5/203","0/5/205","0/5/207");
            
            #####################################################################
            # Read GAs
            #####################################################################
            
            foreach my $element (@GA_Liste) {
                # Subscribe this GA = actively listen for messages from this GA
                $plugin_subscribe{$element}{$plugname} = 1;
            
                # If this GA is coming in then...
                if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $element) {
                    
                    #dpt bestimmen:
                    $dpt = $eibgaconf{$element}{'DPTSubId'};
                    
                    # ...decode the supplied data from this GA
                    $GA_Data = decode_dpt([B]0,[/B]$msg{'data'},$dpt);
                    
                    # Hand over this data to the shell
                    system("echo $element - $GA_Data >> /root/test.log");
                }
            }
            
            return 0;
            Vielen Dank!

            Robert
            "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

            Kommentar


              #7
              Hallo
              Hast Du schon mal versucht unter System einen Befehl einzufügen der etwas länger dauert?
              z.B. find -name "*.txt" und dann mal mit "&" am Ende find -name "*.txt" &.
              Die Ausgabe kamst Du ja zu Kontrolle umleiten.
              Gruß NetFritz
              Zuletzt geändert von NetFritz; 20.11.2015, 11:10.
              KNX & Wago 750-849 ,Wiregate u. Cometvisu, iPad 3G 64GB.
              WP Alpha-Innotec WWC130HX (RS232-Moxa-LAN),Solaranlage für Brauchwasser und Heizung.
              PV-Anlage = SMA Webbox2.0 , SunnyBoy 4000TL, Sharp 4kWP

              Kommentar


                #8
                Zitat von wuestenfuchs Beitrag anzeigen
                #dpt bestimmen:
                $dpt = $eibgaconf{$element}{'DPTSubId'};

                # ...decode the supplied data from this GA
                $GA_Data = decode_dpt(0,$msg{'data'},$dpt);
                Hat das einen Hintergrund, warum auf diese Weise decodiert wird? Warum nicht einfach $msg{'value'} verwenden? Das Ergebnis müsste doch identisch sein.

                Kommentar


                  #9
                  Zitat von NetFritz Beitrag anzeigen
                  Hallo
                  Hast Du schon mal versucht unter System einen Befehl einzufügen der etwas länger dauert?
                  z.B. find -name "*.txt" und dann mal mit "&" am Ende find -name "*.txt" &.
                  Die Ausgabe kamst Du ja zu Kontrolle umleiten.
                  Gruß NetFritz
                  Ja, da bin ich selbst noch etwas unschlüssig. Klar könnte man da etwas drum rum basteln, was die Laufzeit kontrolliert/begrenzt (z.B. 'timeout'), aber bei rund 90 GAs habe ich Bedenken, dass die Laufzeitkontrollfunktion letztlich zu viel Ballast wird.
                  "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

                  Kommentar


                    #10
                    Zitat von XueSheng Beitrag anzeigen

                    Hat das einen Hintergrund, warum auf diese Weise decodiert wird? Warum nicht einfach $msg{'value'} verwenden? Das Ergebnis müsste doch identisch sein.
                    Du hast Recht, so ist es einfacher:

                    Code:
                    # Abonniert bestimmte GAs, auf denen Daten gesendet werden
                    # und gibt ankommende Werte dieser GAs auf der Shell aus.
                    
                    $plugin_info{$plugname.'_cycle'} = 86400;
                    
                    #####################################################################
                    # Definitions
                    #####################################################################
                    my $dpt;
                    my $GA_Data;
                    
                    my @GA_List = (
                        "0/5/201",
                        "0/5/203",
                        "0/5/205",
                        "0/5/207",
                    );
                    
                    
                    #####################################################################
                    # Read GAs
                    #####################################################################
                    
                    foreach my $element (@GA_List) {
                    
                        # Subscribe this GA = actively listen for messages from this GA
                        $plugin_subscribe{$element}{$plugname} = 1;
                    
                        # If this GA is coming in then...
                        if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $element) {
                    
                            # ...fetch the supplied data from this GA
                            $GA_Data = $msg{'value'};
                    
                            # Optionally re-format this GA from 'x/x/x' to 'x_x_x'
                            $element =~ s/\//_/g;
                        
                            # Hand over this data to the shell
                            system("echo $element - $GA_Data >> /root/test.log");
                        }
                    }
                    
                    return 0;
                    "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

                    Kommentar


                      #11
                      Hallo
                      Code:
                      @wuestenfuchs
                      aber bei rund 90 GAs habe ich Bedenken, dass die Laufzeitkontrollfunktion letztlich zu viel Ballast wird
                      Da haben wir uns aber nicht verstanden.
                      Die Anzahl der GAs spielen keine Rolle.
                      Du sendest mit den System Befehl ein Befehl an das Schell.
                      Solange dieser Befehl abgearbeitet wird die Ausführung aller Plugins blockiert.
                      Dauert das zu lange wird der Plugin Dämon neu gestartet.
                      Gruß NetFritz

                      KNX & Wago 750-849 ,Wiregate u. Cometvisu, iPad 3G 64GB.
                      WP Alpha-Innotec WWC130HX (RS232-Moxa-LAN),Solaranlage für Brauchwasser und Heizung.
                      PV-Anlage = SMA Webbox2.0 , SunnyBoy 4000TL, Sharp 4kWP

                      Kommentar


                        #12
                        Ich hab dich schon verstanden. Ein Beispiel, wie ich es meine:

                        Sagen wir, pro Sekunde laufen 10 GAs für das Plugin auf. Das Plugin ruft für jede GA einen recht ressourcenarmen Systembefehl auf, z.B. wirklich nur "echo". Die Abarbeitung dieser Sequenz braucht x Ressourcen pro Sekunde. Nun versehe ich das Ganze mit einer Laufzeitkontrolle - die ihrerseits wieder Ressourcen benötigt: so kommen zu den vorhandenen x Ressourcen die y Ressourcen für die Laufzeitkontrolle dazu.

                        In diesem Beispiel könnte ich mir ja die Laufzeitkontrolle sparen, da ich davon ausgehe, dass ein simpler Befehl wie "echo" nicht wesentlich blockiert. Wäre ja doof, wenn "echo" sagen wir 2 ms Laufzeit benötigt und mit einer Laufzeitkontrolle 20 ms.

                        Ein simpler Vergleich:
                        Code:
                        # Ohne Laufzeitkontrolle
                        me@system:~$ time echo "0_5_201 - 0.120"
                        0_5_201 - 0.120
                        
                        real    [B]0m0.000s[/B]
                        user    0m0.000s
                        sys    0m0.000s
                        Code:
                        # Mit Laufzeitkontrolle
                        me@system:~$ time timeout 2 echo "0_5_201 - 0.120"
                        0_5_201 - 0.120
                        
                        real    [B]0m0.005s[/B]
                        user    0m0.002s
                        sys    0m0.006s
                        Das suggeriert einen Faktor von 5, den die Laufzeitkontrolle zum Befehl hinzufügt - pro Aufruf, versteht sich.

                        Den Prozess einfach in den Hintergrund zu schieben halte ich dabei für zu unsicher; wie du selbst sagst, könnte das Nachteile haben. Dann lieber eine richtige Laufzeitkontrolle wie "timeout":

                        Code:
                        system("timeout 2 echo $element - $GA_Data >> /root/test.log");
                        "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

                        Kommentar


                          #13
                          Und während dessen steht Dein Wiregate still. Bis das Plugin beendet ist.
                          Umgezogen? Ja! ... Fertig? Nein!
                          Baustelle 2.0 !

                          Kommentar


                            #14
                            Richtig, sollte auch heißen:

                            Code:
                            system("timeout 2 echo $element - $GA_Data >> /root/test.log[B] &[/B]");
                            "Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren." - Benjamin Franklin

                            Kommentar

                            Lädt...
                            X