Reload ZHA integration on any error, not just recoverable ones (#105659)

This commit is contained in:
puddly 2023-12-13 10:24:26 -05:00 committed by GitHub
parent 2d59eba4c7
commit e475829ce6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 50 deletions

View file

@ -37,8 +37,6 @@ from .core.const import (
DOMAIN, DOMAIN,
PLATFORMS, PLATFORMS,
SIGNAL_ADD_ENTITIES, SIGNAL_ADD_ENTITIES,
STARTUP_FAILURE_DELAY_S,
STARTUP_RETRIES,
RadioType, RadioType,
) )
from .core.device import get_device_automation_triggers from .core.device import get_device_automation_triggers
@ -161,49 +159,40 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
_LOGGER.debug("Trigger cache: %s", zha_data.device_trigger_cache) _LOGGER.debug("Trigger cache: %s", zha_data.device_trigger_cache)
# Retry setup a few times before giving up to deal with missing serial ports in VMs try:
for attempt in range(STARTUP_RETRIES): zha_gateway = await ZHAGateway.async_from_config(
try: hass=hass,
zha_gateway = await ZHAGateway.async_from_config( config=zha_data.yaml_config,
hass=hass, config_entry=config_entry,
config=zha_data.yaml_config, )
config_entry=config_entry, except NetworkSettingsInconsistent as exc:
) await warn_on_inconsistent_network_settings(
break hass,
except NetworkSettingsInconsistent as exc: config_entry=config_entry,
await warn_on_inconsistent_network_settings( old_state=exc.old_state,
hass, new_state=exc.new_state,
config_entry=config_entry, )
old_state=exc.old_state, raise ConfigEntryError(
new_state=exc.new_state, "Network settings do not match most recent backup"
) ) from exc
raise ConfigEntryError( except TransientConnectionError as exc:
"Network settings do not match most recent backup" raise ConfigEntryNotReady from exc
) from exc except Exception as exc:
except TransientConnectionError as exc: _LOGGER.debug("Failed to set up ZHA", exc_info=exc)
raise ConfigEntryNotReady from exc device_path = config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
except Exception as exc:
_LOGGER.debug(
"Couldn't start coordinator (attempt %s of %s)",
attempt + 1,
STARTUP_RETRIES,
exc_info=exc,
)
if attempt < STARTUP_RETRIES - 1: if (
await asyncio.sleep(STARTUP_FAILURE_DELAY_S) not device_path.startswith("socket://")
continue and RadioType[config_entry.data[CONF_RADIO_TYPE]] == RadioType.ezsp
):
try:
# Ignore all exceptions during probing, they shouldn't halt setup
if await warn_on_wrong_silabs_firmware(hass, device_path):
raise ConfigEntryError("Incorrect firmware installed") from exc
except AlreadyRunningEZSP as ezsp_exc:
raise ConfigEntryNotReady from ezsp_exc
if RadioType[config_entry.data[CONF_RADIO_TYPE]] == RadioType.ezsp: raise ConfigEntryNotReady from exc
try:
# Ignore all exceptions during probing, they shouldn't halt setup
await warn_on_wrong_silabs_firmware(
hass, config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
)
except AlreadyRunningEZSP as ezsp_exc:
raise ConfigEntryNotReady from ezsp_exc
raise
repairs.async_delete_blocking_issues(hass) repairs.async_delete_blocking_issues(hass)

View file

@ -409,9 +409,6 @@ class Strobe(t.enum8):
Strobe = 0x01 Strobe = 0x01
STARTUP_FAILURE_DELAY_S = 3
STARTUP_RETRIES = 3
EZSP_OVERWRITE_EUI64 = ( EZSP_OVERWRITE_EUI64 = (
"i_understand_i_can_update_eui64_only_once_and_i_still_want_to_do_it" "i_understand_i_can_update_eui64_only_once_and_i_still_want_to_do_it"
) )

View file

@ -46,7 +46,7 @@ def disable_request_retry_delay():
with patch( with patch(
"homeassistant.components.zha.core.cluster_handlers.RETRYABLE_REQUEST_DECORATOR", "homeassistant.components.zha.core.cluster_handlers.RETRYABLE_REQUEST_DECORATOR",
zigpy.util.retryable_request(tries=3, delay=0), zigpy.util.retryable_request(tries=3, delay=0),
), patch("homeassistant.components.zha.STARTUP_FAILURE_DELAY_S", 0.01): ):
yield yield

View file

@ -95,7 +95,6 @@ def test_detect_radio_hardware_failure(hass: HomeAssistant) -> None:
assert _detect_radio_hardware(hass, SKYCONNECT_DEVICE) == HardwareType.OTHER assert _detect_radio_hardware(hass, SKYCONNECT_DEVICE) == HardwareType.OTHER
@patch("homeassistant.components.zha.STARTUP_RETRIES", new=1)
@pytest.mark.parametrize( @pytest.mark.parametrize(
("detected_hardware", "expected_learn_more_url"), ("detected_hardware", "expected_learn_more_url"),
[ [
@ -176,7 +175,7 @@ async def test_multipan_firmware_no_repair_on_probe_failure(
await hass.config_entries.async_setup(config_entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.SETUP_ERROR assert config_entry.state == ConfigEntryState.SETUP_RETRY
await hass.config_entries.async_unload(config_entry.entry_id) await hass.config_entries.async_unload(config_entry.entry_id)
@ -189,7 +188,6 @@ async def test_multipan_firmware_no_repair_on_probe_failure(
assert issue is None assert issue is None
@patch("homeassistant.components.zha.STARTUP_RETRIES", new=1)
async def test_multipan_firmware_retry_on_probe_ezsp( async def test_multipan_firmware_retry_on_probe_ezsp(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,