Add EntityFeature enum to Media Player (#69119)

This commit is contained in:
Franck Nijhof 2022-04-03 05:58:23 +02:00 committed by GitHub
parent 721db6d962
commit 17403f930f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 158 additions and 114 deletions

View File

@ -10,24 +10,7 @@ from homeassistant.components.media_player.const import (
MEDIA_TYPE_MUSIC, MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW, MEDIA_TYPE_TVSHOW,
REPEAT_MODE_OFF, REPEAT_MODE_OFF,
SUPPORT_CLEAR_PLAYLIST, MediaPlayerEntityFeature,
SUPPORT_GROUPING,
SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE,
SUPPORT_PLAY,
SUPPORT_PLAY_MEDIA,
SUPPORT_PREVIOUS_TRACK,
SUPPORT_REPEAT_SET,
SUPPORT_SEEK,
SUPPORT_SELECT_SOUND_MODE,
SUPPORT_SELECT_SOURCE,
SUPPORT_SHUFFLE_SET,
SUPPORT_STOP,
SUPPORT_TURN_OFF,
SUPPORT_TURN_ON,
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET,
SUPPORT_VOLUME_STEP,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING
@ -75,48 +58,48 @@ SOUND_MODE_LIST = ["Music", "Movie"]
DEFAULT_SOUND_MODE = "Music" DEFAULT_SOUND_MODE = "Music"
YOUTUBE_PLAYER_SUPPORT = ( YOUTUBE_PLAYER_SUPPORT = (
SUPPORT_PAUSE MediaPlayerEntityFeature.PAUSE
| SUPPORT_VOLUME_SET | MediaPlayerEntityFeature.VOLUME_SET
| SUPPORT_VOLUME_MUTE | MediaPlayerEntityFeature.VOLUME_MUTE
| SUPPORT_TURN_ON | MediaPlayerEntityFeature.TURN_ON
| SUPPORT_TURN_OFF | MediaPlayerEntityFeature.TURN_OFF
| SUPPORT_PLAY_MEDIA | MediaPlayerEntityFeature.PLAY_MEDIA
| SUPPORT_PLAY | MediaPlayerEntityFeature.PLAY
| SUPPORT_SHUFFLE_SET | MediaPlayerEntityFeature.SHUFFLE_SET
| SUPPORT_SELECT_SOUND_MODE | MediaPlayerEntityFeature.SELECT_SOUND_MODE
| SUPPORT_SEEK | MediaPlayerEntityFeature.SEEK
| SUPPORT_STOP | MediaPlayerEntityFeature.STOP
) )
MUSIC_PLAYER_SUPPORT = ( MUSIC_PLAYER_SUPPORT = (
SUPPORT_PAUSE MediaPlayerEntityFeature.PAUSE
| SUPPORT_VOLUME_SET | MediaPlayerEntityFeature.VOLUME_SET
| SUPPORT_VOLUME_MUTE | MediaPlayerEntityFeature.VOLUME_MUTE
| SUPPORT_TURN_ON | MediaPlayerEntityFeature.TURN_ON
| SUPPORT_TURN_OFF | MediaPlayerEntityFeature.TURN_OFF
| SUPPORT_CLEAR_PLAYLIST | MediaPlayerEntityFeature.CLEAR_PLAYLIST
| SUPPORT_GROUPING | MediaPlayerEntityFeature.GROUPING
| SUPPORT_PLAY | MediaPlayerEntityFeature.PLAY
| SUPPORT_SHUFFLE_SET | MediaPlayerEntityFeature.SHUFFLE_SET
| SUPPORT_REPEAT_SET | MediaPlayerEntityFeature.REPEAT_SET
| SUPPORT_VOLUME_STEP | MediaPlayerEntityFeature.VOLUME_STEP
| SUPPORT_PREVIOUS_TRACK | MediaPlayerEntityFeature.PREVIOUS_TRACK
| SUPPORT_NEXT_TRACK | MediaPlayerEntityFeature.NEXT_TRACK
| SUPPORT_SELECT_SOUND_MODE | MediaPlayerEntityFeature.SELECT_SOUND_MODE
| SUPPORT_STOP | MediaPlayerEntityFeature.STOP
) )
NETFLIX_PLAYER_SUPPORT = ( NETFLIX_PLAYER_SUPPORT = (
SUPPORT_PAUSE MediaPlayerEntityFeature.PAUSE
| SUPPORT_TURN_ON | MediaPlayerEntityFeature.TURN_ON
| SUPPORT_TURN_OFF | MediaPlayerEntityFeature.TURN_OFF
| SUPPORT_SELECT_SOURCE | MediaPlayerEntityFeature.SELECT_SOURCE
| SUPPORT_PLAY | MediaPlayerEntityFeature.PLAY
| SUPPORT_SHUFFLE_SET | MediaPlayerEntityFeature.SHUFFLE_SET
| SUPPORT_PREVIOUS_TRACK | MediaPlayerEntityFeature.PREVIOUS_TRACK
| SUPPORT_NEXT_TRACK | MediaPlayerEntityFeature.NEXT_TRACK
| SUPPORT_SELECT_SOUND_MODE | MediaPlayerEntityFeature.SELECT_SOUND_MODE
| SUPPORT_STOP | MediaPlayerEntityFeature.STOP
) )

View File

@ -126,6 +126,7 @@ from .const import ( # noqa: F401
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET, SUPPORT_VOLUME_SET,
SUPPORT_VOLUME_STEP, SUPPORT_VOLUME_STEP,
MediaPlayerEntityFeature,
) )
from .errors import BrowseError from .errors import BrowseError
@ -241,52 +242,61 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
await component.async_setup(config) await component.async_setup(config)
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_TURN_ON, {}, "async_turn_on", [SUPPORT_TURN_ON] SERVICE_TURN_ON, {}, "async_turn_on", [MediaPlayerEntityFeature.TURN_ON]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_TURN_OFF, {}, "async_turn_off", [SUPPORT_TURN_OFF] SERVICE_TURN_OFF, {}, "async_turn_off", [MediaPlayerEntityFeature.TURN_OFF]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_TOGGLE, {}, "async_toggle", [SUPPORT_TURN_OFF | SUPPORT_TURN_ON] SERVICE_TOGGLE,
{},
"async_toggle",
[MediaPlayerEntityFeature.TURN_OFF | MediaPlayerEntityFeature.TURN_ON],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_VOLUME_UP, SERVICE_VOLUME_UP,
{}, {},
"async_volume_up", "async_volume_up",
[SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP], [MediaPlayerEntityFeature.VOLUME_SET, MediaPlayerEntityFeature.VOLUME_STEP],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_VOLUME_DOWN, SERVICE_VOLUME_DOWN,
{}, {},
"async_volume_down", "async_volume_down",
[SUPPORT_VOLUME_SET, SUPPORT_VOLUME_STEP], [MediaPlayerEntityFeature.VOLUME_SET, MediaPlayerEntityFeature.VOLUME_STEP],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_PLAY_PAUSE, SERVICE_MEDIA_PLAY_PAUSE,
{}, {},
"async_media_play_pause", "async_media_play_pause",
[SUPPORT_PLAY | SUPPORT_PAUSE], [MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.PAUSE],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_PLAY, {}, "async_media_play", [SUPPORT_PLAY] SERVICE_MEDIA_PLAY, {}, "async_media_play", [MediaPlayerEntityFeature.PLAY]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_PAUSE, {}, "async_media_pause", [SUPPORT_PAUSE] SERVICE_MEDIA_PAUSE, {}, "async_media_pause", [MediaPlayerEntityFeature.PAUSE]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_STOP, {}, "async_media_stop", [SUPPORT_STOP] SERVICE_MEDIA_STOP, {}, "async_media_stop", [MediaPlayerEntityFeature.STOP]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_NEXT_TRACK, {}, "async_media_next_track", [SUPPORT_NEXT_TRACK] SERVICE_MEDIA_NEXT_TRACK,
{},
"async_media_next_track",
[MediaPlayerEntityFeature.NEXT_TRACK],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_PREVIOUS_TRACK,
{}, {},
"async_media_previous_track", "async_media_previous_track",
[SUPPORT_PREVIOUS_TRACK], [MediaPlayerEntityFeature.PREVIOUS_TRACK],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_CLEAR_PLAYLIST, {}, "async_clear_playlist", [SUPPORT_CLEAR_PLAYLIST] SERVICE_CLEAR_PLAYLIST,
{},
"async_clear_playlist",
[MediaPlayerEntityFeature.CLEAR_PLAYLIST],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_VOLUME_SET, SERVICE_VOLUME_SET,
@ -297,7 +307,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
_rename_keys(volume=ATTR_MEDIA_VOLUME_LEVEL), _rename_keys(volume=ATTR_MEDIA_VOLUME_LEVEL),
), ),
"async_set_volume_level", "async_set_volume_level",
[SUPPORT_VOLUME_SET], [MediaPlayerEntityFeature.VOLUME_SET],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_VOLUME_MUTE, SERVICE_VOLUME_MUTE,
@ -308,7 +318,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
_rename_keys(mute=ATTR_MEDIA_VOLUME_MUTED), _rename_keys(mute=ATTR_MEDIA_VOLUME_MUTED),
), ),
"async_mute_volume", "async_mute_volume",
[SUPPORT_VOLUME_MUTE], [MediaPlayerEntityFeature.VOLUME_MUTE],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_MEDIA_SEEK, SERVICE_MEDIA_SEEK,
@ -319,25 +329,25 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
_rename_keys(position=ATTR_MEDIA_SEEK_POSITION), _rename_keys(position=ATTR_MEDIA_SEEK_POSITION),
), ),
"async_media_seek", "async_media_seek",
[SUPPORT_SEEK], [MediaPlayerEntityFeature.SEEK],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_JOIN, SERVICE_JOIN,
{vol.Required(ATTR_GROUP_MEMBERS): vol.All(cv.ensure_list, [cv.entity_id])}, {vol.Required(ATTR_GROUP_MEMBERS): vol.All(cv.ensure_list, [cv.entity_id])},
"async_join_players", "async_join_players",
[SUPPORT_GROUPING], [MediaPlayerEntityFeature.GROUPING],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_SELECT_SOURCE, SERVICE_SELECT_SOURCE,
{vol.Required(ATTR_INPUT_SOURCE): cv.string}, {vol.Required(ATTR_INPUT_SOURCE): cv.string},
"async_select_source", "async_select_source",
[SUPPORT_SELECT_SOURCE], [MediaPlayerEntityFeature.SELECT_SOURCE],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_SELECT_SOUND_MODE, SERVICE_SELECT_SOUND_MODE,
{vol.Required(ATTR_SOUND_MODE): cv.string}, {vol.Required(ATTR_SOUND_MODE): cv.string},
"async_select_sound_mode", "async_select_sound_mode",
[SUPPORT_SELECT_SOUND_MODE], [MediaPlayerEntityFeature.SELECT_SOUND_MODE],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_PLAY_MEDIA, SERVICE_PLAY_MEDIA,
@ -350,23 +360,23 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
), ),
), ),
"async_play_media", "async_play_media",
[SUPPORT_PLAY_MEDIA], [MediaPlayerEntityFeature.PLAY_MEDIA],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_SHUFFLE_SET, SERVICE_SHUFFLE_SET,
{vol.Required(ATTR_MEDIA_SHUFFLE): cv.boolean}, {vol.Required(ATTR_MEDIA_SHUFFLE): cv.boolean},
"async_set_shuffle", "async_set_shuffle",
[SUPPORT_SHUFFLE_SET], [MediaPlayerEntityFeature.SHUFFLE_SET],
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_UNJOIN, {}, "async_unjoin_player", [SUPPORT_GROUPING] SERVICE_UNJOIN, {}, "async_unjoin_player", [MediaPlayerEntityFeature.GROUPING]
) )
component.async_register_entity_service( component.async_register_entity_service(
SERVICE_REPEAT_SET, SERVICE_REPEAT_SET,
{vol.Required(ATTR_MEDIA_REPEAT): vol.In(REPEAT_MODES)}, {vol.Required(ATTR_MEDIA_REPEAT): vol.In(REPEAT_MODES)},
"async_set_repeat", "async_set_repeat",
[SUPPORT_REPEAT_SET], [MediaPlayerEntityFeature.REPEAT_SET],
) )
return True return True
@ -766,72 +776,74 @@ class MediaPlayerEntity(Entity):
@property @property
def support_play(self): def support_play(self):
"""Boolean if play is supported.""" """Boolean if play is supported."""
return bool(self.supported_features & SUPPORT_PLAY) return bool(self.supported_features & MediaPlayerEntityFeature.PLAY)
@property @property
def support_pause(self): def support_pause(self):
"""Boolean if pause is supported.""" """Boolean if pause is supported."""
return bool(self.supported_features & SUPPORT_PAUSE) return bool(self.supported_features & MediaPlayerEntityFeature.PAUSE)
@property @property
def support_stop(self): def support_stop(self):
"""Boolean if stop is supported.""" """Boolean if stop is supported."""
return bool(self.supported_features & SUPPORT_STOP) return bool(self.supported_features & MediaPlayerEntityFeature.STOP)
@property @property
def support_seek(self): def support_seek(self):
"""Boolean if seek is supported.""" """Boolean if seek is supported."""
return bool(self.supported_features & SUPPORT_SEEK) return bool(self.supported_features & MediaPlayerEntityFeature.SEEK)
@property @property
def support_volume_set(self): def support_volume_set(self):
"""Boolean if setting volume is supported.""" """Boolean if setting volume is supported."""
return bool(self.supported_features & SUPPORT_VOLUME_SET) return bool(self.supported_features & MediaPlayerEntityFeature.VOLUME_SET)
@property @property
def support_volume_mute(self): def support_volume_mute(self):
"""Boolean if muting volume is supported.""" """Boolean if muting volume is supported."""
return bool(self.supported_features & SUPPORT_VOLUME_MUTE) return bool(self.supported_features & MediaPlayerEntityFeature.VOLUME_MUTE)
@property @property
def support_previous_track(self): def support_previous_track(self):
"""Boolean if previous track command supported.""" """Boolean if previous track command supported."""
return bool(self.supported_features & SUPPORT_PREVIOUS_TRACK) return bool(self.supported_features & MediaPlayerEntityFeature.PREVIOUS_TRACK)
@property @property
def support_next_track(self): def support_next_track(self):
"""Boolean if next track command supported.""" """Boolean if next track command supported."""
return bool(self.supported_features & SUPPORT_NEXT_TRACK) return bool(self.supported_features & MediaPlayerEntityFeature.NEXT_TRACK)
@property @property
def support_play_media(self): def support_play_media(self):
"""Boolean if play media command supported.""" """Boolean if play media command supported."""
return bool(self.supported_features & SUPPORT_PLAY_MEDIA) return bool(self.supported_features & MediaPlayerEntityFeature.PLAY_MEDIA)
@property @property
def support_select_source(self): def support_select_source(self):
"""Boolean if select source command supported.""" """Boolean if select source command supported."""
return bool(self.supported_features & SUPPORT_SELECT_SOURCE) return bool(self.supported_features & MediaPlayerEntityFeature.SELECT_SOURCE)
@property @property
def support_select_sound_mode(self): def support_select_sound_mode(self):
"""Boolean if select sound mode command supported.""" """Boolean if select sound mode command supported."""
return bool(self.supported_features & SUPPORT_SELECT_SOUND_MODE) return bool(
self.supported_features & MediaPlayerEntityFeature.SELECT_SOUND_MODE
)
@property @property
def support_clear_playlist(self): def support_clear_playlist(self):
"""Boolean if clear playlist command supported.""" """Boolean if clear playlist command supported."""
return bool(self.supported_features & SUPPORT_CLEAR_PLAYLIST) return bool(self.supported_features & MediaPlayerEntityFeature.CLEAR_PLAYLIST)
@property @property
def support_shuffle_set(self): def support_shuffle_set(self):
"""Boolean if shuffle is supported.""" """Boolean if shuffle is supported."""
return bool(self.supported_features & SUPPORT_SHUFFLE_SET) return bool(self.supported_features & MediaPlayerEntityFeature.SHUFFLE_SET)
@property @property
def support_grouping(self): def support_grouping(self):
"""Boolean if player grouping is supported.""" """Boolean if player grouping is supported."""
return bool(self.supported_features & SUPPORT_GROUPING) return bool(self.supported_features & MediaPlayerEntityFeature.GROUPING)
async def async_toggle(self): async def async_toggle(self):
"""Toggle the power on the media player.""" """Toggle the power on the media player."""
@ -853,7 +865,10 @@ class MediaPlayerEntity(Entity):
await self.hass.async_add_executor_job(self.volume_up) await self.hass.async_add_executor_job(self.volume_up)
return return
if self.volume_level < 1 and self.supported_features & SUPPORT_VOLUME_SET: if (
self.volume_level < 1
and self.supported_features & MediaPlayerEntityFeature.VOLUME_SET
):
await self.async_set_volume_level(min(1, self.volume_level + 0.1)) await self.async_set_volume_level(min(1, self.volume_level + 0.1))
async def async_volume_down(self): async def async_volume_down(self):
@ -865,7 +880,10 @@ class MediaPlayerEntity(Entity):
await self.hass.async_add_executor_job(self.volume_down) await self.hass.async_add_executor_job(self.volume_down)
return return
if self.volume_level > 0 and self.supported_features & SUPPORT_VOLUME_SET: if (
self.volume_level > 0
and self.supported_features & MediaPlayerEntityFeature.VOLUME_SET
):
await self.async_set_volume_level(max(0, self.volume_level - 0.1)) await self.async_set_volume_level(max(0, self.volume_level - 0.1))
async def async_media_play_pause(self): async def async_media_play_pause(self):
@ -907,12 +925,12 @@ class MediaPlayerEntity(Entity):
supported_features = self.supported_features or 0 supported_features = self.supported_features or 0
data = {} data = {}
if supported_features & SUPPORT_SELECT_SOURCE and ( if supported_features & MediaPlayerEntityFeature.SELECT_SOURCE and (
source_list := self.source_list source_list := self.source_list
): ):
data[ATTR_INPUT_SOURCE_LIST] = source_list data[ATTR_INPUT_SOURCE_LIST] = source_list
if supported_features & SUPPORT_SELECT_SOUND_MODE and ( if supported_features & MediaPlayerEntityFeature.SELECT_SOUND_MODE and (
sound_mode_list := self.sound_mode_list sound_mode_list := self.sound_mode_list
): ):
data[ATTR_SOUND_MODE_LIST] = sound_mode_list data[ATTR_SOUND_MODE_LIST] = sound_mode_list
@ -1147,7 +1165,7 @@ async def websocket_browse_media(hass, connection, msg):
connection.send_error(msg["id"], "entity_not_found", "Entity not found") connection.send_error(msg["id"], "entity_not_found", "Entity not found")
return return
if not player.supported_features & SUPPORT_BROWSE_MEDIA: if not player.supported_features & MediaPlayerEntityFeature.BROWSE_MEDIA:
connection.send_message( connection.send_message(
websocket_api.error_message( websocket_api.error_message(
msg["id"], ERR_NOT_SUPPORTED, "Player does not support browsing media" msg["id"], ERR_NOT_SUPPORTED, "Player does not support browsing media"

View File

@ -1,4 +1,6 @@
"""Provides the constants needed for component.""" """Provides the constants needed for component."""
from enum import IntEnum
# How long our auth signature on the content should be valid for # How long our auth signature on the content should be valid for
CONTENT_AUTH_EXPIRY_TIME = 3600 * 24 CONTENT_AUTH_EXPIRY_TIME = 3600 * 24
@ -89,6 +91,34 @@ REPEAT_MODE_OFF = "off"
REPEAT_MODE_ONE = "one" REPEAT_MODE_ONE = "one"
REPEAT_MODES = [REPEAT_MODE_OFF, REPEAT_MODE_ALL, REPEAT_MODE_ONE] REPEAT_MODES = [REPEAT_MODE_OFF, REPEAT_MODE_ALL, REPEAT_MODE_ONE]
class MediaPlayerEntityFeature(IntEnum):
"""Supported features of the media player entity."""
PAUSE = 1
SEEK = 2
VOLUME_SET = 4
VOLUME_MUTE = 8
PREVIOUS_TRACK = 16
NEXT_TRACK = 32
TURN_ON = 128
TURN_OFF = 256
PLAY_MEDIA = 512
VOLUME_STEP = 1024
SELECT_SOURCE = 2048
STOP = 4096
CLEAR_PLAYLIST = 8192
PLAY = 16384
SHUFFLE_SET = 32768
SELECT_SOUND_MODE = 65536
BROWSE_MEDIA = 131072
REPEAT_SET = 262144
GROUPING = 524288
# These SUPPORT_* constants are deprecated as of Home Assistant 2022.5.
# Please use the MediaPlayerEntityFeature enum instead.
SUPPORT_PAUSE = 1 SUPPORT_PAUSE = 1
SUPPORT_SEEK = 2 SUPPORT_SEEK = 2
SUPPORT_VOLUME_SET = 4 SUPPORT_VOLUME_SET = 4

View File

@ -336,7 +336,11 @@ async def test_play_media(hass):
ent_id = "media_player.living_room" ent_id = "media_player.living_room"
state = hass.states.get(ent_id) state = hass.states.get(ent_id)
assert mp.SUPPORT_PLAY_MEDIA & state.attributes.get(ATTR_SUPPORTED_FEATURES) > 0 assert (
mp.MediaPlayerEntityFeature.PLAY_MEDIA
& state.attributes.get(ATTR_SUPPORTED_FEATURES)
> 0
)
assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) is not None assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) is not None
with pytest.raises(vol.Invalid): with pytest.raises(vol.Invalid):
@ -347,7 +351,11 @@ async def test_play_media(hass):
blocking=True, blocking=True,
) )
state = hass.states.get(ent_id) state = hass.states.get(ent_id)
assert mp.SUPPORT_PLAY_MEDIA & state.attributes.get(ATTR_SUPPORTED_FEATURES) > 0 assert (
mp.MediaPlayerEntityFeature.PLAY_MEDIA
& state.attributes.get(ATTR_SUPPORTED_FEATURES)
> 0
)
assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) != "some_id" assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) != "some_id"
await hass.services.async_call( await hass.services.async_call(
@ -361,7 +369,11 @@ async def test_play_media(hass):
blocking=True, blocking=True,
) )
state = hass.states.get(ent_id) state = hass.states.get(ent_id)
assert mp.SUPPORT_PLAY_MEDIA & state.attributes.get(ATTR_SUPPORTED_FEATURES) > 0 assert (
mp.MediaPlayerEntityFeature.PLAY_MEDIA
& state.attributes.get(ATTR_SUPPORTED_FEATURES)
> 0
)
assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) == "some_id" assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) == "some_id"
@ -374,7 +386,7 @@ async def test_seek(hass, mock_media_seek):
ent_id = "media_player.living_room" ent_id = "media_player.living_room"
state = hass.states.get(ent_id) state = hass.states.get(ent_id)
assert state.attributes[ATTR_SUPPORTED_FEATURES] & mp.SUPPORT_SEEK assert state.attributes[ATTR_SUPPORTED_FEATURES] & mp.MediaPlayerEntityFeature.SEEK
assert not mock_media_seek.called assert not mock_media_seek.called
with pytest.raises(vol.Invalid): with pytest.raises(vol.Invalid):

