Sonos: Getter/Setter improvements for the use with FhemWeb

git-svn-id: https://svn.fhem.de/fhem/trunk@7408 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rleins
2015-01-02 15:55:43 +00:00
parent 6493853179
commit 4928a99ac3
3 changed files with 134 additions and 61 deletions

View File

@@ -30,6 +30,14 @@
# Changelog
#
# SVN-History:
# 02.01.2015
# Anzeige bei der Wiedergabe eines Docks verbessert. Dort werden nun der Titel und Album/Artist-Informationen und ein Dock-Cover angezeigt.
# Getter/Setter bei Bedarf um ":noArg" erweitert.
# Getter/Setter sind nun nicht mehr CaseSensitive
# Setter für "Treble" und "Bass" haben nun auch einen Slider
# Setter "Icon" in "RoomIcon" umbenannt, damit die Auswahlliste den aktuellen vorauswählt
# Beim Erzeugen der Sonosplayer-Devices wird nun das Attribut "alias" auf den Sonos-Raumnamen gesetzt.
# Zusätzlich zu "StopAll" oder "PauseAll" gibt es am Sonos-Device nun auch "Stop" und "Pause" mit der gleichen Funktionalität
# 01.01.2015
# Anzeige in der Player-ReadingsGroup für die Darstellung von disappeared angepasst, dabei auch gleich die Höhenverhältnisse etwas angepasst.
# 31.12.2014
@@ -318,7 +326,9 @@ my %gets = (
my %sets = (
'Groups' => 'groupdefinitions',
'StopAll' => '',
'PauseAll' => ''
'Stop' => '',
'PauseAll' => '',
'Pause' => ''
);
my @SONOS_PossibleDefinitions = qw(NAME INTERVAL);
@@ -784,41 +794,10 @@ sub SONOS_FhemWebCallback($) {
return (undef, undef);
}
# Wird im Prinzip einfach nicht mehr aufgerufen...
#if ($URL =~ m/^\/favorit\?res=(.*)/i) {
# my $resURL = uri_unescape($1);
#
# if ($resURL =~ m/^(x-rincon-cpcontainer|x-sonos-spotify).*?(spotify.*?)(\?|$)/i) {
# my $infos = get('https://embed.spotify.com/oembed/?url='.$2);
#
# if ($infos =~ m/"thumbnail_url":"(.*?)cover(.*?)"/i) {
# $resURL = $1.'original'.$2;
# $resURL =~ s/\\//g;
# }
# } elsif($URL =~ m/savedqueues.rsq/i) {
# $resURL = $attr{global}{modpath}.'/FHEM/lib/UPnP/sonos_playlist.jpg';
# } else {
# my @player = SONOS_getAllSonosplayerDevices();
# my $stream = 0;
# $stream = 1 if ($resURL =~ /x-sonosapi-stream/);
# $resURL = $1.'/getaa?'.($stream ? 's=1&' : '').'u='.uri_escape($resURL) if (ReadingsVal($player[0]->{NAME}, 'location', '') =~ m/^(http:\/\/.*?:.*?)\//i);
# }
#
# if ($resURL) {
# SONOS_Log undef, 5, 'Hole Cover: '.$resURL;
#
# if ($resURL =~ /^http/) {
# # Bild holen...
# my $ua = LWP::UserAgent->new(agent => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, likeGecko) Chrome/23.0.1271.64 Safari/537.11');
# my $response = $ua->get($resURL);
# if ($response->is_success) {
# return ($response->header('Content-Type').'; charset=UTF8', $response->content);
# }
# } else {
# return ('charset=UTF8', SONOS_ReadFile($resURL));
# }
# }
#}
if ($URL =~ m/^\/input_dock.jpg/i) {
FW_serveSpecial('sonos_input_dock', 'jpg', $attr{global}{modpath}.'/FHEM/lib/UPnP', 1);
return (undef, undef);
}
}
# Wenn wir hier ankommen, dann konnte nichts verarbeitet werden...
@@ -1654,8 +1633,25 @@ sub SONOS_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
# for the ?-selector: which values are possible
if($a[1] eq '?') {
my @newGets = ();
for my $elem (sort keys %gets) {
push @newGets, $elem.(($gets{$elem} eq '') ? ':noArg' : '');
}
return "Unknown argument, choose one of ".join(" ", @newGets);
}
# check argument
return "SONOS: Get with unknown argument $a[1], choose one of ".join(",", sort keys %gets) if(!defined($gets{$reading}));
my $found = 0;
for my $elem (keys %gets) {
if (lc($reading) eq lc($elem)) {
$reading = $elem; # Korrekte Schreibweise behalten
$found = 1;
last;
}
}
return "SONOS: Get with unknown argument $a[1], choose one of ".join(",", sort keys %gets) if(!$found);
# some argument needs parameter(s), some not
return "SONOS: $a[1] needs parameter(s): ".$gets{$a[1]} if (scalar(split(',', $gets{$a[1]})) > scalar(@a) - 2);
@@ -1746,12 +1742,26 @@ sub SONOS_Set($@) {
} else {
%setcopy = %sets;
}
# for the ?-selector: which values are possible
return join(" ", sort keys %setcopy) if($a[1] eq '?');
if($a[1] eq '?') {
my @newSets = ();
for my $elem (sort keys %setcopy) {
push @newSets, $elem.(($setcopy{$elem} eq '') ? ':noArg' : '');
}
return "Unknown argument, choose one of ".join(" ", @newSets);
}
# check argument
return "SONOS: Set with unknown argument $a[1], choose one of ".join(",", sort keys %sets) if(!defined($sets{$a[1]}));
my $found = 0;
for my $elem (keys %sets) {
if (lc($a[1]) eq lc($elem)) {
$a[1] = $elem; # Korrekte Schreibweise behalten
$found = 1;
last;
}
}
return "SONOS: Set with unknown argument $a[1], choose one of ".join(",", sort keys %sets) if(!$found);
# some argument needs parameter(s), some not
return "SONOS: $a[1] needs parameter(s): ".$sets{$a[1]} if (scalar(split(',', $sets{$a[1]})) > scalar(@a) - 2);
@@ -1841,7 +1851,7 @@ sub SONOS_Set($@) {
#}
#SONOS_Log undef, 5, "Current after List: ".Dumper(\@current);
} elsif (lc($key) =~ m/(Stop|Pause)All/i) {
} elsif (lc($key) =~ m/(Stop|Pause)(All|)/i) {
my $commandType = $1;
# Aktuellen Zustand holen
@@ -4053,6 +4063,7 @@ sub SONOS_Discover_Callback($$$) {
# Define SonosPlayer-Device with attributes
SONOS_Client_Notifier('CommandDefine:'.$name.' SONOSPLAYER '.$udn);
SONOS_Client_Notifier('CommandAttr:'.$name.' room '.$SONOS_Client_Data{SonosDeviceName});
SONOS_Client_Notifier('CommandAttr:'.$name.' alias '.$roomName);
SONOS_Client_Notifier('CommandAttr:'.$name.' group '.$groupName);
SONOS_Client_Notifier('CommandAttr:'.$name.' icon '.$iconPath);
SONOS_Client_Notifier('CommandAttr:'.$name.' sortby 1');
@@ -4064,6 +4075,7 @@ sub SONOS_Discover_Callback($$$) {
SONOS_Client_Notifier('CommandAttr:'.$name.' generateInfoSummarize2 <TransportState/><InfoSummarize1 prefix=" => "/>');
SONOS_Client_Notifier('CommandAttr:'.$name.' generateInfoSummarize3 <Volume prefix="Lautstärke: "/><Mute instead=" ~ Kein Ton" ifempty=" ~ Ton An" emptyval="0"/> ~ Balance: <Balance ifempty="Mitte" emptyval="0"/><HeadphoneConnected instead=" ~ Kopfhörer aktiv" ifempty=" ~ Kein Kopfhörer" emptyval="0"/>');
SONOS_Client_Notifier('CommandAttr:'.$name.' stateVariable Presence');
SONOS_Client_Notifier('CommandAttr:'.$name.' generateVolumeSlider 1');
SONOS_Client_Notifier('CommandAttr:'.$name.' getAlarms 1'); SONOS_Client_Data_Refresh('', $udn, 'getAlarms', 1);
SONOS_Client_Notifier('CommandAttr:'.$name.' minVolume 0'); SONOS_Client_Data_Refresh('', $udn, 'minVolume', 0);
@@ -4644,6 +4656,14 @@ sub SONOS_ServiceCallback($$) {
SONOS_Client_Notifier('SetCurrent:Artist:');
SONOS_Client_Notifier('ProcessCover:'.$udn.':0:/fhem/sonos/cover/input_default.jpg:');
} elsif ($currentTrackURI =~ m/x-sonos-dock:(RINCON_[\dA-Z]+)/) {
# Dock-Wiedergabe feststellen, und dann andere Informationen anzeigen
SONOS_Client_Notifier('SetCurrent:Album:'.SONOS_Client_Data_Retreive($1.'_MR', 'reading', 'currentAlbum', SONOS_Client_Data_Retreive($1.'_MR', 'reading', 'roomName', $1)));
my $tmpTitle = SONOS_replaceSpecialStringCharacters(decode_entities($1)) if ($currentTrackMetaData =~ m/<dc:title>(.*?)<\/dc:title>/i);
SONOS_Client_Notifier('SetCurrent:Title:'.SONOS_Client_Data_Retreive($1.'_MR', 'reading', 'currentTitle', $tmpTitle));
SONOS_Client_Notifier('SetCurrent:Artist:'.SONOS_Client_Data_Retreive($1.'_MR', 'reading', 'currentArtist', ''));
SONOS_Client_Notifier('ProcessCover:'.$udn.':0:/fhem/sonos/cover/input_dock.jpg:');
} elsif ($currentTrackURI =~ m/x-sonos-htastream:(RINCON_[\dA-Z]+):spdif/) {
# LineIn-Wiedergabe der Playbar feststellen, und dann andere Informationen anzeigen
SONOS_Client_Notifier('SetCurrent:Album:'.SONOS_Client_Data_Retreive($1.'_MR', 'reading', 'roomName', $1));

View File

@@ -158,7 +158,7 @@ my %sets = (
'Reboot' => '',
'Wifi' => 'state',
'Name' => 'roomName',
'Icon' => 'iconName'
'RoomIcon' => 'iconName'
);
my @possibleRoomIcons = qw(bathroom library office foyer dining tvroom hallway garage garden guestroom den bedroom kitchen portable media family pool masterbedroom playroom patio living);
@@ -278,13 +278,35 @@ sub SONOSPLAYER_Get($@) {
my $reading = $a[1];
my $name = $hash->{NAME};
my $udn = $hash->{UDN};
my $udn = $hash->{UDN};
# for the ?-selector: which values are possible
if($reading eq '?') {
my @newGets = ();
for my $elem (sort keys %gets) {
my $newElem = $elem.(($gets{$elem} eq '') ? ':noArg' : '');
$newElem = $elem.':0,1' if (lc($elem) eq 'ethernetportstatus');
push @newGets, $newElem;
}
return "Unknown argument, choose one of ".join(" ", @newGets);
}
# check argument
return "SONOSPLAYER: Get with unknown argument $a[1], choose one of ".join(" ", sort keys %gets) if(!defined($gets{$reading}));
my $found = 0;
for my $elem (keys %gets) {
if (lc($reading) eq lc($elem)) {
$a[1] = $elem; # Korrekte Schreibweise behalten
$reading = $elem; # Korrekte Schreibweise behalten
$found = 1;
last;
}
}
return "SONOSPLAYER: Get with unknown argument $a[1], choose one of ".join(" ", sort keys %gets) if(!$found);
# some argument needs parameter(s), some not
return "SONOSPLAYER: $a[1] needs parameter(s): ".$gets{$a[1]} if (scalar(split(',', $gets{$a[1]})) > scalar(@a) - 2);
return "SONOSPLAYER: $a[1] needs parameter(s): ".$gets{$reading} if (scalar(split(',', $gets{$reading})) > scalar(@a) - 2);
# getter
if (lc($reading) eq 'currenttrackposition') {
@@ -345,16 +367,30 @@ sub SONOSPLAYER_Set($@) {
if($a[1] eq '?') {
# %setCopy enthält eine Kopie von %sets, da für eine ?-Anfrage u.U. ein Slider zurückgegeben werden muss...
my %setcopy;
if (AttrVal($hash, 'generateVolumeSlider', 1) == 1) {
foreach my $key (keys %sets) {
my $oldkey = $key;
foreach my $key (keys %sets) {
my $oldkey = $key;
if (AttrVal($hash, 'generateVolumeSlider', 1) == 1) {
$key = $key.':slider,0,1,100' if ($key eq 'Volume');
$key = $key.':slider,0,1,100' if ($key eq 'GroupVolume');
$key = $key.':slider,0,1,100' if ($key eq 'Treble');
$key = $key.':slider,0,1,100' if ($key eq 'Bass');
$key = $key.':slider,-100,1,100' if ($key eq 'Balance');
$setcopy{$key} = $sets{$oldkey};
}
} else {
%setcopy = %sets;
# On/Off einsetzen
$key = $key.':off,on' if ((lc($key) eq 'crossfademode') || (lc($key) eq 'groupmute') || (lc($key) eq 'ledstate') || (lc($key) eq 'loudness') || (lc($key) eq 'lute') || (lc($key) eq 'repeat') || (lc($key) eq 'shuffle'));
# Iconauswahl einsetzen
if (lc($key) eq 'roomicon') {
my $icons = SONOSPLAYER_Get($hash, ($hash->{NAME}, 'PossibleRoomIcons'));
$icons =~ s/ //g;
$key = $key.':'.$icons;
}
# Wifi-Auswahl setzen
$key = $key.':off,on,persist-off' if (lc($key) eq 'wifi');
$setcopy{$key} = $sets{$oldkey};
}
my $sonosDev = SONOS_getDeviceDefHash(undef);
@@ -362,12 +398,29 @@ sub SONOSPLAYER_Set($@) {
$sets{Speak2} = 'volume language text' if (AttrVal($sonosDev->{NAME}, 'Speak2', '') ne '');
$sets{Speak3} = 'volume language text' if (AttrVal($sonosDev->{NAME}, 'Speak3', '') ne '');
$sets{Speak4} = 'volume language text' if (AttrVal($sonosDev->{NAME}, 'Speak4', '') ne '');
# for the ?-selector: which values are possible
if($a[1] eq '?') {
my @newSets = ();
for my $elem (sort keys %setcopy) {
push @newSets, $elem.(($setcopy{$elem} eq '') ? ':noArg' : '');
}
return "Unknown argument, choose one of ".join(" ", @newSets);
}
return join(" ", sort keys %setcopy);
#return join(" ", sort keys %setcopy);
}
# check argument
return "SONOSPLAYER: Set with unknown argument $a[1], choose one of ".join(" ", sort keys %sets) if(!defined($sets{$a[1]}));
my $found = 0;
for my $elem (keys %sets) {
if (lc($a[1]) eq lc($elem)) {
$a[1] = $elem; # Korrekte Schreibweise behalten
$found = 1;
last;
}
}
return "SONOSPLAYER: Set with unknown argument $a[1], choose one of ".join(" ", sort keys %sets) if(!$found);
# some argument needs parameter(s), some not
return "SONOSPLAYER: $a[1] needs parameter(s): ".$sets{$a[1]} if (scalar(split(',', $sets{$a[1]})) > scalar(@a) - 2);
@@ -702,7 +755,7 @@ sub SONOSPLAYER_Set($@) {
}
SONOS_DoWork($udn, 'setName', $text);
} elsif (lc($key) eq 'icon') {
} elsif (lc($key) eq 'roomicon') {
$hash = SONOSPLAYER_GetRealTargetPlayerHash($hash);
$udn = $hash->{UDN};
$value = lc($value);
@@ -835,8 +888,8 @@ sub SONOSPLAYER_Log($$$) {
<li><a name="SONOSPLAYER_setter_DailyIndexRefreshTime">
<code>set &lt;name&gt; DailyIndexRefreshTime &lt;time&gt;</code></a>
<br />Sets the current DailyIndexRefreshTime for the whole bunch of Zoneplayers.</li>
<li><a name="SONOSPLAYER_setter_Icon">
<code>set &lt;name&gt; Icon &lt;Iconname&gt;</code></a>
<li><a name="SONOSPLAYER_setter_RoomIcon">
<code>set &lt;name&gt; RoomIcon &lt;Iconname&gt;</code></a>
<br />Sets the Icon for this Zone</li>
<li><a name="SONOSPLAYER_setter_Name">
<code>set &lt;name&gt; Name &lt;Zonename&gt;</code></a>
@@ -996,7 +1049,7 @@ sub SONOSPLAYER_Log($$$) {
<br /> Gets the Ethernet-Portstatus of the given Port. Can be 'Active' or 'Inactive'.</li>
<li><a name="SONOSPLAYER_getter_PossibleRoomIcons">
<code>get &lt;name&gt; PossibleRoomIcons</code></a>
<br /> Retreives a list of all possible Roomiconnames for the use with "set Icon".</li>
<br /> Retreives a list of all possible Roomiconnames for the use with "set RoomIcon".</li>
</ul></li>
<li><b>Lists</b><ul>
<li><a name="SONOSPLAYER_getter_Favourites">
@@ -1114,8 +1167,8 @@ Here an event is defined, where in time of 2 seconds the Mute-Button has to be p
<li><a name="SONOSPLAYER_setter_DailyIndexRefreshTime">
<code>set &lt;name&gt; DailyIndexRefreshTime &lt;time&gt;</code></a>
<br />Setzt die aktuell gültige DailyIndexRefreshTime für alle Zoneplayer.</li>
<li><a name="SONOSPLAYER_setter_Icon">
<code>set &lt;name&gt; Icon &lt;Iconname&gt;</code></a>
<li><a name="SONOSPLAYER_setter_RoomIcon">
<code>set &lt;name&gt; RoomIcon &lt;Iconname&gt;</code></a>
<br />Legt das Icon für die Zone fest</li>
<li><a name="SONOSPLAYER_setter_Name">
<code>set &lt;name&gt; Name &lt;Zonename&gt;</code></a>

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB