Ensure screenlogic retries if the protocol adapter is still booting (#133444)

* Ensure screenlogic retries if the protocol adapter is still booting

If the protocol adapter is still booting, it will disconnect and never
retry

```
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 640, in __async_setup_with_context
    result = await component.async_setup_entry(hass, self)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/screenlogic/__init__.py", line 65, in async_setup_entry
    await gateway.async_connect(**connect_info)
  File "/usr/local/lib/python3.13/site-packages/screenlogicpy/gateway.py", line 142, in async_connect
    connectPkg = await async_connect_to_gateway(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<4 lines>...
    )
    ^
  File "/usr/local/lib/python3.13/site-packages/screenlogicpy/requests/login.py", line 107, in async_connect_to_gateway
    mac_address = await async_gateway_connect(transport, protocol, max_retries)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/screenlogicpy/requests/login.py", line 77, in async_gateway_connect
    raise ScreenLogicConnectionError("Host unexpectedly disconnected.")
screenlogicpy.const.common.ScreenLogicConnectionError: Host unexpectedly disconnected.
```

* coverage
pull/133096/head^2
J. Nick Koston 2024-12-17 18:57:43 -07:00 committed by GitHub
parent e73512e11c
commit 9bff9c5e7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import logging
from typing import Any
from screenlogicpy import ScreenLogicError, ScreenLogicGateway
from screenlogicpy.const.common import ScreenLogicConnectionError
from screenlogicpy.const.data import SHARED_VALUES
from homeassistant.config_entries import ConfigEntry
@ -64,7 +65,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ScreenLogicConfigEntry)
try:
await gateway.async_connect(**connect_info)
await gateway.async_update()
except ScreenLogicError as ex:
except (ScreenLogicConnectionError, ScreenLogicError) as ex:
raise ConfigEntryNotReady(ex.msg) from ex
coordinator = ScreenlogicDataUpdateCoordinator(

View File

@ -4,12 +4,14 @@ from dataclasses import dataclass
from unittest.mock import DEFAULT, patch
import pytest
from screenlogicpy import ScreenLogicGateway
from screenlogicpy import ScreenLogicError, ScreenLogicGateway
from screenlogicpy.const.common import ScreenLogicConnectionError
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN
from homeassistant.components.screenlogic import DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.util import slugify
@ -284,3 +286,35 @@ async def test_platform_setup(
for entity_id in tested_entity_ids:
assert hass.states.get(entity_id) is not None
@pytest.mark.parametrize(
"exception",
[ScreenLogicConnectionError, ScreenLogicError],
)
async def test_retry_on_connect_exception(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, exception: Exception
) -> None:
"""Test setup retries on expected exceptions."""
def stub_connect(*args, **kwargs):
raise exception
mock_config_entry.add_to_hass(hass)
with (
patch(
GATEWAY_DISCOVERY_IMPORT_PATH,
return_value={},
),
patch.multiple(
ScreenLogicGateway,
async_connect=stub_connect,
is_connected=False,
_async_connected_request=DEFAULT,
),
):
assert not await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY