Improve Roku (#34431)

This commit is contained in:
Chris Talkington 2020-04-21 23:06:23 -05:00 committed by GitHub
parent 7f77e99e4d
commit 6dd836589c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 27 deletions

View File

@ -10,7 +10,6 @@ from roku import RokuException
from homeassistant.components.media_player import MediaPlayerDevice
from homeassistant.components.media_player.const import (
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_MOVIE,
SUPPORT_NEXT_TRACK,
SUPPORT_PLAY,
SUPPORT_PLAY_MEDIA,
@ -66,12 +65,7 @@ class RokuDevice(MediaPlayerDevice):
self._power_state = self.roku.power_state
self.ip_address = self.roku.host
self.channels = self.get_source_list()
if self.roku.current_app is not None:
self.current_app = self.roku.current_app
else:
self.current_app = None
self.current_app = self.roku.current_app
self._available = True
except (RequestsConnectionError, RequestsReadTimeout, RokuException):
self._available = False
@ -90,6 +84,7 @@ class RokuDevice(MediaPlayerDevice):
"""Return the name of the device."""
if self._device_info.user_device_name:
return self._device_info.user_device_name
return f"Roku {self._device_info.serial_num}"
@property
@ -103,8 +98,10 @@ class RokuDevice(MediaPlayerDevice):
if self.current_app.name == "Power Saver" or self.current_app.is_screensaver:
return STATE_IDLE
if self.current_app.name == "Roku":
return STATE_HOME
if self.current_app.name is not None:
return STATE_PLAYING
@ -139,23 +136,17 @@ class RokuDevice(MediaPlayerDevice):
@property
def media_content_type(self):
"""Content type of current playing media."""
if self.current_app is None:
if self.current_app is None or self.current_app.name in ("Power Saver", "Roku"):
return None
if self.current_app.name == "Power Saver":
return None
if self.current_app.name == "Roku":
return None
return MEDIA_TYPE_MOVIE
return MEDIA_TYPE_CHANNEL
@property
def media_image_url(self):
"""Image url of current playing media."""
if self.current_app is None:
return None
if self.current_app.name == "Roku":
return None
if self.current_app.name == "Power Saver":
if self.current_app is None or self.current_app.name in ("Power Saver", "Roku"):
return None
if self.current_app.id is None:
return None
@ -233,14 +224,17 @@ class RokuDevice(MediaPlayerDevice):
MEDIA_TYPE_CHANNEL,
)
return
if self.current_app is not None:
self.roku.launch(self.roku["tvinput.dtv"], {"ch": media_id})
def select_source(self, source):
"""Select input source."""
if self.current_app is not None:
if source == "Home":
self.roku.home()
else:
channel = self.roku[source]
channel.launch()
if self.current_app is None:
return
if source == "Home":
self.roku.home()
else:
channel = self.roku[source]
channel.launch()

View File

@ -1,6 +1,13 @@
"""Tests for the Roku Media Player platform."""
from datetime import timedelta
from asynctest import PropertyMock, patch
from requests.exceptions import (
ConnectionError as RequestsConnectionError,
ReadTimeout as RequestsReadTimeout,
)
from requests_mock import Mocker
from roku import RokuException
from homeassistant.components.media_player.const import (
ATTR_INPUT_SOURCE,
@ -9,7 +16,6 @@ from homeassistant.components.media_player.const import (
ATTR_MEDIA_VOLUME_MUTED,
DOMAIN as MP_DOMAIN,
MEDIA_TYPE_CHANNEL,
MEDIA_TYPE_MOVIE,
SERVICE_PLAY_MEDIA,
SERVICE_SELECT_SOURCE,
SUPPORT_NEXT_TRACK,
@ -32,11 +38,15 @@ from homeassistant.const import (
SERVICE_VOLUME_DOWN,
SERVICE_VOLUME_MUTE,
SERVICE_VOLUME_UP,
STATE_HOME,
STATE_PLAYING,
STATE_STANDBY,
STATE_UNAVAILABLE,
)
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
from tests.components.roku import UPNP_SERIAL, setup_integration
MAIN_ENTITY_ID = f"{MP_DOMAIN}.my_roku_3"
@ -87,6 +97,47 @@ async def test_tv_setup(hass: HomeAssistantType, requests_mock: Mocker) -> None:
assert tv.unique_id == TV_SERIAL
async def test_availability(hass: HomeAssistantType, requests_mock: Mocker) -> None:
"""Test entity availability."""
now = dt_util.utcnow()
future = now + timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=now):
await setup_integration(hass, requests_mock)
with patch("roku.Roku._get", side_effect=RokuException,), patch(
"homeassistant.util.dt.utcnow", return_value=future
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
future += timedelta(minutes=1)
with patch("roku.Roku._get", side_effect=RequestsConnectionError,), patch(
"homeassistant.util.dt.utcnow", return_value=future
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
future += timedelta(minutes=1)
with patch("roku.Roku._get", side_effect=RequestsReadTimeout,), patch(
"homeassistant.util.dt.utcnow", return_value=future
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
future += timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_HOME
async def test_supported_features(
hass: HomeAssistantType, requests_mock: Mocker
) -> None:
@ -142,7 +193,7 @@ async def test_attributes(hass: HomeAssistantType, requests_mock: Mocker) -> Non
await setup_integration(hass, requests_mock)
state = hass.states.get(MAIN_ENTITY_ID)
assert state.state == "home"
assert state.state == STATE_HOME
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Roku"
@ -162,7 +213,7 @@ async def test_tv_attributes(hass: HomeAssistantType, requests_mock: Mocker) ->
state = hass.states.get(TV_ENTITY_ID)
assert state.state == STATE_PLAYING
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_MOVIE
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_CHANNEL
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Antenna TV"