diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 8f7981a8d55..68b6574c388 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -204,13 +204,19 @@ class SamsungTVDevice(MediaPlayerEntity): ) if self._attr_state != STATE_ON: + if self._dmr_device and self._dmr_device.is_subscribed: + await self._dmr_device.async_unsubscribe_services() return - startup_tasks: list[Coroutine[Any, Any, None]] = [] + startup_tasks: list[Coroutine[Any, Any, Any]] = [] if not self._app_list_event.is_set(): startup_tasks.append(self._async_startup_app_list()) + if self._dmr_device and not self._dmr_device.is_subscribed: + startup_tasks.append( + self._dmr_device.async_subscribe_services(auto_resubscribe=True) + ) if not self._dmr_device and self._ssdp_rendering_control_location: startup_tasks.append(self._async_startup_dmr()) diff --git a/tests/components/samsungtv/conftest.py b/tests/components/samsungtv/conftest.py index 0f3bc53905a..d7f8ed0d1a1 100644 --- a/tests/components/samsungtv/conftest.py +++ b/tests/components/samsungtv/conftest.py @@ -101,12 +101,27 @@ async def dmr_device_fixture(upnp_device: Mock) -> Mock: dmr_device.volume_level = 0.44 dmr_device.is_volume_muted = False dmr_device.on_event = None + dmr_device.is_subscribed = False def _raise_event(service, state_variables): if dmr_device.on_event: dmr_device.on_event(service, state_variables) dmr_device.raise_event = _raise_event + + def _async_subscribe_services(auto_resubscribe: bool = False): + dmr_device.is_subscribed = True + + dmr_device.async_subscribe_services = AsyncMock( + side_effect=_async_subscribe_services + ) + + def _async_unsubscribe_services(): + dmr_device.is_subscribed = False + + dmr_device.async_unsubscribe_services = AsyncMock( + side_effect=_async_unsubscribe_services + ) yield dmr_device diff --git a/tests/components/samsungtv/test_media_player.py b/tests/components/samsungtv/test_media_player.py index 5d0ea5e6be0..e8407a86a3e 100644 --- a/tests/components/samsungtv/test_media_player.py +++ b/tests/components/samsungtv/test_media_player.py @@ -1469,3 +1469,39 @@ async def test_upnp_subscribe_events_upnpresponseerror( upnp_notify_server.async_stop_server.assert_not_called() assert "Device rejected subscription" in caplog.text + + +@pytest.mark.usefixtures("rest_api", "upnp_notify_server") +async def test_upnp_re_subscribe_events( + hass: HomeAssistant, remotews: Mock, dmr_device: Mock, mock_now: datetime +) -> None: + """Test for Upnp event feedback.""" + await setup_samsungtv_entry(hass, MOCK_ENTRY_WS) + + state = hass.states.get(ENTITY_ID) + assert state.state == STATE_ON + assert dmr_device.async_subscribe_services.call_count == 1 + assert dmr_device.async_unsubscribe_services.call_count == 0 + + with patch.object( + remotews, "start_listening", side_effect=WebSocketException("Boom") + ), patch.object(remotews, "is_alive", return_value=False): + next_update = mock_now + timedelta(minutes=5) + with patch("homeassistant.util.dt.utcnow", return_value=next_update): + async_fire_time_changed(hass, next_update) + await hass.async_block_till_done() + + state = hass.states.get(ENTITY_ID) + assert state.state == STATE_OFF + assert dmr_device.async_subscribe_services.call_count == 1 + assert dmr_device.async_unsubscribe_services.call_count == 1 + + next_update = mock_now + timedelta(minutes=10) + with patch("homeassistant.util.dt.utcnow", return_value=next_update): + async_fire_time_changed(hass, next_update) + await hass.async_block_till_done() + + state = hass.states.get(ENTITY_ID) + assert state.state == STATE_ON + assert dmr_device.async_subscribe_services.call_count == 2 + assert dmr_device.async_unsubscribe_services.call_count == 1