Ankündigung

Einklappen
Keine Ankündigung bisher.

Hilfe bei einem Onkyo Plugin?

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

    [WireGate-Plugin] Hilfe bei einem Onkyo Plugin?

    Hallo,

    Der Thread wurde Editiert. Die ehemalige Frage hat sich erledigt.

    Anbei ein funktionierendes Plugin für das Onkyo IPSC Protokol.

    Was geht:
    Ein auschalten beider Zonen
    Source Wahl
    Lautstärke up/down step
    Grundlautstärke wird gesendet (aber noch nicht richtig interpretiert)

    Was geht nicht wirklich:
    Lautstärke per Helligkeitswert (Onkyo hat da einen sehr seltsamen Bereich festgelegt. Plugin wird upgedated)

    Was noch gar nicht geht:
    - Stati vom Onkyo empfangen

    Was kommt noch:
    - Receiver Standby Sperre wenn von Radio auf Fernsehen umgeschalten wird


    Code:
    #### Plugin für Radio mit Hilfe des Onkyo 414 #####
    #### Vorraussetzung iscp ####
    
    
    
    ## TODO:
    # Wenn Fernseher an nicht aus sondern umschalten
    # Stati abfragen
    # Firstboot
    
    
    
    ##### Radio on/off ###
    my $Radio_GA = '13/1/32';
    ######################
    
    #### Amp Status GA ######
    my $onkyo = '13/1/31';
    #########################
    
    ##### sources ############
    my $FM = '13/1/36';
    my $Sat = '13/1/37';
    my $Video = '13/1/38';
    my $Game = '';
    ##########################
    
    ##### receive Volume #####
    my $onkyo_volume = '13/1/33'; #DPT 5.001
    my $faktor = "8/100";
    ##########################
    
    ##### Volume step up/down ######
    my $onkyo_vol_up_down= '13/1/34';
    my $vol_up_data = "01";
    my $vol_down_data = "09";
    ################################
    
    ### 2nd Amp ###
    my $verstaerker = '13/1/2';
    ########################
    
    ###### firstboot ############
    my $start_volume = "05";
    
    
    #############################
    
    
    ## definition für iscp, Onkyo Receiver
    my $Port = "60128";
    my $IP = "192.168.178.68";
    
    my $folder = "/home/onkyo-iscp/./onkyo-iscp";
    # my $iscp_folder = "/home/onkyo-iscp/./onkyo-iscp 192.168.178.68";
    # /home/onkyo-iscp/./onkyo-iscp 192.168.178.68
    $plugin_subscribe{$Radio_GA}{$plugname}=1;
    $plugin_subscribe{$onkyo_volume}{$plugname}=1;
    $plugin_subscribe{$onkyo_vol_up_down}{$plugname}=1;
    $plugin_subscribe{$FM}{$plugname}=1;
    $plugin_subscribe{$Sat}{$plugname}=1;
    $plugin_subscribe{$Video}{$plugname}=1;
    $plugin_info{$plugname.'_cycle'} = 0;
    
    
    
    my %commandlist = ("power", "PWR", 
    "volume_main", "MVL",  
    "volume_down", "MVLDOWN",
    "volume_up", "MVLUP",
    "main_selector", "SLI", 
    "zone2", "ZPW",
    "z2_selector", "SLZ",
    "z2_vol", "ZVL",
    );
    my %sources = (
    "VIDEO", "10",
    "SAT", "01",
    "GAME", "02",
    "FM", "24",
    "PC", "05",
    );
    ##### set Source ############################## 
    if (($msg{'dst'} eq ($FM)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {my $cmd = "$commandlist{'main_selector'}$sources{'FM'}";
    command_exec($cmd);}}
    
    if (($msg{'dst'} eq ($Sat)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {my $cmd = "$commandlist{'main_selector'}$sources{'SAT'}";
    command_exec($cmd);}}
    
    if (($msg{'dst'} eq ($Video)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {my $cmd = "$commandlist{'main_selector'}$sources{'VIDEO'}";
    command_exec($cmd);}}
    
    if (($msg{'dst'} eq ($Game)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {my $cmd = "$commandlist{'main_selector'}$sources{'GAME'}";
    command_exec($cmd);}}
    ################################################
    
    ####### Volume step #################
    if (($msg{'dst'} eq ($onkyo_vol_up_down)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {
    if ($msg{'data'} eq $vol_up_data) {
    my $cmd = "$commandlist{'volume_main'}$commandlist{'volume_up'}";
    command_exec($cmd);}
    
    if ($msg{'data'} eq $vol_down_data) {
    my $cmd = "$commandlist{'volume_main'}$commandlist{'volume_down'}";
    command_exec($cmd);}}}
    #####################################
    
    ###### set volume DPT5 (receive Volume)##########
    if (($msg{'dst'} eq ($onkyo_volume)))
    { if ($msg{'apci'} eq 'A_GroupValue_Write') 
    { my $volume1 = decode_dpt(0,$msg{'data'},5.001);
    my $volume2 = ($volume1*$faktor);
    my $volume = sprintf("%02d", $volume1);
    # return $volume;
    my $cmd = "$commandlist{'volume_main'}$volume";
    command_exec($cmd);}}
    ###### End Volume receive ########################
    
    
    
    
    
    ##### Ein Ausschalten #######
    if ($msg{'dst'} eq ($Radio_GA))
    { 
    if ($msg{'apci'} eq 'A_GroupValue_Write') 
    {if ($msg{'data'} == 01 ) {
    knx_write($verstaerker,1,1);
    my $cmd = "$commandlist{'power'}01";
    knx_write($onkyo,1,1);
    knx_write($onkyo_volume,$start_volume,5.001);
    my $cmd3 = "$commandlist{'zone2'}01";
    knx_write($FM,1,1);
    command_exec($cmd, $cmd3)  ;
    #my $shcmd = "$folder $IP $commandlist{'main_selector'} $sources{'FM'}";
    #my $debug = `$shcmd`;
    #my $shcmd2 = "$folder $IP $commandlist{'z2_selector'} $sources{'FM'}";
    #my $debug = `$shcmd2`;
    }
    if ($msg{'data'} == 00 ) {
    my $cmd1 = "$commandlist{'power'}00";
    my $cmd2 = "$commandlist{'zone2'}00";
    command_exec($cmd1, $cmd2)  ;
    
    }
    }}
    
     sub command_exec {
    foreach (@_) {
    my $cmd = $_;
    plugin_log($plugname, $cmd);
    use strict;
    use IO::Socket;
    
    
    # my $cmd="PWR01";
    #my $cmd=$ARGV[0];
    my @iscpPacket;
    my $IP = "192.168.178.68";
    my $Port = "60128";
    $iscpPacket[0] = chr(0x49); 
    $iscpPacket[1] = chr(0x53); 
    $iscpPacket[2] = chr(0x43); 
    $iscpPacket[3] = chr(0x50); 
    $iscpPacket[4] = chr(0x00);
    $iscpPacket[5] = chr(0x00);
    $iscpPacket[6] = chr(0x00);
    $iscpPacket[7] = chr(0x10); 
    $iscpPacket[8] = chr(0x00);
    $iscpPacket[9] = chr(0x00);
    $iscpPacket[10] = chr(0x00);
    $iscpPacket[11] = chr(3+length($cmd));
    $iscpPacket[12] = chr(0x01); 
    $iscpPacket[13] = chr(0x00); 
    $iscpPacket[14] = chr(0x00); 
    $iscpPacket[15] = chr(0x00);
    $iscpPacket[16] = chr(0x21); 
    $iscpPacket[17] = chr(0x31); 
    
    for(my $a=18;$a<=18+length($cmd);$a++) #18
    {
    my $s = substr($cmd,$a-18,1); # 18
    $iscpPacket[$a] = $s;
    }
    
    $iscpPacket[18+length($cmd)] = chr(0x0D); # 18
    
    print #@iscpPacket;
    
    my $host = $IP;
    my $port = $Port;
    
    my $SOCK = new IO::Socket::INET(PeerAddr => $host, PeerPort => $port, Proto => 'tcp', timeout => 3) || die "Socket Error: $!\n";
    $SOCK->autoflush(1);
    print $SOCK @iscpPacket;
    my $datagram;
    $SOCK->recv($datagram, 32);
    close ($SOCK);
    }}
    Wenn mir jemand sagen kann wie ich den socket zum Abfragen der Stati offen halten kann ohne die Perl Plugins komplett zu blockieren wäre ich sehr Dankbar!!

    Irgendwie kann man einen Daemon draus machen??

    Gruß

    #2
    First Post geupdated!

    @Admins: kann man den thread umbenennen,? Wäre sehr nett!

    Kommentar


      #3
      Noch was zum Socket...

      Fast jedes Plugin, dass über LAN stati epfangen undverarbeitenkann, hat das so umgesetzt, dass das Plugin auf den socket im WG subscribet wird. Das Plugin wird also beim eintreffen von Rückmeldungen über den Socket aufgerufen. Schau dir die Plugins im SVN mal an. Da wird esrecht gut aufgezeigt. Z.B die beiden Denon-plugins machen mit der Telnetverbindung genau das selbe. Sollte sich auch auf deinen Fall anwenden lassen.
      Gruss Patrik alias swiss

      Kommentar


        #4
        Hat jemand vielleicht in der Zwischenzeit an dem Script oben weitergearbeitet?

        Grüße, Manuel

        Kommentar


          #5
          Anbei meine Lösung mit Socat.
          Bisher nur Basisfunktionalität (Ein/Aus, Lautstärke, Source) und grob getestet.

          Code:
          # Plugin for AV-Receiver ONKYO, based on ISCP commands over Ethernet
          # Tested with TX-NR636
          # Version 0.14 21.02.2015
          # Copyright: nipponichi, License: GPLv2
          #######################
          ## Wichtige Infos    ##
          #######################
          # Im WG ist eine Socketverbindung mit folgenden Parametern zu erstellen:
          # Webmin -> "Seriell/LAN/Socketverbindungen"
          # Name: z.B. Onkyo
          # Socket1: tcp-listen, Socket: 60127, Optionen: bind=localhost,reuseaddr
          # Socket2: tcp-connect, Socket: 192.168.188.27:60128, Optionen: reuseaddr
          # manually:
          # socat tcp-listen:60127,bind=localhost,reuseaddr tcp-connect:192.168.188.27:60128,reuseaddr
          #   debug: add '-v -d -d -d -d' or '-x -d -d -d -d'
          # Documentation Onkyo ISCP commands: "ISCP AV Receiver v124-1.xls"
          ####################
          ## Settings       ##
          ####################
          
          # KNX settings
          my $ga_power              = '8/1/1';     # DPT:1.002 GA power (0=off, 1=on)
          my $ga_power_status       = '8/1/2';     # DPT:1.002 GA status power (0=off, 1=on)
          #my $ga_volume            = '8/1/10';    # DPT:6.001 GA volume main zone
          #my $start_volume         = "05";        # initial volume
          my $ga_volume_status      = '8/1/11';    # DPT:6.001 GA status for current volume (0..80)
          my $ga_main_vol_up        = '8/1/12';    # DPT:1.002 GA volume up for main zone
          my $ga_main_vol_down      = '8/1/13';    # DPT:1.002 GA volume down for main zone
          my $ga_mute               = '8/1/15';    # DPT:1.002 GA for mute (0=off, 1=on)
          my $ga_mute_status        = '8/1/16';    # DPT:1.002 GA status for mute (0=off, 1=on)
          my $ga_source             = '8/1/20';    # DPT:5.010 GA source (Video: 10h, SAT/CBL: 01h, Game: 02h, DLNA: 2Bh ...)
          my $ga_source_status      = '8/1/21';    # DPT:5.010 GA status source (Video: 10h, SAT/CBL: 01h, Game: 02h, DLNA: 2Bh ...)
          
          # Script settings
          my $debug                 = 2;           # debug level: 0-off, 1-messages, 2-all
          
          # Network settings
          my $socknum               = 2;           # unique number of socket (all WG plugins)
          my $send_ip               = "localhost"; # send ip port (TCP, must match to socket1 of socat call)
          my $send_port             = "60127";     # send port    (TCP, must match to socket1 of socat call)
          
          ######################
          ## End settings     ##
          ######################
          
          # constants for calling
          use constant EVENT_RESTART => 'restart';
          use constant EVENT_MODIFIED => 'modified';
          use constant EVENT_BUS => 'bus';
          use constant EVENT_SOCKET => 'socket';
          use constant EVENT_CYCLE => 'cycle';
          
          # Find out reason for current plugin call
          my $gv_event;
          if (!$plugin_initflag) {
              $gv_event = EVENT_RESTART;           # restart of daemon / reboot
          } elsif ($plugin_info{$plugname.'_lastsaved'} > $plugin_info{$plugname.'_last'}) {
              $gv_event = EVENT_MODIFIED;          # plugin modified
          } elsif (%msg) {
              $gv_event = EVENT_BUS;               # bus traffic
          } elsif ($fh) {
              $gv_event = EVENT_SOCKET;            # network traffic
          } else {
              $gv_event = EVENT_CYCLE;             # cyclic calling
          }
          
          if (($gv_event eq EVENT_RESTART) || ($gv_event eq EVENT_MODIFIED)) {
              $plugin_info{$plugname.'_cycle'} = 600;     # cyclic calling
              # subscribe GAs
              $plugin_subscribe{$ga_power}{$plugname} = 1;
              $plugin_subscribe{$ga_main_vol_up}{$plugname} = 1;
              $plugin_subscribe{$ga_main_vol_down}{$plugname} = 1;
              $plugin_subscribe{$ga_source}{$plugname} = 1;
              
              if (!$socket[$socknum]) { # create socket connection
                  plugin_log($plugname,"old: $socket[$socknum]");
                  my $ret = IO::Socket::INET->new(
                              Proto => "tcp",
                              PeerPort  => $send_port,
                              PeerAddr  => $send_ip,
                              ReuseAddr => 1,
                           )
                  or return ("open of $send_ip : $send_port failed: $!");
                  $socket[$socknum] = $ret;         # set if creation was successful
                  $socksel->add($socket[$socknum]); # add socket to select
                  $socket[$socknum]->autoflush(1);
                  $plugin_socket_subscribe{$socket[$socknum]} = $plugname; # subscribe plugin
                  plugin_log($plugname,"Socket $socknum, $socket[$socknum] opened");
              }
          } elsif ($gv_event eq EVENT_BUS) {
              if ($msg{'apci'} eq "A_GroupValue_Write") {
                  if ($msg{'dst'} eq $ga_power) {
                      send_iscp_cmd('PWR'.$msg{'data'});       # data has hex format 'xx', ok
                  } elsif ($msg{'dst'} eq $ga_main_vol_up) {
                      if (knx_read($msg{'dst'},0,1) == 1){
                          send_iscp_cmd('MVLUP');
                      }
                  } elsif ($msg{'dst'} eq $ga_main_vol_down) {
                      if (knx_read($msg{'dst'},0,1) == 1) {
                          send_iscp_cmd('MVLDOWN');
                      }
                  } elsif ($msg{'dst'} eq $ga_source) {
                      send_iscp_cmd('SLI'.$msg{'data'});       # data has hex format 'xx', ok
                  } elsif ($msg{'dst'} eq $ga_mute) {
                      send_iscp_cmd('SLI'.$msg{'data'});       # data has hex format 'xx', ok
                  }
              }
          } elsif ($gv_event eq EVENT_SOCKET) {    # evaluate messages from onkyo
              my $delim=$/;                        # backup global setting
              $/="\r\n";                           # msg ends with crlf, cr may appear as length info
              my $buf = <$fh>;                     # read socket data, or $socket->recv($buf,1024);
              $/=$delim;                           # restore global setting
              my $bufhex = unpack("H*",$buf);
              if (substr($buf,0,4) ne "ISCP") {    # plausibility checks can be added here
                 return;
              }  
              my $fn = substr($buf,18,3);          # command
              my $fp = substr($buf,21,2);          # value?
          
              my $hex = uc(unpack('H*',$buf));     # convert to hex
          
              if ($debug==1) {
                  plugin_log($plugname,"Rx:".$fn." ".$fp);
              } elsif ($debug==2) {
                  plugin_log($plugname,"Rx:".$hex);
                  plugin_log($plugname,"   ".$fn." ".$fp);
                  #plugin_log($plugname,"rx->".$buf."<-");    # print rx msg as hex
              }
          
              if ($fn eq "PWR") {
                  knx_write($ga_power_status,hex($fp),1);
              } elsif ($fn eq "MVL") {
                  plugin_log($plugname,"Vol:".hex($fp));
                  knx_write($ga_volume_status,hex($fp),6)
              } elsif ($fn eq "SLI") {
                  plugin_log($plugname,"Src:".hex($fp));
                  knx_write($ga_source_status,hex($fp),6)
              } elsif ($fn eq "AMT") {
                  knx_write($ga_mute_status,hex($fp),1);
              }
          } elsif ($gv_event eq EVENT_CYCLE) {
              # state changes are automatically notified by onkyo, no polling needed
              #send_iscp_cmd('PWRQSTN');    # System power status
          }
          return 0;
          
          
          sub send_iscp_cmd {
              my $command = $_[0];
              my @iscpPacket = ("\x{49}","\x{53}","\x{43}","\x{50}","\x{00}","\x{00}","\x{00}","\x{10}",
                                "\x{00}","\x{00}","\x{00}","\x{00}","\x{01}","\x{00}","\x{00}","\x{00}",
                                "\x{21}","\x{31}" );
              $iscpPacket[11] = chr(length($command)+3);
              
              for(my $a=18;$a<=18+length($command);$a++) {
                  $iscpPacket[$a] = substr($command,$a-18,1);
              }
              $iscpPacket[length($command)+18] = chr(0x0D); # CR (EOF+CR, EOF+CR+LF) dependend on model
              my $scalar = join('' , @iscpPacket ) ;
          
              if ($debug==1) {
                  plugin_log($plugname,"Tx:".$command);
              } elsif ($debug==2) {
                  my $hex = uc(unpack('H*',$scalar));  # convert to hex
                  plugin_log($plugname,"Tx:".$command." ".$hex);
              }
              syswrite($socket[$socknum], $scalar);    # write msg to socket
          }
          Nachtrag: Ein Problem tritt gelegentlich auf, wenn wegen Perl-Speicherleck mal wieder alles neu gestartet wird. Dann kann die socket-Verbindung nicht aufgebaut werden: "open of localhost : 60127 failed: Connection refused,0s". Ein erneuter Versuch "Script speichern" behebt dies. Einen entsprechenden Workaround könnte man ins Script einbauen.

          Nachtrag2:
          Ein Problem, falls das Gerät bei Erstellung der Socket-Verbindung nicht erreichbar ist:
          Man erhält im Skript keinen Fehler, scheinbar alles normal, aber das Skript wird ununterbrochen mit Socket-Events aufgerufen. Dies führt zu höherer CPU-Belastung und einem Speichervolllauf alle 2 Stunden.
          Zuletzt geändert von nipponichi; 01.08.2015, 09:23.

          Kommentar

          Lädt...
          X