From 50a399e68256dbccf9b6f1834f29b07831e7020a Mon Sep 17 00:00:00 2001 From: 50watt <> Date: Sun, 18 Nov 2018 14:45:57 +0000 Subject: [PATCH] 70_PIONEERAVR: input alias names are available even after a reboot git-svn-id: https://svn.fhem.de/fhem/trunk@17776 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/70_PIONEERAVR.pm | 262 ++++++++++++++++++++----------------- 1 file changed, 143 insertions(+), 119 deletions(-) diff --git a/fhem/FHEM/70_PIONEERAVR.pm b/fhem/FHEM/70_PIONEERAVR.pm index 68b10c34d..0b68fa385 100644 --- a/fhem/FHEM/70_PIONEERAVR.pm +++ b/fhem/FHEM/70_PIONEERAVR.pm @@ -1,8 +1,8 @@ -############################################## -# $Id$ -# -# 70_PIONEERAVR.pm -# +############################################## +# $Id$ +# +# 70_PIONEERAVR.pm +# # This file is part of Fhem. # # Fhem is free software: you can redistribute it and/or modify @@ -155,16 +155,13 @@ sub PIONEERAVR_Initialize($) { sub PIONEERAVR_Define($$) { my ( $hash, $a, $h ) = @_; my $name = $hash->{NAME}; - - Log3 $name, 5, "PIONEERAVR $name: called function PIONEERAVR_Define()"; - my $protocol = @$a[2]; Log3 $name, 5, "PIONEERAVR $name: called function PIONEERAVR_Define()"; if( int(@$a) != 4 || (($protocol ne "telnet") && ($protocol ne "serial"))) { my $msg = "Wrong syntax: define PIONEERAVR telnet or define PIONEERAVR serial "; - Log3 $name, 3, "PIONEERAVR $name: " . $msg; + Log3 $name, 4, "PIONEERAVR $name: " . $msg; return $msg; } @@ -210,22 +207,22 @@ sub PIONEERAVR_Define($$) { ); } - $hash->{helper}{receiver} = undef; - + $hash->{helper}{receiver} = undef; + unless ( exists( $hash->{helper}{AVAILABLE} ) and ( $hash->{helper}{AVAILABLE} == 0 )) { $hash->{helper}{AVAILABLE} = 1; readingsSingleUpdate( $hash, "presence", "present", 1 ); } - # $hash->{helper}{INPUTNAMES} lists the default input names and their inputNr as provided by Pioneer. - # This module tries to read those names and the alias names from the AVR receiver and tries to check if this input is enabled or disabled - # So this list is just a fall back if the module can't read the names ... - # InputNr with player functions (play,pause,...) ("13","17","18","26","27","33","38","41","44","45","48","49","53"); - # Input number for usbDac, ipodUsb, xmRadio, homeMediaGallery, sirius, adapterPort, internetRadio, pandora, mediaServer, Favorites, mhl, spotify - # Additionally this module tries to get information from the Pioneer AVR - # - about the input level adjust - # - to which connector each input is connected. + # $hash->{helper}{INPUTNAMES} lists the default input names and their inputNr as provided by Pioneer. + # This module can read those names and the alias names from the AVR receiver and can try to check if this input is enabled or disabled + # So this list is a fall back, if the module can't read the names or the reading of the names takes too long (for the user)... + # InputNr with player functions (play,pause,...) ("13","17","18","26","27","33","38","41","44","45","48","49","53"); + # Input number for usbDac, ipodUsb, xmRadio, homeMediaGallery, sirius, adapterPort, internetRadio, pandora, mediaServer, Favorites, mhl, spotify + # Additionally this module tries to get information from the Pioneer AVR + # - about the input level adjust + # - to which connector each input is connected. # There are 3 groups of connectors: # - Audio connectors (possible values are: ANALOG, COAX 1...3, OPT 1...3) # - Component connectors (anaolog video, possible values: COMPONENT 1...3) @@ -259,16 +256,37 @@ sub PIONEERAVR_Define($$) { "34" => {"name" => "hdmi7", "aliasName" => "", "enabled" => "1", "playerCommands" => "0"}, "35" => {"name" => "hdmi8", "aliasName" => "", "enabled" => "1", "playerCommands" => "0"}, "38" => {"name" => "internetRadio", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "41" => {"name" => "pandora", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "44" => {"name" => "mediaServer", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "45" => {"name" => "favorites", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "46" => {"name" => "airplay", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "47" => {"name" => "dmr", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "48" => {"name" => "mhl", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "49" => {"name" => "game", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, - "53" => {"name" => "spotify", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"} - }; - # ----------------Human Readable command mapping table for "set" commands----------------------- + "41" => {"name" => "pandora", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "44" => {"name" => "mediaServer", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "45" => {"name" => "favorites", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "46" => {"name" => "airplay", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "47" => {"name" => "dmr", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "48" => {"name" => "mhl", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "49" => {"name" => "game", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"}, + "53" => {"name" => "spotify", "aliasName" => "", "enabled" => "1", "playerCommands" => "1"} + }; + +# Input Name aliases and which inputs are enabled/disabled should be available after a restart -> setKeyValue/getKeyValue are used to store those values to a file or database. +# Here we restore those values after a rebstart + my $inputindex = undef; + my $inputNr = undef; + for ( my $i=0; $i<60; $i++ ) { + $inputNr = sprintf '%02d', $i; + $inputindex = "PIONEERAVR_InputAlias_".$inputNr; + my ($err, $data) = getKeyValue($inputindex); + if (!defined $err) { + $hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName} = $data; + }; + $inputindex = "PIONEERAVR_InputEnabled_".$inputNr; + my ($err, $data) = getKeyValue($inputindex); + if (!defined $err) { + $hash->{helper}{INPUTNAMES}->{$inputNr}{enabled} = $data; + }; + undef $err; + undef $data; + }; + + # ----------------Human Readable command mapping table for "set" commands----------------------- $hash->{helper}{SETS} = { 'main' => { 'on' => 'PO', @@ -2290,6 +2308,10 @@ sub PIONEERAVR_Read($) # lc first if ( $isAlias ) { $hash->{helper}{INPUTNAMES}->{$inputNr}{aliasName} = lcfirst( substr( $line,6 ) ); + # input name aliases should be available after a restart of FHEM -> setKeyValue + my $inputindex = "PIONEERAVR_InputAlias_".$inputNr; + setKeyValue($inputindex, lcfirst( substr( $line,6 ) )); + } else { $hash->{helper}{INPUTNAMES}->{$inputNr}{name} = lcfirst( substr( $line,6 ) ); } @@ -2381,19 +2403,21 @@ sub PIONEERAVR_Read($) # input enabled } elsif ( $line=~ m/^SSC(\d\d)030(1|0)$/ ) { - # select(undef, undef, undef, 0.001); # check for input skip information # format: ?SSC<2 digit input function nr>03 # response: SSC<2 digit input function nr>0300: use # response: SSC<2 digit input function nr>0301: skip # response: E06: inappropriate parameter (input function nr not available on that device) # we can not trust "E06" as it is not sure that it is the reply for the current input nr - + # the information, which inputs are enabled/disabled should be available after a restart of FHEM -> setKeyValue + my $inputindex = "PIONEERAVR_InputEnabled_".$1; if ( $2 == 1 ) { $hash->{helper}{INPUTNAMES}->{$1}{enabled} = 0; + setKeyValue($inputindex, 0); Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: InputNr: $1 is disabled"; } elsif ( $2 == 0) { $hash->{helper}{INPUTNAMES}->{$1}{enabled} = 1; + setKeyValue($inputindex, 1); Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: InputNr: $1 is enabled"; } @@ -2771,94 +2795,94 @@ sub PIONEERAVR_Read($) if ( $2 eq "02" || $2 eq "03" || $2 eq "04" || $2 eq "05" || $2 eq "06" ) { my $stateAV = PIONEERAVR_GetStateAV($hash); - readingsBulkUpdate( $hash, "stateAV", $stateAV ) - if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV ); - } - # screen type and screen name for XC-HM72 (XC-HM72 has screen name in $9 and no screen update command) - } elsif ( $line =~ m/^(GCP)(\d{2})(\d)(\d)(\d)(\d)(\d)(.*)\"(.*)\"$/ ) { - # Format: - # $2: screen type - # 00:Message - # 01:List - # 02:Playing(Play) - # 03:Playing(Pause) - # 04:Playing(Fwd) - # 05:Playing(Rev) - # 06:Playing(Stop) - # 99:Drawing invalid - - # $3: 0:Same hierarchy 1:Updated hierarchy (Next or Previous list) - # $4: Top menu key flag - # 0:Invalidity - # 1:Effectiveness - # $5: Tools (menu, edit,iPod Control) Key Information - # 0:Invalidity - # 1:Effectiveness - # $6: Return Key Information - # 0:Invalidity - # 1:Effectiveness - # $7: always 0 - # $8: 10 digits (XC-HM72) or nothing - # $9: Screen name (UTF8) max. 128 byte - my $screenType = $hash->{helper}{SCREENTYPES}{$2}; - - readingsBulkUpdate( $hash, "screenType", $screenType ); - readingsBulkUpdate( $hash, "screenName", $9 ); - readingsBulkUpdate( $hash, "screenHierarchy", $3 ); - readingsBulkUpdate( $hash, "screenTopMenuKey", $4 ); - readingsBulkUpdate( $hash, "screenToolsKey", $5 ); - readingsBulkUpdate( $hash, "screenReturnKey", $6 ); - - # to update the OSD/screen while playing from iPad/network a command has to be sent regulary - if ($2 eq "02" ) { - RemoveInternalTimer( $hash, "PIONEERAVR_screenUpdate" ); - # It seems that XC-HM72 does not support the screen update command - ## reset screenUpdate timer -> again in 5s - #my $checkInterval = 5; - #my $next = gettimeofday() + $checkInterval; - #$hash->{helper}{nextScreenUpdate} = $next; - #InternalTimer( $next, "PIONEERAVR_screenUpdate", $hash, 0 ); - #readingsBulkUpdate( $hash, "playStatus", "playing" ); - } elsif ( $2 eq "03" ) { - readingsBulkUpdate( $hash, "playStatus", "paused" ); - } elsif ( $2 eq "04" ) { - readingsBulkUpdate( $hash, "playStatus", "fast-forward" ); - } elsif ( $2 eq "05" ) { - readingsBulkUpdate( $hash, "playStatus", "fast-rewind" ); - } elsif ( $2 eq "06" ) { - readingsBulkUpdate( $hash, "playStatus", "stopped" ); - } - - # stateAV - if ( $2 eq "02" || $2 eq "03" || $2 eq "04" || $2 eq "05" || $2 eq "06" ) { - - my $stateAV = PIONEERAVR_GetStateAV($hash); - readingsBulkUpdate( $hash, "stateAV", $stateAV ) - if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV ); - } - # Source information - } elsif ( $line =~ m/^(GHP|GHH)(\d{2})$/ ) { - my $sourceInfo = $hash->{helper}{SOURCEINFO}{$2}; - readingsBulkUpdate( $hash, "sourceInfo", $sourceInfo ); - Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen source information: $2 $sourceInfo"; - - # total screen lines - } elsif ( $line =~ m/^(GDP|GDH)(\d{5})(\d{5})(\d{5})$/ ) { - readingsBulkUpdate( $hash, "screenLineNumberFirst", $2 + 0 ); - readingsBulkUpdate( $hash, "screenLineNumberLast", $3 + 0 ); - readingsBulkUpdate( $hash, "screenLineNumbersTotal", $4 + 0 ); - Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen Item number of line 1(5byte): $2, Item number of last line(5byte): $3, Total number of items List(5byte): $4 "; - - # Screen line numbers - } elsif ( $line =~ m/^(GBP|GBH|GBI)(\d{2})$/ ) { - readingsBulkUpdate( $hash, "screenLineNumbers", $2 + 0 ); - Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen line numbers = $2"; - - # screenInformation - } elsif ( $line =~ m/^(GEP|GEH|GEI)(\d{2})(\d)(\d{2})\"(.*)\"$/ ) { - # Format: - # $2: Line number - # $3: Focus (yes(1)/no(0)/greyed out(9) + readingsBulkUpdate( $hash, "stateAV", $stateAV ) + if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV ); + } + # screen type and screen name for XC-HM72 (XC-HM72 has screen name in $9 and no screen update command) + } elsif ( $line =~ m/^(GCP)(\d{2})(\d)(\d)(\d)(\d)(\d)(.*)\"(.*)\"$/ ) { + # Format: + # $2: screen type + # 00:Message + # 01:List + # 02:Playing(Play) + # 03:Playing(Pause) + # 04:Playing(Fwd) + # 05:Playing(Rev) + # 06:Playing(Stop) + # 99:Drawing invalid + + # $3: 0:Same hierarchy 1:Updated hierarchy (Next or Previous list) + # $4: Top menu key flag + # 0:Invalidity + # 1:Effectiveness + # $5: Tools (menu, edit,iPod Control) Key Information + # 0:Invalidity + # 1:Effectiveness + # $6: Return Key Information + # 0:Invalidity + # 1:Effectiveness + # $7: always 0 + # $8: 10 digits (XC-HM72) or nothing + # $9: Screen name (UTF8) max. 128 byte + my $screenType = $hash->{helper}{SCREENTYPES}{$2}; + + readingsBulkUpdate( $hash, "screenType", $screenType ); + readingsBulkUpdate( $hash, "screenName", $9 ); + readingsBulkUpdate( $hash, "screenHierarchy", $3 ); + readingsBulkUpdate( $hash, "screenTopMenuKey", $4 ); + readingsBulkUpdate( $hash, "screenToolsKey", $5 ); + readingsBulkUpdate( $hash, "screenReturnKey", $6 ); + + # to update the OSD/screen while playing from iPad/network a command has to be sent regulary + if ($2 eq "02" ) { + RemoveInternalTimer( $hash, "PIONEERAVR_screenUpdate" ); + # It seems that XC-HM72 does not support the screen update command + ## reset screenUpdate timer -> again in 5s + #my $checkInterval = 5; + #my $next = gettimeofday() + $checkInterval; + #$hash->{helper}{nextScreenUpdate} = $next; + #InternalTimer( $next, "PIONEERAVR_screenUpdate", $hash, 0 ); + #readingsBulkUpdate( $hash, "playStatus", "playing" ); + } elsif ( $2 eq "03" ) { + readingsBulkUpdate( $hash, "playStatus", "paused" ); + } elsif ( $2 eq "04" ) { + readingsBulkUpdate( $hash, "playStatus", "fast-forward" ); + } elsif ( $2 eq "05" ) { + readingsBulkUpdate( $hash, "playStatus", "fast-rewind" ); + } elsif ( $2 eq "06" ) { + readingsBulkUpdate( $hash, "playStatus", "stopped" ); + } + + # stateAV + if ( $2 eq "02" || $2 eq "03" || $2 eq "04" || $2 eq "05" || $2 eq "06" ) { + + my $stateAV = PIONEERAVR_GetStateAV($hash); + readingsBulkUpdate( $hash, "stateAV", $stateAV ) + if ( ReadingsVal( $name, "stateAV", "-" ) ne $stateAV ); + } + # Source information + } elsif ( $line =~ m/^(GHP|GHH)(\d{2})$/ ) { + my $sourceInfo = $hash->{helper}{SOURCEINFO}{$2}; + readingsBulkUpdate( $hash, "sourceInfo", $sourceInfo ); + Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen source information: $2 $sourceInfo"; + + # total screen lines + } elsif ( $line =~ m/^(GDP|GDH)(\d{5})(\d{5})(\d{5})$/ ) { + readingsBulkUpdate( $hash, "screenLineNumberFirst", $2 + 0 ); + readingsBulkUpdate( $hash, "screenLineNumberLast", $3 + 0 ); + readingsBulkUpdate( $hash, "screenLineNumbersTotal", $4 + 0 ); + Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen Item number of line 1(5byte): $2, Item number of last line(5byte): $3, Total number of items List(5byte): $4 "; + + # Screen line numbers + } elsif ( $line =~ m/^(GBP|GBH|GBI)(\d{2})$/ ) { + readingsBulkUpdate( $hash, "screenLineNumbers", $2 + 0 ); + Log3 $hash, 5, "PIONEERAVR $name: ".dq( $line ) ." interpreted as: Screen line numbers = $2"; + + # screenInformation + } elsif ( $line =~ m/^(GEP|GEH|GEI)(\d{2})(\d)(\d{2})\"(.*)\"$/ ) { + # Format: + # $2: Line number + # $3: Focus (yes(1)/no(0)/greyed out(9) # $4: Line data type: # 00:Normal(no mark type) # 01:Directory