diff --git a/fhem/FHEM/70_PHTV.pm b/fhem/FHEM/70_PHTV.pm index 0c2f10b35..9a7818d5a 100644 --- a/fhem/FHEM/70_PHTV.pm +++ b/fhem/FHEM/70_PHTV.pm @@ -24,7 +24,7 @@ # along with fhem. If not, see . # # -# Version: 1.2.4 +# Version: 1.2.5 # # Major Version History: # - 1.2.0 - 2014-03-12 @@ -76,7 +76,7 @@ sub PHTV_Initialize($) { $hash->{UndefFn} = "PHTV_Undefine"; $hash->{AttrList} = -"disable:0,1 timeout inputs ambiHueLeft ambiHueRight ambiHueTop ambiHueBottom ambiHueLatency:150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 " +"disable:0,1 timeout sequentialQuery:0,1 inputs ambiHueLeft ambiHueRight ambiHueTop ambiHueBottom ambiHueLatency:150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 " . $readingFnAttributes; $data{RC_layout}{PHTV_SVG} = "PHTV_RClayout_SVG"; @@ -92,8 +92,11 @@ sub PHTV_Initialize($) { ##################################### sub PHTV_GetStatus($;$) { my ( $hash, $update ) = @_; - my $name = $hash->{NAME}; - my $interval = $hash->{INTERVAL}; + my $name = $hash->{NAME}; + my $interval = $hash->{INTERVAL}; + my $sequential = ( defined( $attr{$name}{sequentialQuery} ) + && $attr{$name}{sequentialQuery} == 1 ) ? 1 : 0; + my $querySent = 0; Log3 $name, 5, "PHTV $name: called function PHTV_GetStatus()"; @@ -108,65 +111,98 @@ sub PHTV_GetStatus($;$) { if ( defined( $attr{$name}{disable} ) && $attr{$name}{disable} == 1 ); # try to fetch only some information to check device availability - PHTV_SendCommand( $hash, "audio/volume" ) if ( !$update ); + if ( !$update ) { + PHTV_SendCommand( $hash, "audio/volume" ); + + # in case we should query the device gently, mark we already sent a query + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter} = 1 if $sequential; + } # fetch other info if device is on if ( - ( - defined( $hash->{READINGS}{state}{VAL} ) - && $hash->{READINGS}{state}{VAL} eq "on" + !$querySent + && ( + ( + defined( $hash->{READINGS}{state}{VAL} ) + && $hash->{READINGS}{state}{VAL} eq "on" + ) + || $update ) - || $update ) { # Read device info every 15 minutes only - if ( !defined( $hash->{helper}{lastFullUpdate} ) - || ( !$update && $hash->{helper}{lastFullUpdate} + 900 le time() ) ) + if ( + !$querySent + && ( + !defined( $hash->{helper}{lastFullUpdate} ) + || ( !$update + && $hash->{helper}{lastFullUpdate} + 900 le time() ) + ) + ) { PHTV_SendCommand( $hash, "system" ); PHTV_SendCommand( $hash, "ambilight/topology" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; # Update state $hash->{helper}{lastFullUpdate} = time(); } + # read ambilight details + if ( !$querySent ) { + + # read ambilight mode + PHTV_SendCommand( $hash, "ambilight/mode" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + + # read ambilight RGB value + PHTV_SendCommand( $hash, "ambilight/cached" ) + if ( defined( $hash->{READINGS}{ambiMode}{VAL} ) + && $hash->{READINGS}{ambiMode}{VAL} ne "internal" ); + } + # read all sources if not existing - if ( !defined( $hash->{helper}{device}{sourceName} ) - || !defined( $hash->{helper}{device}{sourceID} ) ) + if ( + !$querySent + && ( !defined( $hash->{helper}{device}{sourceName} ) + || !defined( $hash->{helper}{device}{sourceID} ) ) + ) { PHTV_SendCommand( $hash, "sources" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } # otherwise read current source - else { + elsif ( !$querySent ) { PHTV_SendCommand( $hash, "sources/current" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } # read all channels if not existing - if ( !defined( $hash->{helper}{device}{channelName} ) - || !defined( $hash->{helper}{device}{channelID} ) ) + if ( + !$querySent + && ( !defined( $hash->{helper}{device}{channelName} ) + || !defined( $hash->{helper}{device}{channelID} ) ) + ) { PHTV_SendCommand( $hash, "channels" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } # otherwise read current channel - else { + elsif ( !$querySent ) { PHTV_SendCommand( $hash, "channels/current" ); + $querySent = 1 if $sequential; + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } - # read all channellists if not existing - if ( !defined( $hash->{helper}{device}{channellists} ) ) { - PHTV_SendCommand( $hash, "channellists" ); - } - - # read ambilight mode - PHTV_SendCommand( $hash, "ambilight/mode" ); - - # read ambilight RGB value - PHTV_SendCommand( $hash, "ambilight/cached" ) - if ( defined( $hash->{READINGS}{ambiMode}{VAL} ) - && $hash->{READINGS}{ambiMode}{VAL} ne "internal" ); } # Input alias handling @@ -279,9 +315,12 @@ sub PHTV_Set($@) { my $count = scalar( keys %{ $hash->{helper}{device}{channelPreset} } ); $count = 80 if ( $count > 80 ); while ( $i <= $count ) { + if ( defined($hash->{helper}{device}{channelPreset}{$i}{name}) && + $hash->{helper}{device}{channelPreset}{$i}{name} != "" ) { $channels .= $hash->{helper}{device}{channelPreset}{$i}{name} . ","; - $i++; + } + $i++; } } if ( $channel ne "" @@ -955,7 +994,7 @@ sub PHTV_Set($@) { Log3 $name, 2, "PHTV set $name " . $a[1]; if ( $hash->{READINGS}{state}{VAL} eq "on" ) { - if ( lc( $a[1] ) eq "volumeUp" ) { + if ( lc( $a[1] ) eq "volumeup" ) { $cmd = PHTV_GetRemotecontrolCommand("VOLUP"); } else { @@ -1359,10 +1398,12 @@ sub PHTV_SendCommand($$;$$) { ################################### sub PHTV_ReceiveCommand($$$) { my ( $param, $err, $data ) = @_; - my $hash = $param->{hash}; - my $name = $hash->{NAME}; - my $service = $param->{service}; - my $cmd = $param->{cmd}; + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + my $service = $param->{service}; + my $cmd = $param->{cmd}; + my $sequential = ( defined( $attr{$name}{sequentialQuery} ) + && $attr{$name}{sequentialQuery} == 1 ) ? 1 : 0; my $state = ( $hash->{READINGS}{state}{VAL} ) @@ -1564,7 +1605,10 @@ sub PHTV_ReceiveCommand($$$) { } } - if ( $newstate eq "on" && $newstate ne $state ) { +# trigger query cascade in case the device just came up or sequential query is enabled + if ( $sequential + || ( $newstate eq "on" && $newstate ne $state ) ) + { PHTV_GetStatus( $hash, 1 ); } } @@ -1642,6 +1686,9 @@ sub PHTV_ReceiveCommand($$$) { $hash->{model} = $return->{model}; } } + + # continue query cascade in case sequential query is enabled + PHTV_GetStatus( $hash, 1 ) if $sequential; } # sources @@ -1668,6 +1715,7 @@ sub PHTV_ReceiveCommand($$$) { } PHTV_SendCommand( $hash, "sources/current" ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } } @@ -1702,6 +1750,24 @@ sub PHTV_ReceiveCommand($$$) { readingsBulkUpdate( $hash, "input", $cmd ); } } + + # SEQUENTIAL QUERY CASCADE - next: channels + # read all channels if not existing + if ( + $sequential + && ( !defined( $hash->{helper}{device}{channelName} ) + || !defined( $hash->{helper}{device}{channelID} ) ) + ) + { + PHTV_SendCommand( $hash, "channels" ); + $hash->{helper}{sequentialQueryCounter}++; + } + + # otherwise read current channel + elsif ($sequential) { + PHTV_SendCommand( $hash, "channels/current" ); + $hash->{helper}{sequentialQueryCounter}++; + } } # channels @@ -1738,6 +1804,7 @@ sub PHTV_ReceiveCommand($$$) { } PHTV_SendCommand( $hash, "channels/current" ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } } @@ -1764,8 +1831,17 @@ sub PHTV_ReceiveCommand($$$) { readingsBulkUpdate( $hash, "channel", $cmd ); } - PHTV_SendCommand( $hash, "channels/" . $return->{id} ) - if ( defined( $return->{id} ) && $return->{id} ne "" ); + # read channel details if type is known + if ( defined( $return->{id} ) && $return->{id} ne "" ) { + PHTV_SendCommand( $hash, "channels/" . $return->{id} ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + } + + # read all channellists if not existing + elsif ( !defined( $hash->{helper}{device}{channellists} ) ) { + PHTV_SendCommand( $hash, "channellists" ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + } } elsif ( $return eq "ok" ) { $cmd = @@ -1779,8 +1855,17 @@ sub PHTV_ReceiveCommand($$$) { readingsBulkUpdate( $hash, "channel", $cmd ); } - PHTV_SendCommand( $hash, "channels/" . $type ) - if ( defined($type) && $type ne "" ); + # read channel details if type is known + if ( defined($type) && $type ne "" ) { + PHTV_SendCommand( $hash, "channels/" . $type ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + } + + # read all channellists if not existing + elsif ( !defined( $hash->{helper}{device}{channellists} ) ) { + PHTV_SendCommand( $hash, "channellists" ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + } } } @@ -1915,6 +2000,12 @@ sub PHTV_ReceiveCommand($$$) { } } + + # read all channellists if not existing + if ( !defined( $hash->{helper}{device}{channellists} ) ) { + PHTV_SendCommand( $hash, "channellists" ); + $hash->{helper}{sequentialQueryCounter}++ if $sequential; + } } # channellists @@ -1930,6 +2021,7 @@ sub PHTV_ReceiveCommand($$$) { PHTV_SendCommand( $hash, "channellists/$item", undef, $item ); } + $hash->{helper}{sequentialQueryCounter}++ if $sequential; } } @@ -2048,6 +2140,24 @@ sub PHTV_ReceiveCommand($$$) { readingsBulkUpdate( $hash, "ambiMode", $type ); } } + + # SEQUENTIAL QUERY CASCADE - next: sources + # read all sources if not existing + if ( + $sequential + && ( !defined( $hash->{helper}{device}{sourceName} ) + || !defined( $hash->{helper}{device}{sourceID} ) ) + ) + { + PHTV_SendCommand( $hash, "sources" ); + $hash->{helper}{sequentialQueryCounter}++; + } + + # otherwise read current source + elsif ($sequential) { + PHTV_SendCommand( $hash, "sources/current" ); + $hash->{helper}{sequentialQueryCounter}++; + } } # ambilight/cached (rgb) @@ -2373,11 +2483,11 @@ sub PHTV_ReceiveCommand($$$) { my $satF = ( $sat && $sat > 0 && $sat < 100 ) ? $sat / 100 - : 1; + : 0; my $briF = ( $bri && $bri > 0 && $bri < 100 ) ? $bri / 100 - : 1; + : 0; my ( $hDec, $sDec, $bDec, $h, $s, $b ); if ( $countLEDs > 0 ) { @@ -2745,6 +2855,11 @@ sub PHTV_ReceiveCommand($$$) { readingsEndUpdate( $hash, 1 ); + Log3 $name, 4, + "PHTV $name: sequentialQuery - finished round " + . $hash->{helper}{sequentialQueryCounter} + if $sequential; + return; } @@ -3309,6 +3424,7 @@ sub PHTV_min {
  • ambiHueLatency - Controls the update interval for HUE devices in milliseconds; defaults to 200 ms.
  • disable - Disable polling (true/false)
  • inputs - Presents the inputs read from device. Inputs can be renamed by adding ,NewName right after the original name.
  • +
  • sequentialQuery - avoid parallel queries for low-performance devices
  • timeout - Set different polling timeout in seconds (default=7)