mirror of
https://github.com/home-assistant/core.git
synced 2025-09-10 07:11:37 +02:00
Use media_selector for media_player.play_media (#150721)
This commit is contained in:
@@ -161,6 +161,8 @@ CACHE_LOCK: Final = "lock"
|
||||
CACHE_URL: Final = "url"
|
||||
CACHE_CONTENT: Final = "content"
|
||||
|
||||
ATTR_MEDIA = "media"
|
||||
|
||||
|
||||
class MediaPlayerEnqueue(StrEnum):
|
||||
"""Enqueue types for playing media."""
|
||||
@@ -200,6 +202,24 @@ _DEPRECATED_DEVICE_CLASS_RECEIVER = DeprecatedConstantEnum(
|
||||
DEVICE_CLASSES = [cls.value for cls in MediaPlayerDeviceClass]
|
||||
|
||||
|
||||
def _promote_media_fields(data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""If 'media' key exists, promote its fields to the top level."""
|
||||
if ATTR_MEDIA in data and isinstance(data[ATTR_MEDIA], dict):
|
||||
if ATTR_MEDIA_CONTENT_TYPE in data or ATTR_MEDIA_CONTENT_ID in data:
|
||||
raise vol.Invalid(
|
||||
f"Play media cannot contain '{ATTR_MEDIA}' and '{ATTR_MEDIA_CONTENT_ID}' or '{ATTR_MEDIA_CONTENT_TYPE}'"
|
||||
)
|
||||
media_data = data[ATTR_MEDIA]
|
||||
|
||||
if ATTR_MEDIA_CONTENT_TYPE in media_data:
|
||||
data[ATTR_MEDIA_CONTENT_TYPE] = media_data[ATTR_MEDIA_CONTENT_TYPE]
|
||||
if ATTR_MEDIA_CONTENT_ID in media_data:
|
||||
data[ATTR_MEDIA_CONTENT_ID] = media_data[ATTR_MEDIA_CONTENT_ID]
|
||||
|
||||
del data[ATTR_MEDIA]
|
||||
return data
|
||||
|
||||
|
||||
MEDIA_PLAYER_PLAY_MEDIA_SCHEMA = {
|
||||
vol.Required(ATTR_MEDIA_CONTENT_TYPE): cv.string,
|
||||
vol.Required(ATTR_MEDIA_CONTENT_ID): cv.string,
|
||||
@@ -436,6 +456,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
component.async_register_entity_service(
|
||||
SERVICE_PLAY_MEDIA,
|
||||
vol.All(
|
||||
_promote_media_fields,
|
||||
cv.make_entity_service_schema(MEDIA_PLAYER_PLAY_MEDIA_SCHEMA),
|
||||
_rewrite_enqueue,
|
||||
_rename_keys(
|
||||
|
@@ -131,17 +131,13 @@ play_media:
|
||||
supported_features:
|
||||
- media_player.MediaPlayerEntityFeature.PLAY_MEDIA
|
||||
fields:
|
||||
media_content_id:
|
||||
media:
|
||||
required: true
|
||||
example: "https://home-assistant.io/images/cast/splash.png"
|
||||
selector:
|
||||
text:
|
||||
|
||||
media_content_type:
|
||||
required: true
|
||||
example: "music"
|
||||
selector:
|
||||
text:
|
||||
media:
|
||||
example:
|
||||
media_content_id: "https://home-assistant.io/images/cast/splash.png"
|
||||
media_content_type: "music"
|
||||
|
||||
enqueue:
|
||||
filter:
|
||||
|
@@ -242,13 +242,9 @@
|
||||
"name": "Play media",
|
||||
"description": "Starts playing specified media.",
|
||||
"fields": {
|
||||
"media_content_id": {
|
||||
"name": "Content ID",
|
||||
"description": "The ID of the content to play. Platform dependent."
|
||||
},
|
||||
"media_content_type": {
|
||||
"name": "Content type",
|
||||
"description": "The type of the content to play, such as image, music, tv show, video, episode, channel, or playlist."
|
||||
"media": {
|
||||
"name": "Media",
|
||||
"description": "The media selected to play."
|
||||
},
|
||||
"enqueue": {
|
||||
"name": "Enqueue",
|
||||
|
@@ -654,3 +654,56 @@ async def test_get_async_get_browse_image_quoting(
|
||||
url = player.get_browse_image_url("album", media_content_id)
|
||||
await client.get(url)
|
||||
mock_browse_image.assert_called_with("album", media_content_id, None)
|
||||
|
||||
|
||||
async def test_play_media_via_selector(hass: HomeAssistant) -> None:
|
||||
"""Test that play_media data under 'media' is remapped to top level keys for backward compatibility."""
|
||||
await async_setup_component(
|
||||
hass, "media_player", {"media_player": {"platform": "demo"}}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Fake group support for DemoYoutubePlayer
|
||||
with patch(
|
||||
"homeassistant.components.demo.media_player.DemoYoutubePlayer.play_media",
|
||||
) as mock_play_media:
|
||||
await hass.services.async_call(
|
||||
"media_player",
|
||||
"play_media",
|
||||
{
|
||||
"entity_id": "media_player.bedroom",
|
||||
"media": {
|
||||
"media_content_type": "music",
|
||||
"media_content_id": "1234",
|
||||
},
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
"media_player",
|
||||
"play_media",
|
||||
{
|
||||
"entity_id": "media_player.bedroom",
|
||||
"media_content_type": "music",
|
||||
"media_content_id": "1234",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(mock_play_media.mock_calls) == 2
|
||||
assert mock_play_media.mock_calls[0].args == mock_play_media.mock_calls[1].args
|
||||
|
||||
with pytest.raises(vol.Invalid, match="Play media cannot contain 'media'"):
|
||||
await hass.services.async_call(
|
||||
"media_player",
|
||||
"play_media",
|
||||
{
|
||||
"media_content_id": "1234",
|
||||
"entity_id": "media_player.bedroom",
|
||||
"media": {
|
||||
"media_content_type": "music",
|
||||
"media_content_id": "1234",
|
||||
},
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
Reference in New Issue
Block a user