Use new enums in cast (#77946)

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
This commit is contained in:
epenet 2022-09-09 08:57:14 +02:00 committed by GitHub
parent eb28d7188b
commit 7ff23506fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 52 deletions

View File

@ -7,7 +7,7 @@ from typing import Protocol
from pychromecast import Chromecast
import voluptuous as vol
from homeassistant.components.media_player import BrowseMedia
from homeassistant.components.media_player import BrowseMedia, MediaType
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
@ -74,7 +74,7 @@ class CastProtocol(Protocol):
async def async_browse_media(
self,
hass: HomeAssistant,
media_content_type: str,
media_content_type: MediaType | str,
media_content_id: str,
cast_type: str,
) -> BrowseMedia | None:
@ -88,7 +88,7 @@ class CastProtocol(Protocol):
hass: HomeAssistant,
cast_entity_id: str,
chromecast: Chromecast,
media_type: str,
media_type: MediaType | str,
media_id: str,
) -> bool:
"""Play media.

View File

@ -7,7 +7,7 @@ from contextlib import suppress
from datetime import datetime
import json
import logging
from typing import Any
from typing import TYPE_CHECKING, Any
import pychromecast
from pychromecast.controllers.homeassistant import HomeAssistantController
@ -29,29 +29,21 @@ import yarl
from homeassistant.components import media_source, zeroconf
from homeassistant.components.media_player import (
ATTR_MEDIA_EXTRA,
BrowseError,
BrowseMedia,
MediaClass,
MediaPlayerDeviceClass,
MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerState,
MediaType,
async_process_play_media_url,
)
from homeassistant.components.media_player.const import (
ATTR_MEDIA_EXTRA,
MEDIA_CLASS_DIRECTORY,
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CAST_APP_ID_HOMEASSISTANT_LOVELACE,
EVENT_HOMEASSISTANT_STOP,
STATE_BUFFERING,
STATE_IDLE,
STATE_OFF,
STATE_PAUSED,
STATE_PLAYING,
)
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
@ -83,6 +75,9 @@ from .helpers import (
parse_playlist,
)
if TYPE_CHECKING:
from . import CastProtocol
_LOGGER = logging.getLogger(__name__)
APP_IDS_UNRELIABLE_MEDIA_INFO = ("Netflix",)
@ -590,7 +585,7 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
return BrowseMedia(
title="Cast",
media_class=MEDIA_CLASS_DIRECTORY,
media_class=MediaClass.DIRECTORY,
media_content_id="",
media_content_type="",
can_play=False,
@ -599,7 +594,9 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
)
async def async_browse_media(
self, media_content_type: str | None = None, media_content_id: str | None = None
self,
media_content_type: MediaType | str | None = None,
media_content_id: str | None = None,
) -> BrowseMedia:
"""Implement the websocket media browsing helper."""
content_filter = None
@ -619,6 +616,8 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
if media_content_id is None:
return await self._async_root_payload(content_filter)
platform: CastProtocol
assert media_content_type is not None
for platform in self.hass.data[CAST_DOMAIN]["cast_platform"].values():
browse_media = await platform.async_browse_media(
self.hass,
@ -634,7 +633,7 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
)
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."""
chromecast = self._get_chromecast()
@ -774,27 +773,27 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
return (media_status, media_status_received)
@property
def state(self) -> str | None:
def state(self) -> MediaPlayerState | None:
"""Return the state of the player."""
# The lovelace app loops media to prevent timing out, don't show that
if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
return STATE_PLAYING
return MediaPlayerState.PLAYING
if (media_status := self._media_status()[0]) is not None:
if media_status.player_state == MEDIA_PLAYER_STATE_PLAYING:
return STATE_PLAYING
return MediaPlayerState.PLAYING
if media_status.player_state == MEDIA_PLAYER_STATE_BUFFERING:
return STATE_BUFFERING
return MediaPlayerState.BUFFERING
if media_status.player_is_paused:
return STATE_PAUSED
return MediaPlayerState.PAUSED
if media_status.player_is_idle:
return STATE_IDLE
return MediaPlayerState.IDLE
if self.app_id is not None and self.app_id != pychromecast.IDLE_APP_ID:
if self.app_id in APP_IDS_UNRELIABLE_MEDIA_INFO:
# Some apps don't report media status, show the player as playing
return STATE_PLAYING
return STATE_IDLE
return MediaPlayerState.PLAYING
return MediaPlayerState.IDLE
if self._chromecast is not None and self._chromecast.is_idle:
return STATE_OFF
return MediaPlayerState.OFF
return None
@property
@ -807,7 +806,7 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
return media_status.content_id if media_status else None
@property
def media_content_type(self) -> str | None:
def media_content_type(self) -> MediaType | None:
"""Content type of current playing media."""
# The lovelace app loops media to prevent timing out, don't show that
if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
@ -815,11 +814,11 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
if (media_status := self._media_status()[0]) is None:
return None
if media_status.media_is_tvshow:
return MEDIA_TYPE_TVSHOW
return MediaType.TVSHOW
if media_status.media_is_movie:
return MEDIA_TYPE_MOVIE
return MediaType.MOVIE
if media_status.media_is_musictrack:
return MEDIA_TYPE_MUSIC
return MediaType.MUSIC
return None
@property

