Ankündigung

Einklappen
Keine Ankündigung bisher.

Steuerung der KWL Cofoair mit diesem Protokol möglich?

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

    yes!

    Kommentar


      Ok ich versuche die Tage mal den Decoderteil zu bauen
      Gruss Patrik alias swiss

      Kommentar


        Konnte es doch nicht lassen ...

        Hier mal ein Testskript zur Berechnung der Temperaturen:

        Code:
        # Plugin zur Ansteuerung einer Zender ComfoAir
        # Version 0.3 04.06.2012 ALPHA
        # Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
        # Die Vorlage für die Datenübertragung via socat stammt von makki (https://knx-user-forum.de/members/makki.html)
        # Aufbau möglichst so, dass man unterhalb der Einstellungen nichts verändern muss!
        #
        #
        use Device::SerialPort;
        
        ####################
        ###Einstellungen:###
        ####################
        
        my $ga_stufeabwesend = '14/7/0'; #1bit Trigger für Stufe "Abwesend". 1=Aktivieren
        my $ga_stufe1 = '14/7/1'; #1bit Trigger für Stufe1. 1=Aktivieren
        my $ga_stufe2 = '14/7/2'; #1bit Trigger für Stufe2. 1=Aktivieren
        my $ga_stufe3 = '14/7/3'; #1bit Trigger für Stufe3. 1=Aktivieren
        
        
        my $usb = '/dev/usbserial-2-3';
        
        
        ######################
        ##ENDE Einstellungen##
        ######################
        my $return_value2;
        my $daten;
        my $reciv;
        my $ack = pack("H*","07F3");
        
        $plugin_info{$plugname.'_cycle'} = 30; 
        # Zyklischer Aufruf nach restart und alle 300 sek.
        
        my $seriel = Device::SerialPort->new($usb) || die "Kann $usb nicht öffnen! ($!)\n";
        $seriel->baudrate(9600);
        $seriel->parity("none");
        $seriel->databits(8);
        $seriel->stopbits(1);
        
        
        if ($msg{'apci'} eq "A_GroupValue_Write"){
            if ($msg{'dst'} eq $ga_stufeabwesend && knx_read($msg{'dst'},0,1) == 1) {
                $daten = "00990101";
                plugin_log($plugname,'Stufe abwesend');
                $return_value2 = command_senden($daten);
            }elsif ($msg{'dst'} eq $ga_stufe1 && knx_read($msg{'dst'},0,1) == 1) {
                $daten = "00990102";
                plugin_log($plugname,'Stufe 1');
                $return_value2 = command_senden($daten);
            }elsif ($msg{'dst'} eq $ga_stufe2 && knx_read($msg{'dst'},0,1) == 1) {
                $daten = "00990103";
                plugin_log($plugname,'Stufe 2');
                $return_value2 = command_senden($daten);
            }elsif ($msg{'dst'} eq $ga_stufe3 && knx_read($msg{'dst'},0,1) == 1) {
                $daten = "00990104";
                plugin_log($plugname,'Stufe 3');
                $return_value2 = command_senden($daten);
            }
            return $return_value2;
        } else { # zyklischer Aufruf
        
            # Plugin an Gruppenadresse "anmelden", hierdurch wird das Plugin im folgenden bei jedem eintreffen eines Telegramms auf die GA aufgerufen und der obere Teil dieser if-Schleife durchlaufen
            $plugin_subscribe{$ga_stufeabwesend}{$plugname} = 1;
            $plugin_subscribe{$ga_stufe1}{$plugname} = 1;
            $plugin_subscribe{$ga_stufe2}{$plugname} = 1;
            $plugin_subscribe{$ga_stufe3}{$plugname} = 1;
            
            
            $daten = "000F00";
            plugin_log($plugname,'Temperatur abrufen');
            $return_value2 = command_senden($daten);
        }
        
        # Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir übertragen
        sub command_senden{
            my $checksum = 0;
            my $data = $_[0];
            
            my $datasum = $data . "AD"; #+173 für die Checksummenberechnung
            my @hex  = map { hex($_) } ($datasum =~ /(..)/g);
            
            
            my $x07warschon = 0;
            
            foreach (@hex) {
                $checksum += ($_) unless $x07warschon; # unless ist dasselbe wie if not/!
                if ($_ == 0x07) { $x07warschon = 1; }
            }
        
            $checksum = sprintf "%x\n" , $checksum; #Mache aus Integer wieder HEX
            $checksum = substr($checksum,length($checksum)-3,2); #Verwede nur die letzten beiden stellen
            my $command = pack("H*","07F0" . $data . $checksum . "070F");
            
            my $commandhex = $command;
            $commandhex =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
            
            $plugin_info{$plugname.'_debug_transmit'} = $commandhex;
            plugin_log($plugname,'transmit:' . $commandhex);
            $seriel->write($command);
        
            
            $|=1;
            my $exit=0;
            while($exit < 30000)
            {
                my ($cin, $sin) = $seriel->read(25);
                if($cin > 0){
                    $sin = unpack "H*", $sin;
                    $reciv .= $sin;
                    $exit=0;
                 }else{
                    $exit++
                }
                if($reciv =~ /07f3/i){
                    plugin_log($plugname,'reciv: ACK');
                    $reciv = '';    
                }
                if($reciv =~ /070f/i){
                    plugin_log($plugname,'reciv: ' . $reciv);
                    
                    if($reciv =~ /07f0001004/i){ #Wenn die Temperaturen empfangen wurden
                        my $t1 = substr($reciv,10,2);
                        my $t2 = substr($reciv,12,2);
                        my $t3 = substr($reciv,14,2);
                        my $t4 = substr($reciv,16,2);
                        plugin_log($plugname,'reciv: T1: ' . $t1 . ' T2:' . $t2 . ' T3: ' . $t3 . ' T4: ' . $t4);
                        
                        $t1 =  (hex($t1)/2)-20;
                        $t2 =  (hex($t2)/2)-20;
                        $t3 =  (hex($t3)/2)-20;
                        $t4 =  (hex($t4)/2)-20;
                        
                        plugin_log($plugname,'reciv: T1: ' . $t1 . '°C, T2:' . $t2 . '°C, T3: ' . $t3 . '°C, T4: ' . $t4 . '°C');
                    }
                    
                    $seriel->write($ack);
                    last;    
                }
            }
            #$reciv = pack("H*",$reciv);
            #$reciv =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
            plugin_log($plugname,'reciv: ' . $reciv);
            $plugin_info{$plugname.'_debug_reciv'} = $reciv;
        }
        Bitte wieder ein paar Minuten laufen lassen und mir dann mitteilen was das PluginLog ausspuckt. Damit kann ich überprüfen ob die Berechnung korrekt funktioniert.
        Gruss Patrik alias swiss

        Kommentar


          sieht ganz gut aus.

          Habe mir heute mittag mal kurz Zeit genommen, um Deine Syntax zu verstehen-naja. Ich würd' mal sagen: gewusst wie!

          Die Tempi in rrd dürfte ja dann auch kein problem mehr sein?!?
          Und alle Tempi auf einem Graphen in der CV???
          Angehängte Dateien

          Kommentar


            Naja in dem Code sind noch gefühlte 100 debugzeilen drin Ich werde es, wenn es dann mal funktioniert um die ganzen Debugausgaben kürzen und noch etwas besser kommentieren

            RRD ist kein Problem mehr. Allerdings wegen der CV nur 1 Wert pro RRD.

            Wenn du die dann überlagert darstellen willst, hilft dir das RRD-Tool des WG. Dort einfach die Einstellungen vornemen und das Ergebnis als Bild in der CV einblenden. Multi-RRD ist ist bei der CV noch in der Diskussion bzw. in der Ausarbeitung
            Gruss Patrik alias swiss

            Kommentar


              Also hier noch mit rrd

              Hoffe das klapt so

              Code:
              # Plugin zur Ansteuerung einer Zender ComfoAir
              # Version 0.4 04.06.2012 ALPHA
              # Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
              # Die Vorlage für die Datenübertragung via socat stammt von makki (https://knx-user-forum.de/members/makki.html)
              # Aufbau möglichst so, dass man unterhalb der Einstellungen nichts verändern muss!
              #
              #
              use Device::SerialPort;
              
              ####################
              ###Einstellungen:###
              ####################
              
              #Zuordnung Steuerfunktionen zu den Gruppenadressen:
              my $ga_stufeabwesend = '14/7/0'; #1bit Trigger für Stufe "Abwesend". 1=Aktivieren
              my $ga_stufe1 = '14/7/1'; #1bit Trigger für Stufe1. 1=Aktivieren
              my $ga_stufe2 = '14/7/2'; #1bit Trigger für Stufe2. 1=Aktivieren
              my $ga_stufe3 = '14/7/3'; #1bit Trigger für Stufe3. 1=Aktivieren
              
              #Zuordnung der Namen für die RRD's:
              my $Name_rrd_AUL = 'KWL_Aussenluft'; #Name RRD Aussenluft
              my $Name_rrd_ZUL = 'KWL_Zuluft'; #Name RRD Zuluft
              my $Name_rrd_ABL = 'KWL_Abluft'; #Name RRD Abluft
              my $Name_rrd_FOL = 'KWL_Fortluft'; #Name RRD Fortluft
              
              #Pfand zur seriellen Schnittstelle oder dem USB-Seriell-Wandler:
              my $schnittstelle = '/dev/usbserial-2-3';
              
              ######################
              ##ENDE Einstellungen##
              ######################
              
              #Ab hier nichts mehr ändern.
              #Hauptverarbeitung
              
              my $return_value2;
              my $daten;
              my $reciv;
              my $ack = pack("H*","07F3");
              
              # Zyklischer Aufruf nach restart, empfang GA oder nach einstellung rrd (typisch 300sek).
              $plugin_info{$plugname.'_cycle'}  = $wg_config{''}{'rrd_interval'}; 
              
              #Einrichten der Seriellen Schnittstelle für die Kommunikation mit dem ComfoAir
              my $seriel = Device::SerialPort->new($schnittstelle) || die "Kann $schnittstelle nicht öffnen! ($!)\n";
              $seriel->baudrate(9600);
              $seriel->parity("none");
              $seriel->databits(8);
              $seriel->stopbits(1);
              
              
              if ($msg{'apci'} eq "A_GroupValue_Write"){ #Wenn ein Telegramm vom KNX empfangenwird, ab hier auswerten
                  if ($msg{'dst'} eq $ga_stufeabwesend && knx_read($msg{'dst'},0,1) == 1) {
                      $daten = "00990101";
                      plugin_log($plugname,'Stufe abwesend');
                      $return_value2 = command_senden($daten);
                  }elsif ($msg{'dst'} eq $ga_stufe1 && knx_read($msg{'dst'},0,1) == 1) {
                      $daten = "00990102";
                      plugin_log($plugname,'Stufe 1');
                      $return_value2 = command_senden($daten);
                  }elsif ($msg{'dst'} eq $ga_stufe2 && knx_read($msg{'dst'},0,1) == 1) {
                      $daten = "00990103";
                      plugin_log($plugname,'Stufe 2');
                      $return_value2 = command_senden($daten);
                  }elsif ($msg{'dst'} eq $ga_stufe3 && knx_read($msg{'dst'},0,1) == 1) {
                      $daten = "00990104";
                      plugin_log($plugname,'Stufe 3');
                      $return_value2 = command_senden($daten);
                  }
                  return;
              } else { # zyklischer Aufruf
              
                  # Plugin an Gruppenadresse "anmelden", hierdurch wird das Plugin im folgenden bei jedem eintreffen eines Telegramms auf die GA aufgerufen und der obere Teil dieser if-Schleife durchlaufen
                  $plugin_subscribe{$ga_stufeabwesend}{$plugname} = 1;
                  $plugin_subscribe{$ga_stufe1}{$plugname} = 1;
                  $plugin_subscribe{$ga_stufe2}{$plugname} = 1;
                  $plugin_subscribe{$ga_stufe3}{$plugname} = 1;
                  
                  
                  $daten = "000F00";
              #    plugin_log($plugname,'Temperatur abrufen');
                  return $return_value2 = command_senden($daten);
              }
              
              # Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir übertragen
              sub command_senden{
                  my $checksum = 0;
                  my $data = $_[0];
                  
                  my $datasum = $data . "AD"; #+173 für die Checksummenberechnung
                  my @hex  = map { hex($_) } ($datasum =~ /(..)/g);
                  
                  
                  my $x07warschon = 0;
                  
                  foreach (@hex) {
                      $checksum += ($_) unless $x07warschon; # unless ist dasselbe wie if not/!
                      if ($_ == 0x07) { $x07warschon = 1; }
                  }
              
                  $checksum = sprintf "%x\n" , $checksum; #Mache aus Integer wieder HEX
                  $checksum = substr($checksum,length($checksum)-3,2); #Verwede nur die letzten beiden stellen
                  my $command = pack("H*","07F0" . $data . $checksum . "070F");
                  
              
                  $seriel->write($command); #Befehl an den ComfoAir senden
              
                  
                  $|=1;
                  my $exit=0;
                  while($exit < 30000)
                  {
                      my ($cin, $sin) = $seriel->read(25);
                      if($cin > 0){
                          $sin = unpack "H*", $sin;
                          $reciv .= $sin;
                          $exit=0;
                       }else{
                          $exit++
                      }
                      if($reciv =~ /07f3/i){
              #            plugin_log($plugname,'reciv: ACK');
                          $reciv = '';    
                      }
                      if($reciv =~ /070f/i){
              #            plugin_log($plugname,'reciv: ' . $reciv);
                          
                          if($reciv =~ /07f0001004/i){ #Wenn die Temperaturen empfangen wurden
                              my $t1 = substr($reciv,10,2);
                              my $t2 = substr($reciv,12,2);
                              my $t3 = substr($reciv,14,2);
                              my $t4 = substr($reciv,16,2);
              #                plugin_log($plugname,'reciv: T1: ' . $t1 . ' T2:' . $t2 . ' T3: ' . $t3 . ' T4: ' . $t4);
                              
                              $t1 =  (hex($t1)/2)-20;
                              $t2 =  (hex($t2)/2)-20;
                              $t3 =  (hex($t3)/2)-20;
                              $t4 =  (hex($t4)/2)-20;
                              
                              update_rrd($Name_rrd_AUL,"",$t1);
                              update_rrd($Name_rrd_ZUL,"",$t2);
                              update_rrd($Name_rrd_ABL,"",$t3);
                              update_rrd($Name_rrd_FOL,"",$t4);
                              
              #                plugin_log($plugname,'reciv: T1: ' . $t1 . '°C, T2:' . $t2 . '°C, T3: ' . $t3 . '°C, T4: ' . $t4 . '°C');
                          }
                          
                          $seriel->write($ack); #ACK senden
                          last;    
                      }
                  }
              }
              Gruss Patrik alias swiss

              Kommentar


                Pp

                Hi
                Wenn ich Mir was wünschen darf:
                Kommando (lesen)
                0x00 0x0b ventilator status abrufen
                0x00 0x0d Klappenstatus abrufen
                (evtl. Auch 0x00 0xdf Status Bypassregelung)

                Und schreibend:
                0x00 0xd3 Kompforttemperatur setzen (damit aktiviere/deaktiviere ich indirect die bypassklappe)

                Für alle die hier mitlesen und es nicht wissen: die Bypassregelung funktioniert NICHT wenn man auf Stufe "abwesend" ist - auch wenn man z.B. über analogeingang die Anlage mit 80% fährt!

                In der Kommandoliste finde ich keinen Befehl um die Anlage auf xx% laufen zu lassen (so wie man das über Analogaktoren machen kann) - schade.
                Mein derzeitiges Betriebsmodell (immer Stufe 1 aktiviert, dies auf niedrigsten Wert konfigurier=16%, höherregelung per Analogaktor 16-100%) werde ich daher nicht ändern...

                Gruß
                Thorsten

                Kommentar


                  Zitat von ThorstenGehrig Beitrag anzeigen
                  Hi
                  Wenn ich Mir was wünschen darf:

                  erst faul in der sonne liegen und dann nach getaner Arbeit ansprüche Stellen

                  Im ernst-mich würde die Abweichung der der Comfoairfühlern zu Deinen WG-Fühler interessieren-falls Du mal kuken könntest

                  Kommentar


                    Klar - wird gemacht.
                    Ich versuche auch ein bisschen Sonne mitzubringen - wobei das schlechte Wetter ja gut für die Produktivität war ;-)

                    Cu
                    Thorsten (online von der Sonnenliege am Pool)

                    Kommentar


                      Hallo Thorsten

                      Das lässt sich bestimmt noch integrieren. Ich schaue mir das heute Abend mal an

                      @lio: Funktionieren die RRDs? Oder ist da noch ein BUG drin?
                      Gruss Patrik alias swiss

                      Kommentar


                        Zitat von swiss Beitrag anzeigen
                        @lio: Funktionieren die RRDs? Oder ist da noch ein BUG drin?

                        ..ich kann leider nicht in der Sonne liegen und muss arbeiten. Ich checke das heute abdend.

                        Grüße,
                        Lio

                        Kommentar


                          Patrick,

                          mein Wunsch wäre noch
                          0x03 Eingänge abrufen
                          0xDD Betriebsstunden abrufen

                          erstmal.

                          GGF. Sollten wir bei de menge and Daten das Thema Wunsch diskutieren.


                          Grüße,
                          Lio

                          Kommentar


                            Hallo Tobias

                            Für was brauchst du denn den Zustand der Eingänge?? Das leuchtet mir nicht ganz ein. Steuerst du die KWL nicht über die EASE?

                            Betriebsstunden...

                            Was sagen denn die genau aus? Wäre da Störmeldungen bzw. Filterwechseln nicht sinnvoller?

                            Ich sehe mir das auch mal genauer an. Sollte sich aber machen lassen.

                            Das Problem ist die Ausführungszeit. Solange wir keine Lösung für das socket problem finden habe ich das grosse Problem, dass das daten empfangen im Plugin abgearbeitet werden muss. Das erhöht mit jedem Zusatzwunsch die Ausführungszeit und bremst damit das gesammte Pluginsystem aus. Klar könnte man Optionsschalter einführen, wo jeder sich seine Funktionen die er braucht aktivieren kann aber auch da treten wieder gewisse Probleme auf... Der Code wird noch mal eine ganze scheibe komplexer, länger und unübersichtilicher. Es ist also im aktuellen Zustand eine Gratwanderung zwischen Performanc und Funktionsumfang.

                            Klar gäbe es noch die Möglichkeit das ganze als daemon laufen zu lassen aber dann ist es nicht mehr massentauglich da man das Plugin direkt über z.B. WinSCP auf das WG laden muss und es dann über die Konsole als eigenständiges Programm ausführen müsste.
                            Gruss Patrik alias swiss

                            Kommentar


                              Hallo Patrik,

                              Zustand der Eingänge:

                              Ich steuere Sotßlüftung und "Anlage Aus" derzeit noch via Aktor.

                              Anlage aus bei Gartenarbeiten (Staub) bzw Grillen, Räuchern etc. geht meines Wissens nur Hardwaretechnisch.

                              Stoßlüftung ähnlich-Problem: Aktor zeigt mir nicht den Tatsächlich Status der Lüftung (30Min) sondern schaltet nach 5 Min ab.

                              Genau wegen Filterwechsel das andere Kommando.
                              Das eigentliche Kommando worin das Filterwechsel-Flag ist, ist sehr lange.
                              DEshalb dachte ich, dass das Betriebsstundenflag besser wäre (auch weil ich statistiker bin... ;-) )

                              Die rrd sollten doch im pulldown menü des Diagrammgenerators dann ersichtlich sein?

                              sind sie leider nicht


                              Grüße,
                              Lio

                              Kommentar


                                Fehlanzeige-dauerte nur etwas-alles da!

                                Kommentar

                                Lädt...
                                X