2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

Sonos: added regular expression support for load-commands, proper settings of playing-informations during startup discovery

git-svn-id: https://svn.fhem.de/fhem/trunk@7584 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rleins 2015-01-15 20:55:31 +00:00
parent d39d72761c
commit 9f0b015b75
2 changed files with 111 additions and 19 deletions

View File

@ -48,6 +48,8 @@
#
# SVN-History:
# 15.01.2015
# Für die Setter "LoadPlaylist", "StartPlaylist", "LoadRadio", "StartRadio" und "StartFavourite" kann man jetzt anstatt des Namens einen regulären Ausdruck verwenden.
# Beim Erkennen der Player werden einige Abspielreadings ("transportState", "currentTrackURI", "currentTrackDuration", "currentTrackPosition", "currentTrack", "numberOfTracks", "currentStreamAudio" und "currentNormalAudio") nun direkt abgeholt, und werden somit aktuell korrekt gesetzt.
# Beim Anlegen der neuen Devices werden die Aliasnamen nun mit der Funktion im Team erweitert
# Der Mechanismus zum Starten des SubProzesses wurde angepasst, um auf Synology-Begebenheiten Rücksicht zu nehmen
# Die Coverdarstellung für einige Spotify-Titel wurde korrigiert, indem eine andere Spotify-API verwendet wird
@ -2488,7 +2490,18 @@ sub SONOS_Discover() {
$Data::Dumper::Indent = 2;
}
} elsif ($workType eq 'loadRadio') {
my $radioName = uri_unescape($params[0]);
my $regSearch = ($params[0] =~ m/^ *\/(.*)\/ *$/);
my $radioName = $1 if ($regSearch);
$radioName = uri_unescape($params[0]) if (!$regSearch);
# RegEx prüfen...
if ($regSearch) {
eval { "" =~ m/$radioName/ };
if($@) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Bad RegExp "'.$radioName.'": '.$@);
return;
}
}
if (SONOS_CheckProxyObject($udn, $SONOS_ContentDirectoryControlProxy{$udn})) {
my $result = $SONOS_ContentDirectoryControlProxy{$udn}->Browse('R:0/0', 'BrowseDirectChildren', '', 0, 0, '');
@ -2498,12 +2511,22 @@ sub SONOS_Discover() {
my %resultHash;
while ($tmp =~ m/(<item id="(R:0\/0\/\d+)".*?>)<dc:title>(.*?)<\/dc:title>.*?(<upnp:class>.*?<\/upnp:class>).*?<res.*?>(.*?)<\/res>.*?<\/item>/ig) {
$resultHash{$3}{TITLE} = $3;
$resultHash{$3}{RES} = decode_entities($5);
$resultHash{$3}{METADATA} = $SONOS_DIDLHeader.$1.'<dc:title>'.$3.'</dc:title>'.$4.'<desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON65031_</desc></item>'.$SONOS_DIDLFooter;
my $name = $3;
$resultHash{$name}{TITLE} = $name;
$resultHash{$name}{RES} = decode_entities($5);
$resultHash{$name}{METADATA} = $SONOS_DIDLHeader.$1.'<dc:title>'.$name.'</dc:title>'.$4.'<desc id="cdudn" nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON65031_</desc></item>'.$SONOS_DIDLFooter;
# Den ersten Match ermitteln, und sich den echten Namen für die Zukunft merken...
if ($regSearch) {
if ($name =~ m/$radioName/) {
$radioName = $name;
$regSearch = 0;
}
}
}
if (!$resultHash{$radioName}) {
# Wenn RegSearch gesetzt war, und nichts gefunden wurde...
if (!$resultHash{$radioName} || $regSearch) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Radio "'.$radioName.'" not found. Choose one of: "'.join('","', sort keys %resultHash).'"');
return;
}
@ -2514,7 +2537,19 @@ sub SONOS_Discover() {
}
}
} elsif ($workType eq 'startFavourite') {
my $favouriteName = uri_unescape($params[0]);
my $regSearch = ($params[0] =~ m/^ *\/(.*)\/ *$/);
my $favouriteName = $1 if ($regSearch);
$favouriteName = uri_unescape($params[0]) if (!$regSearch);
# RegEx prüfen...
if ($regSearch) {
eval { "" =~ m/$favouriteName/ };
if($@) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Bad RegExp "'.$favouriteName.'": '.$@);
return;
}
}
my $nostart = 0;
if (defined($params[1]) && lc($params[1]) eq 'nostart') {
$nostart = 1;
@ -2528,12 +2563,22 @@ sub SONOS_Discover() {
my %resultHash;
while ($tmp =~ m/(<item id="(FV:2\/\d+)".*?>)<dc:title>(.*?)<\/dc:title>.*?<res.*?>(.*?)<\/res>.*?<r:resMD>(.*?)<\/r:resMD>.*?<\/item>/ig) {
$resultHash{$3}{TITLE} = $3;
$resultHash{$3}{RES} = decode_entities($4);
$resultHash{$3}{METADATA} = decode_entities($5);
my $name = $3;
$resultHash{$name}{TITLE} = $name;
$resultHash{$name}{RES} = decode_entities($4);
$resultHash{$name}{METADATA} = decode_entities($5);
# Den ersten Match ermitteln, und sich den echten Namen für die Zukunft merken...
if ($regSearch) {
if ($name =~ m/$favouriteName/) {
$favouriteName = $name;
$regSearch = 0;
}
}
}
if (!$resultHash{$favouriteName}) {
# Wenn RegSearch gesetzt war, und nichts gefunden wurde...
if (!$resultHash{$favouriteName} || $regSearch) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Favourite "'.$favouriteName.'" not found. Choose one of: "'.join('","', sort keys %resultHash).'"');
return;
}
@ -2565,7 +2610,20 @@ sub SONOS_Discover() {
}
} elsif ($workType eq 'loadPlaylist') {
my $answer = '';
my $playlistName = uri_unescape($params[0]);
my $regSearch = ($params[0] =~ m/^ *\/(.*)\/ *$/);
my $playlistName = $1 if ($regSearch);
$playlistName = uri_unescape($params[0]) if (!$regSearch);
# RegEx prüfen...
if ($regSearch) {
eval { "" =~ m/$playlistName/ };
if($@) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Bad RegExp "'.$playlistName.'": '.$@);
return;
}
}
my $overwrite = $params[1];
if (SONOS_CheckProxyObject($udn, $SONOS_ContentDirectoryControlProxy{$udn}) && SONOS_CheckProxyObject($udn, $SONOS_AVTransportControlProxy{$udn})) {
@ -2635,10 +2693,20 @@ sub SONOS_Discover() {
my %resultHash;
while ($tmp =~ m/<container id="(SQ:\d+)".*?<dc:title>(.*?)<\/dc:title>.*?<\/container>/ig) {
$resultHash{$2} = $1;
my $name = $2;
$resultHash{$name} = $1;
# Den ersten Match ermitteln, und sich den echten Namen für die Zukunft merken...
if ($regSearch) {
if ($name =~ m/$playlistName/) {
$playlistName = $name;
$regSearch = 0;
}
}
}
if (!$resultHash{$playlistName}) {
# Wenn RegSearch gesetzt war, und nichts gefunden wurde...
if (!$resultHash{$playlistName} || $regSearch) {
SONOS_MakeSigHandlerReturnValue($udn, 'LastActionResult', ucfirst($workType).': Playlist "'.$playlistName.'" not found. Choose one of: "'.join('","', sort keys %resultHash).'"');
return;
}
@ -4351,6 +4419,30 @@ sub SONOS_Discover_Callback($$$) {
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'softwareRevision', $displayVersion);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'serialNum', $serialNum);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'fieldType', $fieldType);
# Abspielreadings vorab ermitteln, um darauf prüfen zu können...
if (SONOS_CheckProxyObject($udn, $SONOS_AVTransportControlProxy{$udn})) {
eval {
my $result = SONOS_AVTransportControlProxy{$udn}->GetTransportInfo(0);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'transportState', $result->getValue('CurrentTransportState'));
$result = SONOS_AVTransportControlProxy{$udn}->GetPositionInfo(0);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentTrackURI', $result->getValue('TrackURI'));
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentTrackDuration', $result->getValue('TrackDuration'));
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentTrackPosition', $result->getValue('RelTime'));
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentTrack', $result->getValue('Track'));
$result = SONOS_AVTransportControlProxy{$udn}->GetMediaInfo(0);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'numberOfTracks', $result->getValue('NrTracks'));
my $stream = ($result->getValue('CurrentURI') =~ m/^x-(sonosapi|rincon)-stream:.*?/);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentStreamAudio', $stream);
SONOS_Client_Data_Refresh('ReadingsBulkUpdateIfChanged', $udn, 'currentNormalAudio', !$stream);
};
if ($@) {
SONOS_Log undef, 4, 'Couldn\'t retrieve Current Transportsettings: '. $@;
}
}
SONOS_Client_Data_Refresh('', $udn, 'LastSubscriptionsRenew', SONOS_TimeNow());
SONOS_Client_Notifier('ReadingsEndUpdate:'.$udn);

