diff --git a/fhem/FHEM/00_SONOS.pm b/fhem/FHEM/00_SONOS.pm index b568d1165..e4485eee7 100755 --- a/fhem/FHEM/00_SONOS.pm +++ b/fhem/FHEM/00_SONOS.pm @@ -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/()(.*?)<\/dc:title>.*?(.*?<\/upnp:class>).*?(.*?)<\/res>.*?<\/item>/ig) { - $resultHash{$3}{TITLE} = $3; - $resultHash{$3}{RES} = decode_entities($5); - $resultHash{$3}{METADATA} = $SONOS_DIDLHeader.$1.''.$3.''.$4.'SA_RINCON65031_'.$SONOS_DIDLFooter; + my $name = $3; + $resultHash{$name}{TITLE} = $name; + $resultHash{$name}{RES} = decode_entities($5); + $resultHash{$name}{METADATA} = $SONOS_DIDLHeader.$1.''.$name.''.$4.'SA_RINCON65031_'.$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/()(.*?)<\/dc:title>.*?(.*?)<\/res>.*?(.*?)<\/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/(.*?)<\/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); diff --git a/fhem/FHEM/21_SONOSPLAYER.pm b/fhem/FHEM/21_SONOSPLAYER.pm index 4fd33d37a..d1a82c9cc 100755 --- a/fhem/FHEM/21_SONOSPLAYER.pm +++ b/fhem/FHEM/21_SONOSPLAYER.pm @@ -936,7 +936,7 @@ sub SONOSPLAYER_Log($$$) {
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"...
  • set <name> StartFavourite <Favouritename> [NoStart] -
    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.
  • +
    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.
    Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. /meine.hits/.
  • set <name> StartPlaylist <Playlistname> [EmptyQueueBeforeImport]
    Loads the given Playlist and starts playing immediately. For all Options have a look at "LoadPlaylist".
  • @@ -1012,10 +1012,10 @@ sub SONOSPLAYER_Log($$$) {
    Clears the current queue
  • set <name> LoadPlaylist <Playlistname> [EmptyQueueBeforeImport] -
    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')
    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.
  • +
    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')
    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.
    Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. /hits.2014/.
  • set <name> LoadRadio <Radiostationname> -
    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.
  • +
    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.
    Additionally it's possible to use a regular expression as the name. The first hit will be used. The format is e.g. /radio/.
  • set <name> SavePlaylist <Playlistname>
    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')
  • @@ -1216,7 +1216,7 @@ Here an event is defined, where in time of 2 seconds the Mute-Button has to be p
    Verwendet die Google Text-To-Speech-Engine um den angegebenen Text in eine MP3-Datei umzuwandeln und anschließend mittels PlayURITemp als Durchsage abzuspielen. Mögliche Sprachen können auf der Google-Seite nachgesehen werden. Möglich sind z.B. "de", "en", "fr", "es"...
  • set <name> StartFavourite <FavouriteName> [NoStart] -
    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.
  • +
    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.
    Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. /meine.hits/.
  • set <name> StartPlaylist <Playlistname> [EmptyQueueBeforeImport]
    Lädt die benannte Playlist und startet sofort die Wiedergabe. Zu den Parametern und Bemerkungen bitte unter "LoadPlaylist" nachsehen.
  • @@ -1292,10 +1292,10 @@ Here an event is defined, where in time of 2 seconds the Mute-Button has to be p
    Leert die aktuelle Abspielliste
  • set <name> LoadPlaylist <Playlistname> [EmptyQueueBeforeImport] -
    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).
    Wenn der Parameter EmptyQueueBeforeImport mit ''1'' angegeben wirde, wird die aktuelle Abspielliste vor dem Import geleert. Standardmäßig wird hier ''1'' angenommen.
  • +
    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).
    Wenn der Parameter EmptyQueueBeforeImport mit ''1'' angegeben wirde, wird die aktuelle Abspielliste vor dem Import geleert. Standardmäßig wird hier ''1'' angenommen.
    Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. /hits.2014/.
  • set <name> LoadRadio <Radiostationname> -
    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.
  • +
    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.
    Zusätzlich kann ein regulärer Ausdruck für den Namen verwendet werden. Der erste Treffer wird verwendet. Das Format ist z.B. /radio/.
  • set <name> SavePlaylist <Playlistname>
    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).