mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-22 02:10:32 +00:00
71_YAMAHA_NP: Bugfix: Prevent directPlay from starting netradio stream several times in case of slow internet connections.
git-svn-id: https://svn.fhem.de/fhem/trunk@14630 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
d4f2ca559f
commit
b36a1a168e
@ -1,5 +1,7 @@
|
||||
# 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.
|
||||
- bugfix: 71_YAMAHA_NP: Prevent directPlay from starting netradio stream
|
||||
several times in slow internet connections
|
||||
- feature: 93_DbLog: V2.18.2, new command configCheck for MySQL, PostgreSQL
|
||||
- new: 98_archetype: introducing new module to inheritance attributes
|
||||
and defines devices
|
||||
|
@ -86,7 +86,9 @@ sub YAMAHA_NP_Initialize
|
||||
." autoUpdatePlayerReadings:1,0"
|
||||
." autoUpdateTunerReadings:1,0"
|
||||
." autoUpdatePlayerlistReadings:1,0"
|
||||
." searchAttempts"
|
||||
." searchAttempts"
|
||||
." directPlaySleepNetradio:3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30"
|
||||
." directPlaySleepServer:2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30"
|
||||
." smoothVolumeChange:1,0"
|
||||
|
||||
." .favoriteList" # Hidden attribute for favorites storage
|
||||
@ -229,9 +231,9 @@ sub YAMAHA_NP_Attr
|
||||
}
|
||||
elsif($attrName eq "searchAttempts")
|
||||
{
|
||||
if ($cmd eq "set" && (($attrVal < 1) || ($attrVal > 100)))
|
||||
if ($cmd eq "set" && (($attrVal < 15) || ($attrVal > 100)))
|
||||
{
|
||||
return "$attrName must be between 1 and 100";
|
||||
return "$attrName must be between 15 and 100";
|
||||
}
|
||||
}
|
||||
elsif(($attrName eq ".favoriteList") && defined($attrVal))
|
||||
@ -240,7 +242,6 @@ sub YAMAHA_NP_Attr
|
||||
{
|
||||
$attr{$name}{$attrName} = $attrVal; #need to set first!
|
||||
}
|
||||
|
||||
YAMAHA_NP_favoriteList($name);
|
||||
}
|
||||
elsif(($attrName eq ".DABList") && defined($attrVal))
|
||||
@ -257,7 +258,21 @@ sub YAMAHA_NP_Attr
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($attrName eq "maxPlayerListItems" && defined($attrVal))
|
||||
elsif(($attrName eq "directPlaySleepNetradio") && defined($attrVal))
|
||||
{
|
||||
if ($cmd eq "set" && (($attrVal < 3) || ($attrVal > 30)))
|
||||
{
|
||||
return "$attrName must be between 3 and 30";
|
||||
}
|
||||
}
|
||||
elsif(($attrName eq "directPlaySleepServer") && defined($attrVal))
|
||||
{
|
||||
if ($cmd eq "set" && (($attrVal < 2) || ($attrVal > 30)))
|
||||
{
|
||||
return "$attrName must be between 2 and 30";
|
||||
}
|
||||
}
|
||||
elsif(($attrName eq "maxPlayerListItems") && defined($attrVal))
|
||||
{
|
||||
if ($cmd eq "set" && (($attrVal < 8) || ($attrVal > 999)))
|
||||
{
|
||||
@ -422,7 +437,13 @@ sub YAMAHA_NP_directSet
|
||||
my $hash = $defs{$name};
|
||||
|
||||
#Log 1,"directSet, directPlay ". $hash->{helper}{directPlayQueue}{input}.":".$hash->{helper}{directPlayQueue}{stream};
|
||||
YAMAHA_NP_Set($hash,"","directPlay",$hash->{helper}{directPlayQueue}{input}.":".$hash->{helper}{directPlayQueue}{stream});
|
||||
$hash->{helper}{directPlayQueue}{stream} = "noStream" if(not($hash->{helper}{directPlayQueue}{stream}));
|
||||
|
||||
# Due to asyncronous timers possible race condition. Supress if already playing.
|
||||
if(ReadingsVal($name,"playerPlaybackInfo", "stop") ne "play")
|
||||
{
|
||||
YAMAHA_NP_Set($hash,"","directPlay",$hash->{helper}{directPlayQueue}{input}.":".$hash->{helper}{directPlayQueue}{stream});
|
||||
}
|
||||
}
|
||||
|
||||
sub YAMAHA_NP_Get
|
||||
@ -574,7 +595,7 @@ sub YAMAHA_NP_Set
|
||||
|
||||
# Sort playerList first numeric items XXX_NAME -> lvlX_XXX -> ...
|
||||
# Replace not allowed characters
|
||||
@playerList = sort map{s/[ :;,']/_/g;$_;} grep/._..*$/,@playerList;
|
||||
@playerList = sort map{s/[ :;,'.]/_/g;$_;} grep/._..*$/,@playerList;
|
||||
|
||||
# Sort CD tracks as 'Track_XX'
|
||||
if($input eq "cd")
|
||||
@ -588,7 +609,7 @@ sub YAMAHA_NP_Set
|
||||
# Add tuneUp/tuneDown in case of tuner input
|
||||
if($input =~ m/^(DAB|FM)/)
|
||||
{
|
||||
push @playerList,("tuneUp","tuneDown");
|
||||
push @playerList, ("tuneUp","tuneDown");
|
||||
}
|
||||
|
||||
# Add selectStream as set command. In addition '---' as dummy for web interface.
|
||||
@ -722,29 +743,36 @@ sub YAMAHA_NP_Set
|
||||
|
||||
delete $hash->{helper}{directPlayQueue};
|
||||
|
||||
return "Please enter stream" if(!$a[2]);
|
||||
return "Please enter stream -> INPUT:STREAM_LVL1,STREAM_LVL2,..." if(!$a[2]);
|
||||
|
||||
if (!defined $hash->{helper}{directPlayQueueTry})
|
||||
{
|
||||
$hash->{helper}{directPlayQueueTry} = 1 ;# we start with 1st try
|
||||
$hash->{helper}{directPlayQueueTry} = 1 ; # 1st try
|
||||
readingsSingleUpdate($hash, "directPlay", "started", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
# Increment and limit the # to searchAttempts
|
||||
# Increment and limit number to searchAttempts
|
||||
$hash->{helper}{directPlayQueueTry}++;
|
||||
|
||||
if ($hash->{helper}{directPlayQueueTry} > AttrVal($name,"searchAttempts", 15))
|
||||
{
|
||||
# Timeout
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-timeout");
|
||||
YAMAHA_NP_directPlayFinish($hash, "abort-timeout");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# INPUT:STREAM_LVL1,STREAM_LVL2,...
|
||||
my ($inputTarget, $stream) = split(":",$a[2],2);
|
||||
|
||||
if (ReadingsVal($name,"state",0) ne "on")
|
||||
$inputTarget = lc($inputTarget);
|
||||
|
||||
# Set default stream name in case none provided
|
||||
$stream = "noStream" if(not $stream);
|
||||
|
||||
# Check if device unpowered
|
||||
if (ReadingsVal($name, "state", 0) ne "on")
|
||||
{
|
||||
$what = "on";
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 2;
|
||||
@ -755,8 +783,17 @@ sub YAMAHA_NP_Set
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
my $input = ReadingsVal($name, "input", "");
|
||||
|
||||
#Log 1, "InputTarget: $inputTarget";
|
||||
#Log 1, "Input: $input";
|
||||
|
||||
if ($inputTarget eq $input)
|
||||
{
|
||||
# Force Playerlist status update.
|
||||
YAMAHA_NP_SendCmd($hash, "GET:Player,List_Info:GetParam", "statusRequest", "playerListGetList", 0);
|
||||
|
||||
if($inputTarget =~ m/(aux|digital|spotify|airplay)/)
|
||||
{
|
||||
# These inputs don't have streams. Finish.
|
||||
@ -784,7 +821,7 @@ sub YAMAHA_NP_Set
|
||||
||($stream > $totalTracks ) # too big
|
||||
)
|
||||
{
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-not found");
|
||||
YAMAHA_NP_directPlayFinish($hash, "abort-not found");
|
||||
return ;
|
||||
}
|
||||
elsif ($currentTrack == $stream)
|
||||
@ -829,7 +866,6 @@ sub YAMAHA_NP_Set
|
||||
}
|
||||
if($found == 0)
|
||||
{
|
||||
# && $hash->{helper}{directPlayQueueTry} > 8){#no match, time out
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-not found");
|
||||
return ;
|
||||
}
|
||||
@ -839,13 +875,28 @@ sub YAMAHA_NP_Set
|
||||
$what = "selectStream" if ($what eq "directPlay");
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 1;
|
||||
}
|
||||
# Server, Netradio
|
||||
elsif(ReadingsVal($name, "playerListMenuStatus", "-") ne "Ready")
|
||||
{
|
||||
YAMAHA_NP_directRestartTimer($name, 3, $a[2], $inputTarget, $stream);# take another chance: data was not complete
|
||||
# Depending on input and server/network speed the duration is unknown
|
||||
# Customization of polling intervall for Server (LAN) and Netradio (vTuner)
|
||||
|
||||
my $sleep = 3; # default
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepNetradio", 3);
|
||||
}
|
||||
# take another chance: data was not complete
|
||||
YAMAHA_NP_directRestartTimer($name, $sleep, $a[2], $inputTarget, $stream);
|
||||
return;
|
||||
}
|
||||
|
||||
# Streams with multilevel selection e.g. server, netradio
|
||||
# Streams with multilevel selection e.g. server, netradio
|
||||
|
||||
else
|
||||
{
|
||||
@ -878,8 +929,22 @@ desiredListNloop:
|
||||
YAMAHA_NP_directPlayFinish($hash);# we are done!!
|
||||
return ;
|
||||
}
|
||||
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 2;
|
||||
|
||||
# Depending on input and server/network speed the duration is unknown
|
||||
# Customization of polling intervall for Server (LAN) and Netradio (vTuner)
|
||||
|
||||
my $sleep = 2; # default
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepNetradio", 3);
|
||||
}
|
||||
|
||||
$hash->{helper}{directPlayQueue}{sleep} = $sleep;
|
||||
}
|
||||
|
||||
my $found = 0;
|
||||
@ -902,13 +967,27 @@ desiredListNloop:
|
||||
|
||||
if (!defined $desiredSong)
|
||||
{# no list item - problem. abort
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-not found");
|
||||
YAMAHA_NP_directPlayFinish($hash, "abort-not found");
|
||||
return;
|
||||
}
|
||||
elsif (!defined $playerSong)
|
||||
{
|
||||
# Depending on input and server/network speed the duration is unknown
|
||||
# Customization of polling intervall for Server (LAN) and Netradio (vTuner)
|
||||
|
||||
my $sleep = 2; # default
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$sleep = AttrVal($name,"directPlaySleepNetradio", 3);
|
||||
}
|
||||
|
||||
# not yet playing?
|
||||
YAMAHA_NP_directRestartTimer($name, 2, $a[2], $inputTarget, $stream);# take another chance: data was not complete
|
||||
YAMAHA_NP_directRestartTimer($name, $sleep, $a[2], $inputTarget, $stream); # take another chance: data was not complete
|
||||
return;
|
||||
}
|
||||
elsif ($desiredSong =~ m/$playerSong/)
|
||||
@ -923,11 +1002,21 @@ desiredListNloop:
|
||||
}
|
||||
elsif ($hash->{helper}{playlist}{state} ne "complete")
|
||||
{
|
||||
YAMAHA_NP_directRestartTimer($name, 2, $a[2], $inputTarget, $stream);# take another chance: data was not complete
|
||||
my $sleep = 2; # default
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$sleep = AttrVal($name, "directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$sleep = AttrVal($name, "directPlaySleepNetradio", 3);
|
||||
}
|
||||
YAMAHA_NP_directRestartTimer($name, $sleep, $a[2], $inputTarget, $stream);# take another chance: data was not complete
|
||||
}
|
||||
else
|
||||
{
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-not found");
|
||||
YAMAHA_NP_directPlayFinish($hash, "abort-not found");
|
||||
} #no chance
|
||||
return;
|
||||
}
|
||||
@ -943,13 +1032,26 @@ desiredListNloop:
|
||||
if ($level > $desiredListLast)
|
||||
{
|
||||
#$level is one less then desiredListLast!
|
||||
YAMAHA_NP_directPlayFinish($hash,"abort-not found");
|
||||
YAMAHA_NP_directPlayFinish($hash, "abort-not found");
|
||||
return;
|
||||
}
|
||||
$what = "selectStream";
|
||||
}
|
||||
$hash->{helper}{directPlayQueue}{state} = "selectInput";
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 2;
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 3; # default
|
||||
|
||||
# Depending on input and server/network speed the duration is unknown
|
||||
# Customization of polling intervall for Server (LAN) and Netradio (vTuner)
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$hash->{helper}{directPlayQueue}{sleep} = AttrVal($name, "directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$hash->{helper}{directPlayQueue}{sleep} = AttrVal($name, "directPlaySleepNetradio", 3);
|
||||
}
|
||||
|
||||
$hash->{helper}{directPlayQueue}{a} = $a[2];
|
||||
$hash->{helper}{directPlayQueue}{input} = $inputTarget;
|
||||
$hash->{helper}{directPlayQueue}{stream} = $stream;
|
||||
@ -961,13 +1063,27 @@ desiredListNloop:
|
||||
# stream set necessary?
|
||||
delete $hash->{helper}{directPlayQueue};
|
||||
$hash->{helper}{directPlayQueue}{state} = "selectInput";
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 3;
|
||||
|
||||
$hash->{helper}{directPlayQueue}{sleep} = 3; # default
|
||||
# Depending on input and server/network speed the duration is unknown
|
||||
# Customization of polling intervall for Server (LAN) and Netradio (vTuner)
|
||||
|
||||
if (lc($inputTarget) eq "server")
|
||||
{
|
||||
$hash->{helper}{directPlayQueue}{sleep} = AttrVal($name, "directPlaySleepServer", 2);
|
||||
}
|
||||
elsif(lc($inputTarget) eq "netradio")
|
||||
{
|
||||
$hash->{helper}{directPlayQueue}{sleep} = AttrVal($name, "directPlaySleepNetradio", 3);
|
||||
}
|
||||
|
||||
$hash->{helper}{directPlayQueue}{a} = $a[2];
|
||||
$hash->{helper}{directPlayQueue}{input} = $inputTarget;
|
||||
$hash->{helper}{directPlayQueue}{stream} = $stream;
|
||||
}
|
||||
$what = "input";
|
||||
$a[2] = $inputTarget;
|
||||
YAMAHA_NP_directRestartTimer($name, 2, $a[2], $inputTarget, $stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -979,7 +1095,7 @@ desiredListNloop:
|
||||
RemoveInternalTimer("statTimeOut:".$hash->{NAME});
|
||||
}
|
||||
|
||||
# Log 1,"General process $what ++++$a[2] --------->$hash->{helper}{directPlayQueue}{a}";
|
||||
#Log 1,"General process $what ++++$a[2] --------->$hash->{helper}{directPlayQueue}{a}";
|
||||
|
||||
if($what eq "selectStream")
|
||||
{
|
||||
@ -1638,8 +1754,8 @@ sub YAMAHA_NP_ParseResponse
|
||||
|
||||
$hash->{MODEL} = $1;
|
||||
$hash->{helper}{dInfo}{MODEL} = $1;
|
||||
$hash->{FIRMWARE} = $3;
|
||||
$hash->{helper}{dInfo}{FIRMWARE} = $3;
|
||||
$hash->{FIRMWARE} = $3;
|
||||
$hash->{helper}{dInfo}{FIRMWARE} = $3;
|
||||
$hash->{helper}{dInfo}{SYSTEM_ID} = $2;
|
||||
readingsBulkUpdate($hash, ".volumeStraightMin" , int($4));
|
||||
readingsBulkUpdate($hash, ".volumeStraightMax" , int($5));
|
||||
@ -1775,9 +1891,24 @@ sub YAMAHA_NP_ParseResponse
|
||||
|
||||
$song = ReadingsVal($name,"listItem_$1","-") if ($song =~ /^Track(.*)/);
|
||||
readingsBulkUpdate($hash, "playerPlaySong" , $song);
|
||||
|
||||
readingsBulkUpdate($hash, "playerPlaybackInfo", ($data !~ /<Playback_Info>(.+)<\/Playback_Info>/)? "" : lc($1));
|
||||
readingsBulkUpdate($hash, "playerPlayTime" , ($data !~ /<Play_Time>(.+)<\/Play_Time>/) ? "" : strftime("\%H:\%M:\%S", gmtime($1)));
|
||||
|
||||
if ($data =~ /<Play_Time>(.+)<\/Play_Time>/)
|
||||
{
|
||||
if(int($1) < 3600) # 00:00
|
||||
{
|
||||
readingsBulkUpdate($hash, "playerPlayTime", strftime("\%M:\%S", gmtime($1)));
|
||||
}
|
||||
else # 00:00:00
|
||||
{
|
||||
readingsBulkUpdate($hash, "playerPlayTime", strftime("\%H:\%M:\%S", gmtime($1)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
readingsBulkUpdate($hash, "playerPlayTime", "");
|
||||
}
|
||||
|
||||
readingsBulkUpdate($hash, "playerPlayArtist" , ($data !~ /<Artist>(.+)<\/Artist>/) ? "" : YAMAHA_NP_html2txt($1));
|
||||
readingsBulkUpdate($hash, "playerPlayAlbum" , ($data !~ /<Album>(.+)<\/Album>/) ? "" : YAMAHA_NP_html2txt($1));
|
||||
readingsBulkUpdate($hash, "playerDeviceType" , ($data !~ /<Device_Type>(.+)<\/Device_Type>/) ? "" : lc($1));
|
||||
@ -2112,99 +2243,99 @@ sub YAMAHA_NP_ParseResponse
|
||||
}
|
||||
elsif($arg eq "playerListGetList")
|
||||
{
|
||||
if($data =~ /<Menu_Status>(.*)<\/Menu_Status>/)
|
||||
{
|
||||
$hash->{helper}{playlist}{ready} = $1;
|
||||
readingsBulkUpdate($hash, "playerListMenuStatus", $hash->{helper}{playlist}{ready});
|
||||
}
|
||||
|
||||
my $lay = ($data =~ /<Menu_Layer>(.*)<\/Menu_Layer>/) ? $1 : "-";
|
||||
my $nam = ($data =~ /<Menu_Name>(.*)<\/Menu_Name>/) ? $1 : "-";
|
||||
my ($lnMax,$lnCur,$lnPg) = (1,1,1);# maxline, currentline, currentpage
|
||||
|
||||
if($data =~ /<Cursor_Position><Current_Line>(.*)<\/Current_Line><Max_Line>(.*)<\/Max_Line><\/Cursor_Position>/)
|
||||
{
|
||||
($lnMax,$lnCur,$lnPg) = ($2,$1,int(($1-1)/8));
|
||||
}
|
||||
if($data =~ /<Menu_Status>(.*)<\/Menu_Status>/)
|
||||
{
|
||||
$hash->{helper}{playlist}{ready} = $1;
|
||||
readingsBulkUpdate($hash, "playerListMenuStatus", $hash->{helper}{playlist}{ready});
|
||||
}
|
||||
|
||||
my $lay = ($data =~ /<Menu_Layer>(.*)<\/Menu_Layer>/) ? $1 : "-";
|
||||
my $nam = ($data =~ /<Menu_Name>(.*)<\/Menu_Name>/) ? $1 : "-";
|
||||
my ($lnMax,$lnCur,$lnPg) = (1,1,1);# maxline, currentline, currentpage
|
||||
|
||||
if($data =~ /<Cursor_Position><Current_Line>(.*)<\/Current_Line><Max_Line>(.*)<\/Max_Line><\/Cursor_Position>/)
|
||||
{
|
||||
($lnMax,$lnCur,$lnPg) = ($2,$1,int(($1-1)/8));
|
||||
}
|
||||
|
||||
$lnMax = AttrVal($name, "maxPlayerListItems", 999) if ($lnMax >= AttrVal($name, "maxPlayerListItems", 999)); # Limit to given attribute value
|
||||
|
||||
if (!$hash->{helper}{playlist}{mnCur} || $hash->{helper}{playlist}{mnCur} ne "$lay:$nam")
|
||||
{
|
||||
# did we change our context? Clean up
|
||||
$hash->{helper}{playlist}{mnCur} = "$lay:$nam";
|
||||
foreach (grep /playerListLvl.*$/,keys %{$hash->{READINGS}})
|
||||
{
|
||||
#delete level information
|
||||
delete $hash->{READINGS}{$_} if (substr($_,13)>$lay);
|
||||
}
|
||||
readingsBulkUpdate($hash, "playerListLvl$lay", "$nam");
|
||||
|
||||
delete $hash->{READINGS}{$_} foreach (grep /listItem_...$/,keys %{$hash->{READINGS}});#delete playlist
|
||||
$lnMax = AttrVal($name, "maxPlayerListItems", 999) if ($lnMax >= AttrVal($name, "maxPlayerListItems", 999)); # Limit to given attribute value
|
||||
|
||||
if (!$hash->{helper}{playlist}{mnCur} || $hash->{helper}{playlist}{mnCur} ne "$lay:$nam")
|
||||
{
|
||||
# did we change our context? Clean up
|
||||
$hash->{helper}{playlist}{mnCur} = "$lay:$nam";
|
||||
foreach (grep /playerListLvl.*$/,keys %{$hash->{READINGS}})
|
||||
{
|
||||
#delete level information
|
||||
delete $hash->{READINGS}{$_} if (substr($_,13)>$lay);
|
||||
}
|
||||
readingsBulkUpdate($hash, "playerListLvl$lay", "$nam");
|
||||
|
||||
delete $hash->{READINGS}{$_} foreach (grep /listItem_...$/,keys %{$hash->{READINGS}});#delete playlist
|
||||
|
||||
for (my $pln = 1;$pln <= $lnMax;$pln++)
|
||||
{
|
||||
#prefill entries as unknown
|
||||
$pln = sprintf("%03d",$pln);
|
||||
next if ($pln > 999);
|
||||
$hash->{READINGS}{"listItem_$pln"}{VAL} = "unknown";
|
||||
$hash->{READINGS}{"listItem_$pln"}{TIME}= "-";
|
||||
}
|
||||
my $lnNext = (($lnPg + 1) % (int(($lnMax-1)/8)+1))*8 + 1;
|
||||
$hash->{helper}{playlist}{state} = ($lnNext == 1) ? "complete" : "incomplete";
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Jump_Line:1","statusRequest", "playerListJumpLine", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($hash->{helper}{playlist}{state} eq "incomplete")
|
||||
{
|
||||
my $lnNext = (($lnPg + 1) % (int(($lnMax-1)/8)+1))*8 + 1;
|
||||
$hash->{helper}{playlist}{state} = "complete" if($lnNext == 1);
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Jump_Line:$lnNext","statusRequest", "playerListJumpLine", 0);
|
||||
}
|
||||
}
|
||||
if($data =~ /<Current_List>(.*)<\/Current_List>/)
|
||||
{
|
||||
# write list entries
|
||||
# <Line_X><Txt>****</Txt><Attribute>Container|Item|Unselectable</Attribute></Line_X>
|
||||
my ($i,$ip) = (1,1);
|
||||
my %pla =( Container => "c_",Item => "i_"); #PlayListAttr - convert to prefix
|
||||
while($data =~ /<Line_$i><Txt>(.*?)<\/Txt><Attribute>(.*?)<\/Attribute><\/Line_$i>/gc)
|
||||
{
|
||||
last if($ip >= AttrVal($name, "maxPlayerListItems", 999)); # Limit to giver attribute value
|
||||
$ip = sprintf("%03d",($lnPg * 8) + $i);
|
||||
if($1){readingsBulkUpdate($hash, "listItem_$ip", $pla{$2}.YAMAHA_NP_html2txt($1));}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$hash->{helper}{playlist}{lnCur} = $lnCur;
|
||||
if (ReadingsVal($name,"playerListMenuStatus","") eq "Ready")
|
||||
{
|
||||
# see whether more action is required
|
||||
if ($hash->{helper}{playlist}{selection})
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Direct_Sel:Line_$hash->{helper}{playlist}{selection}", "selectStream", $hash->{helper}{playlist}{selection}, 0);
|
||||
delete $hash->{helper}{playlist}{selection};
|
||||
}
|
||||
elsif ($hash->{helper}{playlist}{desiredDirectoryLevel})
|
||||
{
|
||||
# want to change directory level
|
||||
my ($currentLevel) = split(":",$hash->{helper}{playlist}{mnCur});# currentLevel,
|
||||
if ($hash->{helper}{playlist}{desiredDirectoryLevel} < $currentLevel)
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Cursor:Return", "playerListCursorReturn", $hash->{helper}{playlist}{desiredDirectoryLevel},0);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete $hash->{helper}{playlist}{desiredDirectoryLevel};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($arg eq "playerListJumpLine")
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "GET:Player,List_Info:GetParam" ,"statusRequest", "playerListGetList" , 0);
|
||||
}
|
||||
for (my $pln = 1;$pln <= $lnMax;$pln++)
|
||||
{
|
||||
#prefill entries as unknown
|
||||
$pln = sprintf("%03d",$pln);
|
||||
next if ($pln > 999);
|
||||
$hash->{READINGS}{"listItem_$pln"}{VAL} = "unknown";
|
||||
$hash->{READINGS}{"listItem_$pln"}{TIME}= "-";
|
||||
}
|
||||
my $lnNext = (($lnPg + 1) % (int(($lnMax-1)/8)+1))*8 + 1;
|
||||
$hash->{helper}{playlist}{state} = ($lnNext == 1) ? "complete" : "incomplete";
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Jump_Line:1","statusRequest", "playerListJumpLine", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($hash->{helper}{playlist}{state} eq "incomplete")
|
||||
{
|
||||
my $lnNext = (($lnPg + 1) % (int(($lnMax-1)/8)+1))*8 + 1;
|
||||
$hash->{helper}{playlist}{state} = "complete" if($lnNext == 1);
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Jump_Line:$lnNext","statusRequest", "playerListJumpLine", 0);
|
||||
}
|
||||
}
|
||||
if($data =~ /<Current_List>(.*)<\/Current_List>/)
|
||||
{
|
||||
# write list entries
|
||||
# <Line_X><Txt>****</Txt><Attribute>Container|Item|Unselectable</Attribute></Line_X>
|
||||
my ($i,$ip) = (1,1);
|
||||
my %pla =( Container => "c_",Item => "i_"); #PlayListAttr - convert to prefix
|
||||
while($data =~ /<Line_$i><Txt>(.*?)<\/Txt><Attribute>(.*?)<\/Attribute><\/Line_$i>/gc)
|
||||
{
|
||||
last if($ip >= AttrVal($name, "maxPlayerListItems", 999)); # Limit to giver attribute value
|
||||
$ip = sprintf("%03d",($lnPg * 8) + $i);
|
||||
if($1){readingsBulkUpdate($hash, "listItem_$ip", $pla{$2}.YAMAHA_NP_html2txt($1));}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$hash->{helper}{playlist}{lnCur} = $lnCur;
|
||||
if (ReadingsVal($name,"playerListMenuStatus","") eq "Ready")
|
||||
{
|
||||
# see whether more action is required
|
||||
if ($hash->{helper}{playlist}{selection})
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Direct_Sel:Line_$hash->{helper}{playlist}{selection}", "selectStream", $hash->{helper}{playlist}{selection}, 0);
|
||||
delete $hash->{helper}{playlist}{selection};
|
||||
}
|
||||
elsif ($hash->{helper}{playlist}{desiredDirectoryLevel})
|
||||
{
|
||||
# want to change directory level
|
||||
my ($currentLevel) = split(":",$hash->{helper}{playlist}{mnCur});# currentLevel,
|
||||
if ($hash->{helper}{playlist}{desiredDirectoryLevel} < $currentLevel)
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:Player,List_Control,Cursor:Return", "playerListCursorReturn", $hash->{helper}{playlist}{desiredDirectoryLevel},0);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete $hash->{helper}{playlist}{desiredDirectoryLevel};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif($arg eq "playerListJumpLine")
|
||||
{
|
||||
YAMAHA_NP_SendCmd($hash, "GET:Player,List_Info:GetParam" ,"statusRequest", "playerListGetList" , 0);
|
||||
}
|
||||
}
|
||||
elsif($cmd eq "on")
|
||||
{
|
||||
@ -2218,7 +2349,9 @@ sub YAMAHA_NP_ParseResponse
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
YAMAHA_NP_ResetTimer($hash);
|
||||
$cmd = $hash->{helper}{directPlayQueue}{state} if($hash->{helper}{directPlayQueue});
|
||||
|
||||
# Used for direct play if device unpowered
|
||||
$cmd = $hash->{helper}{directPlayQueue}{state} if($hash->{helper}{directPlayQueue});
|
||||
return if(!defined $hash->{helper}{directPlayQueue});
|
||||
}
|
||||
}
|
||||
@ -2263,7 +2396,7 @@ sub YAMAHA_NP_ParseResponse
|
||||
if($hash->{helper}{volumeChangeDir} eq "EQUAL")
|
||||
{
|
||||
$hash->{helper}{volumeChangeProcessing} = "0";
|
||||
readingsBulkUpdate($hash, "volumeStraight", $hash->{helper}{targetVolume});
|
||||
readingsBulkUpdate($hash, "volumeStraight", $hash->{helper}{targetVolume});
|
||||
readingsBulkUpdate($hash, "volume", YAMAHA_NP_volume_abs2rel($hash, $hash->{helper}{targetVolume}));
|
||||
}
|
||||
elsif($hash->{helper}{volumeChangeDir} =~ m/(UP|DOWN)/)
|
||||
@ -2276,9 +2409,9 @@ sub YAMAHA_NP_ParseResponse
|
||||
elsif($hash->{helper}{volumeChangeDir} eq "DOWN")
|
||||
{
|
||||
$volumeStraight -= 1;
|
||||
}
|
||||
readingsBulkUpdate($hash, "volumeStraight", $volumeStraight);
|
||||
readingsBulkUpdate($hash, "volume", YAMAHA_NP_volume_abs2rel($hash, $volumeStraight));
|
||||
}
|
||||
readingsBulkUpdate($hash, "volumeStraight", $volumeStraight);
|
||||
readingsBulkUpdate($hash, "volume", YAMAHA_NP_volume_abs2rel($hash, $volumeStraight));
|
||||
YAMAHA_NP_SendCmd($hash, "PUT:System,Volume,Lvl:$volumeStraight", "volume", $volumeStraight, 0);
|
||||
}
|
||||
}
|
||||
@ -2309,25 +2442,32 @@ sub YAMAHA_NP_ParseResponse
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
# Log 1,"General << : $cmd # $arg ".ReadingsVal($name,"playerListMenuStatus","-");
|
||||
|
||||
# Reset internal timer for direct play.
|
||||
|
||||
#Log 1,"General << : $cmd # $arg ".ReadingsVal($name,"playerListMenuStatus","-");
|
||||
|
||||
if ($cmd ne "statusRequest")
|
||||
{
|
||||
if ($hash->{helper}{directPlayQueue})
|
||||
{
|
||||
RemoveInternalTimer("directPlay:".$name);
|
||||
my $slp = $hash->{helper}{directPlayQueue}{sleep} ? $hash->{helper}{directPlayQueue}{sleep} : 0.5;
|
||||
my $slp = $hash->{helper}{directPlayQueue}{sleep} ? $hash->{helper}{directPlayQueue}{sleep} : 0.5;
|
||||
InternalTimer(gettimeofday() + $slp, "YAMAHA_NP_directSet", "directPlay:".$name, 0);
|
||||
}
|
||||
YAMAHA_NP_GetStatus($hash, 1) ;# got to update if parameter changed
|
||||
}
|
||||
elsif( ($hash->{helper}{playlist}{ready} && $hash->{helper}{playlist}{ready} ne "Ready")
|
||||
&& ($arg ne "playerListJumpLine")) {# fast poll
|
||||
elsif
|
||||
(
|
||||
($hash->{helper}{playlist}{ready} && $hash->{helper}{playlist}{ready} ne "Ready")
|
||||
&& ($arg ne "playerListJumpLine")
|
||||
)
|
||||
{
|
||||
# fast poll
|
||||
my $slp = $hash->{helper}{directPlayQueue}{sleep} ? $hash->{helper}{directPlayQueue}{sleep} : 0.5;
|
||||
RemoveInternalTimer($hash);
|
||||
InternalTimer(gettimeofday() + $slp, "YAMAHA_NP_GetStatus", $hash, 0);
|
||||
}
|
||||
|
||||
readingsEndUpdate($hash, 1);
|
||||
}
|
||||
}
|
||||
@ -2348,9 +2488,9 @@ sub blankLineItem
|
||||
delete $hash->{READINGS}{$_} foreach(grep /^listItem_/,keys %{$hash->{READINGS}});
|
||||
}
|
||||
|
||||
sub YAMAHA_NP_directPlayFinish($;@)
|
||||
sub YAMAHA_NP_directPlayFinish
|
||||
{
|
||||
my ($hash,$status) = @_;
|
||||
my ($hash, $status) = @_;
|
||||
delete $hash->{helper}{directPlayQueueTry};
|
||||
delete $hash->{helper}{directPlayQueue};
|
||||
RemoveInternalTimer("statTimeOut:".$hash->{NAME});
|
||||
@ -2607,11 +2747,14 @@ sub YAMAHA_NP_html2txt
|
||||
<li><b>autoUpdatePlayerReadings</b> – optional attribute for auto refresh of player related readings (default is 1).</li>
|
||||
<li><b>autoUpdatePlayerlistReadings</b> – optional attribute for auto scanning of the playerlist content (default is 1). (Due to the playerlist information transfer concept this function might slow down the reaction time of the Yamaha App when used at the same time.)</li>
|
||||
<li><b>autoUpdateTunerReadings</b> – optional attribute for auto refresh of tuner related readings (default is 1).</li>
|
||||
<li><b>directPlaySleepNetradio</b> – optional attribute to define a sleep time between two netradio requests to the vTuner server while using the directPlay command. Increase in case of slow internet connection (default is 5 seconds).</li>
|
||||
<li><b>directPlaySleepServer</b> – optional attribute to define a sleep time between two multimedia server requests while using the directPlay command. Increase in case of slow server connection (default is 2 seconds).</li>
|
||||
<li><b>disable</b> – optional attribute to disable the internal cyclic status update of the NP. Manual status updates via statusRequest command is still possible. Possible values: 0 → perform cyclic status update, 1 → don't perform cyclic status updates (default is 1).</li>
|
||||
<li><b>do_not_notify</b></li>
|
||||
<li><b>maxPlayerListItems</b> – optional attribute to limit the max number of player list items (default is 999).</li>
|
||||
<li><b>readingFnAttributes</b></li><br>
|
||||
<li><b>requestTimeout</b> – optional attribute change the response timeout in seconds for all queries to the receiver. Possible values: 1...5 seconds (default value is 4).</li>
|
||||
<li><b>searchAttempts</b> – optional attribute used by the directPlay command defining the max. number of finding the provided directory content tries before giving up. Possible values: 15...100 (default is 15).</li>
|
||||
<li><b>smoothVolumeChange</b> – optional attribute for smooth volume change (significantly more Ethernet traffic is generated during volume change if set to 1) (default is 1).</li>
|
||||
<li><b>timerHour</b> [0...23] – sets hour of device's internal wake–up timer</li>
|
||||
<li><b>timerMinute</b> [0...59] – sets minutes of device's internal wake–up timer</li>
|
||||
@ -2806,11 +2949,14 @@ sub YAMAHA_NP_html2txt
|
||||
<li><b>autoUpdatePlayerReadings</b> – optionales Attribut zum automtischen aktualisieren der Player–Readings (Default 1)</li>
|
||||
<li><b>autoUpdatePlayerlistReadings</b> – optionales Attribut zum automatischen Scannen der Playerlist (Menü) (Default 1). (Aufgrund des Kommunikationskonzeptes bei der Übertragung der Playerlistinformation kann diese Funktion zu längeren Reaktionszeiten bei der Yamaha App führen, wenn gleichzeitig auf den Netzwerkplayer zugegriffen wird.)</li>
|
||||
<li><b>autoUpdateTunerReadings</b> – optionales Attribut zum automtischen aktualisieren der Tuner–Readings (Default 1)</li>
|
||||
<li><b>disable</b> – optionales Attribut zum Deaktivieren des internen zyklischen Timers zum Aktualisieren des NP–Status. Manuelles Update ist nach wie vor möglich. Mögliche Werte: 0 → Zyklisches Update aktiv., 1 → Zyklisches Update inaktiv (Default 1).</li>
|
||||
<li><b>directPlaySleepNetradio</b> – optionales Attribut zum Definieren der Sleep-Zeit zwischen zwei netradio Anfragen zum vTuner Server, wenn der Befehl directPlay benutzt wird. Kann bei langsamen Interneverbindungen nützlich sein. (Default 5 Sek.).</li>
|
||||
<li><b>directPlaySleepServer</b> – optionales Attribut zum Definieren der Sleep-Zeit zwischen zwei Multimediaserver-Anfragen, wenn der Befehl directPlay benutzt wird. Kann bei langsamen Verbindungen nützlich sein. (Default 2 Sek.).</li>
|
||||
<li><b>disable</b> – optionales Attribut zum Deaktivieren des internen zyklischen Timers zum Aktualisieren des NP–Status. Manuelles Update ist nach wie vor möglich. Mögliche Werte: 0 → Zyklisches Update aktiv., 1 → Zyklisches Update inaktiv (Default 1).</li>
|
||||
<li><b>do_not_notify</b></li>
|
||||
<li><b>maxPlayerListItems</b> – optionales Attribut zum Limitieren der maximalen Anzahl von Menüeinträgen (Default 999).</li>
|
||||
<li><b>readingFnAttributes</b></li>
|
||||
<li><b>requestTimeout</b> – optionales Attribut zum setzen des HTTP response Timeouts (Default 4)</li>
|
||||
<li><b>searchAttempts</b> – optionales Attribut zur Definition von max. Anzahl der Suchversuche des angegebenen Direktoryinhalts bei der Benutzng des directPlay Befehls. Mögliche Werte: 15...100 (Default 15 Sek.).</li>
|
||||
<li><b>smoothVolumeChange</b> – optionales Attribut zur sanften Lautstärkeänderung (Erzeugt deutlich mehr Ethernetkommunikation während der Lautstärkeänderung). (Default 1)</li>
|
||||
<li><b>timerHour</b> [0...23] – Setzt die Stunde des internen Wake–up Timers</li>
|
||||
<li><b>timerMinute</b> [0...59] – Setzt die Minute des internen Wake–up Timers</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user