diff --git a/homeassistant/components/roku/const.py b/homeassistant/components/roku/const.py index 1a1383dceb6..eb2d5040b50 100644 --- a/homeassistant/components/roku/const.py +++ b/homeassistant/components/roku/const.py @@ -2,7 +2,9 @@ DOMAIN = "roku" # Attributes +ATTR_CONTENT_ID = "content_id" ATTR_KEYWORD = "keyword" +ATTR_MEDIA_TYPE = "media_type" # Default Values DEFAULT_PORT = 8060 diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index ebc8feef446..10483d980f9 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -3,6 +3,7 @@ from __future__ import annotations import datetime as dt import logging +from typing import Any import voluptuous as vol @@ -12,6 +13,7 @@ from homeassistant.components.media_player import ( MediaPlayerEntity, ) from homeassistant.components.media_player.const import ( + ATTR_MEDIA_EXTRA, MEDIA_TYPE_APP, MEDIA_TYPE_CHANNEL, SUPPORT_BROWSE_MEDIA, @@ -43,7 +45,13 @@ from homeassistant.helpers.network import is_internal_request from . import roku_exception_handler from .browse_media import build_item_response, library_payload -from .const import ATTR_KEYWORD, DOMAIN, SERVICE_SEARCH +from .const import ( + ATTR_CONTENT_ID, + ATTR_KEYWORD, + ATTR_MEDIA_TYPE, + DOMAIN, + SERVICE_SEARCH, +) from .coordinator import RokuDataUpdateCoordinator from .entity import RokuEntity @@ -63,6 +71,11 @@ SUPPORT_ROKU = ( | SUPPORT_BROWSE_MEDIA ) +ATTRS_TO_LAUNCH_PARAMS = { + ATTR_CONTENT_ID: "contentID", + ATTR_MEDIA_TYPE: "MediaType", +} + SEARCH_SCHEMA = {vol.Required(ATTR_KEYWORD): str} @@ -352,6 +365,8 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity): @roku_exception_handler async def async_play_media(self, media_type: str, media_id: str, **kwargs) -> None: """Tune to channel.""" + extra: dict[str, Any] = kwargs.get(ATTR_MEDIA_EXTRA) or {} + if media_type not in (MEDIA_TYPE_APP, MEDIA_TYPE_CHANNEL): _LOGGER.error( "Invalid media type %s. Only %s and %s are supported", @@ -362,7 +377,13 @@ class RokuMediaPlayer(RokuEntity, MediaPlayerEntity): return if media_type == MEDIA_TYPE_APP: - await self.coordinator.roku.launch(media_id) + params = { + param: extra[attr] + for (attr, param) in ATTRS_TO_LAUNCH_PARAMS.items() + if attr in extra + } + + await self.coordinator.roku.launch(media_id, params) elif media_type == MEDIA_TYPE_CHANNEL: await self.coordinator.roku.tune(media_id) diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py index 55ffa3fe574..d0e0388dde1 100644 --- a/tests/components/roku/test_media_player.py +++ b/tests/components/roku/test_media_player.py @@ -13,6 +13,7 @@ from homeassistant.components.media_player.const import ( ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE, ATTR_MEDIA_DURATION, + ATTR_MEDIA_EXTRA, ATTR_MEDIA_POSITION, ATTR_MEDIA_TITLE, ATTR_MEDIA_VOLUME_MUTED, @@ -38,7 +39,13 @@ from homeassistant.components.media_player.const import ( SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, ) -from homeassistant.components.roku.const import ATTR_KEYWORD, DOMAIN, SERVICE_SEARCH +from homeassistant.components.roku.const import ( + ATTR_CONTENT_ID, + ATTR_KEYWORD, + ATTR_MEDIA_TYPE, + DOMAIN, + SERVICE_SEARCH, +) from homeassistant.components.websocket_api.const import TYPE_RESULT from homeassistant.config import async_process_ha_core_config from homeassistant.const import ( @@ -448,7 +455,31 @@ async def test_services( blocking=True, ) - launch_mock.assert_called_once_with("11") + launch_mock.assert_called_once_with("11", {}) + + with patch("homeassistant.components.roku.coordinator.Roku.launch") as launch_mock: + await hass.services.async_call( + MP_DOMAIN, + SERVICE_PLAY_MEDIA, + { + ATTR_ENTITY_ID: MAIN_ENTITY_ID, + ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP, + ATTR_MEDIA_CONTENT_ID: "291097", + ATTR_MEDIA_EXTRA: { + ATTR_MEDIA_TYPE: "movie", + ATTR_CONTENT_ID: "8e06a8b7-d667-4e31-939d-f40a6dd78a88", + }, + }, + blocking=True, + ) + + launch_mock.assert_called_once_with( + "291097", + { + "contentID": "8e06a8b7-d667-4e31-939d-f40a6dd78a88", + "MediaType": "movie", + }, + ) with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock: await hass.services.async_call(