Fix reauth trigger in SamsungTV (#67850)

Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
epenet 2022-03-08 11:02:00 +01:00 committed by GitHub
parent 2d4d18ab90
commit d12118a425
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 22 deletions

View file

@ -14,7 +14,7 @@ from samsungtvws.async_rest import SamsungTVAsyncRest
from samsungtvws.command import SamsungTVCommand from samsungtvws.command import SamsungTVCommand
from samsungtvws.exceptions import ConnectionFailure, HttpApiError from samsungtvws.exceptions import ConnectionFailure, HttpApiError
from samsungtvws.remote import ChannelEmitCommand, SendRemoteKey from samsungtvws.remote import ChannelEmitCommand, SendRemoteKey
from websockets.exceptions import WebSocketException from websockets.exceptions import ConnectionClosedError, WebSocketException
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_HOST,
@ -461,15 +461,24 @@ class SamsungTVWSBridge(SamsungTVBridge):
) )
try: try:
await self._remote.start_listening() await self._remote.start_listening()
except ConnectionClosedError as err:
# This is only happening when the auth was switched to DENY # This is only happening when the auth was switched to DENY
# A removed auth will lead to socket timeout because waiting for auth popup is just an open socket # A removed auth will lead to socket timeout because waiting
except ConnectionFailure as err: # for auth popup is just an open socket
LOGGER.info( LOGGER.info(
"Failed to get remote for %s, re-authentication required: %s", "Failed to get remote for %s, re-authentication required: %s",
self.host, self.host,
err.__repr__(), err.__repr__(),
) )
self._notify_reauth_callback() self._notify_reauth_callback()
except ConnectionFailure as err:
LOGGER.warning(
"Unexpected ConnectionFailure trying to get remote for %s, "
"please report this issue: %s",
self.host,
err.__repr__(),
)
self._remote = None
except (WebSocketException, AsyncioTimeoutError, OSError) as err: except (WebSocketException, AsyncioTimeoutError, OSError) as err:
LOGGER.debug( LOGGER.debug(
"Failed to get remote for %s: %s", self.host, err.__repr__() "Failed to get remote for %s: %s", self.host, err.__repr__()

View file

@ -10,7 +10,7 @@ from samsungtvws.async_remote import SamsungTVWSAsyncRemote
from samsungtvws.command import SamsungTVSleepCommand from samsungtvws.command import SamsungTVSleepCommand
from samsungtvws.exceptions import ConnectionFailure, HttpApiError from samsungtvws.exceptions import ConnectionFailure, HttpApiError
from samsungtvws.remote import ChannelEmitCommand, SendRemoteKey from samsungtvws.remote import ChannelEmitCommand, SendRemoteKey
from websockets.exceptions import WebSocketException from websockets.exceptions import ConnectionClosedError, WebSocketException
from homeassistant.components.media_player import MediaPlayerDeviceClass from homeassistant.components.media_player import MediaPlayerDeviceClass
from homeassistant.components.media_player.const import ( from homeassistant.components.media_player.const import (
@ -369,24 +369,45 @@ async def test_update_access_denied(hass: HomeAssistant, mock_now: datetime) ->
assert state.state == STATE_UNAVAILABLE assert state.state == STATE_UNAVAILABLE
async def test_update_connection_failure( async def test_update_ws_connection_failure(
hass: HomeAssistant, mock_now: datetime, remotews: Mock hass: HomeAssistant,
mock_now: datetime,
remotews: Mock,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Testing update tv connection failure exception.""" """Testing update tv connection failure exception."""
with patch(
"homeassistant.components.samsungtv.bridge.Remote",
side_effect=[OSError("Boom"), DEFAULT_MOCK],
):
await setup_samsungtv(hass, MOCK_CONFIGWS) await setup_samsungtv(hass, MOCK_CONFIGWS)
with patch.object( with patch.object(
remotews, "start_listening", side_effect=ConnectionFailure("Boom") remotews,
"start_listening",
side_effect=ConnectionFailure('{"event": "ms.voiceApp.hide"}'),
), patch.object(remotews, "is_alive", return_value=False): ), patch.object(remotews, "is_alive", return_value=False):
next_update = mock_now + timedelta(minutes=5) next_update = mock_now + timedelta(minutes=5)
with patch("homeassistant.util.dt.utcnow", return_value=next_update): with patch("homeassistant.util.dt.utcnow", return_value=next_update):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, next_update)
await hass.async_block_till_done() await hass.async_block_till_done()
next_update = mock_now + timedelta(minutes=10)
assert (
"Unexpected ConnectionFailure trying to get remote for fake_host, please "
'report this issue: ConnectionFailure(\'{"event": "ms.voiceApp.hide"}\')'
in caplog.text
)
state = hass.states.get(ENTITY_ID)
assert state.state == STATE_OFF
async def test_update_ws_connection_closed(
hass: HomeAssistant, mock_now: datetime, remotews: Mock
) -> None:
"""Testing update tv connection failure exception."""
await setup_samsungtv(hass, MOCK_CONFIGWS)
with patch.object(
remotews, "start_listening", side_effect=ConnectionClosedError(None, None)
), 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): with patch("homeassistant.util.dt.utcnow", return_value=next_update):
async_fire_time_changed(hass, next_update) async_fire_time_changed(hass, next_update)
await hass.async_block_till_done() await hass.async_block_till_done()