View File

@ -12,8 +12,12 @@ from homeassistant.components.cast.home_assistant_cast import (
NO_URL_AVAILABLE_ERROR,
SERVICE_SHOW_VIEW,
)
from homeassistant.components.media_player import BrowseError, BrowseMedia
from homeassistant.components.media_player.const import MEDIA_CLASS_APP
from homeassistant.components.media_player import (
BrowseError,
BrowseMedia,
MediaClass,
MediaType,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
@ -34,7 +38,7 @@ async def async_get_media_browser_root_object(
return [
BrowseMedia(
title="Dashboards",
media_class=MEDIA_CLASS_APP,
media_class=MediaClass.APP,
media_content_id="",
media_content_type=DOMAIN,
thumbnail="https://brands.home-assistant.io/_/lovelace/logo.png",
@ -46,7 +50,7 @@ async def async_get_media_browser_root_object(
async def async_browse_media(
hass: HomeAssistant,
media_content_type: str,
media_content_type: MediaType | str,
media_content_id: str,
cast_type: str,
) -> BrowseMedia | None:
@ -64,7 +68,7 @@ async def async_browse_media(
children = [
BrowseMedia(
title="Default",
media_class=MEDIA_CLASS_APP,
media_class=MediaClass.APP,
media_content_id=DEFAULT_DASHBOARD,
media_content_type=DOMAIN,
thumbnail="https://brands.home-assistant.io/_/lovelace/logo.png",
@ -96,7 +100,7 @@ async def async_browse_media(
children.append(
BrowseMedia(
title=view["title"],
media_class=MEDIA_CLASS_APP,
media_class=MediaClass.APP,
media_content_id=f'{info["url_path"]}/{view["path"]}',
media_content_type=DOMAIN,
thumbnail="https://brands.home-assistant.io/_/lovelace/logo.png",
@ -114,7 +118,7 @@ async def async_play_media(
hass: HomeAssistant,
cast_entity_id: str,
chromecast: Chromecast,
media_type: str,
media_type: MediaType | str,
media_id: str,
) -> bool:
"""Play media."""
@ -195,7 +199,7 @@ def _item_from_info(info: dict) -> BrowseMedia:
"""Convert dashboard info to browse item."""
return BrowseMedia(
title=info["title"],
media_class=MEDIA_CLASS_APP,
media_class=MediaClass.APP,
media_content_id=info["url_path"],
media_content_type=DOMAIN,
thumbnail="https://brands.home-assistant.io/_/lovelace/logo.png",

View File

@ -5,8 +5,7 @@ from pychromecast import Chromecast
from pychromecast.controllers.plex import PlexController
from homeassistant.components.cast.const import DOMAIN as CAST_DOMAIN
from homeassistant.components.media_player import BrowseMedia
from homeassistant.components.media_player.const import MEDIA_CLASS_APP
from homeassistant.components.media_player import BrowseMedia, MediaClass, MediaType
from homeassistant.core import HomeAssistant
from . import async_browse_media as async_browse_plex_media, is_plex_media_id
@ -20,7 +19,7 @@ async def async_get_media_browser_root_object(
return [
BrowseMedia(
title="Plex",
media_class=MEDIA_CLASS_APP,
media_class=MediaClass.APP,
media_content_id="",
media_content_type="plex",
thumbnail="https://brands.home-assistant.io/_/plex/logo.png",
@ -32,7 +31,7 @@ async def async_get_media_browser_root_object(
async def async_browse_media(
hass: HomeAssistant,
media_content_type: str,
media_content_type: MediaType | str,
media_content_id: str,
cast_type: str,
) -> BrowseMedia | None:
@ -61,7 +60,7 @@ async def async_play_media(
hass: HomeAssistant,
cast_entity_id: str,
chromecast: Chromecast,
media_type: str,
media_type: MediaType | str,
media_id: str,
) -> bool:
"""Play media."""

View File

@ -203,7 +203,7 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = {
function_name="async_browse_media",
arg_types={
0: "HomeAssistant",
1: "str",
1: "MediaType | str",
2: "str",
3: "str",
},
@ -215,7 +215,7 @@ _FUNCTION_MATCH: dict[str, list[TypeHintMatch]] = {
0: "HomeAssistant",
1: "str",
2: "Chromecast",
3: "str",
3: "MediaType | str",
4: "str",
},
return_type="bool",

View File

@ -5,6 +5,7 @@ from unittest.mock import patch
import pytest
from homeassistant.components.lovelace import cast as lovelace_cast
from homeassistant.components.media_player import MediaClass
from homeassistant.config import async_process_ha_core_config
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
@ -71,7 +72,7 @@ async def test_root_object(hass):
assert len(root) == 1
item = root[0]
assert item.title == "Dashboards"
assert item.media_class == lovelace_cast.MEDIA_CLASS_APP
assert item.media_class == MediaClass.APP
assert item.media_content_id == ""
assert item.media_content_type == lovelace_cast.DOMAIN
assert item.thumbnail == "https://brands.home-assistant.io/_/lovelace/logo.png"
@ -106,7 +107,7 @@ async def test_browse_media(hass, mock_yaml_dashboard, mock_https_url):
child_1 = top_level_items.children[0]
assert child_1.title == "Default"
assert child_1.media_class == lovelace_cast.MEDIA_CLASS_APP
assert child_1.media_class == MediaClass.APP
assert child_1.media_content_id == lovelace_cast.DEFAULT_DASHBOARD
assert child_1.media_content_type == lovelace_cast.DOMAIN
assert child_1.thumbnail == "https://brands.home-assistant.io/_/lovelace/logo.png"
@ -115,7 +116,7 @@ async def test_browse_media(hass, mock_yaml_dashboard, mock_https_url):
child_2 = top_level_items.children[1]
assert child_2.title == "YAML Title"
assert child_2.media_class == lovelace_cast.MEDIA_CLASS_APP
assert child_2.media_class == MediaClass.APP
assert child_2.media_content_id == "yaml-with-views"
assert child_2.media_content_type == lovelace_cast.DOMAIN
assert child_2.thumbnail == "https://brands.home-assistant.io/_/lovelace/logo.png"
@ -130,7 +131,7 @@ async def test_browse_media(hass, mock_yaml_dashboard, mock_https_url):
grandchild_1 = child_2.children[0]
assert grandchild_1.title == "Hello"
assert grandchild_1.media_class == lovelace_cast.MEDIA_CLASS_APP
assert grandchild_1.media_class == MediaClass.APP
assert grandchild_1.media_content_id == "yaml-with-views/0"
assert grandchild_1.media_content_type == lovelace_cast.DOMAIN
assert (
@ -141,7 +142,7 @@ async def test_browse_media(hass, mock_yaml_dashboard, mock_https_url):
grandchild_2 = child_2.children[1]
assert grandchild_2.title == "second-view"
assert grandchild_2.media_class == lovelace_cast.MEDIA_CLASS_APP
assert grandchild_2.media_class == MediaClass.APP
assert grandchild_2.media_content_id == "yaml-with-views/second-view"
assert grandchild_2.media_content_type == lovelace_cast.DOMAIN
assert (