View File

@ -936,7 +936,7 @@ sub SONOSPLAYER_Log($$$) {
<br />Uses the Google Text-To-Speech-Engine for generating MP3-Files of the given text and plays it on the SonosPlayer. Possible languages can be obtained from Google. e.g. "de", "en", "fr", "es"...</li>
<li><a name="SONOSPLAYER_setter_StartFavourite">
<code>set &lt;name&gt; StartFavourite &lt;Favouritename&gt; [NoStart]</code></a>
<br /> Starts the named sonos-favorite. The parameter should be URL-encoded for proper naming of lists with special characters. If the Word 'NoStart' is given as second parameter, than the Loading will be done, but the playing-state is leaving untouched e.g. not started.</li>
<br /> Starts the named sonos-favorite. The parameter should be URL-encoded for proper naming of lists with special characters. If the Word 'NoStart' is given as second parameter, than the Loading will be done, but the playing-state is leaving untouched e.g. not started.<br />Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. <code>/meine.hits/</code>.</li>
<li><a name="SONOSPLAYER_setter_StartPlaylist">
<code>set &lt;name&gt; StartPlaylist &lt;Playlistname&gt; [EmptyQueueBeforeImport]</code></a>
<br /> Loads the given Playlist and starts playing immediately. For all Options have a look at "LoadPlaylist".</li>
@ -1012,10 +1012,10 @@ sub SONOSPLAYER_Log($$$) {
<br /> Clears the current queue</li>
<li><a name="SONOSPLAYER_setter_LoadPlaylist">
<code>set &lt;name&gt; LoadPlaylist &lt;Playlistname&gt; [EmptyQueueBeforeImport]</code></a>
<br /> Loads the named playlist to the current playing queue. The parameter should be URL-encoded for proper naming of lists with special characters. The Playlistname can be a filename and then must be startet with 'file:' (e.g. 'file:c:/Test.m3u')<br />If EmptyQueueBeforeImport is given and set to 1, the queue will be emptied before the import process. If not given, the parameter will be interpreted as 1.</li>
<br /> Loads the named playlist to the current playing queue. The parameter should be URL-encoded for proper naming of lists with special characters. The Playlistname can be a filename and then must be startet with 'file:' (e.g. 'file:c:/Test.m3u')<br />If EmptyQueueBeforeImport is given and set to 1, the queue will be emptied before the import process. If not given, the parameter will be interpreted as 1.<br />Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. <code>/hits.2014/</code>.</li>
<li><a name="SONOSPLAYER_setter_LoadRadio">
<code>set &lt;name&gt; LoadRadio &lt;Radiostationname&gt;</code></a>
<br /> Loads the named radiostation (favorite). The current queue will not be touched but deactivated. The parameter should be URL-encoded for proper naming of lists with special characters.</li>
<br /> Loads the named radiostation (favorite). The current queue will not be touched but deactivated. The parameter should be URL-encoded for proper naming of lists with special characters.<br />Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. <code>/radio/</code>.</li>
<li><a name="SONOSPLAYER_setter_SavePlaylist">
<code>set &lt;name&gt; SavePlaylist &lt;Playlistname&gt;</code></a>
<br /> Saves the current queue as a playlist with the given name. An existing playlist with the same name will be overwritten. The parameter should be URL-encoded for proper naming of lists with special characters. The Playlistname can be a filename and then must be startet with 'file:' (e.g. 'file:c:/Test.m3u')</li>
@ -1216,7 +1216,7 @@ Here an event is defined, where in time of 2 seconds the Mute-Button has to be p
<br /> Verwendet die Google Text-To-Speech-Engine um den angegebenen Text in eine MP3-Datei umzuwandeln und anschließend mittels <code>PlayURITemp</code> als Durchsage abzuspielen. Mögliche Sprachen können auf der Google-Seite nachgesehen werden. Möglich sind z.B. "de", "en", "fr", "es"...</li>
<li><a name="SONOSPLAYER_setter_StartFavourite">
<code>set &lt;name&gt; StartFavourite &lt;FavouriteName&gt; [NoStart]</code></a>
<br /> Startet den angegebenen Favoriten. Der Name bezeichnet einen Eintrag in der Sonos-Favoritenliste. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen. Wenn das Wort 'NoStart' als zweiter Parameter angegeben wurde, dann wird der Favorit geladen und fertig vorbereitet, aber nicht explizit gestartet.</li>
<br /> Startet den angegebenen Favoriten. Der Name bezeichnet einen Eintrag in der Sonos-Favoritenliste. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen. Wenn das Wort 'NoStart' als zweiter Parameter angegeben wurde, dann wird der Favorit geladen und fertig vorbereitet, aber nicht explizit gestartet.<br />Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. <code>/meine.hits/</code>.</li>
<li><a name="SONOSPLAYER_setter_StartPlaylist">
<code>set &lt;name&gt; StartPlaylist &lt;Playlistname&gt; [EmptyQueueBeforeImport]</code></a>
<br /> Lädt die benannte Playlist und startet sofort die Wiedergabe. Zu den Parametern und Bemerkungen bitte unter "LoadPlaylist" nachsehen.</li>
@ -1292,10 +1292,10 @@ Here an event is defined, where in time of 2 seconds the Mute-Button has to be p
<br /> Leert die aktuelle Abspielliste</li>
<li><a name="SONOSPLAYER_setter_LoadPlaylist">
<code>set &lt;name&gt; LoadPlaylist &lt;Playlistname&gt; [EmptyQueueBeforeImport]</code></a>
<br /> Lädt die angegebene Playlist in die aktuelle Abspielliste. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen. Der Playlistname kann auch ein Dateiname sein. Dann muss dieser mit 'file:' beginnen (z.B. 'file:c:/Test.m3u).<br />Wenn der Parameter EmptyQueueBeforeImport mit ''1'' angegeben wirde, wird die aktuelle Abspielliste vor dem Import geleert. Standardmäßig wird hier ''1'' angenommen.</li>
<br /> Lädt die angegebene Playlist in die aktuelle Abspielliste. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen. Der Playlistname kann auch ein Dateiname sein. Dann muss dieser mit 'file:' beginnen (z.B. 'file:c:/Test.m3u).<br />Wenn der Parameter EmptyQueueBeforeImport mit ''1'' angegeben wirde, wird die aktuelle Abspielliste vor dem Import geleert. Standardmäßig wird hier ''1'' angenommen.<br />Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. <code>/hits.2014/</code>.</li>
<li><a name="SONOSPLAYER_setter_LoadRadio">
<code>set &lt;name&gt; LoadRadio &lt;Radiostationname&gt;</code></a>
<br /> Startet den angegebenen Radiostream. Der Name bezeichnet einen Sender in der Radiofavoritenliste. Die aktuelle Abspielliste wird nicht verändert. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen.</li>
<br /> Startet den angegebenen Radiostream. Der Name bezeichnet einen Sender in der Radiofavoritenliste. Die aktuelle Abspielliste wird nicht verändert. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen.<br />Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. <code>/radio/</code>.</li>
<li><a name="SONOSPLAYER_setter_SavePlaylist">
<code>set &lt;name&gt; SavePlaylist &lt;Playlistname&gt;</code></a>
<br /> Speichert die aktuelle Abspielliste unter dem angegebenen Namen. Eine bestehende Playlist mit diesem Namen wird überschrieben. Der Parameter sollte/kann URL-Encoded werden um auch Spezialzeichen zu ermöglichen. Der Playlistname kann auch ein Dateiname sein. Dann muss dieser mit 'file:' beginnen (z.B. 'file:c:/Test.m3u).</li>