mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Provide request retry option to overcome intermittant enphase_envoy failures (#168222)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -16,6 +16,9 @@ PLATFORMS = [
|
||||
|
||||
INVALID_AUTH_ERRORS = (EnvoyAuthenticationError, EnvoyAuthenticationRequired)
|
||||
|
||||
SETUP_RETRY_TIMEOUT = 50
|
||||
OPERATIONAL_RETRY_TIMEOUT = 200
|
||||
|
||||
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES = "diagnostics_include_fixtures"
|
||||
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES_DEFAULT_VALUE = False
|
||||
|
||||
|
||||
@@ -18,7 +18,12 @@ from homeassistant.helpers.event import async_call_later, async_track_time_inter
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import DOMAIN, INVALID_AUTH_ERRORS
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
INVALID_AUTH_ERRORS,
|
||||
OPERATIONAL_RETRY_TIMEOUT,
|
||||
SETUP_RETRY_TIMEOUT,
|
||||
)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
@@ -50,6 +55,7 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
self.username = entry_data[CONF_USERNAME]
|
||||
self.password = entry_data[CONF_PASSWORD]
|
||||
self._setup_complete = False
|
||||
self._operational_timeout = False
|
||||
self.envoy_firmware = ""
|
||||
self.interface = None
|
||||
self._cancel_token_refresh: CALLBACK_TYPE | None = None
|
||||
@@ -265,10 +271,15 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
try:
|
||||
if not self._setup_complete:
|
||||
_LOGGER.debug("update on try %s, setup not complete", tries)
|
||||
self.envoy.set_retry_policy(max_delay=SETUP_RETRY_TIMEOUT)
|
||||
self._operational_timeout = False
|
||||
await self._async_setup_and_authenticate()
|
||||
self._async_mark_setup_complete()
|
||||
# dump all received data in debug mode to assist troubleshooting
|
||||
envoy_data = await envoy.update()
|
||||
if not self._operational_timeout:
|
||||
self.envoy.set_retry_policy(max_delay=OPERATIONAL_RETRY_TIMEOUT)
|
||||
self._operational_timeout = True
|
||||
except INVALID_AUTH_ERRORS as err:
|
||||
_LOGGER.debug("update on try %s, INVALID_AUTH_ERRORS %s", tries, err)
|
||||
if self._setup_complete and tries == 0:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from jwt import encode
|
||||
@@ -13,8 +13,10 @@ import respx
|
||||
|
||||
from homeassistant.components.enphase_envoy import DOMAIN
|
||||
from homeassistant.components.enphase_envoy.const import (
|
||||
OPERATIONAL_RETRY_TIMEOUT,
|
||||
OPTION_DIAGNOSTICS_INCLUDE_FIXTURES,
|
||||
OPTION_DISABLE_KEEP_ALIVE,
|
||||
SETUP_RETRY_TIMEOUT,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.components.enphase_envoy.coordinator import (
|
||||
@@ -627,3 +629,42 @@ async def test_coordinator_interface_information_mac_also_in_other_device(
|
||||
"00:11:22:33:44:55",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2024-07-23 00:00:00+00:00")
|
||||
async def test_retry_timeout_settings(
|
||||
hass: HomeAssistant,
|
||||
mock_envoy: AsyncMock,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test coordinator with token provided from config."""
|
||||
token = encode(
|
||||
payload={"name": "envoy", "exp": 1907837780},
|
||||
key="secret",
|
||||
algorithm="HS256",
|
||||
)
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="45a36e55aaddb2007c5f6602e0c38e72",
|
||||
title="Envoy 1234",
|
||||
unique_id="1234",
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_NAME: "Envoy 1234",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
CONF_TOKEN: token,
|
||||
},
|
||||
)
|
||||
mock_envoy.auth = EnvoyTokenAuth("127.0.0.1", token=token, envoy_serial="1234")
|
||||
await setup_integration(hass, entry)
|
||||
|
||||
assert (entity_state := hass.states.get("sensor.inverter_1"))
|
||||
assert entity_state.state == "116"
|
||||
|
||||
assert mock_envoy.mock_calls[0] == call.set_retry_policy(
|
||||
max_delay=SETUP_RETRY_TIMEOUT
|
||||
)
|
||||
assert mock_envoy.mock_calls[-1] == call.set_retry_policy(
|
||||
max_delay=OPERATIONAL_RETRY_TIMEOUT
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user