diff --git a/homeassistant/components/plex/media_player.py b/homeassistant/components/plex/media_player.py
index 24e37216b70..1a57186bd9b 100644
--- a/homeassistant/components/plex/media_player.py
+++ b/homeassistant/components/plex/media_player.py
@@ -22,6 +22,7 @@ from homeassistant.components.media_player.const import (
)
from homeassistant.const import STATE_IDLE, STATE_PAUSED, STATE_PLAYING
from homeassistant.core import callback
+from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect,
async_dispatcher_send,
@@ -495,16 +496,26 @@ class PlexMediaPlayer(MediaPlayerEntity):
if isinstance(src, int):
src = {"plex_key": src}
- shuffle = src.pop("shuffle", 0)
- media = self.plex_server.lookup_media(media_type, **src)
+ playqueue_id = src.pop("playqueue_id", None)
- if media is None:
- _LOGGER.error("Media could not be found: %s", media_id)
- return
+ if playqueue_id:
+ try:
+ playqueue = self.plex_server.get_playqueue(playqueue_id)
+ except plexapi.exceptions.NotFound as err:
+ raise HomeAssistantError(
+ f"PlayQueue '{playqueue_id}' could not be found"
+ ) from err
+ else:
+ shuffle = src.pop("shuffle", 0)
+ media = self.plex_server.lookup_media(media_type, **src)
- _LOGGER.debug("Attempting to play %s on %s", media, self.name)
+ if media is None:
+ _LOGGER.error("Media could not be found: %s", media_id)
+ return
+
+ _LOGGER.debug("Attempting to play %s on %s", media, self.name)
+ playqueue = self.plex_server.create_playqueue(media, shuffle=shuffle)
- playqueue = self.plex_server.create_playqueue(media, shuffle=shuffle)
try:
self.device.playMedia(playqueue)
except requests.exceptions.ConnectTimeout:
diff --git a/homeassistant/components/plex/server.py b/homeassistant/components/plex/server.py
index f8d55c71fc4..1baceb78ff1 100644
--- a/homeassistant/components/plex/server.py
+++ b/homeassistant/components/plex/server.py
@@ -593,6 +593,10 @@ class PlexServer:
"""Create playqueue on Plex server."""
return plexapi.playqueue.PlayQueue.create(self._plex_server, media, **kwargs)
+ def get_playqueue(self, playqueue_id):
+ """Retrieve existing playqueue from Plex server."""
+ return plexapi.playqueue.PlayQueue.get(self._plex_server, playqueue_id)
+
def fetch_item(self, item):
"""Fetch item from Plex server."""
return self._plex_server.fetchItem(item)
diff --git a/homeassistant/components/plex/services.py b/homeassistant/components/plex/services.py
index 2e4057b890a..a5faa56a8bb 100644
--- a/homeassistant/components/plex/services.py
+++ b/homeassistant/components/plex/services.py
@@ -105,15 +105,25 @@ def lookup_plex_media(hass, content_type, content_id):
content_type = DOMAIN
plex_server_name = content.pop("plex_server", None)
- shuffle = content.pop("shuffle", 0)
-
plex_server = get_plex_server(hass, plex_server_name)
- media = plex_server.lookup_media(content_type, **content)
- if media is None:
- raise HomeAssistantError(f"Plex media not found using payload: '{content_id}'")
+ playqueue_id = content.pop("playqueue_id", None)
+ if playqueue_id:
+ try:
+ playqueue = plex_server.get_playqueue(playqueue_id)
+ except NotFound as err:
+ raise HomeAssistantError(
+ f"PlayQueue '{playqueue_id}' could not be found"
+ ) from err
+ else:
+ shuffle = content.pop("shuffle", 0)
+ media = plex_server.lookup_media(content_type, **content)
+ if media is None:
+ raise HomeAssistantError(
+ f"Plex media not found using payload: '{content_id}'"
+ )
+ playqueue = plex_server.create_playqueue(media, shuffle=shuffle)
- playqueue = plex_server.create_playqueue(media, shuffle=shuffle)
return (playqueue, plex_server)
diff --git a/tests/components/plex/conftest.py b/tests/components/plex/conftest.py
index 8fc25a819e8..d3e66cc4989 100644
--- a/tests/components/plex/conftest.py
+++ b/tests/components/plex/conftest.py
@@ -168,6 +168,12 @@ def playqueue_created_fixture():
return load_fixture("plex/playqueue_created.xml")
+@pytest.fixture(name="playqueue_1234", scope="session")
+def playqueue_1234_fixture():
+ """Load payload for playqueue 1234 and return it."""
+ return load_fixture("plex/playqueue_1234.xml")
+
+
@pytest.fixture(name="plex_server_accounts", scope="session")
def plex_server_accounts_fixture():
"""Load payload accounts on the Plex server and return it."""
diff --git a/tests/components/plex/test_services.py b/tests/components/plex/test_services.py
index 9d1715aa72b..cf8bc63c5da 100644
--- a/tests/components/plex/test_services.py
+++ b/tests/components/plex/test_services.py
@@ -113,6 +113,7 @@ async def test_sonos_play_media(
setup_plex_server,
requests_mock,
empty_payload,
+ playqueue_1234,
playqueue_created,
plextv_account,
sonos_resources,
@@ -178,3 +179,19 @@ async def test_sonos_play_media(
play_on_sonos(hass, MEDIA_TYPE_MUSIC, content_id_bad_media, sonos_speaker_name)
assert "Plex media not found" in str(excinfo.value)
assert playback_mock.call_count == 3
+
+ # Test with speakers available and playqueue
+ requests_mock.get("https://1.2.3.4:32400/playQueues/1234", text=playqueue_1234)
+ content_id_with_playqueue = '{"playqueue_id": 1234}'
+ play_on_sonos(hass, MEDIA_TYPE_MUSIC, content_id_with_playqueue, sonos_speaker_name)
+ assert playback_mock.call_count == 4
+
+ # Test with speakers available and invalid playqueue
+ requests_mock.get("https://1.2.3.4:32400/playQueues/1235", status_code=404)
+ content_id_with_playqueue = '{"playqueue_id": 1235}'
+ with pytest.raises(HomeAssistantError) as excinfo:
+ play_on_sonos(
+ hass, MEDIA_TYPE_MUSIC, content_id_with_playqueue, sonos_speaker_name
+ )
+ assert "PlayQueue '1235' could not be found" in str(excinfo.value)
+ assert playback_mock.call_count == 4
diff --git a/tests/fixtures/plex/media_100.xml b/tests/fixtures/plex/media_100.xml
index e1326a4c862..88ad7048fc0 100644
--- a/tests/fixtures/plex/media_100.xml
+++ b/tests/fixtures/plex/media_100.xml
@@ -1 +1,7 @@
-
+
+
+
diff --git a/tests/fixtures/plex/playqueue_1234.xml b/tests/fixtures/plex/playqueue_1234.xml
new file mode 100644
index 00000000000..837c2ffbc3c
--- /dev/null
+++ b/tests/fixtures/plex/playqueue_1234.xml
@@ -0,0 +1,7 @@
+
+
+