Explain why a Husqvarna Automower BLE device could not be connected to (#172774)

This commit is contained in:
J. Nick Koston
2026-06-01 21:05:38 +00:00
committed by Franck Nijhof
parent 4fbc363965
commit c82d32bbae
3 changed files with 31 additions and 5 deletions
@@ -6,6 +6,7 @@ from bleak import BleakError
from bleak_retry_connector import close_stale_connections_by_address, get_device
from homeassistant.components import bluetooth
from homeassistant.components.bluetooth import BluetoothReachabilityIntent
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_ADDRESS, CONF_CLIENT_ID, CONF_PIN, Platform
from homeassistant.core import HomeAssistant
@@ -56,7 +57,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: HusqvarnaConfigEntry) ->
)
except (TimeoutError, BleakError) as exception:
raise ConfigEntryNotReady(
f"Unable to connect to device {address} due to {exception}"
translation_domain=DOMAIN,
translation_key="connection_failed",
translation_placeholders={
"address": address,
"error": str(exception) or type(exception).__name__,
"reason": bluetooth.async_address_reachability_diagnostics(
hass,
address.upper(),
BluetoothReachabilityIntent.CONNECTION,
),
},
) from exception
LOGGER.debug("connected and paired")
@@ -45,6 +45,9 @@
}
},
"exceptions": {
"connection_failed": {
"message": "Unable to connect to device {address} due to {error}: {reason}"
},
"pin_required": {
"message": "PIN is required for {domain_name}"
}
@@ -1,6 +1,6 @@
"""Test the Husqvarna Automower Bluetooth setup."""
from unittest.mock import Mock
from unittest.mock import Mock, patch
from automower_ble.protocol import ResponseResult
import pytest
@@ -75,16 +75,28 @@ async def test_setup_failed_connect(
hass: HomeAssistant,
mock_automower_client: Mock,
mock_config_entry: MockConfigEntry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test setup creates expected devices."""
"""Test setup retries with a diagnostic reason when the device cannot connect."""
mock_automower_client.connect.side_effect = TimeoutError
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
with patch(
"homeassistant.components.husqvarna_automower_ble.bluetooth."
"async_address_reachability_diagnostics",
return_value="mock reachability reason",
):
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
# A bare TimeoutError has an empty str(), so the error falls back to the
# exception class name; both the error and the reachability reason appear.
assert (
f"Unable to connect to device {mock_config_entry.data[CONF_ADDRESS]} "
"due to TimeoutError: mock reachability reason" in caplog.text
)
async def test_setup_unknown_error(