Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BMW: Remove deprecated refresh from cloud button #97864

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 12 additions & 29 deletions homeassistant/components/bmw_connected_drive/button.py
Expand Up @@ -26,14 +26,17 @@


@dataclass
class BMWButtonEntityDescription(ButtonEntityDescription):
class BMWRequiredKeysMixin:
"""Mixin for required keys."""

remote_function: Callable[[MyBMWVehicle], Coroutine[Any, Any, RemoteServiceStatus]]


@dataclass
class BMWButtonEntityDescription(ButtonEntityDescription, BMWRequiredKeysMixin):
"""Class describing BMW button entities."""

enabled_when_read_only: bool = False
remote_function: Callable[
[MyBMWVehicle], Coroutine[Any, Any, RemoteServiceStatus]
] | None = None
account_function: Callable[[BMWDataUpdateCoordinator], Coroutine] | None = None
is_available: Callable[[MyBMWVehicle], bool] = lambda _: True


Expand Down Expand Up @@ -69,13 +72,6 @@ class BMWButtonEntityDescription(ButtonEntityDescription):
icon="mdi:crosshairs-question",
remote_function=lambda vehicle: vehicle.remote_services.trigger_remote_vehicle_finder(),
),
BMWButtonEntityDescription(
key="refresh",
translation_key="refresh",
gjohansson-ST marked this conversation as resolved.
Show resolved Hide resolved
icon="mdi:refresh",
account_function=lambda coordinator: coordinator.async_request_refresh(),
enabled_when_read_only=True,
),
)


Expand Down Expand Up @@ -120,22 +116,9 @@ def __init__(

async def async_press(self) -> None:
"""Press the button."""
if self.entity_description.remote_function:
try:
await self.entity_description.remote_function(self.vehicle)
except MyBMWAPIError as ex:
raise HomeAssistantError(ex) from ex
elif self.entity_description.account_function:
_LOGGER.warning(
"The 'Refresh from cloud' button is deprecated. Use the"
" 'homeassistant.update_entity' service with any BMW entity for a full"
" reload. See"
" https://www.home-assistant.io/integrations/bmw_connected_drive/#update-the-state--refresh-from-api"
" for details"
)
try:
await self.entity_description.account_function(self.coordinator)
except MyBMWAPIError as ex:
raise HomeAssistantError(ex) from ex
try:
await self.entity_description.remote_function(self.vehicle)
except MyBMWAPIError as ex:
raise HomeAssistantError(ex) from ex

self.coordinator.async_update_listeners()
3 changes: 0 additions & 3 deletions homeassistant/components/bmw_connected_drive/strings.json
Expand Up @@ -66,9 +66,6 @@
},
"find_vehicle": {
"name": "Find vehicle"
},
"refresh": {
"name": "Refresh from cloud"
}
},
"lock": {
Expand Down
24 changes: 0 additions & 24 deletions tests/components/bmw_connected_drive/snapshots/test_button.ambr
Expand Up @@ -61,18 +61,6 @@
'last_updated': <ANY>,
'state': 'unknown',
}),
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
'friendly_name': 'i4 eDrive40 Refresh from cloud',
'icon': 'mdi:refresh',
}),
'context': <ANY>,
'entity_id': 'button.i4_edrive40_refresh_from_cloud',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
}),
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
Expand Down Expand Up @@ -121,17 +109,5 @@
'last_updated': <ANY>,
'state': 'unknown',
}),
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
'friendly_name': 'i3 (+ REX) Refresh from cloud',
'icon': 'mdi:refresh',
}),
'context': <ANY>,
'entity_id': 'button.i3_rex_refresh_from_cloud',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
}),
])
# ---
33 changes: 23 additions & 10 deletions tests/components/bmw_connected_drive/test_button.py
@@ -1,4 +1,7 @@
"""Test BMW buttons."""
from unittest.mock import AsyncMock

from bimmer_connected.models import MyBMWRemoteServiceError
from bimmer_connected.vehicle.remote_services import RemoteServices
import pytest
import respx
Expand All @@ -8,6 +11,7 @@
BMWDataUpdateCoordinator,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError

from . import setup_mocked_integration

Expand Down Expand Up @@ -58,22 +62,31 @@ async def test_update_triggers_success(
assert BMWDataUpdateCoordinator.async_update_listeners.call_count == 1


async def test_refresh_from_cloud(
async def test_update_failed(
hass: HomeAssistant,
bmw_fixture: respx.Router,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test button press for deprecated service."""
"""Test button press."""

# Setup component
assert await setup_mocked_integration(hass)
BMWDataUpdateCoordinator.async_update_listeners.reset_mock()

# Test
await hass.services.async_call(
"button",
"press",
blocking=True,
target={"entity_id": "button.i4_edrive40_refresh_from_cloud"},
# Setup exception
monkeypatch.setattr(
RemoteServices,
"trigger_remote_service",
AsyncMock(side_effect=MyBMWRemoteServiceError),
)
assert RemoteServices.trigger_remote_service.call_count == 0
assert BMWDataUpdateCoordinator.async_update_listeners.call_count == 2

# Test
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
"button",
"press",
blocking=True,
target={"entity_id": "button.i4_edrive40_flash_lights"},
)
assert RemoteServices.trigger_remote_service.call_count == 1
assert BMWDataUpdateCoordinator.async_update_listeners.call_count == 0