From d8ad0faf442ebaf8d75f306b46b0990db73a7939 Mon Sep 17 00:00:00 2001 From: markusbloch Date: Sat, 17 May 2014 23:08:21 +0000 Subject: [PATCH] YAMAHA_AVR: new set commands and readings for controlling the sound output behavior (Enhancer, DSP and straight output); minor code optimizations git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@5882 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 3 + fhem/FHEM/71_YAMAHA_AVR.pm | 198 +++++++++++++++++++++++++------------ 2 files changed, 136 insertions(+), 65 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 855009f90..31961f4ec 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: YAMAHA_AVR: new set commands and readings for controlling + the sound output behavior (Enhancer, DSP and straight + output). For details, see commandref. - bugfix: configdb filemove not working after previous changes - change: IMPORTANT CHANGES TO configDB! changed: all files will be imported as binary diff --git a/fhem/FHEM/71_YAMAHA_AVR.pm b/fhem/FHEM/71_YAMAHA_AVR.pm index 50ff40da5..8eac09dbd 100755 --- a/fhem/FHEM/71_YAMAHA_AVR.pm +++ b/fhem/FHEM/71_YAMAHA_AVR.pm @@ -76,7 +76,7 @@ YAMAHA_AVR_GetStatus($;$) my $device = $hash->{helper}{ADDRESS}; # get the model informations and available zones if no informations are available - if(not defined($hash->{ACTIVE_ZONE}) or not defined($hash->{helper}{ZONES}) or not defined($hash->{MODEL}) or not defined($hash->{FIRMWARE})) + if(not defined($hash->{ACTIVE_ZONE}) or not defined($hash->{helper}{ZONES}) or not defined($hash->{MODEL}) or not defined($hash->{FIRMWARE}) or not defined($hash->{helper}{DSP_MODES})) { unless(defined(YAMAHA_AVR_getModel($hash))) { @@ -164,7 +164,7 @@ YAMAHA_AVR_GetStatus($;$) # current input same as the corresponding set command name if($return =~ /(.+)<\/Input_Sel>/) { - readingsBulkUpdate($hash, "input", YAMAHA_AVR_InputParam2Fhem(lc($1), 0)); + readingsBulkUpdate($hash, "input", YAMAHA_AVR_Param2Fhem(lc($1), 0)); if($return =~ /(.+?)<\/Src_Name>/) { @@ -263,6 +263,22 @@ YAMAHA_AVR_GetStatus($;$) readingsBulkUpdate($hash, "inputName", $1); } + if($return =~ /.*?.*?(.+?)<\/Straight>.*?<\/Current>.*?<\/Surround>/) + { + readingsBulkUpdate($hash, "straight", lc($1)); + } + + if($return =~ /.*?.*?(.+?)<\/Enhancer>.*?<\/Current>.*?<\/Surround>/) + { + readingsBulkUpdate($hash, "enhancer", lc($1)); + } + + if($return =~ /.*?.*?(.+?)<\/Sound_Program>.*?<\/Current>.*?<\/Surround>/) + { + readingsBulkUpdate($hash, "dsp", YAMAHA_AVR_Param2Fhem($1, 0)); + } + + readingsEndUpdate($hash, 1); YAMAHA_AVR_ResetTimer($hash) unless($local == 1); @@ -336,19 +352,22 @@ YAMAHA_AVR_Set($@) my $zone = YAMAHA_AVR_getZoneName($hash, $hash->{ACTIVE_ZONE}); - my $inputs_piped = defined($hash->{helper}{INPUTS}) ? YAMAHA_AVR_InputParam2Fhem(lc($hash->{helper}{INPUTS}), 0) : "" ; - my $inputs_comma = defined($hash->{helper}{INPUTS}) ? YAMAHA_AVR_InputParam2Fhem(lc($hash->{helper}{INPUTS}), 1) : "" ; + my $inputs_piped = defined($hash->{helper}{INPUTS}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{INPUTS}), 0) : "" ; + my $inputs_comma = defined($hash->{helper}{INPUTS}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{INPUTS}), 1) : "" ; - my $scenes_piped = defined($hash->{helper}{SCENES}) ? YAMAHA_AVR_InputParam2Fhem(lc($hash->{helper}{SCENES}), 0) : "" ; - my $scenes_comma = defined($hash->{helper}{SCENES}) ? YAMAHA_AVR_InputParam2Fhem(lc($hash->{helper}{SCENES}), 1) : "" ; + my $scenes_piped = defined($hash->{helper}{SCENES}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{SCENES}), 0) : "" ; + my $scenes_comma = defined($hash->{helper}{SCENES}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{SCENES}), 1) : "" ; + + my $dsp_modes_piped = defined($hash->{helper}{DSP_MODES}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{DSP_MODES}), 0) : "" ; + my $dsp_modes_comma = defined($hash->{helper}{DSP_MODES}) ? YAMAHA_AVR_Param2Fhem(lc($hash->{helper}{DSP_MODES}), 1) : "" ; return "No Argument given" if(!defined($a[1])); my $what = $a[1]; - my $usage = "Unknown argument $what, choose one of on:noArg off:noArg volumeStraight:slider,-80,1,16 volume:slider,0,1,100 volumeUp volumeDown input:".$inputs_comma." mute:on,off,toggle remoteControl:setup,up,down,left,right,return,option,display,tunerPresetUp,tunerPresetDown,enter ".(defined($hash->{helper}{SCENES})?"scene:".$scenes_comma." ":"")."statusRequest:noArg"; + my $usage = "Unknown argument $what, choose one of on:noArg off:noArg volumeStraight:slider,-80,1,16 volume:slider,0,1,100 volumeUp volumeDown input:".$inputs_comma." mute:on,off,toggle remoteControl:setup,up,down,left,right,return,option,display,tunerPresetUp,tunerPresetDown,enter ".(defined($hash->{helper}{SCENES})?"scene:".$scenes_comma." ":"").($hash->{helper}{SELECTED_ZONE} eq "mainzone" ? "straight:on,off ".(defined($hash->{helper}{SCENES}) ? "dsp:".$dsp_modes_comma." " : "")." enhancer:on,off " : "")."statusRequest:noArg"; # Depending on the status response, use the short or long Volume command @@ -396,7 +415,7 @@ YAMAHA_AVR_Set($@) { if($a[2] =~ /^($inputs_piped)$/) { - $command = YAMAHA_AVR_getInputParam($hash, $a[2]); + $command = YAMAHA_AVR_getParam($hash, $a[2], $hash->{helper}{INPUTS}); if(defined($command) and length($command) > 0) { $result = YAMAHA_AVR_SendCommand($hash, "<$zone>".$command.""); @@ -441,7 +460,7 @@ YAMAHA_AVR_Set($@) { if($a[2] =~ /^($scenes_piped)$/) { - $command = YAMAHA_AVR_getSceneName($hash, $a[2]); + $command = YAMAHA_AVR_getParamName($hash, $a[2], $hash->{helper}{SCENES}); if(defined($command) and length($command) > 0) { $result = YAMAHA_AVR_SendCommand($hash, "<$zone>".$command.""); @@ -583,6 +602,68 @@ YAMAHA_AVR_Set($@) } } } + elsif($what eq "dsp") + { + if(defined($a[2])) + { + + if(not $dsp_modes_piped eq "") + { + if($a[2] =~ /^($dsp_modes_piped)$/) + { + $command = YAMAHA_AVR_getParamName($hash, $a[2],$hash->{helper}{DSP_MODES}); + if(defined($command) and length($command) > 0) + { + $result = YAMAHA_AVR_SendCommand($hash, "<$zone>$command"); + } + else + { + return "invalid dsp mode: ".$a[2]; + } + + if(not $result =~ /RC="0"/) + { + # if the returncode isn't 0, than the command was not successful + return "Could not set dsp mode to ".$a[2]."."; + } + } + else + { + return $usage; + } + } + else + { + return "No DSP presets are avaible. Please try an statusUpdate."; + } + } + else + { + return $dsp_modes_piped eq "" ? "No dsp presets are available. Please try an statusUpdate." : "No dsp preset was given"; + } + } + elsif($what eq "straight") + { + if($a[2] eq "on") + { + YAMAHA_AVR_SendCommand($hash, "<$zone>On"); + } + elsif($a[2] eq "off") + { + YAMAHA_AVR_SendCommand($hash, "<$zone>Off"); + } + } + elsif($what eq "enhancer") + { + if($a[2] eq "on") + { + YAMAHA_AVR_SendCommand($hash, "<$zone>On"); + } + elsif($a[2] eq "off") + { + YAMAHA_AVR_SendCommand($hash, "<$zone>Off"); + } + } elsif($what eq "remoteControl") { @@ -846,30 +927,17 @@ YAMAHA_AVR_SendCommand($$;$) ############################# -# Converts all Inputs to FHEM usable command lists -sub YAMAHA_AVR_InputParam2Fhem($$) -{ - my ($inputs, $replace_pipes) = @_; - - - $inputs =~ s/\s+//g; - $inputs =~ s/,//g; - $inputs =~ s/\(/_/g; - $inputs =~ s/\)//g; - $inputs =~ s/\|/,/g if($replace_pipes == 1); - - return $inputs; -} - -############################# -# Converts all Zones to FHEM usable command lists +# Converts all Values to FHEM usable command lists sub YAMAHA_AVR_Param2Fhem($$) { my ($param, $replace_pipes) = @_; $param =~ s/\s+//g; + $param =~ s/,//g; $param =~ s/_//g; + $param =~ s/\(/_/g; + $param =~ s/\)//g; $param =~ s/\|/,/g if($replace_pipes == 1); return lc $param; @@ -881,38 +949,25 @@ sub YAMAHA_AVR_Param2Fhem($$) sub YAMAHA_AVR_getZoneName($$) { my ($hash, $zone) = @_; - my $item; - - return undef if(not defined($hash->{helper}{ZONES})); - - my @commands = split("\\|", $hash->{helper}{ZONES}); - - foreach $item (@commands) - { - if(YAMAHA_AVR_Param2Fhem($item, 0) eq $zone) - { - return $item; - } - } - - return undef; + return YAMAHA_AVR_getParamName($hash, $zone, $hash->{helper}{ZONES}); } + ############################# # Returns the Yamaha Parameter Name for the FHEM like aquivalents -sub YAMAHA_AVR_getSceneName($$) +sub YAMAHA_AVR_getParamName($$$) { - my ($hash, $scene) = @_; + my ($hash, $name, $list) = @_; my $item; - return undef if(not defined($hash->{helper}{SCENES})); + return undef if(not defined($list)); - my @commands = split("\\|", $hash->{helper}{SCENES}); + my @commands = split("\\|", $list); foreach $item (@commands) { - if(YAMAHA_AVR_Param2Fhem($item, 0) eq $scene) + if(YAMAHA_AVR_Param2Fhem($item, 0) eq $name) { return $item; } @@ -922,25 +977,7 @@ sub YAMAHA_AVR_getSceneName($$) } -############################# -# Returns the Yamaha Parameter Name for the FHEM like input channel -sub YAMAHA_AVR_getInputParam($$) -{ - my ($hash, $command) = @_; - my $item; - my @commands = split("\\|", $hash->{helper}{INPUTS}); - foreach $item (@commands) - { - if(lc(YAMAHA_AVR_InputParam2Fhem($item, 0)) eq $command) - { - return $item; - } - } - - return undef; - -} ############################# # queries the receiver model, system-id, version and all available zones @@ -1012,6 +1049,23 @@ sub YAMAHA_AVR_getModel($) } + + if($response =~ /.*?(.+?)<\/Get>/) + { + + my $modes = $1; + + while($modes =~ /(.+?)<\/Direct>/gc) + { + if(defined($hash->{helper}{DSP_MODES}) and length($hash->{helper}{DSP_MODES}) > 0) + { + $hash->{helper}{DSP_MODES} .= "|"; + } + + $hash->{helper}{DSP_MODES} .= $1; + + } + } # uncommented line for zone detection testing # # $hash->{helper}{ZONES} .= "|Zone_2"; @@ -1144,8 +1198,9 @@ sub YAMAHA_AVR_html2txt($) my ($string) = @_; - $string =~ s/ / /g; $string =~ s/&/&/g; + $string =~ s/&/&/g; + $string =~ s/ / /g; $string =~ s/'/'/g; $string =~ s/(\xe4|ä)/ä/g; $string =~ s/(\xc4|Ä)/Ä/g; @@ -1154,6 +1209,7 @@ sub YAMAHA_AVR_html2txt($) $string =~ s/(\xfc|ü)/ü/g; $string =~ s/(\xdc|Ü)/Ü/g; $string =~ s/(\xdf|ß)/ß/g; + $string =~ s/<.+?>//g; $string =~ s/(^\s+|\s+$)//g; @@ -1255,6 +1311,9 @@ sub YAMAHA_AVR_html2txt($)
  • volumeUp [0-100]   -   increases the volume level by 5% or the value of attribute volumeSteps (optional the increasing level can be given as argument, which will be used instead)
  • volumeDown [0-100]   -   decreases the volume level by 5% or the value of attribute volumeSteps (optional the decreasing level can be given as argument, which will be used instead)
  • mute on|off|toggle   -   activates volume mute
  • +
  • dsp hallinmunich,hallinvienna,...   -   sets the DSP mode to the given preset
  • +
  • enhancer on|off   -   controls the internal sound enhancer
  • +
  • straight on|off   -   bypasses all sound enhancement features and plays the sound straight directly
  • statusRequest   -   requests the current status of the device
  • remoteControl up,down,...   -   sends remote control commands as listed below
  • @@ -1355,11 +1414,14 @@ sub YAMAHA_AVR_html2txt($) Generated Readings/Events:
      +
    • dsp - The current selected DSP mode for sound output
    • +
    • enhancer - The status of the internal sound enhancer (can be "on" or "off")
    • input - The selected input source according to the FHEM input commands
    • inputName - The input description as seen on the receiver display
    • mute - Reports the mute status of the receiver or zone (can be "on" or "off")
    • power - Reports the power status of the receiver or zone (can be "on" or "off")
    • presence - Reports the presence status of the receiver or zone (can be "absent" or "present"). In case of an absent device, it cannot be controlled via FHEM anymore.
    • +
    • straight - indicates if all sound enhancement features are bypassed or not ("on" => all features are bypassed, "off" => sound enhancement features are used).
    • volume - Reports the current volume level of the receiver or zone in percentage values (between 0 and 100 %)
    • volumeStraight - Reports the current volume level of the receiver or zone in decibel values (between -80.5 and +15.5 dB)
    • state - Reports the current power state and an absence of the device (can be "on", "off" or "absent")
    • @@ -1461,6 +1523,8 @@ sub YAMAHA_AVR_html2txt($)
      • on   -   Schaltet den Receiver ein
      • off   -   Schaltet den Receiver aus
      • +
      • dsp hallinmunich,hallinvienna,...   -   Aktiviert das entsprechende DSP Preset
      • +
      • enhancer on,off   -   Aktiviert den Sound Enhancer für einen verbesserten Raumklang
      • input hdmi1,hdmiX,...   -   Wählt den Eingangskanal (es werden nur die tatsächlich verfügbaren Eingänge angeboten)
      • scene scene1,sceneX   -   Wählt eine vorgefertigte Szene aus
      • volume 0...100   -   Setzt die Lautstärke in Prozent (0 bis 100%)
      • @@ -1468,6 +1532,7 @@ sub YAMAHA_AVR_html2txt($)
      • volumeUp [0...100]   -   Erhöht die Lautstärke um 5% oder entsprechend dem Attribut volumeSteps (optional kann der Wert auch als Argument angehangen werden, dieser hat dann Vorang)
      • volumeDown [0...100]   -   Veringert die Lautstärke um 5% oder entsprechend dem Attribut volumeSteps (optional kann der Wert auch als Argument angehangen werden, dieser hat dann Vorang)
      • mute on,off,toggle   -   Schaltet den Receiver stumm
      • +
      • straight on,off   -   Gibt das Signal direkt und unverändert aus (ohne DSP und Enhancer).
      • statusRequest   -   Fragt den aktuell Status des Receivers ab
      • remoteControl up,down,...   -   Sendet Fernbedienungsbefehle wie im nächsten Abschnitt beschrieben
      @@ -1564,6 +1629,8 @@ sub YAMAHA_AVR_html2txt($)
    Generierte Readings/Events:
      +
    • dsp - Das aktuell aktive DSP Preset
    • +
    • enhancer - Der Status des Enhancers ("on" => an, "off" => aus)
    • input - Der ausgewählte Eingang entsprechend dem FHEM-Kommando
    • inputName - Die Eingangsbezeichnung, so wie sie am Receiver eingestellt wurde und auf dem Display erscheint
    • mute - Der aktuelle Stumm-Status ("on" => Stumm, "off" => Laut)
    • @@ -1571,6 +1638,7 @@ sub YAMAHA_AVR_html2txt($)
    • presence - Die aktuelle Empfangsbereitschaft ("present" => empfangsbereit, "absent" => nicht empfangsbereit, z.B. Stromausfall)
    • volume - Der aktuelle Lautstärkepegel in Prozent (zwischen 0 und 100 %)
    • volumeStraight - Der aktuelle Lautstärkepegel in Dezibel (zwischen -80.0 und +15 dB)
    • +
    • straight - Zeigt an, ob soundverbessernde Features umgangen werden oder nicht ("on" => soundverbessernde Features werden umgangen, "off" => soundverbessernde Features werden benutzt)
    • state - Der aktuelle Schaltzustand (power-Reading) oder die Abwesenheit des Gerätes (mögliche Werte: "on", "off" oder "absent")


    • Eingangsabhängige Readings/Events:
    • currentChannel - Nummer des Eingangskanals (nur bei SIRIUS)