From 50ffbb5bbd58bd5062b22b26cd2cbe41c9245270 Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Wed, 30 Sep 2026 01:48:38 +1000 Subject: [PATCH] Fix Teslemetry streaming media player state while driving (#183452) --- .../components/teslemetry/media_player.py | 19 ++++++-- .../teslemetry/test_media_player.py | 46 ++++++++++++++++++- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/teslemetry/media_player.py b/homeassistant/components/teslemetry/media_player.py index 9c73d05a1703..172a200cc3fb 100644 --- a/homeassistant/components/teslemetry/media_player.py +++ b/homeassistant/components/teslemetry/media_player.py @@ -192,6 +192,7 @@ class TeslemetryStreamingMediaEntity( self.scoped = Scope.VEHICLE_CMDS in scopes if not self.scoped: self._attr_supported_features = MediaPlayerEntityFeature(0) + self._playback_state: MediaPlayerState | None = None @override async def async_added_to_hass(self) -> None: @@ -283,13 +284,23 @@ class TeslemetryStreamingMediaEntity( def _async_handle_center_display(self, value: str | None) -> None: """Update entity attributes.""" - if value is not None: - self._attr_state = DISPLAY_STATES.get(value) - self.async_write_ha_state() + if value is None: + return + display_state = DISPLAY_STATES.get(value) + if display_state is MediaPlayerState.OFF: + self._attr_state = MediaPlayerState.OFF + elif self._playback_state is not None: + self._attr_state = self._playback_state + elif display_state is not None: + self._attr_state = display_state + self.async_write_ha_state() def _async_handle_media_playback_status(self, value: str | None) -> None: """Update entity attributes.""" - self._attr_state = MediaPlayerState.OFF if value is None else STATES.get(value) + self._playback_state = ( + MediaPlayerState.OFF if value is None else STATES.get(value) + ) + self._attr_state = self._playback_state self.async_write_ha_state() def _async_handle_media_playback_source(self, value: str | None) -> None: diff --git a/tests/components/teslemetry/test_media_player.py b/tests/components/teslemetry/test_media_player.py index 02fdfa93f4e5..e9ec1facef0b 100644 --- a/tests/components/teslemetry/test_media_player.py +++ b/tests/components/teslemetry/test_media_player.py @@ -17,7 +17,7 @@ from homeassistant.components.media_player import ( SERVICE_VOLUME_SET, MediaPlayerState, ) -from homeassistant.const import ATTR_ENTITY_ID, Platform +from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er @@ -252,3 +252,47 @@ async def test_update_streaming( # Ensure the restored state is the same as the previous state state = hass.states.get("media_player.test_media_player") assert state == snapshot(name="on") + + +@pytest.mark.parametrize( + "updates", + [ + pytest.param( + [ + ({Signal.MEDIA_PLAYBACK_STATUS: "Playing"}, MediaPlayerState.PLAYING), + ({Signal.CENTER_DISPLAY: "Driving"}, MediaPlayerState.PLAYING), + ({Signal.CENTER_DISPLAY: "On"}, MediaPlayerState.PLAYING), + ({Signal.CENTER_DISPLAY: "Off"}, MediaPlayerState.OFF), + ], + id="playback_known", + ), + pytest.param( + [ + ({Signal.CENTER_DISPLAY: "Driving"}, STATE_UNKNOWN), + ({Signal.CENTER_DISPLAY: "On"}, MediaPlayerState.IDLE), + ({Signal.CENTER_DISPLAY: "Off"}, MediaPlayerState.OFF), + ], + id="playback_unknown", + ), + ], +) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_streaming_center_display( + hass: HomeAssistant, + mock_add_listener: AsyncMock, + updates: list[tuple[dict[Signal, str], str]], +) -> None: + """Test center display changes do not override a known playback state.""" + + await setup_platform(hass, [Platform.MEDIA_PLAYER]) + + for data, expected in updates: + mock_add_listener.send( + { + "vin": VEHICLE_DATA_ALT["response"]["vin"], + "data": data, + "createdAt": "2024-10-04T10:45:17.537Z", + } + ) + await hass.async_block_till_done() + assert hass.states.get("media_player.test_media_player").state == expected