Browse media support in universal media player (#85668)
Allow forward and override browse media in universal media player
This commit is contained in:
parent
27ebee1501
commit
6474297d1f
2 changed files with 128 additions and 49 deletions
|
@ -45,6 +45,7 @@ from homeassistant.components.media_player import (
|
||||||
MediaPlayerEntityFeature,
|
MediaPlayerEntityFeature,
|
||||||
MediaPlayerState,
|
MediaPlayerState,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.media_player.browse_media import BrowseMedia
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
ATTR_ENTITY_PICTURE,
|
ATTR_ENTITY_PICTURE,
|
||||||
|
@ -78,6 +79,7 @@ from homeassistant.const import (
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import TemplateError
|
from homeassistant.exceptions import TemplateError
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import (
|
from homeassistant.helpers.event import (
|
||||||
TrackTemplate,
|
TrackTemplate,
|
||||||
|
@ -93,6 +95,7 @@ ATTR_ACTIVE_CHILD = "active_child"
|
||||||
CONF_ATTRS = "attributes"
|
CONF_ATTRS = "attributes"
|
||||||
CONF_CHILDREN = "children"
|
CONF_CHILDREN = "children"
|
||||||
CONF_COMMANDS = "commands"
|
CONF_COMMANDS = "commands"
|
||||||
|
CONF_BROWSE_MEDIA_ENTITY = "browse_media_entity"
|
||||||
|
|
||||||
STATES_ORDER = [
|
STATES_ORDER = [
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
|
@ -119,6 +122,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
vol.Optional(CONF_ATTRS, default={}): vol.Or(
|
vol.Optional(CONF_ATTRS, default={}): vol.Or(
|
||||||
cv.ensure_list(ATTRS_SCHEMA), ATTRS_SCHEMA
|
cv.ensure_list(ATTRS_SCHEMA), ATTRS_SCHEMA
|
||||||
),
|
),
|
||||||
|
vol.Optional(CONF_BROWSE_MEDIA_ENTITY): cv.string,
|
||||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||||
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
|
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
|
||||||
vol.Optional(CONF_STATE_TEMPLATE): cv.template,
|
vol.Optional(CONF_STATE_TEMPLATE): cv.template,
|
||||||
|
@ -136,17 +140,7 @@ async def async_setup_platform(
|
||||||
"""Set up the universal media players."""
|
"""Set up the universal media players."""
|
||||||
await async_setup_reload_service(hass, "universal", ["media_player"])
|
await async_setup_reload_service(hass, "universal", ["media_player"])
|
||||||
|
|
||||||
player = UniversalMediaPlayer(
|
player = UniversalMediaPlayer(hass, config)
|
||||||
hass,
|
|
||||||
config.get(CONF_NAME),
|
|
||||||
config.get(CONF_CHILDREN),
|
|
||||||
config.get(CONF_COMMANDS),
|
|
||||||
config.get(CONF_ATTRS),
|
|
||||||
config.get(CONF_UNIQUE_ID),
|
|
||||||
config.get(CONF_DEVICE_CLASS),
|
|
||||||
config.get(CONF_STATE_TEMPLATE),
|
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities([player])
|
async_add_entities([player])
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,30 +152,25 @@ class UniversalMediaPlayer(MediaPlayerEntity):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass,
|
hass,
|
||||||
name,
|
config,
|
||||||
children,
|
|
||||||
commands,
|
|
||||||
attributes,
|
|
||||||
unique_id=None,
|
|
||||||
device_class=None,
|
|
||||||
state_template=None,
|
|
||||||
):
|
):
|
||||||
"""Initialize the Universal media device."""
|
"""Initialize the Universal media device."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self._name = name
|
self._name = config.get(CONF_NAME)
|
||||||
self._children = children
|
self._children = config.get(CONF_CHILDREN)
|
||||||
self._cmds = commands
|
self._cmds = config.get(CONF_COMMANDS)
|
||||||
self._attrs = {}
|
self._attrs = {}
|
||||||
for key, val in attributes.items():
|
for key, val in config.get(CONF_ATTRS).items():
|
||||||
attr = list(map(str.strip, val.split("|", 1)))
|
attr = list(map(str.strip, val.split("|", 1)))
|
||||||
if len(attr) == 1:
|
if len(attr) == 1:
|
||||||
attr.append(None)
|
attr.append(None)
|
||||||
self._attrs[key] = attr
|
self._attrs[key] = attr
|
||||||
self._child_state = None
|
self._child_state = None
|
||||||
self._state_template_result = None
|
self._state_template_result = None
|
||||||
self._state_template = state_template
|
self._state_template = config.get(CONF_STATE_TEMPLATE)
|
||||||
self._device_class = device_class
|
self._device_class = config.get(CONF_DEVICE_CLASS)
|
||||||
self._attr_unique_id = unique_id
|
self._attr_unique_id = config.get(CONF_UNIQUE_ID)
|
||||||
|
self._browse_media_entity = config.get(CONF_BROWSE_MEDIA_ENTITY)
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Subscribe to children and template state changes."""
|
"""Subscribe to children and template state changes."""
|
||||||
|
@ -497,6 +486,9 @@ class UniversalMediaPlayer(MediaPlayerEntity):
|
||||||
if SERVICE_PLAY_MEDIA in self._cmds:
|
if SERVICE_PLAY_MEDIA in self._cmds:
|
||||||
flags |= MediaPlayerEntityFeature.PLAY_MEDIA
|
flags |= MediaPlayerEntityFeature.PLAY_MEDIA
|
||||||
|
|
||||||
|
if self._browse_media_entity:
|
||||||
|
flags |= MediaPlayerEntityFeature.BROWSE_MEDIA
|
||||||
|
|
||||||
if SERVICE_CLEAR_PLAYLIST in self._cmds:
|
if SERVICE_CLEAR_PLAYLIST in self._cmds:
|
||||||
flags |= MediaPlayerEntityFeature.CLEAR_PLAYLIST
|
flags |= MediaPlayerEntityFeature.CLEAR_PLAYLIST
|
||||||
|
|
||||||
|
@ -628,6 +620,20 @@ class UniversalMediaPlayer(MediaPlayerEntity):
|
||||||
# Delegate to turn_on or turn_off by default
|
# Delegate to turn_on or turn_off by default
|
||||||
await super().async_toggle()
|
await super().async_toggle()
|
||||||
|
|
||||||
|
async def async_browse_media(
|
||||||
|
self,
|
||||||
|
media_content_type: str | None = None,
|
||||||
|
media_content_id: str | None = None,
|
||||||
|
) -> BrowseMedia:
|
||||||
|
"""Return a BrowseMedia instance."""
|
||||||
|
entity_id = self._browse_media_entity
|
||||||
|
if not entity_id and self._child_state:
|
||||||
|
entity_id = self._child_state.entity_id
|
||||||
|
component: EntityComponent[MediaPlayerEntity] = self.hass.data[DOMAIN]
|
||||||
|
if entity_id and (entity := component.get_entity(entity_id)):
|
||||||
|
return await entity.async_browse_media(media_content_type, media_content_id)
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update state in HA."""
|
"""Update state in HA."""
|
||||||
self._child_state = None
|
self._child_state = None
|
||||||
|
|
|
@ -9,7 +9,8 @@ from homeassistant import config as hass_config
|
||||||
import homeassistant.components.input_number as input_number
|
import homeassistant.components.input_number as input_number
|
||||||
import homeassistant.components.input_select as input_select
|
import homeassistant.components.input_select as input_select
|
||||||
import homeassistant.components.media_player as media_player
|
import homeassistant.components.media_player as media_player
|
||||||
from homeassistant.components.media_player import MediaPlayerEntityFeature
|
from homeassistant.components.media_player import MediaClass, MediaPlayerEntityFeature
|
||||||
|
from homeassistant.components.media_player.browse_media import BrowseMedia
|
||||||
import homeassistant.components.switch as switch
|
import homeassistant.components.switch as switch
|
||||||
import homeassistant.components.universal.media_player as universal
|
import homeassistant.components.universal.media_player as universal
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
@ -36,6 +37,15 @@ CONFIG_CHILDREN_ONLY = {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOCK_BROWSE_MEDIA = BrowseMedia(
|
||||||
|
media_class=MediaClass.APP,
|
||||||
|
media_content_id="mock-id",
|
||||||
|
media_content_type="mock-type",
|
||||||
|
title="Mock Title",
|
||||||
|
can_play=False,
|
||||||
|
can_expand=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_config(config):
|
def validate_config(config):
|
||||||
"""Use the platform schema to validate configuration."""
|
"""Use the platform schema to validate configuration."""
|
||||||
|
@ -376,7 +386,7 @@ async def test_master_state(hass: HomeAssistant) -> None:
|
||||||
"""Test master state property."""
|
"""Test master state property."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.master_state is None
|
assert ump.master_state is None
|
||||||
|
|
||||||
|
@ -387,7 +397,7 @@ async def test_master_state_with_attrs(
|
||||||
"""Test master state property."""
|
"""Test master state property."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.master_state == STATE_OFF
|
assert ump.master_state == STATE_OFF
|
||||||
hass.states.async_set(mock_states.mock_state_switch_id, STATE_ON)
|
hass.states.async_set(mock_states.mock_state_switch_id, STATE_ON)
|
||||||
|
@ -402,7 +412,7 @@ async def test_master_state_with_bad_attrs(
|
||||||
config["attributes"]["state"] = "bad.entity_id"
|
config["attributes"]["state"] = "bad.entity_id"
|
||||||
config = validate_config(config)
|
config = validate_config(config)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.master_state == STATE_OFF
|
assert ump.master_state == STATE_OFF
|
||||||
|
|
||||||
|
@ -411,7 +421,7 @@ async def test_active_child_state(hass: HomeAssistant, mock_states) -> None:
|
||||||
"""Test active child state property."""
|
"""Test active child state property."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -452,7 +462,7 @@ async def test_name(hass: HomeAssistant) -> None:
|
||||||
"""Test name property."""
|
"""Test name property."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert config["name"] == ump.name
|
assert config["name"] == ump.name
|
||||||
|
|
||||||
|
@ -461,7 +471,7 @@ async def test_polling(hass: HomeAssistant) -> None:
|
||||||
"""Test should_poll property."""
|
"""Test should_poll property."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.should_poll is False
|
assert ump.should_poll is False
|
||||||
|
|
||||||
|
@ -470,7 +480,7 @@ async def test_state_children_only(hass: HomeAssistant, mock_states) -> None:
|
||||||
"""Test media player state with only children."""
|
"""Test media player state with only children."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -489,7 +499,7 @@ async def test_state_with_children_and_attrs(
|
||||||
"""Test media player with children and master state."""
|
"""Test media player with children and master state."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -514,7 +524,7 @@ async def test_volume_level(hass: HomeAssistant, mock_states) -> None:
|
||||||
"""Test volume level property."""
|
"""Test volume level property."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -538,7 +548,7 @@ async def test_media_image_url(hass: HomeAssistant, mock_states) -> None:
|
||||||
test_url = "test_url"
|
test_url = "test_url"
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -558,7 +568,7 @@ async def test_is_volume_muted_children_only(hass: HomeAssistant, mock_states) -
|
||||||
"""Test is volume muted property w/ children only."""
|
"""Test is volume muted property w/ children only."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -583,7 +593,7 @@ async def test_sound_mode_list_children_and_attr(
|
||||||
"""Test sound mode list property w/ children and attrs."""
|
"""Test sound mode list property w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.sound_mode_list == "['music', 'movie']"
|
assert ump.sound_mode_list == "['music', 'movie']"
|
||||||
|
|
||||||
|
@ -599,7 +609,7 @@ async def test_source_list_children_and_attr(
|
||||||
"""Test source list property w/ children and attrs."""
|
"""Test source list property w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.source_list == "['dvd', 'htpc']"
|
assert ump.source_list == "['dvd', 'htpc']"
|
||||||
|
|
||||||
|
@ -613,7 +623,7 @@ async def test_sound_mode_children_and_attr(
|
||||||
"""Test sound modeproperty w/ children and attrs."""
|
"""Test sound modeproperty w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.sound_mode == "music"
|
assert ump.sound_mode == "music"
|
||||||
|
|
||||||
|
@ -627,7 +637,7 @@ async def test_source_children_and_attr(
|
||||||
"""Test source property w/ children and attrs."""
|
"""Test source property w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.source == "dvd"
|
assert ump.source == "dvd"
|
||||||
|
|
||||||
|
@ -641,7 +651,7 @@ async def test_volume_level_children_and_attr(
|
||||||
"""Test volume level property w/ children and attrs."""
|
"""Test volume level property w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert ump.volume_level == 0
|
assert ump.volume_level == 0
|
||||||
|
|
||||||
|
@ -655,7 +665,7 @@ async def test_is_volume_muted_children_and_attr(
|
||||||
"""Test is volume muted property w/ children and attrs."""
|
"""Test is volume muted property w/ children and attrs."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
|
||||||
assert not ump.is_volume_muted
|
assert not ump.is_volume_muted
|
||||||
|
|
||||||
|
@ -669,7 +679,7 @@ async def test_supported_features_children_only(
|
||||||
"""Test supported media commands with only children."""
|
"""Test supported media commands with only children."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -709,9 +719,10 @@ async def test_supported_features_children_and_cmds(
|
||||||
"play_media": excmd,
|
"play_media": excmd,
|
||||||
"clear_playlist": excmd,
|
"clear_playlist": excmd,
|
||||||
}
|
}
|
||||||
|
config["browse_media_entity"] = "media_player.test"
|
||||||
config = validate_config(config)
|
config = validate_config(config)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -737,6 +748,7 @@ async def test_supported_features_children_and_cmds(
|
||||||
| MediaPlayerEntityFeature.PREVIOUS_TRACK
|
| MediaPlayerEntityFeature.PREVIOUS_TRACK
|
||||||
| MediaPlayerEntityFeature.PLAY_MEDIA
|
| MediaPlayerEntityFeature.PLAY_MEDIA
|
||||||
| MediaPlayerEntityFeature.CLEAR_PLAYLIST
|
| MediaPlayerEntityFeature.CLEAR_PLAYLIST
|
||||||
|
| MediaPlayerEntityFeature.BROWSE_MEDIA
|
||||||
)
|
)
|
||||||
|
|
||||||
assert check_flags == ump.supported_features
|
assert check_flags == ump.supported_features
|
||||||
|
@ -926,7 +938,7 @@ async def test_supported_features_play_pause(
|
||||||
config["commands"] = {"media_play_pause": excmd}
|
config["commands"] = {"media_play_pause": excmd}
|
||||||
config = validate_config(config)
|
config = validate_config(config)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -946,7 +958,7 @@ async def test_service_call_no_active_child(
|
||||||
"""Test a service call to children with no active child."""
|
"""Test a service call to children with no active child."""
|
||||||
config = validate_config(config_children_and_attr)
|
config = validate_config(config_children_and_attr)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -966,7 +978,7 @@ async def test_service_call_to_child(hass: HomeAssistant, mock_states) -> None:
|
||||||
"""Test service calls that should be routed to a child."""
|
"""Test service calls that should be routed to a child."""
|
||||||
config = validate_config(CONFIG_CHILDREN_ONLY)
|
config = validate_config(CONFIG_CHILDREN_ONLY)
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -1045,7 +1057,7 @@ async def test_service_call_to_command(hass: HomeAssistant, mock_states) -> None
|
||||||
|
|
||||||
service = async_mock_service(hass, "test", "turn_off")
|
service = async_mock_service(hass, "test", "turn_off")
|
||||||
|
|
||||||
ump = universal.UniversalMediaPlayer(hass, **config)
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
await ump.async_update()
|
await ump.async_update()
|
||||||
|
|
||||||
|
@ -1084,6 +1096,67 @@ async def test_state_template(hass: HomeAssistant) -> None:
|
||||||
assert hass.states.get("media_player.tv").state == STATE_OFF
|
assert hass.states.get("media_player.tv").state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
async def test_browse_media(hass: HomeAssistant):
|
||||||
|
"""Test browse media."""
|
||||||
|
await async_setup_component(
|
||||||
|
hass, "media_player", {"media_player": {"platform": "demo"}}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"name": "test",
|
||||||
|
"platform": "universal",
|
||||||
|
"children": [
|
||||||
|
"media_player.bedroom",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
config = validate_config(config)
|
||||||
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
|
await ump.async_update()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.demo.media_player.MediaPlayerEntity.supported_features",
|
||||||
|
MediaPlayerEntityFeature.BROWSE_MEDIA,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.demo.media_player.MediaPlayerEntity.async_browse_media",
|
||||||
|
return_value=MOCK_BROWSE_MEDIA,
|
||||||
|
):
|
||||||
|
result = await ump.async_browse_media()
|
||||||
|
assert result == MOCK_BROWSE_MEDIA
|
||||||
|
|
||||||
|
|
||||||
|
async def test_browse_media_override(hass: HomeAssistant):
|
||||||
|
"""Test browse media override."""
|
||||||
|
await async_setup_component(
|
||||||
|
hass, "media_player", {"media_player": {"platform": "demo"}}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"name": "test",
|
||||||
|
"platform": "universal",
|
||||||
|
"children": [
|
||||||
|
"media_player.mock1",
|
||||||
|
],
|
||||||
|
"browse_media_entity": "media_player.bedroom",
|
||||||
|
}
|
||||||
|
config = validate_config(config)
|
||||||
|
ump = universal.UniversalMediaPlayer(hass, config)
|
||||||
|
ump.entity_id = media_player.ENTITY_ID_FORMAT.format(config["name"])
|
||||||
|
await ump.async_update()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.demo.media_player.MediaPlayerEntity.supported_features",
|
||||||
|
MediaPlayerEntityFeature.BROWSE_MEDIA,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.demo.media_player.MediaPlayerEntity.async_browse_media",
|
||||||
|
return_value=MOCK_BROWSE_MEDIA,
|
||||||
|
):
|
||||||
|
result = await ump.async_browse_media()
|
||||||
|
assert result == MOCK_BROWSE_MEDIA
|
||||||
|
|
||||||
|
|
||||||
async def test_device_class(hass: HomeAssistant) -> None:
|
async def test_device_class(hass: HomeAssistant) -> None:
|
||||||
"""Test device_class property."""
|
"""Test device_class property."""
|
||||||
hass.states.async_set("sensor.test_sensor", "on")
|
hass.states.async_set("sensor.test_sensor", "on")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue