diff --git a/homeassistant/components/icloud/account.py b/homeassistant/components/icloud/account.py index 0433ca936c21..189da4b39ff4 100644 --- a/homeassistant/components/icloud/account.py +++ b/homeassistant/components/icloud/account.py @@ -175,6 +175,11 @@ class IcloudAccount: api_devices = {} try: api_devices = self.api.devices + # Since pyicloud 2.3.0 device reads are cache-only and the library + # requests an active locate from Apple only at service creation, so + # explicitly refresh with locate=True to get a fresh GPS fix on + # every poll instead of Apple's cached location. + api_devices.refresh(locate=True) except Exception as err: # noqa: BLE001 _LOGGER.error("Unknown iCloud error: %s", err) self._fetch_interval = 2 diff --git a/tests/components/icloud/test_account.py b/tests/components/icloud/test_account.py index 3ddc13b5d699..7ba37caa6650 100644 --- a/tests/components/icloud/test_account.py +++ b/tests/components/icloud/test_account.py @@ -99,6 +99,11 @@ class MockDevicesContainer: """Initialize with userinfo and list of device objects.""" self.user_info = userinfo self._devices = devices + self.refresh_calls: list[bool] = [] + + def refresh(self, locate: bool = False) -> None: + """Record refresh calls made by the account.""" + self.refresh_calls.append(locate) def __iter__(self): """Iterate returns device objects (each must have .status(...)).""" @@ -165,3 +170,7 @@ async def test_setup_success_with_devices( assert account.owner_fullname == "user name" assert "johntravolta" in account.family_members_fullname assert account.family_members_fullname["johntravolta"] == "John TRAVOLTA" + # An active locate must be requested on every poll (pyicloud >= 2.3.0 + # only locates at service creation, so the account has to ask for it) + assert mock_icloud_service.devices.refresh_calls == [True] + assert "device1" in account.devices