Ankündigung

Einklappen
Keine Ankündigung bisher.

neues Plugin für Denon AVR-X1100W per Telnet

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

    [wiregate] neues Plugin für Denon AVR-X1100W per Telnet

    Hallo,

    inspiriert durch das Script von Makki habe ich eine überarbeitet Version für meinen AVR-X1100W geschrieben..
    An dieser Stelle vielen Dank Makki für dein Plugin und einige Tipps.
    Das Script benötigt kein Wiregate internes Socket.

    Das Plugin unterstützt momentan:
    - Power ON/OFF/MUTE für Hauptzone und Zone 2 mit Rückmeldung
    - Lautstärke mit Rückmeldung
    - Wahl der Quelle für die Hauptzone

    Das Telnet interface läuft bei mir, bis jetzt, sehr stabil.

    Das besondere an der Telnetschnittstelle ist, das nur carriage return <CR> als Befehlsabschluss akzeptiert wird, ein line feed <LF> stört die Telnetverbindung.
    Sobald man gezielt einen Status abfragt, bekommt man viel zu viele Antworten, auch solche die nichts mit der Anfrage zu tun haben.
    Manchmal mehr als 10 Antworten.
    Auch hier wird jede Zeile mit einem <CR> abgeschlossen.
    Die Abfrage des Status und setzten der Lautstärke ist sehr speziell, der Kommawert wird durch eine dreistellige Zahl dargestellt.

    z.B.
    40,0 - 40,5 - 41
    wird per Telnet so übertragen:
    40 - 405 - 41

    Code:
    # Plugin Denon-AVR
    # Kommunikation via TCP über socket
    # Version: 0.1 2011-01-31
    # Denon-AVR Plugin von Makki überarbeitet von LSD
    # Version lsd_0.1 2015.06.10
    
    #Deaktivieren
    #$plugin_info{$plugname.'_cycle'} = 0;
    #return "deactivated";
    
    # COMPILE_PLUGIN
    
    my $debug = 1;
    my $pwm = '15/3/0'; # Power Main 1bit
    my $pwz = '15/3/1'; # Power Zone2 1bit
    my $vlm = '15/3/2'; # Lautstärke Main 0-100 dpt: 5.010
    my $vlz = '15/3/3'; # Lautstärke Zone2 0-100 dpt: 5.010
    my $vlmt = '15/3/4'; # Lautstärke Main up 1bit dpt: 1.017
    my $vlzt = '15/3/5'; # Lautstärke Zone 2 down 1bit dpt: 1.017
    my $vlms = '15/3/6'; # Status Lautstärke Main 0-100 dpt: 5.010
    my $vlzs = '15/3/7'; # Status Lautstärke Zone2 0-100 dpt: 5.010
    my $select = '15/3/8'; # FAVORITE 1 (ZMFAVORITE1<CR>) dpt:5.010
    my $icm = '15/3/9' ; # Imputwähler Main dpt: 5.010
    my $icz = '15/3/10' ; # Imputwähler Zone 2 dpt: 5.010
    my $mum = '15/3/11' ; # Mute Main
    my $muz = '15/3/12' ; # Mute Zone 2
    
     
    my $denon_ip = "192.168.255.213:23";
    my $socknum = 1;
    
    $plugin_info{$plugname.'_cycle'} = 10;
    
    # Plugin an Gruppenadresse "anmelden"
    $plugin_subscribe{$pwm}{$plugname} = 1; #Plugin ausführen, sobald ein GA angesprochen wird
    $plugin_subscribe{$pwz}{$plugname} = 1;
    $plugin_subscribe{$vlm}{$plugname} = 1;
    $plugin_subscribe{$vlz}{$plugname} = 1;
    $plugin_subscribe{$vlmt}{$plugname} = 1;
    $plugin_subscribe{$vlzt}{$plugname} = 1;
    $plugin_subscribe{$mum}{$plugname} = 1;
    $plugin_subscribe{$muz}{$plugname} = 1;
    $plugin_subscribe{$select}{$plugname} = 1;
    
    
    
    #
    ##
    ### Script Start Grund des Scriptes
    my $event=undef;
    if (!$plugin_initflag) {
        $event='restart'; # Restart des daemons / Reboot
    } elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}) {
        $event='modified'; # Plugin modifiziert
    } elsif (%msg) {
         $event='bus'; # Bus
    } elsif ($fh) {
        $event='socket'; # Netzwerktraffic
    } else {
        $event='cycle'; # Zyklus
    }
    if ($debug == 1){
        plugin_log($plugname, "1 Startgrund - Event: ".$event)
    }
    ###
    ##
    #
    
    ### Loop schleifen Erkennung
    if ($plugin_cache{$plugname.'_LOOP'} == 1) {
        if ($debug > 0){
        plugin_log($plugname, "1  Loop - Loop erkannt Script beenden");
        }
        $plugin_cache{$plugname.'_LOOP'} = 0;
        return "Loop";
    }
    
    if (!$socket[$socknum]) { # socket erstellen
            if ($debug == 1){
                    plugin_log($plugname, "2  socket - Socket:$socknum zur IP $denon_ip wird aufgebaut ");
            }
    
    $socket[$socknum] = new IO::Socket::INET (
                    PeerHost => $denon_ip,
                    PeerPort => '23',
                    Proto => 'tcp',
                    Timeout => 1,
                    ReadTimeout => 0.5,
                    WriteTimeout => 0.5,
                    Blocking => 0
            ) or return ("open of $denon_ip  failed: $!");
    
        #$socksel->add($socket[$socknum]); # add socket to select
    
        #$plugin_socket_subscribe{$socket[$socknum]} = $plugname; # subscribe plugin
        return "opened Socket $socknum";
    }else{
            if ($debug == 1){
                    plugin_log($plugname, "2a socket - Socket:$socknum zur IP $denon_ip besteht ");
                    plugin_log($plugname, "2b socket - Inhalt fh: $fh ");
                    
            }
    }
    
    ### Zyklscher oder Initial Aufruf
    if ($event eq 'cycle' or $event eq 'modified' or $event eq 'restart') {
        if ($debug == 1){
            plugin_log($plugname, "1  Cycle - Zuekilisch oder Initial Start");
    
        }
            
    my $vals;
    my $read;
    my @split;
    my $runden=0;
    
    #Power On Off bei Hauptzone und Zone 2
     syswrite($socket[$socknum], "PW?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     while($runden <= $vals) {
       if ($debug == 1 or $debug == 2){
          plugin_log($plugname, "2a Cycel - Split PW? ".$runden." : ".$split[$runden]);
       }
      if ($split[$runden] eq "ZMOFF" or $split[$runden] eq "PWSTANDBY") {
       if ($plugin_cache{$plugname.'_ZM'} == 0) {
          if ($debug == 2){
            plugin_log($plugname, '2b Cycle - ZMOFF erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_ZM'} = 0;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($pwm ,0,1);
           if ($debug == 1 or $debug == 2){
        plugin_log($plugname, "2b Cycle - ZMOFF erkannt");
           }
      }
     } elsif ($split[$runden] eq "ZMON")  {
       if ($plugin_cache{$plugname.'_ZM'} == 1) {
          if ($debug == 2){
            plugin_log($plugname, '2b Cycle - ZMON erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_ZM'} = 1;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($pwm ,1,1);
            if ($debug == 2){
         plugin_log($plugname, "2b Cycle - ZMON erkannt");
            }
         }
       } elsif ($split[$runden] eq "Z2OFF")  {
        if ($plugin_cache{$plugname.'_Z2'} == 0) {
          if ($debug == 2){
            plugin_log($plugname, '2b Cycle - Z2OFF erkannt - keine Aenderung');
          }
        } else {
         $plugin_cache{$plugname.'_Z2'} = 0;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($pwz ,0,1);
           if ($debug == 1 or $debug == 2){
            plugin_log($plugname, "2b Cycle - Z2OFF erkannt");
           }
         }
       } elsif ($split[$runden] eq "Z2ON")  {
        if ($plugin_cache{$plugname.'_Z2'} == 1) {
          if ($debug == 2){
            plugin_log($plugname, '$split[$runden]2b Cycle - Z2ON erkannt - keine Aenderung');
          }
        } else {$split[$runden] =
         $plugin_cache{$plugname.'_Z2'} = 1;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($pwz ,1,1);
           if ($debug == 1 or $debug == 2){
            plugin_log($plugname, "2b Cycle - Z2ON erkannt");
           }
         }
        }
    
     $runden++;
     }
    
    #Lautstärke ermillung bei Hauptzone
     $runden=0;
     syswrite($socket[$socknum], "MV?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     while($runden <= $vals) {
       if ($debug == 3){
          plugin_log($plugname, "2a Cycel - Split MV? ".$runden." : ".$split[$runden]);
       }
    #Prüfen ob Antwort auf MV<Zahl> besteht (z.B. MVxx oder MVxxx)
      if ($split[$runden] =~ /^MV\d/) {
    #erste zwei Zeichen entfernen    
        $split[$runden] =~ s/^..//;
    #Prüfen ob zwei oder dreistellig -> xxy wird nach xx.y gewandelt
        if ($split[$runden] =~ /\d\d\d/) {
           $split[$runden] = $split[$runden]/10;
         }
         if ($debug == 3){
          plugin_log($plugname, "2b Cycel - Erkannte MV Lautstärke $split[$runden]");
        }
    # Wert von 0 - 100 nach 0 - 255 umrechnrn    
        #$split[$runden] = sprintf("%.0f",($split[$runden]*2.55));
        #$split[$runden] = $split[$runden]*10;
        if ($debug == 3){
          plugin_log($plugname, "2c Cycel - Umwandlung MV % nach Binaer: $split[$runden]");
        }  
    
        knx_write($vlms ,$split[$runden],5.010);
           if ($debug == 1 or $debug == 3){
        plugin_log($plugname, "2d Cycle - MV erkannt $split[$runden] geschrieben ");
           }
            
     }
      
     $runden++;
     }
    
    #Lautstärke ermillung bei Zone 2
     $runden=0;
     syswrite($socket[$socknum], "Z2?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     while($runden <= $vals) {
       if ($debug == 4){
          plugin_log($plugname, "2a Cycel - Split Z2? ".$runden." : ".$split[$runden]);
       }
    #Prüfen ob Antwort auf Z2<Zahl> besteht (z.B. MVxx oder MVxxx)
      if ($split[$runden] =~ /^Z2\d/) {
    #erste zwei Zeichen entfernen    
        $split[$runden] =~ s/^..//;
    #Prüfen ob zwei oder dreistellig -> xxy wird nach xx.y gewandelt
        if ($split[$runden] =~ /\d\d\d/) {
           $split[$runden] = $split[$runden]/10;
         }
         if ($debug == 4){
          plugin_log($plugname, "2b Cycel - Erkannte Z2 Lautstärke $split[$runden]");
        }
    # Wert von 0 - 100 nach 0 - 255 umrechnrn    
        #$split[$runden] = sprintf("%.0f",($split[$runden]*2.55));
    
        if ($debug == 4){
          plugin_log($plugname, "2c Cycel - Umwandlung Z2 % nach Binaer: $split[$runden]");
        }  
    
        knx_write($vlzs ,$split[$runden],5.010);
           if ($debug == 1 or $debug == 4){
        plugin_log($plugname, "2d Cycle - Z2 erkannt $split[$runden] geschrieben ");
           }
            
     }
      
     $runden++;
     }
     
    #Source Ermittlung Main und Zone 2
     syswrite($socket[$socknum], "SI?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     $runden=0;
     
      while($runden <= $vals) {
       if ($debug == 5){
          plugin_log($plugname, "2a Cycel - Split SI? ".$runden." : ".$split[$runden]);
       }
       if ($split[$runden] =~ /^SI\w/) {
    #erste zwei Zeichen entfernen    
        $split[$runden] =~ s/^..//;
        
         if ($debug == 5){
          plugin_log($plugname, "2b Cycel - SI: $split[$runden]");
         }  
        }
    
     $runden++;
     }
    
    #Mute Main
     syswrite($socket[$socknum], "MU?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     $runden=0;
     
      while($runden <= $vals) {
       if ($debug == 6){
          plugin_log($plugname, "2a Cycel - Split MU? ".$runden." : ".$split[$runden]);
       }
       if ($split[$runden] eq "MUOFF") {
          if ($plugin_cache{$plugname.'_MMUTE'} == 0) {
          if ($debug == 6){
            plugin_log($plugname, '2b Cycle - MMUTE off erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_MMUTE'} = 0;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($mum ,0,1);
           if ($debug == 1 or $debug == 6){
        plugin_log($plugname, "2b Cycle - Main Mute off");
           }
         }
       } elsif ($split[$runden] eq "MUON") {
           if ($plugin_cache{$plugname.'_MMUTE'} == 1) {
          if ($debug == 6){
            plugin_log($plugname, '2b Cycle - Main MUTE on erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_MMUTE'} = 1;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($mum ,1,1);
           if ($debug == 1 or $debug == 6){
        plugin_log($plugname, "2b Cycle - Main Mute on");
           }
         }
       }  
      
     $runden++;
     }
     
    #Mute Zone2
     syswrite($socket[$socknum], "Z2MU?"."\r");
     $vals=sysread($socket[$socknum],$read,10240);
     @split=split("\r",$read);
     $vals=@split;
     $vals--;
     $runden=0;
     
      while($runden <= $vals) {
       if ($debug == 6){
          plugin_log($plugname, "2a Cycel - Split Z2MU? ".$runden." : ".$split[$runden]);
       }
       if ($split[$runden] eq "Z2MUOFF") {
          if ($plugin_cache{$plugname.'_ZMUTE'} == 0) {
          if ($debug == 6){
            plugin_log($plugname, '2b Cycle - Zone2 MUTE off erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_ZMUTE'} = 0;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($muz ,0,1);
           if ($debug == 1 or $debug == 6){
        plugin_log($plugname, "2b Cycle - Zone2 Mute off");
           }
         }
       } elsif ($split[$runden] eq "Z2MUON") {
           if ($plugin_cache{$plugname.'_ZMUTE'} == 1) {
          if ($debug == 6){
            plugin_log($plugname, '2b Cycle - Zone2 MUTE on erkannt - keine Aenderung');
          }
       } else {
         $plugin_cache{$plugname.'_MMUTE'} = 1;
         $plugin_cache{$plugname.'_LOOP'} = 1;
         knx_write($muz ,1,1);
           if ($debug == 1 or $debug == 6){
        plugin_log($plugname, "2b Cycle - Zone2 Mute on");
           }
         }
       }  
      
     $runden++;
     }
    return "3  Cycle - Anzahl der Befehle: $runden";
    }
    
    ### Aktion ausführen nach einer Modifizirung Variabeln initalisieren
    if ($event eq 'modified' or $event eq 'restart') {
        if ($debug == 1){
            plugin_log($plugname, "3 - Initalisirung gestartet");
    
        }
    }
    
    
    
    ### Power Main angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $pwm ) {
        if ($debug == 1){
            plugin_log($plugname, "3 PM - Power Main on/off" );
        }
    
     #my @vals = qw/PWSTANDBY PWON/; #1bit on/off
     my @vals = qw/ZMOFF ZMON/; #1bit on/off
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 PM - erkannt $vals[$msg{'data'}]";
     
    }
    
    ### Power Zone2 angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $pwz ) {
        if ($debug == 1){
            plugin_log($plugname, "3 ZM - Power Zone2 on/off" );
        }
        
     my @vals = qw/Z2OFF Z2ON/; #1bit on/off
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 ZM - erkannt $vals[$msg{'data'}]";
        
    }
    
    ### Lautstaerke Master dynamische 0-255 angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $vlm ) {
        if ($debug == 1){
            plugin_log($plugname, "3 - Lautstaerke Master dynamisch" );
        }
        #$msg{'data'}=hex($msg{'data'});
        #$msg{'data'}=100/255*$msg{'data'};
        #$msg{'data'}=sprintf "%.1f", $msg{'data'};
        syswrite($socket[$socknum], sprintf("MV%02d\r",$msg{'data'}));
        return "4 - erkannt MV: $msg{'data'}]";
        
    }
    
    ### Lautstaerke Zone2 dynamische 0-255 angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $vlz ) {
        if ($debug == 1){    
            plugin_log($plugname, "3 - Lautstaerke Zone2 dynamisch" );
        }
        #$msg{'data'}=sprintf "%.1f", 100/255*hex($msg{'data'});
        syswrite($socket[$socknum], sprintf("Z2%02d\r",$msg{'data'}));
        return "4 - erkannt Z2: $msg{'data'}]";
    }
    
    ### Lautstaerke Master Up/Down angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $vlmt ) {
        if ($debug == 1){
            plugin_log($plugname, "3 - Lautstaerke Master up/down" );
        }
     my @vals = qw/MVDOWN MVUP/; #1bit on/off
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 - erkannt $vals[$msg{'data'}]";
        
    
    }
    
    ### Lautstaerke Zone2 Up/Down angesprochen wurde
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $vlzt ) {
        if ($debug == 1){    
            plugin_log($plugname, "3 - Lautstaerke Zone2 up/down" );
        }
         my @vals = qw/Z2DOWN Z2UP/; #1 on/off
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 - erkannt $vals[$msg{'data'}]";
        
    }
    
    ### MUTE Main on/off
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $mum ) {
        if ($debug == 1){    
            plugin_log($plugname, "3 - Mute Main" );
        }
         my @vals = qw/MUOFF MUON/;
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 - erkannt $vals[$msg{'data'}]";
        
    }
    
    ### MUTE Zone2 on/off
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $muz ) {
        if ($debug == 1){    
            plugin_log($plugname, "3 - Mute Zone2" );
        }
         my @vals = qw/Z2MUOFF Z2MUON/;
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     return "4 - erkannt $vals[$msg{'data'}]";
        
    }
    
    ### Quelle waehlen
    if ($msg{'apci'} eq "A_GroupValue_Write" and $msg{'dst'} eq $select ) {
        if ($debug == 1){    
            plugin_log($plugname, "3 - Quelle waehlen" );
        }
         #my @vals = qw/SISAT\/CBL SIMPLAY/; #1 on/off
         my @vals = qw /SISAT\/CBL SIMPLAY SIIRP SIIRADIO SIPHONO SICD SITUNER SIDVD SIBD SITV SIDVR SIGAME SIV.AUX SIDOCK SIIPOD SINET\/USB SINAPSTER SILASTFM SIFLICKR SIFAVORITES SSIERVER SIUSB\/IPOD/;
     syswrite($socket[$socknum], $vals[$msg{'data'}]."\r");
     select(undef, undef, undef, 2.5); #kleine Pause
     syswrite($socket[$socknum], "PSMULTEQ:AUDYSSEY"."\r");
     
     return "4 - erkannt $vals[$msg{'data'}]";
        
    }
    
    
    
    return "ende";
    Auswahl_175.png

    Als Basis für die Befehle habe ich im I-Net ein Dokument mit dem Titel "Denon_Maranze__AV_SR_NR_PROTOCOL_V02" gefunden.
    Hier kann noch sehr viel ausgebaut werden.
    Zuletzt geändert von lo4dro; 23.06.2015, 12:50.
    --
    Gruß
    Lothar

    #2
    Hallo Lothar,

    Vielen Dank fürs Teilen Deiner Arbeit!

    na dann kann ich nun vielleicht doch auch den Denon ohne RS232 Schnittstelle wieder ins Auge fassen. Bin auf weitere Erfahrungen zur Stabilität der Telnet Schnittstelle gespannt. Bitte berichte unbedingt weiter.

    Gruß
    Andi
    Gruß
    Andi

    Kommentar


      #3
      Zitat von tger977 Beitrag anzeigen
      Hallo Lothar,

      Vielen Dank fürs Teilen Deiner Arbeit!

      na dann kann ich nun vielleicht doch auch den Denon ohne RS232 Schnittstelle wieder ins Auge fassen. Bin auf weitere Erfahrungen zur Stabilität der Telnet Schnittstelle gespannt. Bitte berichte unbedingt weiter.

      Gruß
      Andi
      Bei mir funktioniert das ganze bis jetzt Störungsfrei, ich polle all 10 Sekunden die Schnittstelle und das 7x24h lang.
      Am besten testest du das mit deinem System mal selbst.
      Was für einen Denon AVR hast du?
      --
      Gruß
      Lothar

      Kommentar

      Lädt...
      X