From 8b3ce8c58c584de8ef0643453b1bf14c8c4f561b Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 9 Sep 2022 09:03:59 +0200 Subject: [PATCH] Use new constants in dlna_dmr media player (#78045) --- homeassistant/components/dlna_dmr/const.py | 140 +++++++------- .../components/dlna_dmr/media_player.py | 49 ++--- .../components/dlna_dmr/test_media_player.py | 173 +++++++++--------- 3 files changed, 179 insertions(+), 183 deletions(-) diff --git a/homeassistant/components/dlna_dmr/const.py b/homeassistant/components/dlna_dmr/const.py index 4f9982061fb..4cea664f058 100644 --- a/homeassistant/components/dlna_dmr/const.py +++ b/homeassistant/components/dlna_dmr/const.py @@ -7,7 +7,7 @@ from typing import Final from async_upnp_client.profiles.dlna import PlayMode as _PlayMode -from homeassistant.components.media_player import const as _mp_const +from homeassistant.components.media_player import MediaType, RepeatMode LOGGER = logging.getLogger(__package__) @@ -28,66 +28,66 @@ PROTOCOL_ANY: Final = "*" STREAMABLE_PROTOCOLS: Final = [PROTOCOL_HTTP, PROTOCOL_RTSP, PROTOCOL_ANY] # Map UPnP class to media_player media_content_type -MEDIA_TYPE_MAP: Mapping[str, str] = { - "object": _mp_const.MEDIA_TYPE_URL, - "object.item": _mp_const.MEDIA_TYPE_URL, - "object.item.imageItem": _mp_const.MEDIA_TYPE_IMAGE, - "object.item.imageItem.photo": _mp_const.MEDIA_TYPE_IMAGE, - "object.item.audioItem": _mp_const.MEDIA_TYPE_MUSIC, - "object.item.audioItem.musicTrack": _mp_const.MEDIA_TYPE_MUSIC, - "object.item.audioItem.audioBroadcast": _mp_const.MEDIA_TYPE_MUSIC, - "object.item.audioItem.audioBook": _mp_const.MEDIA_TYPE_PODCAST, - "object.item.videoItem": _mp_const.MEDIA_TYPE_VIDEO, - "object.item.videoItem.movie": _mp_const.MEDIA_TYPE_MOVIE, - "object.item.videoItem.videoBroadcast": _mp_const.MEDIA_TYPE_TVSHOW, - "object.item.videoItem.musicVideoClip": _mp_const.MEDIA_TYPE_VIDEO, - "object.item.playlistItem": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.item.textItem": _mp_const.MEDIA_TYPE_URL, - "object.item.bookmarkItem": _mp_const.MEDIA_TYPE_URL, - "object.item.epgItem": _mp_const.MEDIA_TYPE_EPISODE, - "object.item.epgItem.audioProgram": _mp_const.MEDIA_TYPE_EPISODE, - "object.item.epgItem.videoProgram": _mp_const.MEDIA_TYPE_EPISODE, - "object.container": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.container.person": _mp_const.MEDIA_TYPE_ARTIST, - "object.container.person.musicArtist": _mp_const.MEDIA_TYPE_ARTIST, - "object.container.playlistContainer": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.container.album": _mp_const.MEDIA_TYPE_ALBUM, - "object.container.album.musicAlbum": _mp_const.MEDIA_TYPE_ALBUM, - "object.container.album.photoAlbum": _mp_const.MEDIA_TYPE_ALBUM, - "object.container.genre": _mp_const.MEDIA_TYPE_GENRE, - "object.container.genre.musicGenre": _mp_const.MEDIA_TYPE_GENRE, - "object.container.genre.movieGenre": _mp_const.MEDIA_TYPE_GENRE, - "object.container.channelGroup": _mp_const.MEDIA_TYPE_CHANNELS, - "object.container.channelGroup.audioChannelGroup": _mp_const.MEDIA_TYPE_CHANNELS, - "object.container.channelGroup.videoChannelGroup": _mp_const.MEDIA_TYPE_CHANNELS, - "object.container.epgContainer": _mp_const.MEDIA_TYPE_TVSHOW, - "object.container.storageSystem": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.container.storageVolume": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.container.storageFolder": _mp_const.MEDIA_TYPE_PLAYLIST, - "object.container.bookmarkFolder": _mp_const.MEDIA_TYPE_PLAYLIST, +MEDIA_TYPE_MAP: Mapping[str, MediaType] = { + "object": MediaType.URL, + "object.item": MediaType.URL, + "object.item.imageItem": MediaType.IMAGE, + "object.item.imageItem.photo": MediaType.IMAGE, + "object.item.audioItem": MediaType.MUSIC, + "object.item.audioItem.musicTrack": MediaType.MUSIC, + "object.item.audioItem.audioBroadcast": MediaType.MUSIC, + "object.item.audioItem.audioBook": MediaType.PODCAST, + "object.item.videoItem": MediaType.VIDEO, + "object.item.videoItem.movie": MediaType.MOVIE, + "object.item.videoItem.videoBroadcast": MediaType.TVSHOW, + "object.item.videoItem.musicVideoClip": MediaType.VIDEO, + "object.item.playlistItem": MediaType.PLAYLIST, + "object.item.textItem": MediaType.URL, + "object.item.bookmarkItem": MediaType.URL, + "object.item.epgItem": MediaType.EPISODE, + "object.item.epgItem.audioProgram": MediaType.EPISODE, + "object.item.epgItem.videoProgram": MediaType.EPISODE, + "object.container": MediaType.PLAYLIST, + "object.container.person": MediaType.ARTIST, + "object.container.person.musicArtist": MediaType.ARTIST, + "object.container.playlistContainer": MediaType.PLAYLIST, + "object.container.album": MediaType.ALBUM, + "object.container.album.musicAlbum": MediaType.ALBUM, + "object.container.album.photoAlbum": MediaType.ALBUM, + "object.container.genre": MediaType.GENRE, + "object.container.genre.musicGenre": MediaType.GENRE, + "object.container.genre.movieGenre": MediaType.GENRE, + "object.container.channelGroup": MediaType.CHANNELS, + "object.container.channelGroup.audioChannelGroup": MediaType.CHANNELS, + "object.container.channelGroup.videoChannelGroup": MediaType.CHANNELS, + "object.container.epgContainer": MediaType.TVSHOW, + "object.container.storageSystem": MediaType.PLAYLIST, + "object.container.storageVolume": MediaType.PLAYLIST, + "object.container.storageFolder": MediaType.PLAYLIST, + "object.container.bookmarkFolder": MediaType.PLAYLIST, } # Map media_player media_content_type to UPnP class. Not everything will map # directly, in which case it's not specified and other defaults will be used. -MEDIA_UPNP_CLASS_MAP: Mapping[str, str] = { - _mp_const.MEDIA_TYPE_ALBUM: "object.container.album.musicAlbum", - _mp_const.MEDIA_TYPE_ARTIST: "object.container.person.musicArtist", - _mp_const.MEDIA_TYPE_CHANNEL: "object.item.videoItem.videoBroadcast", - _mp_const.MEDIA_TYPE_CHANNELS: "object.container.channelGroup", - _mp_const.MEDIA_TYPE_COMPOSER: "object.container.person.musicArtist", - _mp_const.MEDIA_TYPE_CONTRIBUTING_ARTIST: "object.container.person.musicArtist", - _mp_const.MEDIA_TYPE_EPISODE: "object.item.epgItem.videoProgram", - _mp_const.MEDIA_TYPE_GENRE: "object.container.genre", - _mp_const.MEDIA_TYPE_IMAGE: "object.item.imageItem", - _mp_const.MEDIA_TYPE_MOVIE: "object.item.videoItem.movie", - _mp_const.MEDIA_TYPE_MUSIC: "object.item.audioItem.musicTrack", - _mp_const.MEDIA_TYPE_PLAYLIST: "object.item.playlistItem", - _mp_const.MEDIA_TYPE_PODCAST: "object.item.audioItem.audioBook", - _mp_const.MEDIA_TYPE_SEASON: "object.item.epgItem.videoProgram", - _mp_const.MEDIA_TYPE_TRACK: "object.item.audioItem.musicTrack", - _mp_const.MEDIA_TYPE_TVSHOW: "object.item.videoItem.videoBroadcast", - _mp_const.MEDIA_TYPE_URL: "object.item.bookmarkItem", - _mp_const.MEDIA_TYPE_VIDEO: "object.item.videoItem", +MEDIA_UPNP_CLASS_MAP: Mapping[MediaType | str, str] = { + MediaType.ALBUM: "object.container.album.musicAlbum", + MediaType.ARTIST: "object.container.person.musicArtist", + MediaType.CHANNEL: "object.item.videoItem.videoBroadcast", + MediaType.CHANNELS: "object.container.channelGroup", + MediaType.COMPOSER: "object.container.person.musicArtist", + MediaType.CONTRIBUTING_ARTIST: "object.container.person.musicArtist", + MediaType.EPISODE: "object.item.epgItem.videoProgram", + MediaType.GENRE: "object.container.genre", + MediaType.IMAGE: "object.item.imageItem", + MediaType.MOVIE: "object.item.videoItem.movie", + MediaType.MUSIC: "object.item.audioItem.musicTrack", + MediaType.PLAYLIST: "object.item.playlistItem", + MediaType.PODCAST: "object.item.audioItem.audioBook", + MediaType.SEASON: "object.item.epgItem.videoProgram", + MediaType.TRACK: "object.item.audioItem.musicTrack", + MediaType.TVSHOW: "object.item.videoItem.videoBroadcast", + MediaType.URL: "object.item.bookmarkItem", + MediaType.VIDEO: "object.item.videoItem", } # Translation of MediaMetadata keys to DIDL-Lite keys. @@ -109,32 +109,32 @@ MEDIA_METADATA_DIDL: Mapping[str, str] = { # of play modes in order of suitability. Fall back to _PlayMode.NORMAL in any # case. NOTE: This list is slightly different to that in SHUFFLE_PLAY_MODES, # due to fallback behaviour when turning on repeat modes. -REPEAT_PLAY_MODES: Mapping[tuple[bool, str], list[_PlayMode]] = { - (False, _mp_const.REPEAT_MODE_OFF): [ +REPEAT_PLAY_MODES: Mapping[tuple[bool, RepeatMode], list[_PlayMode]] = { + (False, RepeatMode.OFF): [ _PlayMode.NORMAL, ], - (False, _mp_const.REPEAT_MODE_ONE): [ + (False, RepeatMode.ONE): [ _PlayMode.REPEAT_ONE, _PlayMode.REPEAT_ALL, _PlayMode.NORMAL, ], - (False, _mp_const.REPEAT_MODE_ALL): [ + (False, RepeatMode.ALL): [ _PlayMode.REPEAT_ALL, _PlayMode.REPEAT_ONE, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_OFF): [ + (True, RepeatMode.OFF): [ _PlayMode.SHUFFLE, _PlayMode.RANDOM, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_ONE): [ + (True, RepeatMode.ONE): [ _PlayMode.REPEAT_ONE, _PlayMode.RANDOM, _PlayMode.SHUFFLE, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_ALL): [ + (True, RepeatMode.ALL): [ _PlayMode.RANDOM, _PlayMode.REPEAT_ALL, _PlayMode.SHUFFLE, @@ -146,31 +146,31 @@ REPEAT_PLAY_MODES: Mapping[tuple[bool, str], list[_PlayMode]] = { # of play modes in order of suitability. Fall back to _PlayMode.NORMAL in any # case. SHUFFLE_PLAY_MODES: Mapping[tuple[bool, str], list[_PlayMode]] = { - (False, _mp_const.REPEAT_MODE_OFF): [ + (False, RepeatMode.OFF): [ _PlayMode.NORMAL, ], - (False, _mp_const.REPEAT_MODE_ONE): [ + (False, RepeatMode.ONE): [ _PlayMode.REPEAT_ONE, _PlayMode.REPEAT_ALL, _PlayMode.NORMAL, ], - (False, _mp_const.REPEAT_MODE_ALL): [ + (False, RepeatMode.ALL): [ _PlayMode.REPEAT_ALL, _PlayMode.REPEAT_ONE, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_OFF): [ + (True, RepeatMode.OFF): [ _PlayMode.SHUFFLE, _PlayMode.RANDOM, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_ONE): [ + (True, RepeatMode.ONE): [ _PlayMode.RANDOM, _PlayMode.SHUFFLE, _PlayMode.REPEAT_ONE, _PlayMode.NORMAL, ], - (True, _mp_const.REPEAT_MODE_ALL): [ + (True, RepeatMode.ALL): [ _PlayMode.RANDOM, _PlayMode.SHUFFLE, _PlayMode.REPEAT_ALL, diff --git a/homeassistant/components/dlna_dmr/media_player.py b/homeassistant/components/dlna_dmr/media_player.py index 156e8fdffef..ff09f018639 100644 --- a/homeassistant/components/dlna_dmr/media_player.py +++ b/homeassistant/components/dlna_dmr/media_player.py @@ -19,27 +19,16 @@ from typing_extensions import Concatenate, ParamSpec from homeassistant import config_entries from homeassistant.components import media_source, ssdp from homeassistant.components.media_player import ( + ATTR_MEDIA_EXTRA, BrowseMedia, MediaPlayerEntity, MediaPlayerEntityFeature, + MediaPlayerState, + MediaType, + RepeatMode, async_process_play_media_url, ) -from homeassistant.components.media_player.const import ( - ATTR_MEDIA_EXTRA, - REPEAT_MODE_ALL, - REPEAT_MODE_OFF, - REPEAT_MODE_ONE, -) -from homeassistant.const import ( - CONF_DEVICE_ID, - CONF_TYPE, - CONF_URL, - STATE_IDLE, - STATE_OFF, - STATE_ON, - STATE_PAUSED, - STATE_PLAYING, -) +from homeassistant.const import CONF_DEVICE_ID, CONF_TYPE, CONF_URL from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry, entity_registry from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -466,27 +455,27 @@ class DlnaDmrEntity(MediaPlayerEntity): return f"{self.udn}::{self.device_type}" @property - def state(self) -> str | None: + def state(self) -> MediaPlayerState | None: """State of the player.""" if not self._device or not self.available: - return STATE_OFF + return MediaPlayerState.OFF if self._device.transport_state is None: - return STATE_ON + return MediaPlayerState.ON if self._device.transport_state in ( TransportState.PLAYING, TransportState.TRANSITIONING, ): - return STATE_PLAYING + return MediaPlayerState.PLAYING if self._device.transport_state in ( TransportState.PAUSED_PLAYBACK, TransportState.PAUSED_RECORDING, ): - return STATE_PAUSED + return MediaPlayerState.PAUSED if self._device.transport_state == TransportState.VENDOR_DEFINED: # Unable to map this state to anything reasonable, so it's "Unknown" return None - return STATE_IDLE + return MediaPlayerState.IDLE @property def supported_features(self) -> int: @@ -586,7 +575,7 @@ class DlnaDmrEntity(MediaPlayerEntity): @catch_request_errors async def async_play_media( - self, media_type: str, media_id: str, **kwargs: Any + self, media_type: MediaType | str, media_id: str, **kwargs: Any ) -> None: """Play a piece of media.""" _LOGGER.debug("Playing media: %s, %s, %s", media_type, media_id, kwargs) @@ -683,7 +672,7 @@ class DlnaDmrEntity(MediaPlayerEntity): """Enable/disable shuffle mode.""" assert self._device is not None - repeat = self.repeat or REPEAT_MODE_OFF + repeat = self.repeat or RepeatMode.OFF potential_play_modes = SHUFFLE_PLAY_MODES[(shuffle, repeat)] valid_play_modes = self._device.valid_play_modes @@ -698,7 +687,7 @@ class DlnaDmrEntity(MediaPlayerEntity): ) @property - def repeat(self) -> str | None: + def repeat(self) -> RepeatMode | None: """Return current repeat mode.""" if not self._device: return None @@ -710,15 +699,15 @@ class DlnaDmrEntity(MediaPlayerEntity): return None if play_mode == PlayMode.REPEAT_ONE: - return REPEAT_MODE_ONE + return RepeatMode.ONE if play_mode in (PlayMode.REPEAT_ALL, PlayMode.RANDOM): - return REPEAT_MODE_ALL + return RepeatMode.ALL - return REPEAT_MODE_OFF + return RepeatMode.OFF @catch_request_errors - async def async_set_repeat(self, repeat: str) -> None: + async def async_set_repeat(self, repeat: RepeatMode) -> None: """Set repeat mode.""" assert self._device is not None @@ -839,7 +828,7 @@ class DlnaDmrEntity(MediaPlayerEntity): return self._device.current_track_uri @property - def media_content_type(self) -> str | None: + def media_content_type(self) -> MediaType | None: """Content type of current playing media.""" if not self._device or not self._device.media_class: return None diff --git a/tests/components/dlna_dmr/test_media_player.py b/tests/components/dlna_dmr/test_media_player.py index eef5d936396..0091826db84 100644 --- a/tests/components/dlna_dmr/test_media_player.py +++ b/tests/components/dlna_dmr/test_media_player.py @@ -21,7 +21,6 @@ import pytest from homeassistant import const as ha_const from homeassistant.components import ssdp -from homeassistant.components.dlna_dmr import media_player from homeassistant.components.dlna_dmr.const import ( CONF_BROWSE_UNFILTERED, CONF_CALLBACK_URL_OVERRIDE, @@ -30,10 +29,17 @@ from homeassistant.components.dlna_dmr.const import ( DOMAIN as DLNA_DOMAIN, ) from homeassistant.components.dlna_dmr.data import EventListenAddr -from homeassistant.components.media_player import ATTR_TO_PROPERTY, const as mp_const -from homeassistant.components.media_player.const import DOMAIN as MP_DOMAIN -from homeassistant.components.media_source.const import DOMAIN as MS_DOMAIN -from homeassistant.components.media_source.models import PlayMedia +from homeassistant.components.dlna_dmr.media_player import DlnaDmrEntity +from homeassistant.components.media_player import ( + ATTR_TO_PROPERTY, + DOMAIN as MP_DOMAIN, + MediaPlayerEntityFeature, + MediaPlayerState, + MediaType, + RepeatMode, + const as mp_const, +) +from homeassistant.components.media_source import DOMAIN as MS_DOMAIN, PlayMedia from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant from homeassistant.helpers.device_registry import async_get as async_get_dr @@ -223,7 +229,7 @@ async def test_setup_entry_no_options( ANY, {"_udn": MOCK_DEVICE_UDN, "NTS": "ssdp:byebye"} ) # Quick check of the state to verify the entity has a connected DmrDevice - assert mock_state.state == media_player.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Check the name matches that supplied assert mock_state.name == MOCK_DEVICE_NAME @@ -292,7 +298,7 @@ async def test_setup_entry_with_options( ANY, {"_udn": MOCK_DEVICE_UDN, "NTS": "ssdp:byebye"} ) # Quick check of the state to verify the entity has a connected DmrDevice - assert mock_state.state == media_player.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Check the name matches that supplied assert mock_state.name == MOCK_DEVICE_NAME @@ -359,7 +365,7 @@ async def test_event_subscribe_rejected( assert mock_state is not None # Device should be connected - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Device should not be unsubscribed dmr_device_mock.async_unsubscribe_services.assert_not_awaited() @@ -385,14 +391,14 @@ async def test_available_device( # Check entity state gets updated when device changes state for (dev_state, ent_state) in [ - (None, ha_const.STATE_ON), - (TransportState.STOPPED, ha_const.STATE_IDLE), - (TransportState.PLAYING, ha_const.STATE_PLAYING), - (TransportState.TRANSITIONING, ha_const.STATE_PLAYING), - (TransportState.PAUSED_PLAYBACK, ha_const.STATE_PAUSED), - (TransportState.PAUSED_RECORDING, ha_const.STATE_PAUSED), - (TransportState.RECORDING, ha_const.STATE_IDLE), - (TransportState.NO_MEDIA_PRESENT, ha_const.STATE_IDLE), + (None, MediaPlayerState.ON), + (TransportState.STOPPED, MediaPlayerState.IDLE), + (TransportState.PLAYING, MediaPlayerState.PLAYING), + (TransportState.TRANSITIONING, MediaPlayerState.PLAYING), + (TransportState.PAUSED_PLAYBACK, MediaPlayerState.PAUSED), + (TransportState.PAUSED_RECORDING, MediaPlayerState.PAUSED), + (TransportState.RECORDING, MediaPlayerState.IDLE), + (TransportState.NO_MEDIA_PRESENT, MediaPlayerState.IDLE), (TransportState.VENDOR_DEFINED, ha_const.STATE_UNKNOWN), ]: dmr_device_mock.profile_device.available = True @@ -416,16 +422,19 @@ async def test_feature_flags( """Test feature flags of a connected DlnaDmrEntity.""" # Check supported feature flags, one at a time. FEATURE_FLAGS: list[tuple[str, int]] = [ - ("has_volume_level", mp_const.SUPPORT_VOLUME_SET), - ("has_volume_mute", mp_const.SUPPORT_VOLUME_MUTE), - ("can_play", mp_const.SUPPORT_PLAY), - ("can_pause", mp_const.SUPPORT_PAUSE), - ("can_stop", mp_const.SUPPORT_STOP), - ("can_previous", mp_const.SUPPORT_PREVIOUS_TRACK), - ("can_next", mp_const.SUPPORT_NEXT_TRACK), - ("has_play_media", mp_const.SUPPORT_PLAY_MEDIA | mp_const.SUPPORT_BROWSE_MEDIA), - ("can_seek_rel_time", mp_const.SUPPORT_SEEK), - ("has_presets", mp_const.SUPPORT_SELECT_SOUND_MODE), + ("has_volume_level", MediaPlayerEntityFeature.VOLUME_SET), + ("has_volume_mute", MediaPlayerEntityFeature.VOLUME_MUTE), + ("can_play", MediaPlayerEntityFeature.PLAY), + ("can_pause", MediaPlayerEntityFeature.PAUSE), + ("can_stop", MediaPlayerEntityFeature.STOP), + ("can_previous", MediaPlayerEntityFeature.PREVIOUS_TRACK), + ("can_next", MediaPlayerEntityFeature.NEXT_TRACK), + ( + "has_play_media", + MediaPlayerEntityFeature.PLAY_MEDIA | MediaPlayerEntityFeature.BROWSE_MEDIA, + ), + ("can_seek_rel_time", MediaPlayerEntityFeature.SEEK), + ("has_presets", MediaPlayerEntityFeature.SELECT_SOUND_MODE), ] # Clear all feature properties @@ -446,10 +455,10 @@ async def test_feature_flags( # shuffle and repeat features depend on the available play modes PLAY_MODE_FEATURE_FLAGS: list[tuple[PlayMode, int]] = [ (PlayMode.NORMAL, 0), - (PlayMode.SHUFFLE, mp_const.SUPPORT_SHUFFLE_SET), - (PlayMode.REPEAT_ONE, mp_const.SUPPORT_REPEAT_SET), - (PlayMode.REPEAT_ALL, mp_const.SUPPORT_REPEAT_SET), - (PlayMode.RANDOM, mp_const.SUPPORT_SHUFFLE_SET), + (PlayMode.SHUFFLE, MediaPlayerEntityFeature.SHUFFLE_SET), + (PlayMode.REPEAT_ONE, MediaPlayerEntityFeature.REPEAT_SET), + (PlayMode.REPEAT_ALL, MediaPlayerEntityFeature.REPEAT_SET), + (PlayMode.RANDOM, MediaPlayerEntityFeature.SHUFFLE_SET), (PlayMode.DIRECT_1, 0), (PlayMode.INTRO, 0), (PlayMode.VENDOR_DEFINED, 0), @@ -497,13 +506,13 @@ async def test_attributes( # media_content_type is mapped from UPnP class to MediaPlayer type dmr_device_mock.media_class = "object.item.audioItem.musicTrack" attrs = await get_attrs(hass, mock_entity_id) - assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == mp_const.MEDIA_TYPE_MUSIC + assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC dmr_device_mock.media_class = "object.item.videoItem.movie" attrs = await get_attrs(hass, mock_entity_id) - assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == mp_const.MEDIA_TYPE_MOVIE + assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == MediaType.MOVIE dmr_device_mock.media_class = "object.item.videoItem.videoBroadcast" attrs = await get_attrs(hass, mock_entity_id) - assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == mp_const.MEDIA_TYPE_TVSHOW + assert attrs[mp_const.ATTR_MEDIA_CONTENT_TYPE] == MediaType.TVSHOW # media_season & media_episode have a special case dmr_device_mock.media_season_number = "0" @@ -519,13 +528,13 @@ async def test_attributes( # shuffle and repeat is based on device's play mode for play_mode, shuffle, repeat in [ - (PlayMode.NORMAL, False, mp_const.REPEAT_MODE_OFF), - (PlayMode.SHUFFLE, True, mp_const.REPEAT_MODE_OFF), - (PlayMode.REPEAT_ONE, False, mp_const.REPEAT_MODE_ONE), - (PlayMode.REPEAT_ALL, False, mp_const.REPEAT_MODE_ALL), - (PlayMode.RANDOM, True, mp_const.REPEAT_MODE_ALL), - (PlayMode.DIRECT_1, False, mp_const.REPEAT_MODE_OFF), - (PlayMode.INTRO, False, mp_const.REPEAT_MODE_OFF), + (PlayMode.NORMAL, False, RepeatMode.OFF), + (PlayMode.SHUFFLE, True, RepeatMode.OFF), + (PlayMode.REPEAT_ONE, False, RepeatMode.ONE), + (PlayMode.REPEAT_ALL, False, RepeatMode.ALL), + (PlayMode.RANDOM, True, RepeatMode.ALL), + (PlayMode.DIRECT_1, False, RepeatMode.OFF), + (PlayMode.INTRO, False, RepeatMode.OFF), ]: dmr_device_mock.play_mode = play_mode attrs = await get_attrs(hass, mock_entity_id) @@ -620,7 +629,7 @@ async def test_play_media_stopped( mp_const.SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_MUSIC, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/17621.mp3", mp_const.ATTR_MEDIA_ENQUEUE: False, }, @@ -652,7 +661,7 @@ async def test_play_media_playing( mp_const.SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_MUSIC, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/17621.mp3", mp_const.ATTR_MEDIA_ENQUEUE: False, }, @@ -685,7 +694,7 @@ async def test_play_media_no_autoplay( mp_const.SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_MUSIC, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/17621.mp3", mp_const.ATTR_MEDIA_ENQUEUE: False, mp_const.ATTR_MEDIA_EXTRA: {"autoplay": False}, @@ -716,7 +725,7 @@ async def test_play_media_metadata( mp_const.SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_MUSIC, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/17621.mp3", mp_const.ATTR_MEDIA_ENQUEUE: False, mp_const.ATTR_MEDIA_EXTRA: { @@ -746,7 +755,7 @@ async def test_play_media_metadata( mp_const.SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_TVSHOW, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.TVSHOW, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/123.mkv", mp_const.ATTR_MEDIA_ENQUEUE: False, mp_const.ATTR_MEDIA_EXTRA: { @@ -878,21 +887,21 @@ async def test_shuffle_repeat_modes( # Test repeat with all variations of existing play mode for init_mode, repeat_set, expect_mode in [ - (PlayMode.NORMAL, mp_const.REPEAT_MODE_OFF, PlayMode.NORMAL), - (PlayMode.SHUFFLE, mp_const.REPEAT_MODE_OFF, PlayMode.SHUFFLE), - (PlayMode.REPEAT_ONE, mp_const.REPEAT_MODE_OFF, PlayMode.NORMAL), - (PlayMode.REPEAT_ALL, mp_const.REPEAT_MODE_OFF, PlayMode.NORMAL), - (PlayMode.RANDOM, mp_const.REPEAT_MODE_OFF, PlayMode.SHUFFLE), - (PlayMode.NORMAL, mp_const.REPEAT_MODE_ONE, PlayMode.REPEAT_ONE), - (PlayMode.SHUFFLE, mp_const.REPEAT_MODE_ONE, PlayMode.REPEAT_ONE), - (PlayMode.REPEAT_ONE, mp_const.REPEAT_MODE_ONE, PlayMode.REPEAT_ONE), - (PlayMode.REPEAT_ALL, mp_const.REPEAT_MODE_ONE, PlayMode.REPEAT_ONE), - (PlayMode.RANDOM, mp_const.REPEAT_MODE_ONE, PlayMode.REPEAT_ONE), - (PlayMode.NORMAL, mp_const.REPEAT_MODE_ALL, PlayMode.REPEAT_ALL), - (PlayMode.SHUFFLE, mp_const.REPEAT_MODE_ALL, PlayMode.RANDOM), - (PlayMode.REPEAT_ONE, mp_const.REPEAT_MODE_ALL, PlayMode.REPEAT_ALL), - (PlayMode.REPEAT_ALL, mp_const.REPEAT_MODE_ALL, PlayMode.REPEAT_ALL), - (PlayMode.RANDOM, mp_const.REPEAT_MODE_ALL, PlayMode.RANDOM), + (PlayMode.NORMAL, RepeatMode.OFF, PlayMode.NORMAL), + (PlayMode.SHUFFLE, RepeatMode.OFF, PlayMode.SHUFFLE), + (PlayMode.REPEAT_ONE, RepeatMode.OFF, PlayMode.NORMAL), + (PlayMode.REPEAT_ALL, RepeatMode.OFF, PlayMode.NORMAL), + (PlayMode.RANDOM, RepeatMode.OFF, PlayMode.SHUFFLE), + (PlayMode.NORMAL, RepeatMode.ONE, PlayMode.REPEAT_ONE), + (PlayMode.SHUFFLE, RepeatMode.ONE, PlayMode.REPEAT_ONE), + (PlayMode.REPEAT_ONE, RepeatMode.ONE, PlayMode.REPEAT_ONE), + (PlayMode.REPEAT_ALL, RepeatMode.ONE, PlayMode.REPEAT_ONE), + (PlayMode.RANDOM, RepeatMode.ONE, PlayMode.REPEAT_ONE), + (PlayMode.NORMAL, RepeatMode.ALL, PlayMode.REPEAT_ALL), + (PlayMode.SHUFFLE, RepeatMode.ALL, PlayMode.RANDOM), + (PlayMode.REPEAT_ONE, RepeatMode.ALL, PlayMode.REPEAT_ALL), + (PlayMode.REPEAT_ALL, RepeatMode.ALL, PlayMode.REPEAT_ALL), + (PlayMode.RANDOM, RepeatMode.ALL, PlayMode.RANDOM), ]: dmr_device_mock.play_mode = init_mode await hass.services.async_call( @@ -926,7 +935,7 @@ async def test_shuffle_repeat_modes( ha_const.SERVICE_REPEAT_SET, { ATTR_ENTITY_ID: mock_entity_id, - mp_const.ATTR_MEDIA_REPEAT: mp_const.REPEAT_MODE_OFF, + mp_const.ATTR_MEDIA_REPEAT: RepeatMode.OFF, }, blocking=True, ) @@ -1226,7 +1235,7 @@ async def test_unavailable_device( ( mp_const.SERVICE_PLAY_MEDIA, { - mp_const.ATTR_MEDIA_CONTENT_TYPE: mp_const.MEDIA_TYPE_MUSIC, + mp_const.ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC, mp_const.ATTR_MEDIA_CONTENT_ID: "http://192.88.99.20:8200/MediaItems/17621.mp3", mp_const.ATTR_MEDIA_ENQUEUE: False, }, @@ -1318,7 +1327,7 @@ async def test_become_available( # Quick check of the state to verify the entity has a connected DmrDevice mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Check hass device information is now filled in dev_reg = async_get_dr(hass) device = dev_reg.async_get_device(identifiers={(DLNA_DOMAIN, MOCK_DEVICE_UDN)}) @@ -1496,7 +1505,7 @@ async def test_multiple_ssdp_alive( # Device should be available mock_state = hass.states.get(mock_disconnected_entity_id) assert mock_state is not None - assert mock_state.state == media_player.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE async def test_ssdp_byebye( @@ -1592,7 +1601,7 @@ async def test_ssdp_update_seen_bootid( # Device was not reconnected, even with a new boot ID mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 0 assert dmr_device_mock.async_subscribe_services.await_count == 1 @@ -1617,7 +1626,7 @@ async def test_ssdp_update_seen_bootid( # Nothing should change mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 0 assert dmr_device_mock.async_subscribe_services.await_count == 1 @@ -1642,7 +1651,7 @@ async def test_ssdp_update_seen_bootid( # Nothing should change mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 0 assert dmr_device_mock.async_subscribe_services.await_count == 1 @@ -1662,7 +1671,7 @@ async def test_ssdp_update_seen_bootid( mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 0 assert dmr_device_mock.async_subscribe_services.await_count == 1 @@ -1719,7 +1728,7 @@ async def test_ssdp_update_missed_bootid( # Device should not reconnect yet mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 0 assert dmr_device_mock.async_subscribe_services.await_count == 1 @@ -1739,7 +1748,7 @@ async def test_ssdp_update_missed_bootid( mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_unsubscribe_services.await_count == 1 assert dmr_device_mock.async_subscribe_services.await_count == 2 @@ -1778,7 +1787,7 @@ async def test_ssdp_bootid( mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_subscribe_services.call_count == 1 assert dmr_device_mock.async_unsubscribe_services.call_count == 0 @@ -1798,7 +1807,7 @@ async def test_ssdp_bootid( mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_subscribe_services.call_count == 1 assert dmr_device_mock.async_unsubscribe_services.call_count == 0 @@ -1818,7 +1827,7 @@ async def test_ssdp_bootid( mock_state = hass.states.get(entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE assert dmr_device_mock.async_subscribe_services.call_count == 2 assert dmr_device_mock.async_unsubscribe_services.call_count == 1 @@ -1849,14 +1858,14 @@ async def test_become_unavailable( mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # With a working connection, the state should be restored await async_update_entity(hass, mock_entity_id) dmr_device_mock.async_update.assert_any_call(do_ping=True) mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Break the service again, and the connection too. An update will cause the # device to be disconnected @@ -1918,7 +1927,7 @@ async def test_poll_availability( mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE # Clean up assert await hass.config_entries.async_remove(config_entry_mock.entry_id) == { @@ -1938,9 +1947,7 @@ async def test_disappearing_device( directly to skip the availability check. """ # Retrieve entity directly. - entity: media_player.DlnaDmrEntity = hass.data[MP_DOMAIN].get_entity( - mock_disconnected_entity_id - ) + entity: DlnaDmrEntity = hass.data[MP_DOMAIN].get_entity(mock_disconnected_entity_id) # Test attribute access for attr in ATTR_TO_PROPERTY: @@ -1964,7 +1971,7 @@ async def test_disappearing_device( await entity.async_media_previous_track() await entity.async_media_next_track() await entity.async_set_shuffle(True) - await entity.async_set_repeat(mp_const.REPEAT_MODE_ALL) + await entity.async_set_repeat(RepeatMode.ALL) await entity.async_select_sound_mode("Default") @@ -2023,7 +2030,7 @@ async def test_config_update_listen_port( # Check that its still connected mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE async def test_config_update_connect_failure( @@ -2097,7 +2104,7 @@ async def test_config_update_callback_url( # Check that its still connected mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE async def test_config_update_poll_availability( @@ -2138,4 +2145,4 @@ async def test_config_update_poll_availability( # Check that its still connected mock_state = hass.states.get(mock_entity_id) assert mock_state is not None - assert mock_state.state == ha_const.STATE_IDLE + assert mock_state.state == MediaPlayerState.IDLE