mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 01:37:08 +00:00
Revert cast platform polling mode (#14027)
This commit is contained in:
parent
5d3471269a
commit
7f634c6ed0
@ -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]:
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user