View File

@ -34,12 +34,12 @@ class ExtendedMediaPlayer(mp.MediaPlayerEntity):
def supported_features(self): def supported_features(self):
"""Flag media player features that are supported.""" """Flag media player features that are supported."""
return ( return (
mp.const.SUPPORT_VOLUME_SET mp.const.MediaPlayerEntityFeature.VOLUME_SET
| mp.const.SUPPORT_VOLUME_STEP | mp.const.MediaPlayerEntityFeature.VOLUME_STEP
| mp.const.SUPPORT_PLAY | mp.const.MediaPlayerEntityFeature.PLAY
| mp.const.SUPPORT_PAUSE | mp.const.MediaPlayerEntityFeature.PAUSE
| mp.const.SUPPORT_TURN_OFF | mp.const.MediaPlayerEntityFeature.TURN_OFF
| mp.const.SUPPORT_TURN_ON | mp.const.MediaPlayerEntityFeature.TURN_ON
) )
def set_volume_level(self, volume): def set_volume_level(self, volume):
@ -110,12 +110,12 @@ class SimpleMediaPlayer(mp.MediaPlayerEntity):
def supported_features(self): def supported_features(self):
"""Flag media player features that are supported.""" """Flag media player features that are supported."""
return ( return (
mp.const.SUPPORT_VOLUME_SET mp.const.MediaPlayerEntityFeature.VOLUME_SET
| mp.const.SUPPORT_VOLUME_STEP | mp.const.MediaPlayerEntityFeature.VOLUME_STEP
| mp.const.SUPPORT_PLAY | mp.const.MediaPlayerEntityFeature.PLAY
| mp.const.SUPPORT_PAUSE | mp.const.MediaPlayerEntityFeature.PAUSE
| mp.const.SUPPORT_TURN_OFF | mp.const.MediaPlayerEntityFeature.TURN_OFF
| mp.const.SUPPORT_TURN_ON | mp.const.MediaPlayerEntityFeature.TURN_ON
) )
def set_volume_level(self, volume): def set_volume_level(self, volume):

