Ankündigung

Einklappen
Keine Ankündigung bisher.

ComfoAir Steuerung über RS232

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

    Hallo Marco

    Du hast recht. Das ist noch nicht wirklich geschickt gelöst... Ich werde mal schauen wie ich das am besten löse. Am ehsten wird es wohl darauf hinaus laufen, dass ich im Plugin auch die Lesetelegramme verarbeite und die angefragten Werte direkt aus der ComfoAir lese und dann auf den BUS ausgebe...
    Gruss Patrik alias swiss

    Kommentar


      Ich habe mich mal hin gesetzt und ein bischen was zusammen gestrickt...

      Hoffe das funktioniert so. Kann es wie üblich nicht selber testen daher bitte ich um hilfe

      Code:
      # Plugin zur Ansteuerung einer Zender ComfoAir
      # Version 1.6.8 28.05.2014 BETA
      # Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
      # Aufbau moeglichst so, dass man unterhalb der Einstellungen nichts veraendern muss!
      # - Neu mit der Moeglichkeit zur Anbindung über einen Moxa NPort von Fechter65 (https://knx-user-forum.de/members/fechter65.html)
      # - Neustrukturierung des Codes von Fechter65 (https://knx-user-forum.de/members/fechter65.html)
      # - Besseres Fehlerhandling bei der Verarbeitung der Reuckmeldungen von swiss (https://knx-user-forum.de/members/swiss.html)
      # - Neu nun mit direktem abfragen der Stufe nach dem setzen und auswerten der Komforttemperatur von swiss (https://knx-user-forum.de/members/swiss.html)
      # - Neu mit der Möglichkeit die Ventilationsstufe direkt zu setzen von swiss (https://knx-user-forum.de/members/swiss.html)
      # - Neu mit der Möglichkeit die Ventilatorstufe für Zuluft und Abluft getrennt zu setzen (0% - 100%) von Netsrac80 (https://knx-user-forum.de/members/netsrac80.html)
      # - Korrektur Stufe direkt setzen. Senden / empfangen hat nun das gleiche Mapping 1=Auto, 2=Sufe1, 3=Stufe2, 4=Stufe3
      # - Neu mit Rückmeldung auf Lesetelegramme
      
       
      
      ####################
      ###Einstellungen:###
      ####################
      
      #BITTE ab sofort die Einstellungen unter conf.d vornemen. Damit bleiben die Einstellungen auch bei einem Update erhalten.
       
      
      ######################
      ##ENDE Einstellungen##
      ######################
      
      
      #Ab hier nichts mehr aendern.
      #Hauptverarbeitung
      
      
      #Erzeuge Variablen fuer die Zuordnung der Steuerfunktionen zu den Gruppenadressen:
      my $ga_stufeabwesend = ''; #1bit Trigger fuer Stufe "Abwesend". 1=Aktivieren
      my $ga_stufe1 = ''; #1bit Trigger fuer Stufe1. 1=Aktivieren
      my $ga_stufe2 = ''; #1bit Trigger fuer Stufe2. 1=Aktivieren
      my $ga_stufe3 = ''; #1bit Trigger fuer Stufe3. 1=Aktivieren
      my $ga_stufe_setzen = ''; # GA DPT 5.005 zum direkten setzen der Stufe (1=Abwesend, 2=Stufe1, 3=Stufe2, 4=Stufe3)
      my $ga_komforttemp = ''; #GA DPT 9.001 zum setzen der Komforttemperatur
      my $ga_drehzahl_ventilator_zul = ''; #GA DPT 5.001 zum setzen der Zuluftdrehzahl
      my $ga_drehzahl_ventilator_abl = ''; #GA DPT 5.001 zum setzen der Abluftdrehzahl
      my $ga_reset_filter = ''; #1bit Trigger fuer das Zuruecksetzen des Betriebsstundenzaehlers des Filters. 1=Reset
      my $ga_reset_error = ''; #1bit Trigger fuer das zuruecksetzen der KWL nach einem Fehler. 1=Reset
       
      
      #Hier werden die Gruppenadressen fuer die Rueckmeldungen vergeben: (Nich vergeben = inaktiv)
      my $ga_status_ventilator_zul = ''; #GA DPT 5.001 fuer Status Ventilator Zuluft %
      my $ga_status_ventilator_abl = ''; #GA DPT 5.001 fuer Status Ventilator Abluft %
      my $ga_status_bypass_prozent = ''; #GA DPT 5.001 fuer Status Bypassklappe %
      my $ga_betriebsstunden_filter = ''; #GA DPT 16.000 fuer die Rueckmeldung der Betribsstunden des Filters
      my $ga_zustand_badschalter = ''; #GA DPT 1.001 fuer die Rueckmeldung des Zustandes des Badezimmerschalters
      my $ga_fehler_filter = ''; #GA DPT 1.001 fuer den Zustand des Filters. 0=OK, 1=Filter Voll
      my $ga_fehlercode = ''; #GA DPT 16.000 fuer die Ausgabe des Fehlercodes als Text
      my $ga_aktstufe = ''; #GA DPT 5.005 liefert den Wert für die aktuelle Stufe (1=A, 2=Stufe1, 3=Stufe2, 4=Stufe3)
       
      #Hier werden die Gruppenadressen für die Rückmeldung der Temperaturen vergeben: (Nicht vergeben=inaktiv)
      my $ga_aul_temp = ''; #GA DPT 9.001 für die Aussenlufttemperatur
      my $ga_zul_temp = ''; #GA DPT 9.001 für die Zulufttemperatur
      my $ga_abl_temp = ''; #GA DPT 9.001 für die Ablufttemperatur
      my $ga_fol_temp = ''; #GA DPT 9.001 für die Fortlufttemperatur
      my $ga_komfort_temp = ''; #GA DPT 9.001 für die Komforttemperatur
       
      #Zuordnung der Namen fuer 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
       
      #Pfad zur seriellen Schnittstelle oder dem USB-Seriell-Wandler:
      my $schnittstelle = '/dev/ttyUSB-2-4';
       
      
      #Angaben für die Kommunikation über den UDP-Port einer MOXA [diese Einstellungen reichen aus, d.h. auf dem Wiregate muss unter "Seriell/LAN/Socketverbindungen" KEINE Socketverbindung erstellt werden
      my $socknum = ""; # Eindeutige Nummer des Sockets
      my $send_ip = ""; # SendeIP (UDP)
      my $send_port = ""; # Sendeport (UDP)   
      my $recv_ip = ""; # EmpfangsIP (UDP)
      my $recv_port = ""; # Empfangsport (UDP)
       
      
      # Kommunikationsart
      my $Kom_Art = "S"; # "S" = seriell; "M" = Moxa
       
      
      # Dauer einer Abfrage
      my $Zaehler = "2500"; #Mit dieser Variable Zaehler wird beeinflusst, wie lange das Plugin auf den Abschluss einer Rückmeldung der KWL wartet; empfohlener Wert für seriell: 2500; für Moxa: 250
       
      # Debug level 0 = nur die wichtigsten Infos, 1 = Alle Zustaende, 2 = Rohdaten (nur für Fehlersuche)
      my $debug=0;
       
       
      #Weitere Variablen die benoetigt werden -> NICHT veraendern!
      my $seriel;
      my $sin; #Serial Input = Empangener Datenstrom
      my $cin; #Counter Input =  Länge des Datenpackets
      my $laenge; #Länge des empfangenen Datenstrings nach dem kürzen
       
      my $checksum = 0; #Checksumme
      my @hex; #Hilfsarray für die Checksummenberechnung
      my $x07warschon; #Hilfsvariable für die Checksummenberechnung
       
      &readConf(); #conf.d einlesen
       
      my $return_value2;
      my $daten;
      my $reciv;
      my $reciv_all;
      my $ack = pack("H*","07F3");
      my $rcv_checksum;
       
      # Zyklischer Aufruf nach restart, empfang GA oder 1/2 der einstellung rrd (typisch 150sek).
      $plugin_info{$plugname.'_cycle'}  = 150;
      
      use Device::SerialPort;
      use Time::Local;
      
       
      #Einrichten der Seriellen Schnittstelle fuer die Kommunikation mit der ComfoAir falls die Schnittstelle auf "S" steht
      if ($Kom_Art eq "S"){
                   $seriel = Device::SerialPort->new($schnittstelle) || die "Kann $schnittstelle nicht öffnen! ($!)\n";
                   $seriel->baudrate(9600);
                   $seriel->parity("none");
                   $seriel->databits(8);
                   $seriel->stopbits(1);
                   if($debug>=1){plugin_log($plugname,'Schnittstelle: ' . $schnittstelle . ' erfolgreich geöffnet')};
      }elsif ($Kom_Art eq "M"){
          if (!$socket[$socknum]) { # socket erstellen
                  $socket[$socknum] = IO::Socket::INET->new(LocalPort => $recv_port,
                                            Proto => "udp",
                                            LocalAddr => $recv_ip,
                                            PeerPort  => $send_port,
                                            PeerAddr  => $send_ip,
                                            ReuseAddr => 1
                                             )
              or return ("open of $recv_ip : $recv_port failed: $!");
              $socksel->add($socket[$socknum]); # add socket to select
              $plugin_socket_subscribe{$socket[$socknum]} = $plugname; # Plugin an Socket "anmelden"
              if($debug>=1){plugin_log($plugname,'Socket: ' . $socknum . ' erfolgreich geöffnet')};
              return "opened Socket $socknum";
          }
      }
      
      
      ###############################################################################################
      ###############################################################################################
      ## Ab hier werden die Befehle die vom KNX kommen für die ComfoAir uebersetzt und gesendet... ##
      ###############################################################################################
      ###############################################################################################
       
       if ($msg{'apci'} eq "A_GroupValue_Read"){
          if ($msg{'dst'} eq $ga_aktstufe){
                  $daten = "00CD00";
                  if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                  $return_value2 = command_senden($daten);        
          }elsif($msg{'dst'} eq $ga_status_bypass_prozent){
                  $daten = "000D00";
                  if($debug>=1){plugin_log($plugname,'Bypass Zustand abrufen');}
                  $return_value2 = command_senden($daten);
          }elsif($msg{'dst'} eq $ga_status_ventilator_zul or $msg{'dst'} eq $ga_status_ventilator_abl){
                  $daten = "000B00";
                  if($debug>=1){plugin_log($plugname,'Ventilator Status abrufen');}
                  $return_value2 = command_senden($daten);
          }elsif($msg{'dst'} eq $ga_aul_temp or $msg{'dst'} eq $ga_zul_temp or $msg{'dst'} eq $ga_abl_temp or $msg{'dst'} eq $ga_fol_temp or $msg{'dst'} eq $ga_komfort_temp){
                  $daten = "00D100";
                  plugin_log($plugname,'Temperatur abrufen');
                  $return_value2 = command_senden($daten);
          }
      }elsif ($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 setzen');
              $return_value2 = command_senden($daten);
                  if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                      $daten = "00CD00";
                      if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                      $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 setzen');
              $return_value2 = command_senden($daten);
                  if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                      $daten = "00CD00";
                      if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                      $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 setzen');
              $return_value2 = command_senden($daten);
                  if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                      $daten = "00CD00";
                      if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                      $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 setzen');
              $return_value2 = command_senden($daten);
                  if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                      $daten = "00CD00";
                      if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                      $return_value2 = command_senden($daten);
                  }
          }elsif ($msg{'dst'} eq $ga_stufe_setzen) {
              my $stufenwert = knx_read($msg{'dst'},0,5.005);
              $daten = "0099010" . $stufenwert;
              plugin_log($plugname,'Stufe direkt setzen auf: ' . $stufenwert);
              $return_value2 = command_senden($daten);
                  if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                      $daten = "00CD00";
                      if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                      $return_value2 = command_senden($daten);
                  }
          }elsif ($msg{'dst'} eq $ga_komforttemp) {
              my $komforttemp = knx_read($msg{'dst'},0,9.001);
              plugin_log($plugname,'Komforttemp auf: ' . $komforttemp . '°C setzen');
              my $temphex = ($komforttemp + 20)*2; #Rechne die Temperatur fuer die ComfoAir um
              $temphex = sprintf "%x" , $temphex; # Mache aus Integer HEX
              $daten = "00D301" . $temphex;
              $return_value2 = command_senden($daten);
          }elsif ($msg{'dst'} eq $ga_reset_filter && knx_read($msg{'dst'},0,1) == 1) {
              $daten = "00DB0400000001";
              knx_write($ga_fehler_filter,0,1);
              plugin_log($plugname,'Filter zuruecksetzen');
              $return_value2 = command_senden($daten);
          }elsif ($msg{'dst'} eq $ga_reset_error && knx_read($msg{'dst'},0,1) == 1) {
              $daten = "00DB0401000000";
              plugin_log($plugname,'Fehler zuruecksetzen');
              $return_value2 = command_senden($daten);
          }elsif ($msg{'dst'} eq $ga_drehzahl_ventilator_zul) {
              my $drehzahl_zul = knx_read($msg{'dst'},0,5.001);
              plugin_log($plugname,'Drehzahl Zuluftluefter auf: ' . $drehzahl_zul . '% setzen');
              $plugin_info{$plugname."_zuluftdrehzahl_1"} = $drehzahl_zul;
             
              my $temp_abluftdrehzahl = sprintf "%x",$plugin_info{$plugname."_abluftdrehzahl_1"};
              my $hex_zuluftdrehzahl = sprintf "%x" , $drehzahl_zul; # Mache aus Integer HEX
              $daten = "00CF090F" . $temp_abluftdrehzahl.'0F0F'. $hex_zuluftdrehzahl.'0F0F0F0F';
              $return_value2 = command_senden($daten);
          }elsif ($msg{'dst'} eq $ga_drehzahl_ventilator_abl) {
              my $drehzahl_abl = knx_read($msg{'dst'},0,5.001);
              plugin_log($plugname,'Drehzahl Abluftluefter auf: ' . $drehzahl_abl . '% setzen');
              $plugin_info{$plugname."_abluftdrehzahl_1"} = $drehzahl_abl;
              
              my $temp_zuluftdrehzahl = sprintf "%x",$plugin_info{$plugname."_zuluftdrehzahl_1"};
              my $hex_abluftdrehzahl = sprintf "%x" , $drehzahl_abl; # Mache aus Integer HEX
              $daten = "00CF090F" . $hex_abluftdrehzahl.'0F0F'. $temp_zuluftdrehzahl.'0F0F0F0F';
              $return_value2 = command_senden($daten);
              if($debug>=2){plugin_log($plugname,'Drehzahl Abluftlüfter DATEN: ' . $daten . ' mit '. $drehzahl_abl. ' setzen! Antwort:'.$return_value2); }
          }
          if($debug>=2){plugin_log($plugname,'ENDE Aufruf durch GA');}
          return;
                  
      } else { # zyklischer Aufruf
          if(($plugin_info{$plugname.'_time'}+$plugin_info{$plugname.'_cycle'}) >= $plugin_info{$plugname.'_last'}){
              return;
          }
          $plugin_info{$plugname.'_time'} = time();
         
          # 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;
          $plugin_subscribe{$ga_stufe_setzen}{$plugname} = 1;
          $plugin_subscribe{$ga_komforttemp}{$plugname} = 1;
          $plugin_subscribe{$ga_reset_filter}{$plugname} = 1;
          $plugin_subscribe{$ga_reset_error}{$plugname} = 1;
          $plugin_subscribe{$ga_drehzahl_ventilator_zul}{$plugname} = 1;
          $plugin_subscribe{$ga_drehzahl_ventilator_abl}{$plugname} = 1;
          
          $plugin_subscribe{$ga_aktstufe}{$plugname} = 1;
          $plugin_subscribe{$ga_status_bypass_prozent}{$plugname} = 1;
          $plugin_subscribe{$ga_status_ventilator_zul}{$plugname} = 1;
          $plugin_subscribe{$ga_status_ventilator_abl}{$plugname} = 1;
          $plugin_subscribe{$ga_aul_temp}{$plugname} = 1;
          $plugin_subscribe{$ga_zul_temp}{$plugname} = 1;
          $plugin_subscribe{$ga_abl_temp}{$plugname} = 1;
          $plugin_subscribe{$ga_fol_temp}{$plugname} = 1;
          $plugin_subscribe{$ga_komfort_temp}{$plugname} = 1;
         
      
      ####################################################################################################
      ####################################################################################################
      ## Ab hier werden zyklisch diverse Werte von der ComfoAir abgefragt und an das KNX uebertragen... ##
      ####################################################################################################
      ####################################################################################################
      
        
          $daten = "00D100";
          plugin_log($plugname,'Temperatur abrufen');
          $return_value2 = command_senden($daten);
         
          if($ga_status_ventilator_zul && $ga_status_ventilator_abl){ #Nur wenn beide GA's vergeben sind, dann die Zustaende der Ventilatoren abfragen
              $daten = "000B00";
              if($debug>=1){plugin_log($plugname,'Ventilator Status abrufen');}
              $return_value2 = command_senden($daten);
          }
                  
          if($ga_status_bypass_prozent){ #Nur wenn die GA vergeben ist, dann Zustand Bypassklappe abfragen
              $daten = "000D00";
              if($debug>=1){plugin_log($plugname,'Bypass Zustand abrufen');}
              $return_value2 = command_senden($daten);
          }
                  
          if($ga_betriebsstunden_filter){ #Nur wenn die GA vergeben ist, die Betriebsstunden des Filters abfragen
              $daten = "00DD00";
              if($debug>=1){plugin_log($plugname,'Betriebsstunden Filter abrufen');}
              $return_value2 = command_senden($daten);
          }
                  
          if($ga_zustand_badschalter){ #Nur wenn die GA vergeben ist, die Binaereingaenge abfragen
              $daten = "000300";
              if($debug>=1){plugin_log($plugname,'Binäreingänge abrufen');}
              $return_value2 = command_senden($daten);
          }
                  
          if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
              $daten = "00CD00";
              if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
              $return_value2 = command_senden($daten);
          }
                  
          if($ga_fehlercode){ #Nur wenn die GA vergeben ist, werden hier die Stoermeldungen abgefragt
              $daten = "00D900";
              if($debug>=1){plugin_log($plugname,'Störungen abrufen');}
              $return_value2 = command_senden($daten);
          }
      
          if($debug>=2){plugin_log($plugname,'ENDE Zyklische Abfrage');}
          return;
      }
       
       
      # Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir uebertragen
      sub command_senden{
          my $data = $_[0];
          if($debug>=2){plugin_log($plugname,'data: ' . $data);}
          $checksum = checksum_berechnen($data);
          if($debug>=2){plugin_log($plugname,'Checksumme aus der Subroutine: '.$checksum);}
          my $command = pack("H*","07F0" . $data . $checksum . "070F");
          my $commandhex = $command;
         
          $commandhex =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
          if($debug>=2){plugin_log($plugname,'transmit: ' . $commandhex);} #Zeigt im Pluginlog das fertige Datenpaket, dass uebertragen wird
                   if ($Kom_Art eq "S"){   
                                   $seriel->write($command); #Befehl an die ComfoAir senden
                   } elsif ($Kom_Art eq "M"){   
                                   $plugin_info{$plugname.'_debug'} = $command;
                                   syswrite($socket[$socknum], $command);
                   }
          $reciv = '';
          $cin = '';
          $sin = '';
             
          $|=1;
          my $exit=0;
          while($exit < $Zaehler)
          {
              if ($Kom_Art eq "S"){
                   ($cin, $sin) = $seriel->read(45);
              }elsif ($Kom_Art eq "M"){
                                       $sin ='';
                                       if ($fh) { # Antwort auslesen
                                                      recv($fh,$sin,80,0);
                                       }
                                       $cin = length($sin);
              }
              if($cin > 0){
                  $sin = unpack "H*", $sin;
                  $reciv .= $sin;
                  $exit=0;
              }else{
                  $exit++
              }
             
              if($debug>=2){plugin_log($plugname,'reciv-direkt:     ' . $sin);}
          
                  if($reciv =~ /070f/i){ 
                      if (substr($reciv,(length($reciv)-6),6) ne '07070f'){            
                          last;
                      }
                  }
          }#Ende While  
      
          if ($Kom_Art eq "S"){
              $seriel->write($ack); #ACK senden
              if($debug>=2){plugin_log($plugname,'ACK senden');}
          } elsif ($Kom_Art eq "M"){
              syswrite($socket[$socknum], $ack); #ACK senden
              if($debug>=2){plugin_log($plugname,'ACK senden');}
          }
      
          if($reciv eq ""){
              if($debug>=2){plugin_log($plugname,'FEHLER: Keine Daten empfangen!');}
              return;
          }
         
          while ((length($reciv) > 3) && (substr($reciv,(length($reciv)-4),4) ne '070f')) #solange das Ende nicht 070f lautet
          {
                          if($debug>=2){plugin_log($plugname,'String vor Kuerzung Ende: '.$reciv);}
                          $reciv = substr($reciv,0,-2); #String um die letzten zwei Zeichen kürzen
                          if($debug>=2){plugin_log($plugname,'String nach Kuerzung Ende: '.$reciv);}
          }  
         
       
              #Hier wird der empfangene String um Start- und Endbyte gekürzt
              $laenge = length($reciv); #Laenge des Antworttelegramms ermitteln
              $reciv = substr($reciv,0,($laenge-4)); #Entferne 07f0 vom Ende
             
              if(substr($reciv,(length($reciv)-4),4) eq '07f3'){
                  $reciv = substr($reciv,0,($laenge-4));
                  if($debug>=2){plugin_log($plugname,'String ohne 07f3: '.$reciv);}
              }
      
              if($debug>=2){plugin_log($plugname,'Erste 4 Byte des Datenpakets: '.(substr($reciv,0,4)));}
      
                                                 
              while ((length($reciv) > 3) && (substr($reciv,0,4)) ne '07f0'){
                  $reciv = substr($reciv,2); #falls noch falsche Zeichen am Anfang des Strings enthalten sind, werden diese hier entfernt.
                  if($debug>=2){plugin_log($plugname,'reciv gekuerzt: '.$reciv);}
              }
             
              $reciv = substr($reciv,4);
              if($debug>=2){plugin_log($plugname,'String ohne 07f0 am Anfang: '.$reciv);}
             
              #Test einer Methode falls aussversehen mehrere Datenpakete auf einmal im Datenstring enthalten sind...
              if($reciv =~ /07f307f0/i){
                  my @dataarray=split(/07f307f0/,$reciv);
                  $reciv = $dataarray[0];
              }
      
                                  
              #Nun wird die Checksumme gelesen und aus dem Datenstring entfernt
              $checksum = 0;
              $checksum = substr($reciv,-2,2);
              if($debug>=2){plugin_log($plugname,'Checksumme gelesen: '.$checksum);}
              $laenge = length($reciv); #Laenge des Antworttelegramms ermitteln
              $reciv = substr($reciv,0,($laenge-2));
              if($debug>=2){plugin_log($plugname,'Datenpaket ohne Checksumme: '.$reciv);}
      
              #Hier wird die Subroutine für die Berechnung der Checksumme aufgerufen und das Ergebnis in $rcv_checksum zurück gegeben
              $rcv_checksum = checksum_berechnen($reciv);
      
              
      #######################################################################
      #######################################################################
      ## Ab hier werden die Rueckmeldungen von der ComfoAir ausgewertet... ##
      #######################################################################
      #######################################################################
      
      
              if($rcv_checksum eq $checksum){ #Hier wird geprüft ob die Checksumme korrekt ist
                  if($debug>=2){plugin_log($plugname,'Checksumme OK ');}
                  
                  #Hier werden die doppelten 07 aus dem Antwortstring entfernt.
                  if($debug>=2){plugin_log($plugname,'String vor 07 bereinigung:  '.$reciv);}
                  while ($reciv =~ s/0707/07/) {}
                  if($debug>=2){plugin_log($plugname,'String nach 07 bereinigung: '.$reciv);}
                  
                  if($reciv =~ /00D209/i){ #Wenn die Temperaturen empfangen wurden
                      my $t1 = substr($reciv,6,2);
                      my $t2 = substr($reciv,8,2);
                      my $t3 = substr($reciv,10,2);
                      my $t4 = substr($reciv,12,2);
                      my $t5 = substr($reciv,14,2);
                                                                                
                      #Hier werden die Temperaturen "decodiert" damit sie einen Sinn ergeben
                      $t1 =  (hex($t1)/2)-20;
                      $t2 =  (hex($t2)/2)-20;
                      $t3 =  (hex($t3)/2)-20;
                      $t4 =  (hex($t4)/2)-20;
                      $t5 =  (hex($t5)/2)-20;
      
                      #Wenn die GA's vergeben wurde, die Temperaturen auf die GA's senden
                      if($ga_komfort_temp ne ''){knx_write($ga_komfort_temp,$t1,9.001);}
                      if($ga_aul_temp ne ''){knx_write($ga_aul_temp,$t2,9.001);}
                      if($ga_zul_temp ne ''){knx_write($ga_zul_temp,$t3,9.001);}
                      if($ga_abl_temp ne ''){knx_write($ga_abl_temp,$t4,9.001);}
                      if($ga_fol_temp ne ''){knx_write($ga_fol_temp,$t5,9.001);}
                     
                      #Ab hier werden die RRD's mit den aktuellen Temperaturen aktualisiert:
                      update_rrd($Name_rrd_AUL,"",$t2);
                      update_rrd($Name_rrd_ZUL,"",$t3);
                      update_rrd($Name_rrd_ABL,"",$t4);
                      update_rrd($Name_rrd_FOL,"",$t5);
                     
                      plugin_log($plugname,'AUL: ' . $t2 . '°C, ZUL:' . $t3 . '°C, ABL: ' . $t4 . '°C, FOL: ' . $t5 . '°C, Komforttemp: ' . $t1 . '°C');
      
                  }elsif($reciv =~ /000C06/i){ #Wenn der Status fuer die Ventilatoren empfangen wurden
                      my $vent_zul = substr($reciv,6,2);
                      my $vent_abl = substr($reciv,8,2);
                      plugin_log($plugname,'ZUL: ' . hex($vent_zul) . '% ABL: ' . hex($vent_abl) . '%');
                      knx_write($ga_status_ventilator_zul,hex($vent_zul),5.001);
                      knx_write($ga_status_ventilator_abl,hex($vent_abl),5.001);   
                     
                  }elsif($reciv =~ /00CE0E/i){ #Wenn der Status der Ventilatorenstufe empfangen wurden
                      my $akt_stufe = substr($reciv,22,2);
                      if(hex($akt_stufe) == 1){
                          plugin_log($plugname,'AKT_STUFE: A');
                      }else{
                          plugin_log($plugname,'AKT_STUFE: ' . (hex($akt_stufe)-1));
                      }
                      knx_write($ga_aktstufe,hex($akt_stufe),5.005);                                                                               
      
                  }elsif($reciv =~ /000E04/i){ #Wenn der Status fuer die Bypassklappe empfangen wurden
                      my $bypass_prozent = substr($reciv,6,2);
                      plugin_log($plugname,'Bypass: ' . hex($bypass_prozent) . '%');               
                      knx_write($ga_status_bypass_prozent,hex($bypass_prozent),5.001);
      
                  }elsif($reciv =~ /00DE14/i){ #Wenn die Rueckmeldung der Betriebsstunden des Filters empfangen wurden
                      my $betriebsstunden_filter = substr($reciv,36,4);
                      if($debug>=3){plugin_log($plugname,'Betriebsstunden Filter Roh: '.$betriebsstunden_filter);}
                      plugin_log($plugname,'Betriebsstunden Filter: ' . hex($betriebsstunden_filter) . 'h');                
                      knx_write($ga_betriebsstunden_filter,hex($betriebsstunden_filter) . 'h',16.000);
                     
                  }elsif($reciv =~ /000402/i){ #Wenn die Rueckmeldung der Binaereingaenge empfangen wurden
                      my $zustand_badschalter = substr($reciv,8,1);
                      plugin_log($plugname,'Zustand Badezimmerschalter: ' . $zustand_badschalter);                
                      knx_write($ga_zustand_badschalter,$zustand_badschalter,1.001);
                     
                  }elsif($reciv =~ /00DA11/i){ #Wenn die Rueckmeldung der Stoermeldungen empfangen wurden
                      my $fehlerAlo = substr($reciv,6,2);
                      my $fehlerAhi = substr($reciv,30,2);
                      my $fehlerE = substr($reciv,8,2);
                      my $fehlerFilter = substr($reciv,22,2);
                      my $fehlerEA = substr($reciv,24,2);
                     
                      my $numAlo = 'A';
                      my $numAhi = 'A';
                      my $numE = 'A';
                      my $numEA = 'A';
                     
                      $numAlo .= unpack("B*",pack("H*",$fehlerAlo));
                      $numAhi .= unpack("B*",pack("H*",$fehlerAhi));
                      $numE .= unpack("B*",pack("H*",$fehlerE));
                      $numEA .= unpack("B*",pack("H*",$fehlerEA));
                     
                     
                      $fehlerAlo = reverse($numAlo); #Wandle den Wert in Binaer und drehe die Reihenfolge um. z.B 0x02 = 00000010 = 010000000
                      $fehlerAlo = index($fehlerAlo,'1')+1; # Zaehle an welcher Stelle die 1 auftaucht (von links gelesen) z.B. 01000000 = INDEX 2 = Fehler2
                     
                      if($fehlerAhi ne '00'){
                          $fehlerAhi = index(reverse($numAhi),'1')+9;
                      }else{
                          $fehlerAhi = '';
                      }
                     
                      $fehlerE = index(reverse($numE),'1')+1;
                      $fehlerEA = index(reverse($numEA),'1')+1;
                                                                                 
                      if($fehlerAhi == 16){$fehlerAhi = 0;}
                                                                                 
                      if($ga_fehlercode){ #Wenn die GA fuer das uebertragen den Fehlercodes eingertagen wurde, ab hier auswerten
                          if($fehlerAlo > 0){
                              plugin_log($plugname,'Aktueller Fehlercode: A' . $fehlerAlo);
                              knx_write($ga_fehlercode,'A' . $fehlerAlo,16.001);
                          }elsif($fehlerAhi ne ''){
                              plugin_log($plugname,'Aktueller Fehlercode: A' . $fehlerAhi);
                              knx_write($ga_fehlercode,'A' . $fehlerAhi,16.001);                       
                          }elsif($fehlerE > 0){
                              plugin_log($plugname,'Aktueller Fehlercode: E' . $fehlerE);
                              knx_write($ga_fehlercode,'E' . $fehlerE,16.001);
                          }elsif($fehlerEA > 0){
                              plugin_log($plugname,'Aktueller Fehlercode: EA' . $fehlerEA);
                              knx_write($ga_fehlercode,'EA' . $fehlerEA,16.001);
                          }else{
                              plugin_log($plugname,'Aktueller Fehlercode: keiner' );
                              knx_write($ga_fehlercode,'keiner',16.001);
                          }   
                      }
                     
                      if(hex($fehlerFilter) > 0){
                          plugin_log($plugname,'Aktueller Fehler: Filter Voll');
                          knx_write($ga_fehler_filter,1,1);
                      }else{
                          knx_write($ga_fehler_filter,0,1);
                      }              
                  }
              }else{
                  if($debug>=2){plugin_log($plugname,'Checksumme fehlerhaft! Gelesen: '.$checksum.' Berechnet: '.$rcv_checksum);}
              }
      } #ENDE Sub command_senden
      
      sub checksum_berechnen {   
          my $chk_datasum = $_[0];
          $rcv_checksum = 0;
          my $i;
           $chk_datasum = $chk_datasum . "AD"; #+173 fuer die Checksummenberechnung
              if($debug>=2){plugin_log($plugname,'String für die Berechnung der Checksumme: '.$chk_datasum);}
          $x07warschon = 0;
          $laenge = length($chk_datasum);
              for($i = 0; $i< $laenge; $i++) {
                  my $wertstring = substr($chk_datasum,$i,2);
                  if($debug>=3){plugin_log($plugname,'Zahl: '.$wertstring);}
                  my $wertbetrag = hex($wertstring);
                  if ($wertbetrag == 7) {
                      if ($x07warschon == 1) {
                          $x07warschon = 0;
                          $i++;
                          next;
                      } else {
                          $x07warschon = 1;
                      }
                  }
              $rcv_checksum += $wertbetrag;
                  if($debug>=3){plugin_log($plugname,'Summe: '.$rcv_checksum);}
              $i++;
          }
                  if($debug>=3){plugin_log($plugname,'Summe def: '.$rcv_checksum);}
      
          if($debug>=2){plugin_log($plugname,'Checksumme vor der Umwandlung: '.$rcv_checksum);}
          $rcv_checksum = sprintf "%x\n" , $rcv_checksum; #Mache aus Integer wieder HEX
          if($debug>=2){plugin_log($plugname,'Checksumme vor der Kürzung: '.$rcv_checksum);}
          $rcv_checksum = substr($rcv_checksum,-3,2); #Verwende nur die letzten beiden Stellen
          if($debug>=2){plugin_log($plugname,'Checksumme nach der Kürzung: '.$rcv_checksum);}
          return $rcv_checksum;
      } #Ende checksum_berechnen
      
       
      
      sub readConf
      {
          my $confFile = '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
          if (! -f $confFile)
          {
              plugin_log($plugname, " no conf file [$confFile] found!");
          }
          else
          {
              if($debug>=1){plugin_log($plugname, " reading conf file [$confFile].");}
              open(CONF, $confFile);
              my @lines = <CONF>;
              close($confFile);
              my $result = eval("@lines");
      #        ($result) and plugin_log($plugname, "conf file [$confFile] returned result[$result]");
              if ($@)
              {
                  if($debug>=2){plugin_log($plugname, " conf file [$confFile] returned:");}
                  my @parts = split(/\n/, $@);
                  if($debug>=2){plugin_log($plugname, " --> $_") foreach (@parts);}
              }
          }
      } # readConf
      Gruss Patrik alias swiss

      Kommentar


        Zitat von swiss Beitrag anzeigen
        Ich habe mich mal hin gesetzt und ein bischen was zusammen gestrickt...

        Hoffe das funktioniert so. Kann es wie üblich nicht selber testen daher bitte ich um hilfe
        Vielen Dank für die neue Version des Plugins.
        Ich habe gestern endlich mal meine ComfoAir richtig mit dem Wiregate verkabelt und das Plugin in Betrieb genommen und es hat auf Anhieb funktioniert :-)
        Bei einer Leseanforderung der Komfort-Temperatur, kommt diese mit den anderen Temperaturen als Antwort.

        Ich habe ein paar kleine Änderungen vorgenommen:
        Code:
        # 1
        my $cycle = 150;
        
        $plugin_info{$plugname.'_cycle'}  = $cycle;
        
        #2 
        if($debug>=1){plugin_log($plugname,'ENDE Aufruf durch GA');}
        
        #3
        if($debug>=2  && $sin){plugin_log($plugname,'reciv-direkt:     ' . $sin);}
        1. Der Cycle kann jetzt in der Conf definiert werden.
        2. Debug von 2 auf 1 gesetzt. Ich wunderte mich, warum bei $debug=1 im Log "Schnittstelle erfolgreich geöffnet" auftauchte und dann nichts mehr. Jetzt sieht man, warum.
        3. es erfolgt nur noch ein Logeintrag, wenn wirklich Daten da sind. Ansonsten hat man 2500 leere Einträge pro Abfrage. Ein Plugin-Aufruf führt sonst zu über 17000 Log-Einträgen (war bei mir der Fall, weil ich das Plugin aktiviert hatte, bevor die ComfoAir wieder am Strom hing...).


        Frage:
        Wofür ist diese Abfrage?
        Code:
            if(($plugin_info{$plugname.'_time'}+$plugin_info{$plugname.'_cycle'}) >= $plugin_info{$plugname.'_last'}){
                return;
            }
        Bei mir sorgt sie dafür, daß das Plugin nur bei jedem zweiten zyklischen Aufruf durchläuft und Werte liefert. Kommentiere ich das "Return" aus, funktioniert alles problemlos.
        Gruß, Carsten

        Kommentar


          Hallo Carsten

          Freut mich dass es soweit funktioniert

          Das mit den Debug Level muss ich nochmal genauer ansehen. Default sollte 1 sein. Alles andere ist nicht wirklich sinvoll im normalen Betrieb.

          Zu der if abfrage mit dem Zeitstempel...

          Das habe ich absichtlich eingebaut um das Plugin künstlich auszubremsen. Der Grund dafür ist folgender...

          Es gibt Leute die haben NUR das ComfoAir Plugin am laufen. dies führt dazu dass das Plugin in einer Endlosschleife (unabhängig vom Zyklus) läuft. Dadurch entsteht innert kurzer Zeit das Problem dass mehr Anfragen auf die ComfoAir gefeuert werden als diese verarbeiten kann... Desshalb habe ich eine abfrage eingebaut die Prüft ob das Plugin in zu kurzer Zeit durchläuft und somit in kurzer Zeit die Kommunikation zur ComfoAir blokiert.

          Die Frage ist nur. Wesshalb das Plugin bei dir bei jedem zweiten Durchlauf in den Return läuft... Kann auch damit zusammen hängen dass bei die das WG auch nicht den eingestellten Zyklus einhält und das Plugin zu schnell wieder aufgerufen wird.

          Ich würde dass auf jeden Fall drinn lassen oder eventuell optimieren aber auskommentieren kann zu Problemen führen.
          Gruss Patrik alias swiss

          Kommentar


            Level 2 hatte ich nur, als die Anlage sich nicht meldete (wie auch, ohne Strom...).

            Ich werde mir das mit dem Abbruch mal genauer ansehen, komme aber frühestens nächstes Wochenende dazu.
            Gruß, Carsten

            Kommentar


              Hallo zusammen,

              ich war auf der Suche nach einem Plugin für die Steuerung meiner KWL, dabei bin ich auf dieses Exemplar gestossen.
              Fix beide Dateien runtergeladen und auf´s Wiregate geschoben, dabei sind mir aber Fragen aufgekommen:

              - Ist dieses Plugin überhaupt für eine Steuerung rein über IOs (als eine GA mit 0 oder 1 je Stufe) geeignet (da in der Conf in Zeile 51 entweder seriell oder per Moxa entschieden werden muß)
              - Welche Logik verfolgt die Anlage? In beiden Dateien konnte ich nur eine Aufrufzeit von 150s sehen, aber keine Hysterse oder dergleichen. Einzig eine "Komforttemperatur" ist vorgesehen, aber was soll die machen?

              Bevor ich mich darin versenke frage ich daher lieber mal nach...

              Kommentar


                Hallo

                Das Plugin ist für die Ansteuerng der Zender ComfoAir 350 programmiert. Diese wird per RS232 entweder direkt oder über einen Moxa an das Wiregate angebunden.

                Im Plugin gibt es beide Möglichkeiten die Stufen zu setzen. Entweder über einen 8bit Wert oder über 4 getrennte 1bit Objekte. Die 1bit Objekte sind z.B. für die Steuerung über normale KNX Taster geeignet.

                Was ich aus deiner Frage nicht verstehe...

                Was meinst du mit IO??
                Hast du eine ComfoAir 350 luxe?
                Was möchtest du tun? -> Logik??
                Gruss Patrik alias swiss

                Kommentar


                  Hallo Swiss,

                  ich habe eine Wolf CWL 300 welche per Wiregate Multi-IO eingebunden ist, die weitere Beschreibung hatte ich der Übersichtlichkeit in einen Link gepackt. Grundsätzlich sind die IO nur ein "billiger" Ersatz für einen Aktorkanal, sobald ein Kanal geschlossen wird ändert sich die Lüftungsstufe. Wenn bspw. Kanal 2 (-> Stufe 2) und Kanal 3 (-> Stufe 3) beide geschlossen sind (per Wiregate also eine 1 senden) dann zieht die jeweils höchste Stufe. Alles in allem also eine recht simple Steuerung, vom Hersteller selber kommt daher auch nur ein Stufenschalter mit 0-1-2-3 mitgeliefert.

                  Die notwendigen Temperaturen habe ich bereits per Wiregate-Sensoren in den einzelnen Rohrleitungen erfasst, Ziel soll nun sein falls die Zuluft eine bestimmten Temperatur SOLL (bspw. 21°C) überschreitet die Anlage auf Stufe 1 runterzufahren und bei SOLL + 2K komplett auszustellen. Weitere Logiken (aus bei zu kalt usw.) sollen folgen, manuelles Übersteuern (15 Min Stufe 3 bei Dusche o.ä.) wäre super.

                  So, hoffe das nun klarer beschrieben zu haben!

                  Danke & Gruß,
                  Hannatz

                  Kommentar


                    Zitat von Hannatz Beitrag anzeigen
                    ich habe eine Wolf CWL 300 welche per Wiregate Multi-IO eingebunden ist, ...Wenn bspw. Kanal 2 (-> Stufe 2) und Kanal 3 (-> Stufe 3) beide geschlossen sind (per Wiregate also eine 1 senden) dann zieht die jeweils höchste Stufe. Alles in allem also eine recht simple Steuerung, vom Hersteller selber kommt daher auch nur ein Stufenschalter mit 0-1-2-3 mitgeliefert.
                    Diese Plugin ist für Deine Anlage nicht geeignet. Es ist ausschließlich für eine Zehnder ComfoAir CA350, welche per RS232 kommunizieren kann. Also wirklich Befehle entgegennehmen und bestätigen, bzw Temperaturen liefern kann.
                    Gruß, Carsten

                    Kommentar


                      Mist, das hab ich mir fast gedacht. Werde dann mal mit nem Schwellwert-Plugin basteln und vorher mal etwas Brain in das Konzept stecken...

                      Gruss Hannatz

                      Kommentar


                        @swiss
                        Vielen Dank für die Plugin-Überarbeitung.
                        Leider klappt das mit den Rückmeldungen bei mir nicht wie von Northman beschrieben.
                        Muss in der config auch etwas angepasst werden?
                        Gruß -mfd-
                        KNX-UF-IconSet since 2011

                        Kommentar


                          Hallo mfd,

                          hast Du in der Conf alle GAs für die Temperaturen definiert?

                          Code:
                          #Hier werden die Gruppenadressen für die Rückmeldung der Temperaturen vergeben: (Nicht vergeben=inaktiv)
                          $ga_aul_temp = '14/1/6'; #GA DPT 9.001 für die Aussenlufttemperatur
                          $ga_zul_temp = '14/1/7'; #GA DPT 9.001 für die Zulufttemperatur
                          $ga_abl_temp = '14/1/8'; #GA DPT 9.001 für die Ablufttemperatur
                          $ga_fol_temp = '14/1/9'; #GA DPT 9.001 für die Fortlufttemperatur
                          $ga_komfort_temp = '14/1/22'; #GA DPT 9.001 für die Komforttemperatur
                          "$ga_komfort_temp" ist neu (zumindest im Vergleich zu der Version, die ich vorher im Einsatz hatte).
                          Gruß, Carsten

                          Kommentar


                            Ah, das mit der zusätzlichen Komforttemperatur-GA hatte ich übersehen.
                            Das klappt jetzt wie es soll.
                            Ich hatte keine Beispiel-Conf zur aktuellen Plugin-Version gefunden, deshalb dachte ich es hätte sich nichts geändert...
                            Gruß -mfd-
                            KNX-UF-IconSet since 2011

                            Kommentar


                              Ich muss leider nochmal wegen der Komforttemperatur und der aktuellen Lüftungsstufe nachhaken.

                              Wenn ich $ga_komforttemp zum Setzen der Komforttemperatur (write) in der CV anlege und $ga_komfort_temp zum Lesen (read) klappt es zwar, dass nach einem Neustart des WG der letzte eingestellte Wert übernommen wird, allerdings wird der angezeigte Wert nicht mehr aktualisiert wenn ich eine andere Komforttemperatur in der Visu einstelle...

                              Sind die Version des Plugins und der Beispielconfig im SVN aktuell, dann würde ich das nochmal komplett neu installieren.
                              Gruß -mfd-
                              KNX-UF-IconSet since 2011

                              Kommentar


                                Ja dass das nicht mehr funktioniert liegt daran, dass es nun 2 KO's sind an stelle von 1. Aber ich habe mal einen schnellen Workaround dafür erstellt:

                                Code:
                                # Plugin zur Ansteuerung einer Zender ComfoAir
                                # Version 1.6.9 15.07.2014 BETA
                                # Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
                                # Aufbau moeglichst so, dass man unterhalb der Einstellungen nichts veraendern muss!
                                # - Neu mit der Moeglichkeit zur Anbindung über einen Moxa NPort von Fechter65 (https://knx-user-forum.de/members/fechter65.html)
                                # - Neustrukturierung des Codes von Fechter65 (https://knx-user-forum.de/members/fechter65.html)
                                # - Besseres Fehlerhandling bei der Verarbeitung der Reuckmeldungen von swiss (https://knx-user-forum.de/members/swiss.html)
                                # - Neu nun mit direktem abfragen der Stufe nach dem setzen und auswerten der Komforttemperatur von swiss (https://knx-user-forum.de/members/swiss.html)
                                # - Neu mit der Möglichkeit die Ventilationsstufe direkt zu setzen von swiss (https://knx-user-forum.de/members/swiss.html)
                                # - Neu mit der Möglichkeit die Ventilatorstufe für Zuluft und Abluft getrennt zu setzen (0% - 100%) von Netsrac80 (https://knx-user-forum.de/members/netsrac80.html)
                                # - Korrektur Stufe direkt setzen. Senden / empfangen hat nun das gleiche Mapping 1=Auto, 2=Sufe1, 3=Stufe2, 4=Stufe3
                                # - Neu mit Rückmeldung auf Lesetelegramme
                                # - Bugfix: Themperatur wird nach dem Verstellen nicht direkt als Status zurückgegeben
                                
                                 
                                
                                ####################
                                ###Einstellungen:###
                                ####################
                                
                                #BITTE ab sofort die Einstellungen unter conf.d vornemen. Damit bleiben die Einstellungen auch bei einem Update erhalten.
                                 
                                
                                ######################
                                ##ENDE Einstellungen##
                                ######################
                                
                                
                                #Ab hier nichts mehr aendern.
                                #Hauptverarbeitung
                                
                                
                                #Erzeuge Variablen fuer die Zuordnung der Steuerfunktionen zu den Gruppenadressen:
                                my $ga_stufeabwesend = ''; #1bit Trigger fuer Stufe "Abwesend". 1=Aktivieren
                                my $ga_stufe1 = ''; #1bit Trigger fuer Stufe1. 1=Aktivieren
                                my $ga_stufe2 = ''; #1bit Trigger fuer Stufe2. 1=Aktivieren
                                my $ga_stufe3 = ''; #1bit Trigger fuer Stufe3. 1=Aktivieren
                                my $ga_stufe_setzen = ''; # GA DPT 5.005 zum direkten setzen der Stufe (1=Abwesend, 2=Stufe1, 3=Stufe2, 4=Stufe3)
                                my $ga_komforttemp = ''; #GA DPT 9.001 zum setzen der Komforttemperatur
                                my $ga_drehzahl_ventilator_zul = ''; #GA DPT 5.001 zum setzen der Zuluftdrehzahl
                                my $ga_drehzahl_ventilator_abl = ''; #GA DPT 5.001 zum setzen der Abluftdrehzahl
                                my $ga_reset_filter = ''; #1bit Trigger fuer das Zuruecksetzen des Betriebsstundenzaehlers des Filters. 1=Reset
                                my $ga_reset_error = ''; #1bit Trigger fuer das zuruecksetzen der KWL nach einem Fehler. 1=Reset
                                 
                                
                                #Hier werden die Gruppenadressen fuer die Rueckmeldungen vergeben: (Nich vergeben = inaktiv)
                                my $ga_status_ventilator_zul = ''; #GA DPT 5.001 fuer Status Ventilator Zuluft %
                                my $ga_status_ventilator_abl = ''; #GA DPT 5.001 fuer Status Ventilator Abluft %
                                my $ga_status_bypass_prozent = ''; #GA DPT 5.001 fuer Status Bypassklappe %
                                my $ga_betriebsstunden_filter = ''; #GA DPT 16.000 fuer die Rueckmeldung der Betribsstunden des Filters
                                my $ga_zustand_badschalter = ''; #GA DPT 1.001 fuer die Rueckmeldung des Zustandes des Badezimmerschalters
                                my $ga_fehler_filter = ''; #GA DPT 1.001 fuer den Zustand des Filters. 0=OK, 1=Filter Voll
                                my $ga_fehlercode = ''; #GA DPT 16.000 fuer die Ausgabe des Fehlercodes als Text
                                my $ga_aktstufe = ''; #GA DPT 5.005 liefert den Wert für die aktuelle Stufe (1=A, 2=Stufe1, 3=Stufe2, 4=Stufe3)
                                 
                                #Hier werden die Gruppenadressen für die Rueckmeldung der Temperaturen vergeben: (Nicht vergeben=inaktiv)
                                my $ga_aul_temp = ''; #GA DPT 9.001 für die Aussenlufttemperatur
                                my $ga_zul_temp = ''; #GA DPT 9.001 für die Zulufttemperatur
                                my $ga_abl_temp = ''; #GA DPT 9.001 für die Ablufttemperatur
                                my $ga_fol_temp = ''; #GA DPT 9.001 für die Fortlufttemperatur
                                my $ga_komfort_temp = ''; #GA DPT 9.001 für die Komforttemperatur
                                 
                                #Zuordnung der Namen fuer 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
                                 
                                #Pfad zur seriellen Schnittstelle oder dem USB-Seriell-Wandler:
                                my $schnittstelle = '/dev/ttyUSB-2-4';
                                 
                                
                                #Angaben für die Kommunikation über den UDP-Port einer MOXA [diese Einstellungen reichen aus, d.h. auf dem Wiregate muss unter "Seriell/LAN/Socketverbindungen" KEINE Socketverbindung erstellt werden
                                my $socknum = ""; # Eindeutige Nummer des Sockets
                                my $send_ip = ""; # SendeIP (UDP)
                                my $send_port = ""; # Sendeport (UDP)   
                                my $recv_ip = ""; # EmpfangsIP (UDP)
                                my $recv_port = ""; # Empfangsport (UDP)
                                 
                                
                                # Kommunikationsart
                                my $Kom_Art = "S"; # "S" = seriell; "M" = Moxa
                                 
                                
                                # Dauer einer Abfrage
                                my $Zaehler = "2500"; #Mit dieser Variable Zaehler wird beeinflusst, wie lange das Plugin auf den Abschluss einer Rückmeldung der KWL wartet; empfohlener Wert für seriell: 2500; für Moxa: 250
                                 
                                # Debug level 0 = nur die wichtigsten Infos, 1 = Alle Zustaende, 2 = Rohdaten (nur für Fehlersuche)
                                my $debug=0;
                                 
                                 
                                #Weitere Variablen die benoetigt werden -> NICHT veraendern!
                                my $seriel;
                                my $sin; #Serial Input = Empangener Datenstrom
                                my $cin; #Counter Input =  Länge des Datenpackets
                                my $laenge; #Länge des empfangenen Datenstrings nach dem kürzen
                                 
                                my $checksum = 0; #Checksumme
                                my @hex; #Hilfsarray für die Checksummenberechnung
                                my $x07warschon; #Hilfsvariable für die Checksummenberechnung
                                 
                                &readConf(); #conf.d einlesen
                                 
                                my $return_value2;
                                my $daten;
                                my $reciv;
                                my $reciv_all;
                                my $ack = pack("H*","07F3");
                                my $rcv_checksum;
                                 
                                # Zyklischer Aufruf nach restart, empfang GA oder 1/2 der einstellung rrd (typisch 150sek).
                                $plugin_info{$plugname.'_cycle'}  = 150;
                                
                                use Device::SerialPort;
                                use Time::Local;
                                
                                 
                                #Einrichten der Seriellen Schnittstelle fuer die Kommunikation mit der ComfoAir falls die Schnittstelle auf "S" steht
                                if ($Kom_Art eq "S"){
                                             $seriel = Device::SerialPort->new($schnittstelle) || die "Kann $schnittstelle nicht öffnen! ($!)\n";
                                             $seriel->baudrate(9600);
                                             $seriel->parity("none");
                                             $seriel->databits(8);
                                             $seriel->stopbits(1);
                                             if($debug>=1){plugin_log($plugname,'Schnittstelle: ' . $schnittstelle . ' erfolgreich geöffnet')};
                                }elsif ($Kom_Art eq "M"){
                                    if (!$socket[$socknum]) { # socket erstellen
                                            $socket[$socknum] = IO::Socket::INET->new(LocalPort => $recv_port,
                                                                      Proto => "udp",
                                                                      LocalAddr => $recv_ip,
                                                                      PeerPort  => $send_port,
                                                                      PeerAddr  => $send_ip,
                                                                      ReuseAddr => 1
                                                                       )
                                        or return ("open of $recv_ip : $recv_port failed: $!");
                                        $socksel->add($socket[$socknum]); # add socket to select
                                        $plugin_socket_subscribe{$socket[$socknum]} = $plugname; # Plugin an Socket "anmelden"
                                        if($debug>=1){plugin_log($plugname,'Socket: ' . $socknum . ' erfolgreich geöffnet')};
                                        return "opened Socket $socknum";
                                    }
                                }
                                
                                
                                ###############################################################################################
                                ###############################################################################################
                                ## Ab hier werden die Befehle die vom KNX kommen für die ComfoAir uebersetzt und gesendet... ##
                                ###############################################################################################
                                ###############################################################################################
                                 
                                 if ($msg{'apci'} eq "A_GroupValue_Read"){ #Hier werden die Lesetelegramme verarbeitet und beantwortet
                                    if ($msg{'dst'} eq $ga_aktstufe){
                                            $daten = "00CD00";
                                            if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                            $return_value2 = command_senden($daten);        
                                    }elsif($msg{'dst'} eq $ga_status_bypass_prozent){
                                            $daten = "000D00";
                                            if($debug>=1){plugin_log($plugname,'Bypass Zustand abrufen');}
                                            $return_value2 = command_senden($daten);
                                    }elsif($msg{'dst'} eq $ga_status_ventilator_zul or $msg{'dst'} eq $ga_status_ventilator_abl){
                                            $daten = "000B00";
                                            if($debug>=1){plugin_log($plugname,'Ventilator Status abrufen');}
                                            $return_value2 = command_senden($daten);
                                    }elsif($msg{'dst'} eq $ga_aul_temp or $msg{'dst'} eq $ga_zul_temp or $msg{'dst'} eq $ga_abl_temp or $msg{'dst'} eq $ga_fol_temp or $msg{'dst'} eq $ga_komfort_temp){
                                            $daten = "00D100";
                                            plugin_log($plugname,'Temperatur abrufen');
                                            $return_value2 = command_senden($daten);
                                    }
                                    
                                }elsif ($msg{'apci'} eq "A_GroupValue_Write"){ #Hier werden neue Werte vom KNX an die ComfoAir gesendet
                                    if ($msg{'dst'} eq $ga_stufeabwesend && knx_read($msg{'dst'},0,1) == 1) {
                                        $daten = "00990101";
                                        plugin_log($plugname,'Stufe abwesend setzen');
                                        $return_value2 = command_senden($daten);
                                            if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                                $daten = "00CD00";
                                                if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                                $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 setzen');
                                        $return_value2 = command_senden($daten);
                                            if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                                $daten = "00CD00";
                                                if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                                $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 setzen');
                                        $return_value2 = command_senden($daten);
                                            if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                                $daten = "00CD00";
                                                if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                                $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 setzen');
                                        $return_value2 = command_senden($daten);
                                            if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                                $daten = "00CD00";
                                                if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                                $return_value2 = command_senden($daten);
                                            }
                                    }elsif ($msg{'dst'} eq $ga_stufe_setzen) {
                                        my $stufenwert = knx_read($msg{'dst'},0,5.005);
                                        $daten = "0099010" . $stufenwert;
                                        plugin_log($plugname,'Stufe direkt setzen auf: ' . $stufenwert);
                                        $return_value2 = command_senden($daten);
                                            if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                                $daten = "00CD00";
                                                if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                                $return_value2 = command_senden($daten);
                                            }
                                    }elsif ($msg{'dst'} eq $ga_komforttemp) {
                                        my $komforttemp = knx_read($msg{'dst'},0,9.001);
                                        if($ga_komfort_temp ne ''){knx_write($ga_komfort_temp,$komforttemp,9.001);}
                                        plugin_log($plugname,'Komforttemp auf: ' . $komforttemp . '°C setzen');
                                        my $temphex = ($komforttemp + 20)*2; #Rechne die Temperatur fuer die ComfoAir um
                                        $temphex = sprintf "%x" , $temphex; # Mache aus Integer HEX
                                        $daten = "00D301" . $temphex;
                                        $return_value2 = command_senden($daten);
                                    }elsif ($msg{'dst'} eq $ga_reset_filter && knx_read($msg{'dst'},0,1) == 1) {
                                        $daten = "00DB0400000001";
                                        knx_write($ga_fehler_filter,0,1);
                                        plugin_log($plugname,'Filter zuruecksetzen');
                                        $return_value2 = command_senden($daten);
                                    }elsif ($msg{'dst'} eq $ga_reset_error && knx_read($msg{'dst'},0,1) == 1) {
                                        $daten = "00DB0401000000";
                                        plugin_log($plugname,'Fehler zuruecksetzen');
                                        $return_value2 = command_senden($daten);
                                    }elsif ($msg{'dst'} eq $ga_drehzahl_ventilator_zul) {
                                        my $drehzahl_zul = knx_read($msg{'dst'},0,5.001);
                                        plugin_log($plugname,'Drehzahl Zuluftluefter auf: ' . $drehzahl_zul . '% setzen');
                                        $plugin_info{$plugname."_zuluftdrehzahl_1"} = $drehzahl_zul;
                                       
                                        my $temp_abluftdrehzahl = sprintf "%x",$plugin_info{$plugname."_abluftdrehzahl_1"};
                                        my $hex_zuluftdrehzahl = sprintf "%x" , $drehzahl_zul; # Mache aus Integer HEX
                                        $daten = "00CF090F" . $temp_abluftdrehzahl.'0F0F'. $hex_zuluftdrehzahl.'0F0F0F0F';
                                        $return_value2 = command_senden($daten);
                                    }elsif ($msg{'dst'} eq $ga_drehzahl_ventilator_abl) {
                                        my $drehzahl_abl = knx_read($msg{'dst'},0,5.001);
                                        plugin_log($plugname,'Drehzahl Abluftluefter auf: ' . $drehzahl_abl . '% setzen');
                                        $plugin_info{$plugname."_abluftdrehzahl_1"} = $drehzahl_abl;
                                        
                                        my $temp_zuluftdrehzahl = sprintf "%x",$plugin_info{$plugname."_zuluftdrehzahl_1"};
                                        my $hex_abluftdrehzahl = sprintf "%x" , $drehzahl_abl; # Mache aus Integer HEX
                                        $daten = "00CF090F" . $hex_abluftdrehzahl.'0F0F'. $temp_zuluftdrehzahl.'0F0F0F0F';
                                        $return_value2 = command_senden($daten);
                                        if($debug>=2){plugin_log($plugname,'Drehzahl Abluftlüfter DATEN: ' . $daten . ' mit '. $drehzahl_abl. ' setzen! Antwort:'.$return_value2); }
                                    }
                                    if($debug>=2){plugin_log($plugname,'ENDE Aufruf durch GA');}
                                    return;
                                            
                                } else { # zyklischer Aufruf
                                    if(($plugin_info{$plugname.'_time'}+$plugin_info{$plugname.'_cycle'}) >= $plugin_info{$plugname.'_last'}){
                                        return;
                                    }
                                    $plugin_info{$plugname.'_time'} = time();
                                   
                                    # 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;
                                    $plugin_subscribe{$ga_stufe_setzen}{$plugname} = 1;
                                    $plugin_subscribe{$ga_komforttemp}{$plugname} = 1;
                                    $plugin_subscribe{$ga_reset_filter}{$plugname} = 1;
                                    $plugin_subscribe{$ga_reset_error}{$plugname} = 1;
                                    $plugin_subscribe{$ga_drehzahl_ventilator_zul}{$plugname} = 1;
                                    $plugin_subscribe{$ga_drehzahl_ventilator_abl}{$plugname} = 1;
                                    
                                    $plugin_subscribe{$ga_aktstufe}{$plugname} = 1;
                                    $plugin_subscribe{$ga_status_bypass_prozent}{$plugname} = 1;
                                    $plugin_subscribe{$ga_status_ventilator_zul}{$plugname} = 1;
                                    $plugin_subscribe{$ga_status_ventilator_abl}{$plugname} = 1;
                                    $plugin_subscribe{$ga_aul_temp}{$plugname} = 1;
                                    $plugin_subscribe{$ga_zul_temp}{$plugname} = 1;
                                    $plugin_subscribe{$ga_abl_temp}{$plugname} = 1;
                                    $plugin_subscribe{$ga_fol_temp}{$plugname} = 1;
                                    $plugin_subscribe{$ga_komfort_temp}{$plugname} = 1;
                                   
                                
                                ####################################################################################################
                                ####################################################################################################
                                ## Ab hier werden zyklisch diverse Werte von der ComfoAir abgefragt und an das KNX uebertragen... ##
                                ####################################################################################################
                                ####################################################################################################
                                
                                  
                                    $daten = "00D100";
                                    plugin_log($plugname,'Temperatur abrufen');
                                    $return_value2 = command_senden($daten);
                                   
                                    if($ga_status_ventilator_zul && $ga_status_ventilator_abl){ #Nur wenn beide GA's vergeben sind, dann die Zustaende der Ventilatoren abfragen
                                        $daten = "000B00";
                                        if($debug>=1){plugin_log($plugname,'Ventilator Status abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                            
                                    if($ga_status_bypass_prozent){ #Nur wenn die GA vergeben ist, dann Zustand Bypassklappe abfragen
                                        $daten = "000D00";
                                        if($debug>=1){plugin_log($plugname,'Bypass Zustand abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                            
                                    if($ga_betriebsstunden_filter){ #Nur wenn die GA vergeben ist, die Betriebsstunden des Filters abfragen
                                        $daten = "00DD00";
                                        if($debug>=1){plugin_log($plugname,'Betriebsstunden Filter abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                            
                                    if($ga_zustand_badschalter){ #Nur wenn die GA vergeben ist, die Binaereingaenge abfragen
                                        $daten = "000300";
                                        if($debug>=1){plugin_log($plugname,'Binäreingänge abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                            
                                    if($ga_aktstufe){ #Nur wenn die GA vergeben ist, die Ventilationsstufe abfragen
                                        $daten = "00CD00";
                                        if($debug>=1){plugin_log($plugname,'Ventilationsstufe abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                            
                                    if($ga_fehlercode){ #Nur wenn die GA vergeben ist, werden hier die Stoermeldungen abgefragt
                                        $daten = "00D900";
                                        if($debug>=1){plugin_log($plugname,'Störungen abrufen');}
                                        $return_value2 = command_senden($daten);
                                    }
                                
                                    if($debug>=2){plugin_log($plugname,'ENDE Zyklische Abfrage');}
                                    return;
                                }
                                 
                                 
                                # Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir uebertragen
                                sub command_senden{
                                    my $data = $_[0];
                                    if($debug>=2){plugin_log($plugname,'data: ' . $data);}
                                    $checksum = checksum_berechnen($data);
                                    if($debug>=2){plugin_log($plugname,'Checksumme aus der Subroutine: '.$checksum);}
                                    my $command = pack("H*","07F0" . $data . $checksum . "070F");
                                    my $commandhex = $command;
                                   
                                    $commandhex =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
                                    if($debug>=2){plugin_log($plugname,'transmit: ' . $commandhex);} #Zeigt im Pluginlog das fertige Datenpaket, dass uebertragen wird
                                             if ($Kom_Art eq "S"){   
                                                             $seriel->write($command); #Befehl an die ComfoAir senden
                                             } elsif ($Kom_Art eq "M"){   
                                                             $plugin_info{$plugname.'_debug'} = $command;
                                                             syswrite($socket[$socknum], $command);
                                             }
                                    $reciv = '';
                                    $cin = '';
                                    $sin = '';
                                       
                                    $|=1;
                                    my $exit=0;
                                    while($exit < $Zaehler)
                                    {
                                        if ($Kom_Art eq "S"){
                                             ($cin, $sin) = $seriel->read(45);
                                        }elsif ($Kom_Art eq "M"){
                                                                 $sin ='';
                                                                 if ($fh) { # Antwort auslesen
                                                                                recv($fh,$sin,80,0);
                                                                 }
                                                                 $cin = length($sin);
                                        }
                                        if($cin > 0){
                                            $sin = unpack "H*", $sin;
                                            $reciv .= $sin;
                                            $exit=0;
                                        }else{
                                            $exit++
                                        }
                                       
                                        if($debug>=2){plugin_log($plugname,'reciv-direkt:     ' . $sin);}
                                    
                                            if($reciv =~ /070f/i){ 
                                                if (substr($reciv,(length($reciv)-6),6) ne '07070f'){            
                                                    last;
                                                }
                                            }
                                    }#Ende While  
                                
                                    if ($Kom_Art eq "S"){
                                        $seriel->write($ack); #ACK senden
                                        if($debug>=2){plugin_log($plugname,'ACK senden');}
                                    } elsif ($Kom_Art eq "M"){
                                        syswrite($socket[$socknum], $ack); #ACK senden
                                        if($debug>=2){plugin_log($plugname,'ACK senden');}
                                    }
                                
                                    if($reciv eq ""){
                                        if($debug>=2){plugin_log($plugname,'FEHLER: Keine Daten empfangen!');}
                                        return;
                                    }
                                   
                                    while ((length($reciv) > 3) && (substr($reciv,(length($reciv)-4),4) ne '070f')) #solange das Ende nicht 070f lautet
                                    {
                                                    if($debug>=2){plugin_log($plugname,'String vor Kuerzung Ende: '.$reciv);}
                                                    $reciv = substr($reciv,0,-2); #String um die letzten zwei Zeichen kürzen
                                                    if($debug>=2){plugin_log($plugname,'String nach Kuerzung Ende: '.$reciv);}
                                    }  
                                   
                                 
                                        #Hier wird der empfangene String um Start- und Endbyte gekürzt
                                        $laenge = length($reciv); #Laenge des Antworttelegramms ermitteln
                                        $reciv = substr($reciv,0,($laenge-4)); #Entferne 07f0 vom Ende
                                       
                                        if(substr($reciv,(length($reciv)-4),4) eq '07f3'){
                                            $reciv = substr($reciv,0,($laenge-4));
                                            if($debug>=2){plugin_log($plugname,'String ohne 07f3: '.$reciv);}
                                        }
                                
                                        if($debug>=2){plugin_log($plugname,'Erste 4 Byte des Datenpakets: '.(substr($reciv,0,4)));}
                                
                                                                           
                                        while ((length($reciv) > 3) && (substr($reciv,0,4)) ne '07f0'){
                                            $reciv = substr($reciv,2); #falls noch falsche Zeichen am Anfang des Strings enthalten sind, werden diese hier entfernt.
                                            if($debug>=2){plugin_log($plugname,'reciv gekuerzt: '.$reciv);}
                                        }
                                       
                                        $reciv = substr($reciv,4);
                                        if($debug>=2){plugin_log($plugname,'String ohne 07f0 am Anfang: '.$reciv);}
                                       
                                        #Test einer Methode falls aussversehen mehrere Datenpakete auf einmal im Datenstring enthalten sind...
                                        if($reciv =~ /07f307f0/i){
                                            my @dataarray=split(/07f307f0/,$reciv);
                                            $reciv = $dataarray[0];
                                        }
                                
                                                            
                                        #Nun wird die Checksumme gelesen und aus dem Datenstring entfernt
                                        $checksum = 0;
                                        $checksum = substr($reciv,-2,2);
                                        if($debug>=2){plugin_log($plugname,'Checksumme gelesen: '.$checksum);}
                                        $laenge = length($reciv); #Laenge des Antworttelegramms ermitteln
                                        $reciv = substr($reciv,0,($laenge-2));
                                        if($debug>=2){plugin_log($plugname,'Datenpaket ohne Checksumme: '.$reciv);}
                                
                                        #Hier wird die Subroutine für die Berechnung der Checksumme aufgerufen und das Ergebnis in $rcv_checksum zurück gegeben
                                        $rcv_checksum = checksum_berechnen($reciv);
                                
                                        
                                #######################################################################
                                #######################################################################
                                ## Ab hier werden die Rueckmeldungen von der ComfoAir ausgewertet... ##
                                #######################################################################
                                #######################################################################
                                
                                
                                        if($rcv_checksum eq $checksum){ #Hier wird geprüft ob die Checksumme korrekt ist
                                            if($debug>=2){plugin_log($plugname,'Checksumme OK ');}
                                            
                                            #Hier werden die doppelten 07 aus dem Antwortstring entfernt.
                                            if($debug>=2){plugin_log($plugname,'String vor 07 bereinigung:  '.$reciv);}
                                            while ($reciv =~ s/0707/07/) {}
                                            if($debug>=2){plugin_log($plugname,'String nach 07 bereinigung: '.$reciv);}
                                            
                                            if($reciv =~ /00D209/i){ #Wenn die Temperaturen empfangen wurden
                                                my $t1 = substr($reciv,6,2);
                                                my $t2 = substr($reciv,8,2);
                                                my $t3 = substr($reciv,10,2);
                                                my $t4 = substr($reciv,12,2);
                                                my $t5 = substr($reciv,14,2);
                                                                                                          
                                                #Hier werden die Temperaturen "decodiert" damit sie einen Sinn ergeben
                                                $t1 =  (hex($t1)/2)-20;
                                                $t2 =  (hex($t2)/2)-20;
                                                $t3 =  (hex($t3)/2)-20;
                                                $t4 =  (hex($t4)/2)-20;
                                                $t5 =  (hex($t5)/2)-20;
                                
                                                #Wenn die GA's vergeben wurde, die Temperaturen auf die GA's senden
                                                if($ga_komfort_temp ne ''){knx_write($ga_komfort_temp,$t1,9.001);}
                                                if($ga_aul_temp ne ''){knx_write($ga_aul_temp,$t2,9.001);}
                                                if($ga_zul_temp ne ''){knx_write($ga_zul_temp,$t3,9.001);}
                                                if($ga_abl_temp ne ''){knx_write($ga_abl_temp,$t4,9.001);}
                                                if($ga_fol_temp ne ''){knx_write($ga_fol_temp,$t5,9.001);}
                                               
                                                #Ab hier werden die RRD's mit den aktuellen Temperaturen aktualisiert:
                                                update_rrd($Name_rrd_AUL,"",$t2);
                                                update_rrd($Name_rrd_ZUL,"",$t3);
                                                update_rrd($Name_rrd_ABL,"",$t4);
                                                update_rrd($Name_rrd_FOL,"",$t5);
                                               
                                                plugin_log($plugname,'AUL: ' . $t2 . '°C, ZUL:' . $t3 . '°C, ABL: ' . $t4 . '°C, FOL: ' . $t5 . '°C, Komforttemp: ' . $t1 . '°C');
                                
                                            }elsif($reciv =~ /000C06/i){ #Wenn der Status fuer die Ventilatoren empfangen wurden
                                                my $vent_zul = substr($reciv,6,2);
                                                my $vent_abl = substr($reciv,8,2);
                                                plugin_log($plugname,'ZUL: ' . hex($vent_zul) . '% ABL: ' . hex($vent_abl) . '%');
                                                knx_write($ga_status_ventilator_zul,hex($vent_zul),5.001);
                                                knx_write($ga_status_ventilator_abl,hex($vent_abl),5.001);   
                                               
                                            }elsif($reciv =~ /00CE0E/i){ #Wenn der Status der Ventilatorenstufe empfangen wurden
                                                my $akt_stufe = substr($reciv,22,2);
                                                if(hex($akt_stufe) == 1){
                                                    plugin_log($plugname,'AKT_STUFE: A');
                                                }else{
                                                    plugin_log($plugname,'AKT_STUFE: ' . (hex($akt_stufe)-1));
                                                }
                                                knx_write($ga_aktstufe,hex($akt_stufe),5.005);                                                                               
                                
                                            }elsif($reciv =~ /000E04/i){ #Wenn der Status fuer die Bypassklappe empfangen wurden
                                                my $bypass_prozent = substr($reciv,6,2);
                                                plugin_log($plugname,'Bypass: ' . hex($bypass_prozent) . '%');               
                                                knx_write($ga_status_bypass_prozent,hex($bypass_prozent),5.001);
                                
                                            }elsif($reciv =~ /00DE14/i){ #Wenn die Rueckmeldung der Betriebsstunden des Filters empfangen wurden
                                                my $betriebsstunden_filter = substr($reciv,36,4);
                                                if($debug>=3){plugin_log($plugname,'Betriebsstunden Filter Roh: '.$betriebsstunden_filter);}
                                                plugin_log($plugname,'Betriebsstunden Filter: ' . hex($betriebsstunden_filter) . 'h');                
                                                knx_write($ga_betriebsstunden_filter,hex($betriebsstunden_filter) . 'h',16.000);
                                               
                                            }elsif($reciv =~ /000402/i){ #Wenn die Rueckmeldung der Binaereingaenge empfangen wurden
                                                my $zustand_badschalter = substr($reciv,8,1);
                                                plugin_log($plugname,'Zustand Badezimmerschalter: ' . $zustand_badschalter);                
                                                knx_write($ga_zustand_badschalter,$zustand_badschalter,1.001);
                                               
                                            }elsif($reciv =~ /00DA11/i){ #Wenn die Rueckmeldung der Stoermeldungen empfangen wurden
                                                my $fehlerAlo = substr($reciv,6,2);
                                                my $fehlerAhi = substr($reciv,30,2);
                                                my $fehlerE = substr($reciv,8,2);
                                                my $fehlerFilter = substr($reciv,22,2);
                                                my $fehlerEA = substr($reciv,24,2);
                                               
                                                my $numAlo = 'A';
                                                my $numAhi = 'A';
                                                my $numE = 'A';
                                                my $numEA = 'A';
                                               
                                                $numAlo .= unpack("B*",pack("H*",$fehlerAlo));
                                                $numAhi .= unpack("B*",pack("H*",$fehlerAhi));
                                                $numE .= unpack("B*",pack("H*",$fehlerE));
                                                $numEA .= unpack("B*",pack("H*",$fehlerEA));
                                               
                                               
                                                $fehlerAlo = reverse($numAlo); #Wandle den Wert in Binaer und drehe die Reihenfolge um. z.B 0x02 = 00000010 = 010000000
                                                $fehlerAlo = index($fehlerAlo,'1')+1; # Zaehle an welcher Stelle die 1 auftaucht (von links gelesen) z.B. 01000000 = INDEX 2 = Fehler2
                                               
                                                if($fehlerAhi ne '00'){
                                                    $fehlerAhi = index(reverse($numAhi),'1')+9;
                                                }else{
                                                    $fehlerAhi = '';
                                                }
                                               
                                                $fehlerE = index(reverse($numE),'1')+1;
                                                $fehlerEA = index(reverse($numEA),'1')+1;
                                                                                                           
                                                if($fehlerAhi == 16){$fehlerAhi = 0;}
                                                                                                           
                                                if($ga_fehlercode){ #Wenn die GA fuer das uebertragen den Fehlercodes eingertagen wurde, ab hier auswerten
                                                    if($fehlerAlo > 0){
                                                        plugin_log($plugname,'Aktueller Fehlercode: A' . $fehlerAlo);
                                                        knx_write($ga_fehlercode,'A' . $fehlerAlo,16.001);
                                                    }elsif($fehlerAhi ne ''){
                                                        plugin_log($plugname,'Aktueller Fehlercode: A' . $fehlerAhi);
                                                        knx_write($ga_fehlercode,'A' . $fehlerAhi,16.001);                       
                                                    }elsif($fehlerE > 0){
                                                        plugin_log($plugname,'Aktueller Fehlercode: E' . $fehlerE);
                                                        knx_write($ga_fehlercode,'E' . $fehlerE,16.001);
                                                    }elsif($fehlerEA > 0){
                                                        plugin_log($plugname,'Aktueller Fehlercode: EA' . $fehlerEA);
                                                        knx_write($ga_fehlercode,'EA' . $fehlerEA,16.001);
                                                    }else{
                                                        plugin_log($plugname,'Aktueller Fehlercode: keiner' );
                                                        knx_write($ga_fehlercode,'keiner',16.001);
                                                    }   
                                                }
                                               
                                                if(hex($fehlerFilter) > 0){
                                                    plugin_log($plugname,'Aktueller Fehler: Filter Voll');
                                                    knx_write($ga_fehler_filter,1,1);
                                                }else{
                                                    knx_write($ga_fehler_filter,0,1);
                                                }              
                                            }
                                        }else{
                                            if($debug>=2){plugin_log($plugname,'Checksumme fehlerhaft! Gelesen: '.$checksum.' Berechnet: '.$rcv_checksum);}
                                        }
                                } #ENDE Sub command_senden
                                
                                sub checksum_berechnen {   
                                    my $chk_datasum = $_[0];
                                    $rcv_checksum = 0;
                                    my $i;
                                     $chk_datasum = $chk_datasum . "AD"; #+173 fuer die Checksummenberechnung
                                        if($debug>=2){plugin_log($plugname,'String für die Berechnung der Checksumme: '.$chk_datasum);}
                                    $x07warschon = 0;
                                    $laenge = length($chk_datasum);
                                        for($i = 0; $i< $laenge; $i++) {
                                            my $wertstring = substr($chk_datasum,$i,2);
                                            if($debug>=3){plugin_log($plugname,'Zahl: '.$wertstring);}
                                            my $wertbetrag = hex($wertstring);
                                            if ($wertbetrag == 7) {
                                                if ($x07warschon == 1) {
                                                    $x07warschon = 0;
                                                    $i++;
                                                    next;
                                                } else {
                                                    $x07warschon = 1;
                                                }
                                            }
                                        $rcv_checksum += $wertbetrag;
                                            if($debug>=3){plugin_log($plugname,'Summe: '.$rcv_checksum);}
                                        $i++;
                                    }
                                            if($debug>=3){plugin_log($plugname,'Summe def: '.$rcv_checksum);}
                                
                                    if($debug>=2){plugin_log($plugname,'Checksumme vor der Umwandlung: '.$rcv_checksum);}
                                    $rcv_checksum = sprintf "%x\n" , $rcv_checksum; #Mache aus Integer wieder HEX
                                    if($debug>=2){plugin_log($plugname,'Checksumme vor der Kürzung: '.$rcv_checksum);}
                                    $rcv_checksum = substr($rcv_checksum,-3,2); #Verwende nur die letzten beiden Stellen
                                    if($debug>=2){plugin_log($plugname,'Checksumme nach der Kürzung: '.$rcv_checksum);}
                                    return $rcv_checksum;
                                } #Ende checksum_berechnen
                                
                                 
                                
                                sub readConf
                                {
                                    my $confFile = '/etc/wiregate/plugin/generic/conf.d/'.basename($plugname,'.pl').'.conf';
                                    if (! -f $confFile)
                                    {
                                        plugin_log($plugname, " no conf file [$confFile] found!");
                                    }
                                    else
                                    {
                                        if($debug>=1){plugin_log($plugname, " reading conf file [$confFile].");}
                                        open(CONF, $confFile);
                                        my @lines = <CONF>;
                                        close($confFile);
                                        my $result = eval("@lines");
                                #        ($result) and plugin_log($plugname, "conf file [$confFile] returned result[$result]");
                                        if ($@)
                                        {
                                            if($debug>=2){plugin_log($plugname, " conf file [$confFile] returned:");}
                                            my @parts = split(/\n/, $@);
                                            if($debug>=2){plugin_log($plugname, " --> $_") foreach (@parts);}
                                        }
                                    }
                                } # readConf
                                Übrigens ist die Neuste Version hier in diesem Thema zu finden. Die SVN ist einzig aus dem einfachen Grund nicht mehr aktuell, weil ich seit der Umstellung von SF mit dem login/checkin auf Kriegsfuss stehe. Ich bekomme das nicht mehr hin -.-
                                Gruss Patrik alias swiss

                                Kommentar

                                Lädt...
                                X