mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Add EntityFeature enum to Media Player (#69119)
This commit is contained in:
parent
721db6d962
commit
17403f930f
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user