Skip to content

Commit badc6cb

Browse files
authored
refactor: Added connection retry when network is not ready (#80)
- Added connection retry when network is not ready - Use old connection configuration for reconnection
1 parent 3b6ce1d commit badc6cb

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

intg-appletv/tv.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
BACKOFF_SEC = 2
6969
ARTWORK_WIDTH = 400
7070
ARTWORK_HEIGHT = 400
71+
ERROR_OS_WAIT = 0.5
7172

7273
# pylint: disable=too-many-lines
7374

@@ -199,6 +200,7 @@ def __init__(
199200
self._playback_state = PlaybackState.NORMAL
200201
self._output_devices_volume: dict[str, float] = {}
201202
self._volume_level: float = 0.0
203+
self._apple_tv_conf: pyatv.interface.BaseConfig | None = None
202204

203205
@property
204206
def device_config(self) -> AtvDevice:
@@ -456,8 +458,11 @@ async def _connect_loop(self) -> None:
456458

457459
async def _connect_once(self) -> None:
458460
try:
459-
if conf := await self._find_atv():
460-
await self._connect(conf)
461+
# Reuse the latest AppleTV instance (Mac and IP) if defined to avoid a scan
462+
if self._apple_tv_conf is None:
463+
self._apple_tv_conf = await self._find_atv()
464+
if self._apple_tv_conf:
465+
await self._connect(self._apple_tv_conf)
461466
except pyatv.exceptions.AuthenticationError:
462467
_LOG.warning("[%s] Could not connect: auth error", self.log_id)
463468
await self.disconnect()
@@ -466,7 +471,22 @@ async def _connect_once(self) -> None:
466471
pass
467472
except Exception as err: # pylint: disable=broad-exception-caught
468473
_LOG.warning("[%s] Could not connect: %s", self.log_id, err)
469-
self._atv = None
474+
# OSError(101, 'Network is unreachable') or 10065 for Windows
475+
if err.__cause__ and isinstance(err.__cause__, OSError) and err.__cause__.errno in [101, 10065]:
476+
_LOG.warning("[%s] Network may not be ready yet %s : retry", self.log_id, err)
477+
await asyncio.sleep(ERROR_OS_WAIT)
478+
try:
479+
if self._apple_tv_conf is None:
480+
self._apple_tv_conf = await self._find_atv()
481+
if self._apple_tv_conf:
482+
await self._connect(self._apple_tv_conf)
483+
except Exception as err2: # pylint: disable=broad-exception-caught
484+
_LOG.warning("[%s] Could not connect: %s", self.log_id, err2)
485+
self._atv = None
486+
else:
487+
# Reset AppleTV configuration in case this is the wrong conf (changed Mac or IP)
488+
self._apple_tv_conf = None
489+
self._atv = None
470490

471491
async def _connect(self, conf: pyatv.interface.BaseConfig) -> None:
472492
# We try to connect with all the protocols.

0 commit comments

Comments
 (0)