bugfixes, diverse Playlisterweiterungen, channelring Attribut

This commit is contained in:
Marko Oldenburg 2017-03-15 05:18:34 +01:00
parent 721df09790
commit 19ffb719ca
3 changed files with 330 additions and 286 deletions

View File

@ -37,7 +37,7 @@ use JSON qw(decode_json);
use Encode qw(encode_utf8);
my $version = "0.1.70";
my $version = "0.1.71";
@ -218,12 +218,9 @@ sub HEOSGroup_Notify($$) {
my $events = deviceEvents($dev,1);
#print "notify ####################################################\n".Dumper($events);
return if( !$events );
readingsBeginUpdate($hash);
#my %playerEevents = map { my ( $key, $value ) = split /:\s/; $value =~ s/^\s+//; ( $key, $value ) } @$events;
my %playerEevents = map { my ( $key, $value ) = split /:\s/; ( $key, $value ) } @$events;
foreach my $key ( keys %playerEevents ) {
@ -263,19 +260,19 @@ sub HEOSGroup_Set($$@) {
$action = "state=$args[0]";
} elsif( $cmd eq 'volume' ) {
return "usage: volume 0-100" if( @args != 1 );
return "usage: volume 0-100" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > 100 || $args[0] < 0 );
$heosCmd = 'setGroupVolume';
$action = "level=$args[0]";
} elsif( $cmd eq 'volumeUp' ) {
return "usage: volumeUp 0-10" if( @args != 1 );
return "usage: volumeUp 0-10" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > 10 || $args[0] < 0 );
$heosCmd = 'GroupVolumeUp';
$action = "step=$args[0]";
} elsif( $cmd eq 'volumeDown' ) {
return "usage: volumeDown 0-10" if( @args != 1 );
return "usage: volumeDown 0-10" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > 10 || $args[0] < 0 );
$heosCmd = 'groupVolumeDown';
$action = "step=$args[0]";
@ -286,7 +283,7 @@ sub HEOSGroup_Set($$@) {
$heosCmd = 'createGroup';
$string = "pid=$gid";
} elsif( grep { $_ =~ /\Q$cmd\E/ } ("play", "stop", "pause", "next", "prev", "channel", "channelUp", "channelDown", "playlist" ) ) {
} elsif( grep { $_ eq $cmd } ("play", "stop", "pause", "next", "prev", "channel", "channelUp", "channelDown", "playlist" ) ) {
#ab hier Playerbefehle emuliert
$string = "pid=$gid";
@ -334,34 +331,57 @@ sub HEOSGroup_Set($$@) {
$heosCmd = 'playPrev';
} elsif ( $cmd eq 'channel' ) {
} elsif ( $cmd =~ /channel/ ) {
$favoritcount = scalar(@{$hash->{IODev}{helper}{favorites}}) if ( defined $hash->{IODev}{helper}{favorites} );
return "usage: channel 1-$favoritcount" if( @args != 1 );
$heosCmd = 'playPresetStation';
$action = "preset=$args[0]";
} elsif( $cmd eq 'channelUp' ) {
return "usage: channelUp" if( @args != 0 );
my $favorit = ReadingsVal($name,"channel", 1);
$favoritcount = scalar(@{$hash->{IODev}{helper}{favorites}}) if ( defined $hash->{IODev}{helper}{favorites} );
$heosCmd = 'playPresetStation';
$favorit = ReadingsVal($name,"channel", 0) + 1;
$favorit = $favoritcount if ( $favorit > $favoritcount);
$action = "preset=".$favorit;
} elsif( $cmd eq 'channelDown' ) {
return "usage: channelDown" if( @args != 0 );
if ( $cmd eq 'channel' ) {
return "usage: $cmd 1-$favoritcount" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > $favoritcount || $args[0] < 1);
$heosCmd = 'playPresetStation';
$favorit = ReadingsVal($name,"channel", 0) - 1;
$favorit = 1 if ($favorit <= 0);
$action = "preset=".$favorit;
$action = "preset=$args[0]";
} elsif( $cmd eq 'channelUp' ) {
return "usage: $cmd" if( @args != 0 );
++$favorit;
if ( $favorit > $favoritcount ) {
if ( AttrVal($name, 'channelring', 0) == 1 ) {
$favorit = 1;
} else {
$favorit = $favoritcount;
}
}
$action = "preset=".$favorit;
} elsif( $cmd eq 'channelDown' ) {
return "usage: $cmd" if( @args != 0 );
--$favorit;
if ( $favorit <= 0 ) {
if ( AttrVal($name, 'channelring', 0) == 1 ) {
$favorit = $favoritcount;
} else {
$favorit = 1;
}
}
$action = "preset=".$favorit;
}
} elsif ( $cmd =~ /Playlist/ ) {
my @cids = map { $_->{cid} } grep { $_->{name} =~ /$args[0]/i } (@{ $hash->{IODev}{helper}{playlists} });
my @cids = map { $_->{cid} } grep { $_->{name} =~ /\Q$args[0]\E/i } (@{ $hash->{IODev}{helper}{playlists} });
if ( scalar @args == 1 && scalar @cids > 0 ) {
if ( $cmd eq 'playPlaylist' ) {
@ -468,7 +488,7 @@ sub HEOSGroup_WriteReadings($$) {
my $name = $hash->{NAME};
Log3 $name, 3, "HEOSGroup ($name) - processing data to write readings";
Log3 $name, 4, "HEOSGroup ($name) - processing data to write readings";
############################
#### Aufbereiten der Daten soweit nötig (bei Events zum Beispiel)
my $readingsHash = HEOSGroup_PreProcessingReadings($hash,$decode_json)
@ -556,7 +576,7 @@ sub HEOSGroup_PreProcessingReadings($$) {
} else {
Log3 $name, 3, "HEOSGroup ($name) - no match found";
Log3 $name, 4, "HEOSGroup ($name) - no match found";
return undef;
}

View File

@ -54,7 +54,7 @@ eval "use IO::Socket::Multicast;1" or $missingModulNet .= "IO::Socket::Multicast
my $version = "0.1.70";
my $version = "0.1.71";
my %heosCmds = (
'enableChangeEvents' => 'system/register_for_change_events?enable=',
@ -134,8 +134,8 @@ sub HEOSMaster_GetInputs($);
sub HEOSMaster_GetMusicSources($);
sub HEOSMaster_GetPlaylists($);
sub HEOSMaster_GetServers($);
sub HEOSMaster_Hexdump;
sub HEOSMaster_MakePlayLink($$$$);
sub HEOSMaster_MakeImage($$);
@ -282,59 +282,52 @@ sub HEOSMaster_Set($@) {
if($cmd eq 'reopen') {
return "usage: reopen" if( @args != 0 );
HEOSMaster_ReOpen($hash);
return undef;
} elsif($cmd eq 'getPlayers') {
return "usage: getPlayers" if( @args != 0 );
$heosCmd = 'getPlayers';
$action = undef;
} elsif($cmd eq 'getGroups') {
return "usage: getGroups" if( @args != 0 );
$heosCmd = 'getGroups';
$action = undef;
} elsif($cmd eq 'enableChangeEvents') {
return "usage: enableChangeEvents" if( @args != 1 );
$heosCmd = $cmd;
$action = $args[0];
} elsif($cmd eq 'checkAccount') {
return "usage: checkAccount" if( @args != 0 );
$heosCmd = $cmd;
$action = undef;
} elsif($cmd eq 'signAccount') {
return "usage: signAccountIn" if( @args != 1 );
return "please set account informattion first" if(AttrVal($name,'heosUsername','none') eq 'none');
$heosCmd = $cmd . $args[0];
$action = 'un='. AttrVal($name,'heosUsername','none') . '&pw=' . HEOSMaster_ReadPassword($hash) if($args[0] eq 'In');
} elsif($cmd eq 'password') {
return "usage: password" if( @args != 1 );
return HEOSMaster_StorePassword( $hash, $args[0] );
} elsif($cmd eq 'reboot') {
return "usage: reboot" if( @args != 0 );
return HEOSMaster_StorePassword( $hash, $args[0] );
###################################################
### Dieser Menüpunkt ist nur zum testen
} elsif($cmd eq 'eventSend') {
return "usage: eventSend" if( @args != 0 );
HEOSMaster_send($hash);
return undef;
###################################################
$heosCmd = $cmd;
$action = undef;
} else {
@ -507,7 +500,8 @@ sub HEOSMaster_ProcessRead($$) {
$hash->{LAST_RECV} = time();
Log3 $name, 5, "HEOSMaster ($name) - Decoding JSON message. Length: " . length($json) . " Content: " . $json;
my $obj = JSON->new->utf8(0)->decode($json);
#my $obj = JSON->new->utf8(0)->decode($json); Änderung unter großem Vorbehalt wegen Sorge was Umlaute an geht!!!
my $obj = decode_json($json);
if(defined($obj->{heos})) {
@ -533,6 +527,7 @@ sub HEOSMaster_ResponseProcessing($$) {
my ($hash,$json) = @_;
my $name = $hash->{NAME};
my $decode_json;
my %message;
Log3 $name, 5, "HEOSMaster ($name) - JSON String: $json";
@ -546,7 +541,7 @@ sub HEOSMaster_ResponseProcessing($$) {
unless(ref($decode_json) eq "HASH");
return Log3 $name, 4, "HEOSMaster ($name) - heos worked"
if( $decode_json->{heos}{message} =~ /command\sunder\sprocess/ );
if( defined($decode_json->{heos}{message}) && $decode_json->{heos}{message} =~ /command\sunder\sprocess/ );
if( defined($decode_json->{heos}{result}) or $decode_json->{heos}{command} =~ /^system/ ) {
@ -554,16 +549,12 @@ sub HEOSMaster_ResponseProcessing($$) {
Log3 $name, 4, "HEOSMaster ($name) - call Sub HEOSMaster_WriteReadings";
}
my %message = map { my ( $key, $value ) = split "="; $key => $value } split('&', $decode_json->{heos}{message});
if( defined($decode_json->{heos}{message}) ) {
return Log3 $name, 4, "HEOSMaster ($name) - general error ID $message{eid} - $message{text}"
if( defined($decode_json->{heos}{result}) && $decode_json->{heos}{result} =~ /fail/ );
%message = map { my ( $key, $value ) = split "="; $key => $value } split('&', $decode_json->{heos}{message});
#Quellen neu einlesen
if( $decode_json->{heos}{command} =~ /^event\/sources_changed/ ) {
HEOSMaster_Write($hash,'getMusicSources',undef,undef);
return Log3 $name, 4, "HEOSMaster ($name) - source changed";
return Log3 $name, 4, "HEOSMaster ($name) - general error ID $message{eid} - $message{text}"
if( defined($message{eid}) );
}
#Player neu einlesen
@ -573,6 +564,23 @@ sub HEOSMaster_ResponseProcessing($$) {
return Log3 $name, 4, "HEOSMaster ($name) - player changed";
}
#Gruppen neu einlesen
if( $decode_json->{heos}{command} =~ /^event\/groups_changed/ ) {
HEOSMaster_Write($hash,'getGroups',undef,undef);
#Player neu einlesen da Stereopaare sonst nicht erkannt werden
InternalTimer( gettimeofday()+3, 'HEOSMaster_GetPlayers', $hash, 0 );
return Log3 $name, 4, "HEOSMaster ($name) - groups changed";
}
#Quellen neu einlesen
if( $decode_json->{heos}{command} =~ /^event\/sources_changed/ ) {
HEOSMaster_Write($hash,'getMusicSources',undef,undef);
return Log3 $name, 4, "HEOSMaster ($name) - source changed";
}
#User neu einlesen
if( $decode_json->{heos}{command} =~ /^event\/user_changed/ ) {
@ -580,14 +588,6 @@ sub HEOSMaster_ResponseProcessing($$) {
return Log3 $name, 4, "HEOSMaster ($name) - user changed";
}
#Gruppen neu einlesen
if( $decode_json->{heos}{command} =~ /^event\/groups_changed/ ) {
#InternalTimer( gettimeofday()+5, 'HEOSMaster_GetGroups', $hash, 0 );
HEOSMaster_Write($hash,'getGroups',undef,undef);
return Log3 $name, 4, "HEOSMaster ($name) - groups changed";
}
#Queue für Player neu einlesen
if ( $decode_json->{heos}{command} =~ /^event\/player_queue_changed/ ) {
@ -668,7 +668,43 @@ sub HEOSMaster_ResponseProcessing($$) {
my $start = $message{range} + $message{returned};
if( $message{sid} eq '1028' ) {
if( $message{sid} eq '1024' ) {
#Lokal einlesen
push( @{$hash->{helper}{sources}}, map { $_->{name} .= " USB" if ( $_->{sid} < 0 ); $_ } (@{$decode_json->{payload}}) );
foreach my $source (@{$hash->{helper}{sources}}) {
HEOSMaster_Write($hash,'searchCriteria','sid='.$source->{sid},undef);
Log3 $name, 3, "HEOSMaster ($name) - call Browser for searchCriteria for sid $source->{sid}";
}
} elsif( $message{sid} eq '1025' ) {
#Playlisten einlesen
$hash->{helper}{playlists} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{playlists}}, (@{$decode_json->{payload}}) );
} elsif( $message{sid} eq '1026' ) {
#History einlesen
$hash->{helper}{history} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{history}}, (@{$decode_json->{payload}}) );
} elsif( $message{sid} eq '1027' ) {
#Inputs einlesen
$hash->{helper}{aux} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{aux}}, (@{$decode_json->{payload}}) );
foreach my $item (@{$decode_json->{payload}}) {
HEOSMaster_Write($hash,'browseSource',"sid=$item->{sid}",undef);
Log3 $name, 3, "HEOSMaster ($name) - call Browser for Input with sid $item->{sid}";
}
} elsif( $message{sid} eq '1028' ) {
#Favoriten einlesen
$hash->{helper}{favorites} = [] if ( $message{range} == 0 );
@ -685,46 +721,10 @@ sub HEOSMaster_ResponseProcessing($$) {
}
}
} elsif( $message{sid} eq '1026' ) {
#History einlesen
$hash->{helper}{history} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{history}}, (@{$decode_json->{payload}}) );
} elsif( $message{sid} eq '1025' ) {
#Playlisten einlesen
$hash->{helper}{playlists} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{playlists}}, (@{$decode_json->{payload}}) );
} elsif( $message{sid} eq '1027' ) {
#Inputs einlesen
$hash->{helper}{aux} = [] if ( $message{range} == 0 );
push( @{$hash->{helper}{aux}}, (@{$decode_json->{payload}}) );
foreach my $item (@{$decode_json->{payload}}) {
#$hash->{helper}{aux}{$item->{sid}} = $item->{name};
HEOSMaster_Write($hash,'browseSource',"sid=$item->{sid}",undef);
Log3 $name, 3, "HEOSMaster ($name) - call Browser for Input with sid $item->{sid}";
}
} elsif( $message{sid} eq '1024' ) {
#Lokal einlesen
push( @{$hash->{helper}{sources}}, map { $_->{name} .= " USB" if ( $_->{sid} < 0 ); $_ } (@{$decode_json->{payload}}) );
foreach my $source (@{$hash->{helper}{sources}}) {
HEOSMaster_Write($hash,'searchCriteria','sid='.$source->{sid},undef);
Log3 $name, 3, "HEOSMaster ($name) - call Browser for searchCriteria for sid $source->{sid}";
}
} else {
#AUX Eingang des Player im Player abspeichern
if ( defined $hash->{helper}{aux} && grep( $_->{sid} =~ /$message{sid}/, (@{ $hash->{helper}{aux} }) ) ) {
if ( defined $hash->{helper}{aux} && grep( $_->{sid} =~ /^$message{sid}$/, (@{ $hash->{helper}{aux} }) ) ) {
my $code = abs($message{sid});
$code = $hash->{NAME} ."-". $code if( defined($hash->{NAME}) );
@ -783,16 +783,6 @@ sub HEOSMaster_ResponseProcessing($$) {
@list = (@{$hash->{helper}{favorites}});
} elsif ( $message{sid} eq "1029" ) {
my $code = abs($hash->{helper}{blocking}{$idx}{pid});
$code = $hash->{NAME} ."-". $code if( defined($hash->{NAME}) );
if( my $phash = $modules{HEOSPlayer}{defptr}{$code} ) {
@list = (@{$phash->{helper}{queue}});
}
} else {
@list = (@{$hash->{helper}{media}});
@ -867,10 +857,10 @@ sub HEOSMaster_ResponseProcessing($$) {
my $ret = '';
$ret .= sprintf( "%-35s %-10s %s\n", 'Fav', 'type', 'title' );
foreach my $item (@{ $hash->{helper}{searchresult}}) {
#foreach my $item (@{ $hash->{helper}{searchresult}}) {
$ret .= HEOSMaster_MakePlayLink($hash->{helper}{blocking}{name}, 'input', $message{sid}, $item, sprintf( "%-35s %-10s %s\n", "x", $item->{type}, $item->{name} ) );
}
# $ret .= HEOSMaster_MakePlayLink($hash->{helper}{blocking}{name}, 'input', $message{sid}, $item, sprintf( "%-35s %-10s %s\n", "x", $item->{type}, $item->{name} ) );
#}
$ret .= "\n\n";
@ -968,7 +958,7 @@ sub HEOSMaster_ResponseProcessing($$) {
if ( $start < $message{count} ) {
HEOSMaster_Write($hash,'getQueue',"pid=$message{pid}&range=$start,".($start + 100),undef);
Log3 $name, 3, "HEOSMaster ($name) - call getQueue for player pid $message{pid} next Range from $message{returned}";
Log3 $name, 4, "HEOSMaster ($name) - call getQueue for player pid $message{pid} next Range from $start";
} else {
@ -977,8 +967,8 @@ sub HEOSMaster_ResponseProcessing($$) {
if( my $phash = $modules{HEOSPlayer}{defptr}{$code} ) {
$phash->{helper}{queue} = $hash->{helper}{queue};
delete $hash->{helper}{queue};
$phash->{helper}{queue} = $hash->{helper}{queue}{$message{pid}};
delete $hash->{helper}{queue}{$message{pid}};
}
$json = '{"heos": {"command": "event/player_queue_changed", "message": "pid='.$message{pid}.'"}}';
@ -1108,7 +1098,7 @@ sub HEOSMaster_PreProcessingReadings($$) {
$buffer{'enableChangeEvents'} = $message{enable};
} elsif ( $decode_json->{heos}{command} eq 'system/check_account' or $decode_json->{heos}{command} eq 'system/sign_in' ) {
if ( exists $message{signed_out} ) {
if ( exists $message{signed_out} || exists $message{eid} ) {
$buffer{'heosAccount'} = "signed_out";
@ -1326,7 +1316,6 @@ sub HEOSMaster_MakePlayLink($$$$) {
my $xcmd;
my $xtext = $message->{sid};
#return $txt if( !$FW_ME );
if ( (exists $item->{playable} && $item->{playable} eq "yes") || exists $item->{qid} ) {
@ -1375,29 +1364,16 @@ sub HEOSMaster_MakePlayLink($$$$) {
$xtext .= ','.$item->{qid};
}
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$xcmd = "FW_cmd('$FW_ME$FW_subdir?XHR=1&$xcmd')";
return '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", $xtext, $item->{type}, $item->{name} )."</a></li>\n";
#$FW_ME$FW_subdir
}
sub HEOSMaster_Hexdump {
my $str = ref $_[0] ? ${$_[0]} : $_[0];
sub HEOSMaster_MakeImage($$) {
return "[ZERO-LENGTH STRING]\n" unless length $str;
my ($url, $size) = @_;
my $ret .= "<img src=\"$url\" &width=$size&height=$size\">\n";
# split input up into 16-byte chunks:
my @chunks = $str =~ /([\0-\377]{1,16})/g;
# format and print:
my @print;
for (@chunks) {
my $hex = unpack "H*", $_;
tr/ -~/./c; # mask non-print chars
$hex =~ s/(..)(?!$)/$1 /g; # insert spaces in hex
# make sure our hex output has the correct length
$hex .= ' ' x ( length($hex) < 48 ? 48 - length($hex) : 0 );
push @print, "$hex $_\n";
}
wantarray ? @print : join '', @print;
return $ret;
}

View File

@ -38,7 +38,7 @@ use Encode qw(encode_utf8);
use URI::Escape;
use Data::Dumper;
my $version = "0.1.70";
my $version = "0.1.71";
@ -60,7 +60,6 @@ sub HEOSPlayer_GetPlayMode($);
sub HEOSPlayer_GetVolume($);
sub HEOSPlayer_Get($$@);
sub HEOSPlayer_GetMute($);
sub HEOSPlayer_Hexdump;
@ -82,6 +81,7 @@ sub HEOSPlayer_Initialize($) {
$hash->{AttrList} = "IODev ".
"disable:1 ".
"mute2play:1 ".
"channelring:1 ".
$readingFnAttributes;
foreach my $d(sort keys %{$modules{HEOSPlayer}{defptr}}) {
@ -149,6 +149,7 @@ sub HEOSPlayer_Define($$) {
InternalTimer( gettimeofday()+int(rand(8)), "HEOSPlayer_GetPlayMode", $hash, 0 );
InternalTimer( gettimeofday()+int(rand(10)), "HEOSPlayer_GetVolume", $hash, 0 );
InternalTimer( gettimeofday()+int(rand(12)), "HEOSPlayer_GetMute", $hash, 0 );
InternalTimer( gettimeofday()+int(rand(14)), "HEOSPlayer_GetQueue", $hash, 0 );
} else {
@ -158,6 +159,7 @@ sub HEOSPlayer_Define($$) {
InternalTimer( gettimeofday()+15+int(rand(8)), "HEOSPlayer_GetPlayMode", $hash, 0 );
InternalTimer( gettimeofday()+15+int(rand(10)), "HEOSPlayer_GetVolume", $hash, 0 );
InternalTimer( gettimeofday()+15+int(rand(12)), "HEOSPlayer_GetMute", $hash, 0 );
InternalTimer( gettimeofday()+15+int(rand(14)), "HEOSPlayer_GetQueue", $hash, 0 );
}
readingsBeginUpdate($hash);
@ -242,60 +244,41 @@ sub HEOSPlayer_Get($$@) {
if ( $param eq '' ) {
my $xcmd;
my $ret = "Quellen\n";
$ret .= sprintf( "%-35s %-15s %s\n", 'key', 'type', 'title' );
my $ret = "Musik\n";
#$ret .= sprintf( "%-35s %-15s %s\n", 'key', 'type', 'title' );
foreach my $item (@{ $hash->{IODev}{helper}{sources}}) {
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls '.$item->{sid});
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", $item->{sid}, $item->{type}, $item->{name} )."</a></li>\n";
#$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", $item->{sid}, $item->{type}, $item->{name} )."</a></li>\n";
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, $item->{sid}, $item->{type}, $item->{name});
}
if ( defined $hash->{IODev}{helper}{playlists} ) {
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1025", "heos_service", "Playlist")
if ( defined $hash->{IODev}{helper}{playlists} );
#https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_playlists.png
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls 1025');
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", '1025', "heos_service", "Playlist" )."</a></li>\n";
}
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1026", "heos_service", "Verlauf")
if ( defined $hash->{IODev}{helper}{history} );
#https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_history.png
if ( defined $hash->{IODev}{helper}{history} ) {
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1027", "heos_service", "Eingänge")
if ( defined $hash->{IODev}{helper}{aux} );
#https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_aux.png
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls 1026');
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", '1026', "heos_service", "Verlauf" )."</a></li>\n";
}
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1028", "heos_service", "Favoriten")
if ( defined $hash->{IODev}{helper}{favorites} );
#https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_favorites.png
if ( defined $hash->{IODev}{helper}{aux} ) {
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls 1027');
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", '1027', "heos_service", "Eingänge" )."</a></li>\n";
}
if ( defined $hash->{IODev}{helper}{favorites} ) {
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls 1028');
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", '1028', "heos_service", "Favoriten" )."</a></li>\n";
}
if ( defined $hash->{helper}{queue} ) {
$xcmd = 'cmd'.uri_escape('=get '.$hash->{NAME}.' ls 1029');
$xcmd = "FW_cmd('/fhem?XHR=1&$xcmd')";
$ret .= '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", '1029', "heos_service", "Warteschlange" )."</a></li>\n";
}
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1029", "heos_service", "Warteschlange")
if ( defined $hash->{helper}{queue} );
#https://production.ws.skyegloup.com:443/media/images/service/logos/musicsource_logo_playlists.png
$ret .= "\n\n";
return $ret;
} else {
my @path = split(",", $param);
my $sid = $path[0] if ( scalar @path > 0);
my $cid = $path[1] if ( scalar @path > 1);
my ($sid,$cid)=$param=~/^(-?\d+),?(.*)$/;
$me->{cl} = $hash->{CL} if( ref($hash->{CL}) eq 'HASH' );
$me->{name} = $hash->{NAME};
@ -330,7 +313,7 @@ sub HEOSPlayer_Get($$@) {
my $heosCmd = "browseSource";
my $action;
if ( defined $sid && defined $cid ) {
if ( defined $sid && defined $cid && $cid ne "" ) {
if ( $sid eq "1027" ) {
$action = "sid=$cid";
@ -347,6 +330,40 @@ sub HEOSPlayer_Get($$@) {
$action = "sid=$sid&cid=$cid";
}
} elsif ( defined $sid && $sid eq "1029" ) {
my $ret = "$hash->{NAME}/Warteschlange\n";
$ret .= sprintf( "%-35s %-15s %s\n", 'key', 'type', 'title' );
my $x = 0;
foreach my $item (@{ $hash->{helper}{queue}}) {
$ret .= HEOSPlayer_MakePlayLink($hash->{NAME}, "1029,".++$x, "heos_queue", $item->{song} );
}
$ret .= "\n\n";
if( $me->{cl}->{TYPE} eq 'FHEMWEB' ) {
$ret =~ s/&/&amp;/g;
$ret =~ s/'/&apos;/g;
$ret =~ s/\n/<br>/g;
$ret = "<pre>$ret</pre>" if( $ret =~ m/ / );
$ret = "<html>$ret</html>";
} else {
$ret =~ s/<a[^>]*>//g;
$ret =~ s/<\/a>//g;
$ret =~ s/<img[^>]*>\n//g;
$ret .= "\n";
}
asyncOutput( $me->{cl}, $ret );
#delete $me;
return undef;
} else {
$action = "sid=$sid";
@ -461,7 +478,7 @@ sub HEOSPlayer_Set($$@) {
foreach ( split('\,', $args[0]) ) {
$string .= ",$defs{$_}->{PID}";
$string .= ",$defs{$_}->{PID}" if ( defined $defs{$_} );
printf "String: $string\n";
}
@ -490,30 +507,52 @@ sub HEOSPlayer_Set($$@) {
$heosCmd = 'playPresetStation';
if ( $cmd eq 'channel' ) {
return "usage: channel 1-$favoritcount" if( @args != 1 );
return "usage: channel 1-$favoritcount" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > $favoritcount || $args[0] < 1);
$action = "preset=$args[0]";
} elsif( $cmd eq 'channelUp' ) {
return "usage: $cmd" if( @args != 0 );
$favorit = $favoritcount if ( ++$favorit > $favoritcount );
++$favorit;
if ( $favorit > $favoritcount ) {
if ( AttrVal($name, 'channelring', 0) == 1 ) {
$favorit = 1;
} else {
$favorit = $favoritcount;
}
}
$action = "preset=".$favorit;
} elsif( $cmd eq 'channelDown' ) {
return "usage: $cmd" if( @args != 0 );
$favorit = 1 if ( --$favorit <= 0 );
--$favorit;
if ( $favorit <= 0 ) {
if ( AttrVal($name, 'channelring', 0) == 1 ) {
$favorit = $favoritcount;
} else {
$favorit = 1;
}
}
$action = "preset=".$favorit;
}
} elsif ( $cmd =~ /Queue/ ) {
$heosCmd = $cmd;
if ( $cmd eq 'playQueue' ) {
if ( $cmd eq 'playQueueItem' ) {
$qcount = scalar(@{$hash->{helper}{queue}}) if ( defined $hash->{helper}{queue} );
return "usage: queue 1-$qcount" if( @args != 1 );
return "usage: queue 1-$qcount" if( @args != 1 || $args[0] !~ /(\d+)/ || $args[0] > $qcount || $args[0] < 1);
$action = "qid=$args[0]";
@ -584,90 +623,86 @@ sub HEOSPlayer_Set($$@) {
readingsSingleUpdate($hash, "input", $args[0], 1);
} elsif( $cmd eq 'input' ) {
return 'usage: '.$cmd.' sid[,cid][,mid]' if( @args != 1 );
return "usage: $cmd sid[,cid][,mid]" if( @args != 1 );
my $param = shift( @args );
my @path = split( ",", $param);
my $sid = $path[0] if ( scalar @path > 0);
my $cid = $path[1] if ( scalar @path > 1);
my $mid = $path[2] if ( scalar @path > 2);
my ($sid,$cid,$mid)=$param=~/^(-?\d+),(.+?)(?:,(.*))?/;
if ( $sid =~ /^-*[0-9]+$/ ) {
if ( $sid eq "1024" ) {
return 'usage: '.$cmd.' sid,cid[,mid]' unless( defined($cid) && defined($mid) );
return "usage: $cmd sid[,cid][,mid]" unless( defined $sid || $sid eq "" );
if ( $sid eq "1024" ) {
return "usage: $cmd sid,cid[,mid]" unless( defined($cid) && defined($mid) );
#Server abspielen
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $sid eq "1025" ) {
return "usage: $cmd sid,cid[,mid]" unless( defined($cid) );
#Playlist abspielen
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $sid eq "1026" ) {
return "usage: $cmd sid,cid,mid" unless( defined($cid) );
#Verlauf abspielen
if ( $cid eq "TRACKS" ) {
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $cid eq "STATIONS" ) {
$heosCmd = 'playStream';
$action = "sid=$sid&cid=$cid&mid=$mid";
}
} elsif ( $sid eq "1027" ) {
return "usage: $cmd sid,spid,mid" unless( defined($cid) );
#Eingang abspielen
$heosCmd = 'playInput';
$action = "input=$mid";
$action = "spid=$cid&".$action if ( $pid ne $cid );
} elsif ( $sid eq "1028" ) {
return "usage: $cmd sid,nr" unless( defined($cid) );
#Favoriten abspielen
$heosCmd = 'playPresetStation';
$action = "preset=$cid";
} elsif ( $sid eq "1029" ) {
return "usage: $cmd sid,qid" unless( defined($cid) );
#Warteschlange abspielen
$heosCmd = 'playQueue';
$action = "qid=$cid";
} else {
if ( $sid > 0 && $sid < 1024 ) {
return "usage: $cmd sid,cid,mid" unless( defined($cid) && defined($mid) );
#Radio abspielen
$heosCmd = 'playStream';
$action = "sid=$sid&cid=$cid&mid=$mid";
} else {
return "usage: $cmd sid,cid[,mid]" unless( defined($cid) );
#Server abspielen
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $sid eq "1025" ) {
return 'usage: '.$cmd.' sid,cid[,mid]' unless( defined($cid) );
#Playlist abspielen
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $sid eq "1026" ) {
return 'usage: '.$cmd.' sid,cid,mid' unless( defined($cid) );
#Verlauf abspielen
if ( $cid eq "TRACKS" ) {
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
} elsif ( $cid eq "STATIONS" ) {
$heosCmd = 'playStream';
$action = "sid=$sid&cid=$cid&mid=$mid";
}
} elsif ( $sid eq "1027" ) {
return 'usage: '.$cmd.' sid,spid,mid' unless( defined($cid) );
#Eingang abspielen
$heosCmd = 'playInput';
$action = "input=$mid";
$action = "spid=$cid&".$action if ( $pid ne $cid );
} elsif ( $sid eq "1028" ) {
return 'usage: '.$cmd.' sid,nr' unless( defined($cid) );
#Favoriten abspielen
$heosCmd = 'playPresetStation';
$action = "preset=$cid";
} elsif ( $sid eq "1029" ) {
return 'usage: '.$cmd.' sid,qid' unless( defined($cid) );
#Warteschlange abspielen
$heosCmd = 'playQueue';
$action = "qid=$sid";
} else {
if ( $sid > 0 && $sid < 30 ) {
return 'usage: '.$cmd.' sid,cid,mid' unless( defined($cid) && defined($mid) );
#Radio abspielen
$heosCmd = 'playStream';
$action = "sid=$sid&cid=$cid&mid=$mid";
} else {
return 'usage: '.$cmd.' sid,cid[,mid]' unless( defined($cid) );
#Server abspielen
$heosCmd = 'playPlaylist';
$action = "sid=$sid&cid=$cid&aid=4";
$action = "sid=$sid&cid=$cid&mid=$mid&aid=4" if ( defined($mid) );
}
}
} else {
return 'usage: '.$cmd.' sid,cid[,mid]';
}
} else {
my $list = "getPlayerInfo:noArg getPlayState:noArg getNowPlayingMedia:noArg getPlayMode:noArg play:noArg stop:noArg pause:noArg mute:on,off volume:slider,0,5,100 volumeUp:slider,0,1,10 volumeDown:slider,0,1,10 repeat:one,all,off shuffle:on,off next:noArg prev:noArg input";
@ -686,14 +721,14 @@ sub HEOSPlayer_Set($$@) {
if ( defined($hash->{helper}{queue}) && ref($hash->{helper}{queue}) eq "ARRAY" && scalar(@{$hash->{helper}{queue}}) > 0 ) {
$list .= " playQueue:slider,1,1,".scalar(@{$hash->{helper}{queue}}) if ( defined $hash->{helper}{queue} );
$list .= " playQueueItem:slider,1,1,".scalar(@{$hash->{helper}{queue}}) if ( defined $hash->{helper}{queue} );
$list .= " clearQueue:noArg saveQueue";
}
if ( defined $hash->{IODev}{helper}{playlists} ) {
my @playlists = map { my %n; $n{name} = $_->{name}; $n{name} =~ s/\s+/\&nbsp;/g; $n{name} } (@{ $hash->{IODev}{helper}{playlists}});
#$list .= " playPlaylistItem:slider,1,1,".scalar @playlists;
$list .= " playPlaylist:".join(",",@playlists) if( scalar @playlists > 0 );
$list .= " deletePlaylist:".join(",",@playlists) if( scalar @playlists > 0 );
}
@ -772,7 +807,7 @@ sub HEOSPlayer_WriteReadings($$) {
my $name = $hash->{NAME};
Log3 $name, 3, "HEOSPlayer ($name) - processing data to write readings";
Log3 $name, 4, "HEOSPlayer ($name) - processing data to write readings";
############################
#### Aufbereiten der Daten soweit nötig (bei Events zum Beispiel)
my $readingsHash = HEOSPlayer_PreProcessingReadings($hash,$decode_json)
@ -887,7 +922,7 @@ sub HEOSPlayer_PreProcessingReadings($$) {
} else {
Log3 $name, 3, "HEOSPlayer ($name) - no match found";
Log3 $name, 4, "HEOSPlayer ($name) - no match found";
return undef;
}
@ -958,29 +993,42 @@ sub HEOSPlayer_GetQueue($) {
IOWrite($hash,'getQueue',"pid=$hash->{PID}",undef);
}
sub HEOSPlayer_Hexdump {
sub HEOSPlayer_MakePlayLink($$$$) {
my $str = ref $_[0] ? ${$_[0]} : $_[0];
my ($name, $sid, $itemtype, $itemname) = @_;
my $xcmd = 'cmd'.uri_escape('=get '.$name.' ls '.$sid);
my $xtext = $sid;
return "[ZERO-LENGTH STRING]\n" unless length $str;
$xcmd = 'cmd'.uri_escape('=set '.$name.' input '.$sid) if ( $itemtype eq "heos_queue" );
$xcmd = "FW_cmd('$FW_ME$FW_subdir?XHR=1&$xcmd')";
return '<li style="list-style-type: none; display: inline;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.sprintf( "%-35s %-15s %s", $xtext, $itemtype, $itemname )."</a></li>\n";
}
# split input up into 16-byte chunks:
my @chunks = $str =~ /([\0-\377]{1,16})/g;
# format and print:
my @print;
for (@chunks) {
my $hex = unpack "H*", $_;
tr/ -~/./c; # mask non-print chars
$hex =~ s/(..)(?!$)/$1 /g; # insert spaces in hex
# make sure our hex output has the correct length
$hex .= ' ' x ( length($hex) < 48 ? 48 - length($hex) : 0 );
push @print, "$hex $_\n";
}
wantarray ? @print : join '', @print;
sub HEOSPlayer_MakePlayLink2($$$$) {
my ($name, $sid, $itemname, $itemurl, $xsize, $ysize) = @_;
my $xcmd = 'cmd'.uri_escape('=get '.$name.' ls '.$sid);
my $xtext = $sid;
$xcmd = "FW_cmd('$FW_ME$FW_subdir?XHR=1&$xcmd')";
return '<li style="list-style-type: none; display: inline;"><img src="'.$itemurl.'" width="'.$xsize.'" height="'.$ysize.'" style="float:left;"><a style="cursor:pointer" onclick="'.$xcmd.'">'.$itemname."</a></li>\n";
}
sub HEOSPlayer_makeImage($$) {
my ($url, $xsize, $ysize) = @_;
my $ret .= "<img src=\"$url\" width=\"$xsize\" height=\"$ysize\" style=\"float:left;\">\n";
return $ret;
}
1;