diff --git a/homeassistant/components/media_player/cast.py b/homeassistant/components/media_player/cast.py index 30d4bd166d0..632ab4214b8 100644 --- a/homeassistant/components/media_player/cast.py +++ b/homeassistant/components/media_player/cast.py @@ -288,8 +288,7 @@ class CastDevice(MediaPlayerDevice): self._chromecast = None # type: Optional[pychromecast.Chromecast] self.cast_status = None self.media_status = None - self.media_status_position = None - self.media_status_position_received = None + self.media_status_received = None self._available = False # type: bool self._status_listener = None # type: Optional[CastStatusListener] @@ -362,26 +361,10 @@ class CastDevice(MediaPlayerDevice): self._chromecast = None self.cast_status = None self.media_status = None - self.media_status_position = None - self.media_status_position_received = None + self.media_status_received = None self._status_listener.invalidate() self._status_listener = None - def update(self): - """Periodically update the properties. - - Even though we receive callbacks for most state changes, some 3rd party - apps don't always send them. Better poll every now and then if the - chromecast is active (i.e. an app is running). - """ - if not self._available: - # Not connected or not available. - return - - if self._chromecast.media_controller.is_active: - # We can only update status if the media namespace is active - self._chromecast.media_controller.update_status() - # ========== Callbacks ========== def new_cast_status(self, cast_status): """Handle updates of the cast status.""" @@ -390,36 +373,8 @@ class CastDevice(MediaPlayerDevice): def new_media_status(self, media_status): """Handle updates of the media status.""" - # Only use media position for playing/paused, - # and for normal playback rate - if (media_status is None or - abs(media_status.playback_rate - 1) > 0.01 or - not (media_status.player_is_playing or - media_status.player_is_paused)): - self.media_status_position = None - self.media_status_position_received = None - else: - # Avoid unnecessary state attribute updates if player_state and - # calculated position stay the same - now = dt_util.utcnow() - do_update = \ - (self.media_status is None or - self.media_status_position is None or - self.media_status.player_state != media_status.player_state) - if not do_update: - if media_status.player_is_playing: - elapsed = now - self.media_status_position_received - do_update = abs(media_status.current_time - - (self.media_status_position + - elapsed.total_seconds())) > 1 - else: - do_update = \ - self.media_status_position != media_status.current_time - if do_update: - self.media_status_position = media_status.current_time - self.media_status_position_received = now - self.media_status = media_status + self.media_status_received = dt_util.utcnow() self.schedule_update_ha_state() def new_connection_status(self, connection_status): @@ -496,8 +451,8 @@ class CastDevice(MediaPlayerDevice): # ========== Properties ========== @property def should_poll(self): - """Polling needed for cast integration, see async_update.""" - return True + """No polling needed.""" + return False @property def name(self): @@ -625,7 +580,12 @@ class CastDevice(MediaPlayerDevice): @property def media_position(self): """Position of current playing media in seconds.""" - return self.media_status_position + if self.media_status is None or \ + not (self.media_status.player_is_playing or + self.media_status.player_is_paused or + self.media_status.player_is_idle): + return None + return self.media_status.current_time @property def media_position_updated_at(self): @@ -633,7 +593,7 @@ class CastDevice(MediaPlayerDevice): Returns value from homeassistant.util.dt.utcnow(). """ - return self.media_status_position_received + return self.media_status_received @property def unique_id(self) -> Optional[str]: diff --git a/tests/components/media_player/test_cast.py b/tests/components/media_player/test_cast.py index 0c0f3906dc2..ee69ec1c85d 100644 --- a/tests/components/media_player/test_cast.py +++ b/tests/components/media_player/test_cast.py @@ -1,7 +1,6 @@ """The tests for the Cast Media player platform.""" # pylint: disable=protected-access import asyncio -import datetime as dt from typing import Optional from unittest.mock import patch, MagicMock, Mock from uuid import UUID @@ -15,8 +14,7 @@ from homeassistant.components.media_player.cast import ChromecastInfo from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.helpers.dispatcher import async_dispatcher_connect, \ async_dispatcher_send -from homeassistant.components.media_player import cast, \ - ATTR_MEDIA_POSITION, ATTR_MEDIA_POSITION_UPDATED_AT +from homeassistant.components.media_player import cast from homeassistant.setup import async_setup_component @@ -288,8 +286,6 @@ async def test_entity_media_states(hass: HomeAssistantType): assert entity.unique_id == full_info.uuid media_status = MagicMock(images=None) - media_status.current_time = 0 - media_status.playback_rate = 1 media_status.player_is_playing = True entity.new_media_status(media_status) await hass.async_block_till_done() @@ -324,85 +320,6 @@ async def test_entity_media_states(hass: HomeAssistantType): assert state.state == 'unknown' -async def test_entity_media_position(hass: HomeAssistantType): - """Test various entity media states.""" - info = get_fake_chromecast_info() - full_info = attr.evolve(info, model_name='google home', - friendly_name='Speaker', uuid=FakeUUID) - - with patch('pychromecast.dial.get_device_status', - return_value=full_info): - chromecast, entity = await async_setup_media_player_cast(hass, info) - - media_status = MagicMock(images=None) - media_status.current_time = 10 - media_status.playback_rate = 1 - media_status.player_is_playing = True - media_status.player_is_paused = False - media_status.player_is_idle = False - now = dt.datetime.now(dt.timezone.utc) - with patch('homeassistant.util.dt.utcnow', return_value=now): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 10 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now - - media_status.current_time = 15 - now_plus_5 = now + dt.timedelta(seconds=5) - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_5): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 10 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now - - media_status.current_time = 20 - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_5): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 20 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now_plus_5 - - media_status.current_time = 25 - now_plus_10 = now + dt.timedelta(seconds=10) - media_status.player_is_playing = False - media_status.player_is_paused = True - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_10): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 25 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now_plus_10 - - now_plus_15 = now + dt.timedelta(seconds=15) - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_15): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 25 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now_plus_10 - - media_status.current_time = 30 - now_plus_20 = now + dt.timedelta(seconds=20) - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_20): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert state.attributes[ATTR_MEDIA_POSITION] == 30 - assert state.attributes[ATTR_MEDIA_POSITION_UPDATED_AT] == now_plus_20 - - media_status.player_is_paused = False - media_status.player_is_idle = True - with patch('homeassistant.util.dt.utcnow', return_value=now_plus_20): - entity.new_media_status(media_status) - await hass.async_block_till_done() - state = hass.states.get('media_player.speaker') - assert ATTR_MEDIA_POSITION not in state.attributes - assert ATTR_MEDIA_POSITION_UPDATED_AT not in state.attributes - - async def test_switched_host(hass: HomeAssistantType): """Test cast device listens for changed hosts and disconnects old cast.""" info = get_fake_chromecast_info()