Support DirecTV music channels with extended meta (#34228)

This commit is contained in:
Chris Talkington 2020-04-15 20:08:54 -05:00 committed by GitHub
parent 446c7349ff
commit 1f4cdda234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 167 additions and 3 deletions

View File

@ -8,6 +8,7 @@ from homeassistant.components.media_player import MediaPlayerDevice
from homeassistant.components.media_player.const import (
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
SUPPORT_NEXT_TRACK,
SUPPORT_PAUSE,
@ -34,6 +35,8 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
KNOWN_MEDIA_TYPES = [MEDIA_TYPE_MOVIE, MEDIA_TYPE_MUSIC, MEDIA_TYPE_TVSHOW]
SUPPORT_DTV = (
SUPPORT_PAUSE
| SUPPORT_TURN_ON
@ -177,8 +180,7 @@ class DIRECTVMediaPlayer(DIRECTVEntity, MediaPlayerDevice):
if self._is_standby or self._program is None:
return None
known_types = [MEDIA_TYPE_MOVIE, MEDIA_TYPE_TVSHOW]
if self._program.program_type in known_types:
if self._program.program_type in KNOWN_MEDIA_TYPES:
return self._program.program_type
return MEDIA_TYPE_MOVIE
@ -213,8 +215,27 @@ class DIRECTVMediaPlayer(DIRECTVEntity, MediaPlayerDevice):
if self._is_standby or self._program is None:
return None
if self.media_content_type == MEDIA_TYPE_MUSIC:
return self._program.music_title
return self._program.title
@property
def media_artist(self):
"""Artist of current playing media, music track only."""
if self._is_standby or self._program is None:
return None
return self._program.music_artist
@property
def media_album_name(self):
"""Album name of current playing media, music track only."""
if self._is_standby or self._program is None:
return None
return self._program.music_album
@property
def media_series_title(self):
"""Return the title of current episode of TV show."""

View File

@ -1,7 +1,7 @@
"""Tests for the DirecTV component."""
from homeassistant.components.directv.const import CONF_RECEIVER_ID, DOMAIN
from homeassistant.components.ssdp import ATTR_SSDP_LOCATION
from homeassistant.const import CONF_HOST, HTTP_INTERNAL_SERVER_ERROR
from homeassistant.const import CONF_HOST, HTTP_FORBIDDEN, HTTP_INTERNAL_SERVER_ERROR
from homeassistant.helpers.typing import HomeAssistantType
from tests.common import MockConfigEntry, load_fixture
@ -31,6 +31,13 @@ def mock_connection(aioclient_mock: AiohttpClientMocker) -> None:
headers={"Content-Type": "application/json"},
)
aioclient_mock.get(
f"http://{HOST}:8080/info/mode",
params={"clientAddr": "B01234567890"},
text=load_fixture("directv/info-mode-standby.json"),
headers={"Content-Type": "application/json"},
)
aioclient_mock.get(
f"http://{HOST}:8080/info/mode",
params={"clientAddr": "9XXXXXXXXXX9"},
@ -64,6 +71,21 @@ def mock_connection(aioclient_mock: AiohttpClientMocker) -> None:
headers={"Content-Type": "application/json"},
)
aioclient_mock.get(
f"http://{HOST}:8080/tv/getTuned",
params={"clientAddr": "A01234567890"},
text=load_fixture("directv/tv-get-tuned-music.json"),
headers={"Content-Type": "application/json"},
)
aioclient_mock.get(
f"http://{HOST}:8080/tv/getTuned",
params={"clientAddr": "C01234567890"},
status=HTTP_FORBIDDEN,
text=load_fixture("directv/tv-get-tuned-restricted.json"),
headers={"Content-Type": "application/json"},
)
aioclient_mock.get(
f"http://{HOST}:8080/tv/getTuned",
text=load_fixture("directv/tv-get-tuned-movie.json"),

View File

@ -13,6 +13,8 @@ from homeassistant.components.directv.media_player import (
)
from homeassistant.components.media_player.const import (
ATTR_INPUT_SOURCE,
ATTR_MEDIA_ALBUM_NAME,
ATTR_MEDIA_ARTIST,
ATTR_MEDIA_CHANNEL,
ATTR_MEDIA_CONTENT_ID,
ATTR_MEDIA_CONTENT_TYPE,
@ -24,6 +26,7 @@ from homeassistant.components.media_player.const import (
ATTR_MEDIA_TITLE,
DOMAIN as MP_DOMAIN,
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_TVSHOW,
SERVICE_PLAY_MEDIA,
SUPPORT_NEXT_TRACK,
@ -44,6 +47,7 @@ from homeassistant.const import (
SERVICE_MEDIA_STOP,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_PAUSED,
STATE_PLAYING,
STATE_UNAVAILABLE,
@ -57,6 +61,9 @@ from tests.test_util.aiohttp import AiohttpClientMocker
ATTR_UNIQUE_ID = "unique_id"
CLIENT_ENTITY_ID = f"{MP_DOMAIN}.client"
MAIN_ENTITY_ID = f"{MP_DOMAIN}.host"
MUSIC_ENTITY_ID = f"{MP_DOMAIN}.music_client"
RESTRICTED_ENTITY_ID = f"{MP_DOMAIN}.restricted_client"
STANDBY_ENTITY_ID = f"{MP_DOMAIN}.standby_client"
UNAVAILABLE_ENTITY_ID = f"{MP_DOMAIN}.unavailable_client"
# pylint: disable=redefined-outer-name
@ -250,6 +257,63 @@ async def test_check_attributes(
2010, 7, 5, 15, 0, 8, tzinfo=dt_util.UTC
)
state = hass.states.get(MUSIC_ENTITY_ID)
assert state.state == STATE_PLAYING
assert state.attributes.get(ATTR_MEDIA_CONTENT_ID) == "76917562"
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_MUSIC
assert state.attributes.get(ATTR_MEDIA_DURATION) == 86400
assert state.attributes.get(ATTR_MEDIA_POSITION) == 15050
assert state.attributes.get(ATTR_MEDIA_POSITION_UPDATED_AT)
assert state.attributes.get(ATTR_MEDIA_TITLE) == "Sparkle In Your Eyes"
assert state.attributes.get(ATTR_MEDIA_ARTIST) == "Gerald Albright"
assert state.attributes.get(ATTR_MEDIA_ALBUM_NAME) == "Slam Dunk (2014)"
assert state.attributes.get(ATTR_MEDIA_SERIES_TITLE) is None
assert state.attributes.get(ATTR_MEDIA_CHANNEL) == "{} ({})".format("MCSJ", "851")
assert state.attributes.get(ATTR_INPUT_SOURCE) == "851"
assert not state.attributes.get(ATTR_MEDIA_CURRENTLY_RECORDING)
assert state.attributes.get(ATTR_MEDIA_RATING) == "TV-PG"
assert not state.attributes.get(ATTR_MEDIA_RECORDED)
assert state.attributes.get(ATTR_MEDIA_START_TIME) == datetime(
2020, 3, 21, 10, 0, 0, tzinfo=dt_util.UTC
)
state = hass.states.get(STANDBY_ENTITY_ID)
assert state.state == STATE_OFF
assert state.attributes.get(ATTR_MEDIA_CONTENT_ID) is None
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None
assert state.attributes.get(ATTR_MEDIA_DURATION) is None
assert state.attributes.get(ATTR_MEDIA_POSITION) is None
assert state.attributes.get(ATTR_MEDIA_POSITION_UPDATED_AT) is None
assert state.attributes.get(ATTR_MEDIA_TITLE) is None
assert state.attributes.get(ATTR_MEDIA_ARTIST) is None
assert state.attributes.get(ATTR_MEDIA_ALBUM_NAME) is None
assert state.attributes.get(ATTR_MEDIA_SERIES_TITLE) is None
assert state.attributes.get(ATTR_MEDIA_CHANNEL) is None
assert state.attributes.get(ATTR_INPUT_SOURCE) is None
assert not state.attributes.get(ATTR_MEDIA_CURRENTLY_RECORDING)
assert state.attributes.get(ATTR_MEDIA_RATING) is None
assert not state.attributes.get(ATTR_MEDIA_RECORDED)
state = hass.states.get(RESTRICTED_ENTITY_ID)
assert state.state == STATE_PLAYING
assert state.attributes.get(ATTR_MEDIA_CONTENT_ID) is None
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None
assert state.attributes.get(ATTR_MEDIA_DURATION) is None
assert state.attributes.get(ATTR_MEDIA_POSITION) is None
assert state.attributes.get(ATTR_MEDIA_POSITION_UPDATED_AT) is None
assert state.attributes.get(ATTR_MEDIA_TITLE) is None
assert state.attributes.get(ATTR_MEDIA_ARTIST) is None
assert state.attributes.get(ATTR_MEDIA_ALBUM_NAME) is None
assert state.attributes.get(ATTR_MEDIA_SERIES_TITLE) is None
assert state.attributes.get(ATTR_MEDIA_CHANNEL) is None
assert state.attributes.get(ATTR_INPUT_SOURCE) is None
assert not state.attributes.get(ATTR_MEDIA_CURRENTLY_RECORDING)
assert state.attributes.get(ATTR_MEDIA_RATING) is None
assert not state.attributes.get(ATTR_MEDIA_RECORDED)
state = hass.states.get(UNAVAILABLE_ENTITY_ID)
assert state.state == STATE_UNAVAILABLE

View File

@ -8,6 +8,18 @@
"clientAddr": "2CA17D1CD30X",
"locationName": "Client"
},
{
"clientAddr": "A01234567890",
"locationName": "Music Client"
},
{
"clientAddr": "B01234567890",
"locationName": "Standby Client"
},
{
"clientAddr": "C01234567890",
"locationName": "Restricted Client"
},
{
"clientAddr": "9XXXXXXXXXX9",
"locationName": "Unavailable Client"

View File

@ -0,0 +1,9 @@
{
"mode": 1,
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK",
"query": "/info/mode"
}
}

View File

@ -0,0 +1,28 @@
{
"callsign": "MCSJ",
"duration": 86400,
"isOffAir": false,
"isPclocked": 3,
"isPpv": false,
"isRecording": false,
"isVod": false,
"major": 851,
"minor": 65535,
"music": {
"by": "Gerald Albright",
"cd": "Slam Dunk (2014)",
"title": "Sparkle In Your Eyes"
},
"offset": 15050,
"programId": "76917562",
"rating": "TV-PG",
"startTime": 1584784800,
"stationId": 2872196,
"status": {
"code": 200,
"commandResult": 0,
"msg": "OK.",
"query": "/tv/getTuned"
},
"title": "Smooth Jazz"
}

View File

@ -0,0 +1,8 @@
{
"status": {
"code": 403,
"commandResult": 1,
"msg": "Forbidden.",
"query": "/tv/getTuned"
}
}