View File

@ -164,7 +164,7 @@ async def test_media_browse(hass, hass_ws_client):
with patch( with patch(
"homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT", "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
media_player.SUPPORT_BROWSE_MEDIA, media_player.MediaPlayerEntityFeature.BROWSE_MEDIA,
), patch( ), patch(
"homeassistant.components.media_player.MediaPlayerEntity.async_browse_media", "homeassistant.components.media_player.MediaPlayerEntity.async_browse_media",
return_value=BrowseMedia( return_value=BrowseMedia(
@ -207,7 +207,7 @@ async def test_media_browse(hass, hass_ws_client):
with patch( with patch(
"homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT", "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
media_player.SUPPORT_BROWSE_MEDIA, media_player.MediaPlayerEntityFeature.BROWSE_MEDIA,
), patch( ), patch(
"homeassistant.components.media_player.MediaPlayerEntity.async_browse_media", "homeassistant.components.media_player.MediaPlayerEntity.async_browse_media",
return_value={"bla": "yo"}, return_value={"bla": "yo"},
@ -238,7 +238,8 @@ async def test_group_members_available_when_off(hass):
# Fake group support for DemoYoutubePlayer # Fake group support for DemoYoutubePlayer
with patch( with patch(
"homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT", "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
media_player.SUPPORT_GROUPING | media_player.SUPPORT_TURN_OFF, media_player.MediaPlayerEntityFeature.GROUPING
| media_player.MediaPlayerEntityFeature.TURN_OFF,
): ):
await hass.services.async_call( await hass.services.async_call(
"media_player", "media_player",