From ca75581d43a670487747731ba646216c58d4dae3 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 21 Aug 2025 10:59:10 +0200 Subject: [PATCH] Bump automower-ble to 0.2.7 (#150979) --- .../components/husqvarna_automower_ble/__init__.py | 9 +++++++-- .../components/husqvarna_automower_ble/coordinator.py | 3 ++- .../components/husqvarna_automower_ble/lawn_mower.py | 8 ++++---- .../components/husqvarna_automower_ble/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/husqvarna_automower_ble/conftest.py | 3 ++- tests/components/husqvarna_automower_ble/test_init.py | 11 +++++------ 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/husqvarna_automower_ble/__init__.py b/homeassistant/components/husqvarna_automower_ble/__init__.py index fd4521549a22..4537dec0e287 100644 --- a/homeassistant/components/husqvarna_automower_ble/__init__.py +++ b/homeassistant/components/husqvarna_automower_ble/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from automower_ble.mower import Mower +from automower_ble.protocol import ResponseResult from bleak import BleakError from bleak_retry_connector import close_stale_connections_by_address, get_device @@ -37,12 +38,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: HusqvarnaConfigEntry) -> device = bluetooth.async_ble_device_from_address( hass, address, connectable=True ) or await get_device(address) - if not await mower.connect(device): - raise ConfigEntryNotReady + response_result = await mower.connect(device) + if response_result != ResponseResult.OK: + raise ConfigEntryNotReady( + f"Unable to connect to device {address}, mower returned {response_result}" + ) except (TimeoutError, BleakError) as exception: raise ConfigEntryNotReady( f"Unable to connect to device {address} due to {exception}" ) from exception + LOGGER.debug("connected and paired") model = await mower.get_model() diff --git a/homeassistant/components/husqvarna_automower_ble/coordinator.py b/homeassistant/components/husqvarna_automower_ble/coordinator.py index ef9ccfa5a473..cd5b4e06005e 100644 --- a/homeassistant/components/husqvarna_automower_ble/coordinator.py +++ b/homeassistant/components/husqvarna_automower_ble/coordinator.py @@ -6,6 +6,7 @@ from datetime import timedelta from typing import TYPE_CHECKING from automower_ble.mower import Mower +from automower_ble.protocol import ResponseResult from bleak import BleakError from bleak_retry_connector import close_stale_connections_by_address @@ -62,7 +63,7 @@ class HusqvarnaCoordinator(DataUpdateCoordinator[dict[str, str | int]]): ) try: - if not await self.mower.connect(device): + if await self.mower.connect(device) is not ResponseResult.OK: raise UpdateFailed("Failed to connect") except BleakError as err: raise UpdateFailed("Failed to connect") from err diff --git a/homeassistant/components/husqvarna_automower_ble/lawn_mower.py b/homeassistant/components/husqvarna_automower_ble/lawn_mower.py index 4b4a16ba1dbe..78d39ddd96a6 100644 --- a/homeassistant/components/husqvarna_automower_ble/lawn_mower.py +++ b/homeassistant/components/husqvarna_automower_ble/lawn_mower.py @@ -2,7 +2,7 @@ from __future__ import annotations -from automower_ble.protocol import MowerActivity, MowerState +from automower_ble.protocol import MowerActivity, MowerState, ResponseResult from homeassistant.components import bluetooth from homeassistant.components.lawn_mower import ( @@ -107,7 +107,7 @@ class AutomowerLawnMower(HusqvarnaAutomowerBleEntity, LawnMowerEntity): device = bluetooth.async_ble_device_from_address( self.coordinator.hass, self.coordinator.address, connectable=True ) - if not await self.coordinator.mower.connect(device): + if await self.coordinator.mower.connect(device) is not ResponseResult.OK: return await self.coordinator.mower.mower_resume() @@ -126,7 +126,7 @@ class AutomowerLawnMower(HusqvarnaAutomowerBleEntity, LawnMowerEntity): device = bluetooth.async_ble_device_from_address( self.coordinator.hass, self.coordinator.address, connectable=True ) - if not await self.coordinator.mower.connect(device): + if await self.coordinator.mower.connect(device) is not ResponseResult.OK: return await self.coordinator.mower.mower_park() @@ -143,7 +143,7 @@ class AutomowerLawnMower(HusqvarnaAutomowerBleEntity, LawnMowerEntity): device = bluetooth.async_ble_device_from_address( self.coordinator.hass, self.coordinator.address, connectable=True ) - if not await self.coordinator.mower.connect(device): + if await self.coordinator.mower.connect(device) is not ResponseResult.OK: return await self.coordinator.mower.mower_pause() diff --git a/homeassistant/components/husqvarna_automower_ble/manifest.json b/homeassistant/components/husqvarna_automower_ble/manifest.json index 6eb618cbb04c..50430c2a9fad 100644 --- a/homeassistant/components/husqvarna_automower_ble/manifest.json +++ b/homeassistant/components/husqvarna_automower_ble/manifest.json @@ -12,5 +12,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/husqvarna_automower_ble", "iot_class": "local_polling", - "requirements": ["automower-ble==0.2.1"] + "requirements": ["automower-ble==0.2.7"] } diff --git a/requirements_all.txt b/requirements_all.txt index 0699f046095a..3cf08cf15a81 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -563,7 +563,7 @@ aurorapy==0.2.7 autarco==3.1.0 # homeassistant.components.husqvarna_automower_ble -automower-ble==0.2.1 +automower-ble==0.2.7 # homeassistant.components.generic # homeassistant.components.stream diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 40c988a03e1c..8b87b683899a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -518,7 +518,7 @@ aurorapy==0.2.7 autarco==3.1.0 # homeassistant.components.husqvarna_automower_ble -automower-ble==0.2.1 +automower-ble==0.2.7 # homeassistant.components.generic # homeassistant.components.stream diff --git a/tests/components/husqvarna_automower_ble/conftest.py b/tests/components/husqvarna_automower_ble/conftest.py index 3a8e881aba0b..1081db014e3f 100644 --- a/tests/components/husqvarna_automower_ble/conftest.py +++ b/tests/components/husqvarna_automower_ble/conftest.py @@ -3,6 +3,7 @@ from collections.abc import Generator from unittest.mock import AsyncMock, patch +from automower_ble.protocol import ResponseResult import pytest from homeassistant.components.husqvarna_automower_ble.const import DOMAIN @@ -37,7 +38,7 @@ def mock_automower_client(enable_bluetooth: None) -> Generator[AsyncMock]: ), ): client = mock_client.return_value - client.connect.return_value = True + client.connect.return_value = ResponseResult.OK client.is_connected.return_value = True client.get_model.return_value = "305" client.battery_level.return_value = 100 diff --git a/tests/components/husqvarna_automower_ble/test_init.py b/tests/components/husqvarna_automower_ble/test_init.py index 3cb4338eca40..95a0a1f20371 100644 --- a/tests/components/husqvarna_automower_ble/test_init.py +++ b/tests/components/husqvarna_automower_ble/test_init.py @@ -2,7 +2,7 @@ from unittest.mock import Mock -from bleak import BleakError +from automower_ble.protocol import ResponseResult import pytest from syrupy.assertion import SnapshotAssertion @@ -46,7 +46,7 @@ async def test_setup_retry_connect( ) -> None: """Test setup creates expected devices.""" - mock_automower_client.connect.return_value = False + 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) @@ -55,14 +55,13 @@ async def test_setup_retry_connect( assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY -async def test_setup_failed_connect( +async def test_setup_unknown_error( hass: HomeAssistant, mock_automower_client: Mock, mock_config_entry: MockConfigEntry, ) -> None: - """Test setup creates expected devices.""" - - mock_automower_client.connect.side_effect = BleakError + """Test setup fails when we receive an error from the device.""" + mock_automower_client.connect.return_value = ResponseResult.UNKNOWN_ERROR mock_config_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_config_entry.entry_id)