1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-02 08:26:41 +01:00

Restore handling of is active input for chromecast (#164735)

This commit is contained in:
Joakim Plate
2026-03-04 13:10:10 +01:00
committed by GitHub
parent c4f64598a0
commit 25489c224b
2 changed files with 72 additions and 18 deletions

View File

@@ -804,8 +804,22 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
@property
def state(self) -> MediaPlayerState | None:
"""Return the state of the player."""
# The lovelace app loops media to prevent timing out, don't show that
if (chromecast := self._chromecast) is None or (
cast_status := self.cast_status
) is None:
# Not connected to any chromecast, or not yet got any status
return None
if (
chromecast.cast_type == pychromecast.const.CAST_TYPE_CHROMECAST
and not chromecast.ignore_cec
and cast_status.is_active_input is False
):
# The display interface for the device has been turned off or switched away
return MediaPlayerState.OFF
if self.app_id == CAST_APP_ID_HOMEASSISTANT_LOVELACE:
# The lovelace app loops media to prevent timing out, don't show that
return MediaPlayerState.PLAYING
if (media_status := self._media_status()[0]) is not None:
@@ -822,16 +836,12 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity):
# Some apps don't report media status, show the player as playing
return MediaPlayerState.PLAYING
if self.app_id is not None and self.app_id != pychromecast.config.APP_BACKDROP:
# We have an active app
return MediaPlayerState.IDLE
if self._chromecast is not None and self._chromecast.is_idle:
# If library consider us idle, that is our off state
# it takes HDMI status into account for cast devices.
if self.app_id in (pychromecast.IDLE_APP_ID, None):
# We have no active app or the home screen app. This is
# same app as APP_BACKDROP.
return MediaPlayerState.OFF
return None
return MediaPlayerState.IDLE
@property
def media_content_id(self) -> str | None:

View File

@@ -68,7 +68,7 @@ def get_fake_chromecast(info: ChromecastInfo):
mock = MagicMock(uuid=info.uuid)
mock.app_id = None
mock.media_controller.status = None
mock.is_idle = True
mock.ignore_cec = False
return mock
@@ -888,7 +888,6 @@ async def test_entity_cast_status(
assert not state.attributes.get("is_volume_muted")
chromecast.app_id = "1234"
chromecast.is_idle = False
cast_status = MagicMock()
cast_status.volume_level = 0.5
cast_status.volume_muted = False
@@ -1601,7 +1600,6 @@ async def test_entity_media_states(
# App id updated, but no media status
chromecast.app_id = app_id
chromecast.is_idle = False
cast_status = MagicMock()
cast_status_cb(cast_status)
await hass.async_block_till_done()
@@ -1644,7 +1642,6 @@ async def test_entity_media_states(
# App no longer running
chromecast.app_id = pychromecast.IDLE_APP_ID
chromecast.is_idle = True
cast_status = MagicMock()
cast_status_cb(cast_status)
await hass.async_block_till_done()
@@ -1653,7 +1650,6 @@ async def test_entity_media_states(
# No cast status
chromecast.app_id = None
chromecast.is_idle = False
cast_status_cb(None)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
@@ -1721,20 +1717,70 @@ async def test_entity_media_states_lovelace_app(
chromecast.app_id = pychromecast.IDLE_APP_ID
media_status.player_is_idle = False
chromecast.is_idle = True
media_status_cb(media_status)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == "off"
chromecast.app_id = None
chromecast.is_idle = False
cast_status_cb(None)
media_status_cb(media_status)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == "unknown"
async def test_entity_media_states_active_input(
hass: HomeAssistant, entity_registry: er.EntityRegistry
) -> None:
"""Test various entity media states when the lovelace app is active."""
entity_id = "media_player.speaker"
info = get_fake_chromecast_info()
chromecast, _ = await async_setup_media_player_cast(hass, info)
chromecast.cast_type = pychromecast.const.CAST_TYPE_CHROMECAST
cast_status_cb, conn_status_cb, _ = get_status_callbacks(chromecast)
chromecast.app_id = "84912283"
cast_status = MagicMock()
connection_status = MagicMock()
connection_status.status = "CONNECTED"
conn_status_cb(connection_status)
await hass.async_block_till_done()
# Unknown input status
cast_status.is_active_input = None
cast_status_cb(cast_status)
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "idle"
# Active input status
cast_status.is_active_input = True
cast_status_cb(cast_status)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == "idle"
# Inactive input status
cast_status.is_active_input = False
cast_status_cb(cast_status)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "off"
# Inactive input status, but ignored
chromecast.ignore_cec = True
cast_status_cb(cast_status)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "idle"
async def test_group_media_states(
hass: HomeAssistant, entity_registry: er.EntityRegistry, mz_mock
) -> None:
@@ -2404,7 +2450,6 @@ async def test_entity_media_states_active_app_reported_idle(
# Scenario: Custom App is running (e.g. DashCast), but device reports is_idle=True
chromecast.app_id = "84912283" # Example Custom App ID
chromecast.is_idle = True # Device thinks it's idle/standby
# Trigger a status update
cast_status = MagicMock()
@@ -2417,7 +2462,6 @@ async def test_entity_media_states_active_app_reported_idle(
# Scenario: Backdrop (Screensaver) is running. Should still be OFF.
chromecast.app_id = pychromecast.config.APP_BACKDROP
chromecast.is_idle = True
cast_status_cb(cast_status)
await hass.async_block_till_done()