diff --git a/homeassistant/components/cast/media_player.py b/homeassistant/components/cast/media_player.py index 837284ab546..e63fedd3598 100644 --- a/homeassistant/components/cast/media_player.py +++ b/homeassistant/components/cast/media_player.py @@ -10,7 +10,12 @@ import logging import pychromecast from pychromecast.controllers.homeassistant import HomeAssistantController -from pychromecast.controllers.media import MEDIA_PLAYER_ERROR_CODES +from pychromecast.controllers.media import ( + MEDIA_PLAYER_ERROR_CODES, + MEDIA_PLAYER_STATE_BUFFERING, + MEDIA_PLAYER_STATE_PLAYING, + MEDIA_PLAYER_STATE_UNKNOWN, +) from pychromecast.controllers.multizone import MultizoneManager from pychromecast.controllers.receiver import VOLUME_CONTROL_TYPE_FIXED from pychromecast.quick_play import quick_play @@ -40,6 +45,7 @@ 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, @@ -453,10 +459,13 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity): media_status = self.media_status media_controller = self._chromecast.media_controller - if media_status is None or media_status.player_state == "UNKNOWN": + if ( + media_status is None + or media_status.player_state == MEDIA_PLAYER_STATE_UNKNOWN + ): groups = self.mz_media_status for k, val in groups.items(): - if val and val.player_state != "UNKNOWN": + if val and val.player_state != MEDIA_PLAYER_STATE_UNKNOWN: media_controller = self.mz_mgr.get_multizone_mediacontroller(k) break @@ -716,10 +725,13 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity): media_status = self.media_status media_status_received = self.media_status_received - if media_status is None or media_status.player_state == "UNKNOWN": + if ( + media_status is None + or media_status.player_state == MEDIA_PLAYER_STATE_UNKNOWN + ): groups = self.mz_media_status for k, val in groups.items(): - if val and val.player_state != "UNKNOWN": + if val and val.player_state != MEDIA_PLAYER_STATE_UNKNOWN: media_status = val media_status_received = self.mz_media_status_received[k] break @@ -733,8 +745,10 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity): if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE: return STATE_PLAYING if (media_status := self._media_status()[0]) is not None: - if media_status.player_is_playing: + if media_status.player_state == MEDIA_PLAYER_STATE_PLAYING: return STATE_PLAYING + if media_status.player_state == MEDIA_PLAYER_STATE_BUFFERING: + return STATE_BUFFERING if media_status.player_is_paused: return STATE_PAUSED if media_status.player_is_idle: diff --git a/homeassistant/const.py b/homeassistant/const.py index b2654da367a..ffe5825bf89 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -323,6 +323,7 @@ STATE_OPEN: Final = "open" STATE_OPENING: Final = "opening" STATE_CLOSED: Final = "closed" STATE_CLOSING: Final = "closing" +STATE_BUFFERING: Final = "buffering" STATE_PLAYING: Final = "playing" STATE_PAUSED: Final = "paused" STATE_IDLE: Final = "idle" diff --git a/tests/components/cast/test_media_player.py b/tests/components/cast/test_media_player.py index 063490e6e13..88cf281c8a5 100644 --- a/tests/components/cast/test_media_player.py +++ b/tests/components/cast/test_media_player.py @@ -1257,6 +1257,7 @@ async def test_entity_control(hass: HomeAssistant, quick_play_mock): # Fake media status media_status = MagicMock(images=None) + media_status.player_state = "PLAYING" media_status.supports_queue_next = False media_status.supports_seek = False media_status_cb(media_status) @@ -1397,13 +1398,19 @@ async def test_entity_media_states(hass: HomeAssistant, app_id, state_no_media): # Got media status media_status = MagicMock(images=None) - media_status.player_is_playing = True + media_status.player_state = "BUFFERING" + media_status_cb(media_status) + await hass.async_block_till_done() + state = hass.states.get(entity_id) + assert state.state == "buffering" + + media_status.player_state = "PLAYING" media_status_cb(media_status) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == "playing" - media_status.player_is_playing = False + media_status.player_state = None media_status.player_is_paused = True media_status_cb(media_status) await hass.async_block_till_done() @@ -1536,15 +1543,22 @@ async def test_group_media_states(hass, mz_mock): group_media_status = MagicMock(images=None) player_media_status = MagicMock(images=None) + # Player has no state, group is buffering -> Should report 'buffering' + group_media_status.player_state = "BUFFERING" + group_media_status_cb(str(FakeGroupUUID), group_media_status) + await hass.async_block_till_done() + state = hass.states.get(entity_id) + assert state.state == "buffering" + # Player has no state, group is playing -> Should report 'playing' - group_media_status.player_is_playing = True + group_media_status.player_state = "PLAYING" group_media_status_cb(str(FakeGroupUUID), group_media_status) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == "playing" # Player is paused, group is playing -> Should report 'paused' - player_media_status.player_is_playing = False + player_media_status.player_state = None player_media_status.player_is_paused = True media_status_cb(player_media_status) await hass.async_block_till_done()