Skip to content

Commit 87a6eba

Browse files
committed
disable movement commands if no ble
1 parent 227093e commit 87a6eba

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

custom_components/mammotion/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from pymammotion.client import MammotionClient
3131
from pymammotion.data.model.account import Credentials
3232
from pymammotion.data.model.device import MowingDevice
33-
from pymammotion.transport.base import LoginFailedError, TransportType
33+
from pymammotion.transport.base import LoginFailedError, ReLoginRequiredError, TransportType
3434
from Tea.exceptions import UnretryableException
3535

3636
from .const import (
@@ -149,7 +149,7 @@ async def _async_attempt_login(
149149
account, password, aiohttp_client.async_get_clientsession(hass)
150150
)
151151
return True
152-
except LoginFailedError as retry_err:
152+
except (LoginFailedError, ReLoginRequiredError) as retry_err:
153153
if ble_fallback:
154154
LOGGER.warning(
155155
"Login failed after cache clear; continuing in BLE-only mode: %s",

custom_components/mammotion/button.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from homeassistant.helpers.entity import EntityCategory
1313
from homeassistant.helpers.entity_platform import AddEntitiesCallback
1414
from pymammotion.data.model.hash_list import Plan
15+
from pymammotion.transport.base import TransportType
1516
from pymammotion.utility.device_type import DeviceType
1617

1718
from . import MammotionConfigEntry
@@ -28,6 +29,7 @@ class MammotionButtonSensorEntityDescription(ButtonEntityDescription):
2829
"""Describes Mammotion button sensor entity."""
2930

3031
press_fn: Callable[[MammotionBaseUpdateCoordinator], Awaitable[None]]
32+
available_fn: Callable[[MammotionBaseUpdateCoordinator], bool] | None = None
3133

3234

3335
@dataclass(frozen=True, kw_only=True)
@@ -38,6 +40,17 @@ class MammotionTaskButtonSensorEntityDescription(ButtonEntityDescription):
3840
press_fn: Callable[[MammotionBaseUpdateCoordinator, str], Awaitable[None]]
3941

4042

43+
def _nudge_available(coordinator: MammotionBaseUpdateCoordinator) -> bool:
44+
"""Return True when movement via BLE or Wi-Fi is possible."""
45+
if coordinator.config_entry.options.get(CONF_MOVEMENT_USE_WIFI, False):
46+
return True
47+
handle = coordinator.manager.mower(coordinator.device_name)
48+
if handle is None:
49+
return False
50+
ble = handle.get_transport(TransportType.BLE)
51+
return ble is not None and ble.is_usable
52+
53+
4154
BUTTON_SENSORS: tuple[MammotionButtonSensorEntityDescription, ...] = (
4255
MammotionButtonSensorEntityDescription(
4356
key="start_map_sync",
@@ -64,27 +77,31 @@ class MammotionTaskButtonSensorEntityDescription(ButtonEntityDescription):
6477
0.4,
6578
coordinator.config_entry.options.get(CONF_MOVEMENT_USE_WIFI, False),
6679
),
80+
available_fn=_nudge_available,
6781
),
6882
MammotionButtonSensorEntityDescription(
6983
key="emergency_nudge_left",
7084
press_fn=lambda coordinator: coordinator.async_move_left(
7185
0.4,
7286
coordinator.config_entry.options.get(CONF_MOVEMENT_USE_WIFI, False),
7387
),
88+
available_fn=_nudge_available,
7489
),
7590
MammotionButtonSensorEntityDescription(
7691
key="emergency_nudge_right",
7792
press_fn=lambda coordinator: coordinator.async_move_right(
7893
0.4,
7994
coordinator.config_entry.options.get(CONF_MOVEMENT_USE_WIFI, False),
8095
),
96+
available_fn=_nudge_available,
8197
),
8298
MammotionButtonSensorEntityDescription(
8399
key="emergency_nudge_back",
84100
press_fn=lambda coordinator: coordinator.async_move_back(
85101
0.4,
86102
coordinator.config_entry.options.get(CONF_MOVEMENT_USE_WIFI, False),
87103
),
104+
available_fn=_nudge_available,
88105
),
89106
MammotionButtonSensorEntityDescription(
90107
key="cancel_task",
@@ -161,6 +178,15 @@ def __init__(
161178
self.entity_description = entity_description
162179
self._attr_translation_key = entity_description.key
163180

181+
@property
182+
def available(self) -> bool:
183+
"""Return True if entity is available."""
184+
if self.entity_description.available_fn is not None:
185+
return super().available and self.entity_description.available_fn(
186+
self.coordinator
187+
)
188+
return super().available
189+
164190
async def async_press(self) -> None:
165191
"""Handle the button press."""
166192
await self.entity_description.press_fn(self.coordinator)

custom_components/mammotion/coordinator.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
from pymammotion.state.device_state import DeviceSnapshot
6060
from pymammotion.transport.base import (
6161
AuthError,
62+
BLEUnavailableError,
6263
CommandTimeoutError,
6364
ConcurrentRequestError,
6465
LoginFailedError,
@@ -290,7 +291,7 @@ async def async_refresh_login(self, exc: Exception | None = None) -> None:
290291
if not self.has_cloud_account:
291292
return
292293

293-
if isinstance(exc, (LoginFailedError, ReLoginRequiredError)):
294+
if isinstance(exc, LoginFailedError):
294295
raise ConfigEntryAuthFailed(
295296
f"Login failed for Mammotion account: {exc}"
296297
) from exc
@@ -1226,7 +1227,14 @@ async def _async_update_data(self) -> MowingDevice:
12261227
if handle := self.manager.mower(self.device_name):
12271228
if ble := handle.get_transport(TransportType.BLE):
12281229
if ble.is_usable and not ble.is_connected:
1229-
await ble.connect()
1230+
try:
1231+
await ble.connect()
1232+
except BLEUnavailableError as exc:
1233+
LOGGER.debug(
1234+
"BLE unavailable for %s during update — continuing via cloud: %s",
1235+
self.device_name,
1236+
exc,
1237+
)
12301238

12311239
return device
12321240

0 commit comments

Comments
 (0)