Disable the ZHA bellows UART thread when connecting to a TCP coordinator (#88202)

Disable the bellows UART thread when connecting to a TCP coordinator
pull/88979/head
puddly 2023-02-22 15:12:55 -05:00 committed by Paulus Schoutsen
parent cebc6dd096
commit 45547d226e
3 changed files with 48 additions and 0 deletions

View File

@ -139,6 +139,7 @@ CONF_ENABLE_QUIRKS = "enable_quirks"
CONF_FLOWCONTROL = "flow_control"
CONF_RADIO_TYPE = "radio_type"
CONF_USB_PATH = "usb_path"
CONF_USE_THREAD = "use_thread"
CONF_ZIGPY = "zigpy_config"
CONF_CONSIDER_UNAVAILABLE_MAINS = "consider_unavailable_mains"

View File

@ -40,7 +40,9 @@ from .const import (
ATTR_SIGNATURE,
ATTR_TYPE,
CONF_DATABASE,
CONF_DEVICE_PATH,
CONF_RADIO_TYPE,
CONF_USE_THREAD,
CONF_ZIGPY,
DATA_ZHA,
DATA_ZHA_BRIDGE_ID,
@ -167,6 +169,15 @@ class ZHAGateway:
app_config[CONF_DATABASE] = database
app_config[CONF_DEVICE] = self.config_entry.data[CONF_DEVICE]
# The bellows UART thread sometimes propagates a cancellation into the main Core
# event loop, when a connection to a TCP coordinator fails in a specific way
if (
CONF_USE_THREAD not in app_config
and RadioType[radio_type] is RadioType.ezsp
and app_config[CONF_DEVICE][CONF_DEVICE_PATH].startswith("socket://")
):
app_config[CONF_USE_THREAD] = False
app_config = app_controller_cls.SCHEMA(app_config)
for attempt in range(STARTUP_RETRIES):

View File

@ -287,3 +287,39 @@ async def test_gateway_initialize_failure_transient(
# Initialization immediately stops and is retried after TransientConnectionError
assert mock_new.call_count == 2
@patch(
"homeassistant.components.zha.core.gateway.ZHAGateway.async_load_devices",
MagicMock(),
)
@patch(
"homeassistant.components.zha.core.gateway.ZHAGateway.async_load_groups",
MagicMock(),
)
@pytest.mark.parametrize(
("device_path", "thread_state", "config_override"),
[
("/dev/ttyUSB0", True, {}),
("socket://192.168.1.123:9999", False, {}),
("socket://192.168.1.123:9999", True, {"use_thread": True}),
],
)
async def test_gateway_initialize_bellows_thread(
device_path, thread_state, config_override, hass, coordinator
):
"""Test ZHA disabling the UART thread when connecting to a TCP coordinator."""
zha_gateway = get_zha_gateway(hass)
assert zha_gateway is not None
zha_gateway.config_entry.data = dict(zha_gateway.config_entry.data)
zha_gateway.config_entry.data["device"]["path"] = device_path
zha_gateway._config.setdefault("zigpy_config", {}).update(config_override)
with patch(
"bellows.zigbee.application.ControllerApplication.new",
new=AsyncMock(),
) as mock_new:
await zha_gateway.async_initialize()
assert mock_new.mock_calls[0].args[0]["use_thread"] is thread_state