Fix upnp subscription in SamsungTV (#69652)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
epenet 2022-04-09 08:05:00 +02:00 committed by GitHub
parent 632d75e009
commit 071ef6c74f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 1 deletions

View File

@ -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())

View File

@ -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

View File

@ -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