From d009f06a55ae1e8761ae6522ac67b9806ac79a1b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 24 Jun 2021 19:31:44 -1000 Subject: [PATCH] Handle connection being closed in legacy samsungtv (#52137) * Handle connection being closed in legacy samsungtv - Mirror the websocket behavior Fixes ``` 2021-06-24 02:54:13 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.89_guestroom fails Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 401, in async_update_ha_state await self.async_device_update() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 609, in async_device_update raise exc File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/usr/src/homeassistant/homeassistant/components/samsungtv/media_player.py", line 124, in update self._state = STATE_ON if self._bridge.is_on() else STATE_OFF File "/usr/src/homeassistant/homeassistant/components/samsungtv/bridge.py", line 113, in is_on return self._get_remote() is not None File "/usr/src/homeassistant/homeassistant/components/samsungtv/bridge.py", line 232, in _get_remote self._remote = Remote(self.config.copy()) File "/usr/local/lib/python3.8/site-packages/samsungctl/remote.py", line 9, in __init__ self.remote = RemoteLegacy(config) File "/usr/local/lib/python3.8/site-packages/samsungctl/remote_legacy.py", line 32, in __init__ self._read_response(True) File "/usr/local/lib/python3.8/site-packages/samsungctl/remote_legacy.py", line 77, in _read_response raise exceptions.ConnectionClosed() samsungctl.exceptions.ConnectionClosed ``` * add coverage * pass instead --- homeassistant/components/samsungtv/bridge.py | 2 ++ .../components/samsungtv/test_media_player.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index e1d3f042a45..1cdd63acd3c 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -234,6 +234,8 @@ class SamsungTVLegacyBridge(SamsungTVBridge): except AccessDenied: self._notify_callback() raise + except (ConnectionClosed, OSError): + pass return self._remote def _send_key(self, key): diff --git a/tests/components/samsungtv/test_media_player.py b/tests/components/samsungtv/test_media_player.py index 2e87f67d4e6..de9183915a2 100644 --- a/tests/components/samsungtv/test_media_player.py +++ b/tests/components/samsungtv/test_media_player.py @@ -340,6 +340,32 @@ async def test_update_unhandled_response(hass, remote, mock_now): assert state.state == STATE_ON +async def test_connection_closed_during_update_can_recover(hass, remote, mock_now): + """Testing update tv connection closed exception can recover.""" + await setup_samsungtv(hass, MOCK_CONFIG) + + with patch( + "homeassistant.components.samsungtv.bridge.Remote", + side_effect=[exceptions.ConnectionClosed(), DEFAULT_MOCK], + ): + + 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 + + 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 + + async def test_send_key(hass, remote): """Test for send key.""" await setup_samsungtv(hass, MOCK_CONFIG)