Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions findmy/accessory.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ def get_max_index(self, dt: datetime) -> int:
@abstractmethod
def update_alignment(self, dt: datetime, index: int) -> None:
"""
Update alignment of the accessory.
Update alignment of the accessory based on a key index that was observed at a specific time.

Alignment can be updated based on a LocationReport that was observed at a specific index.
Implementations of this method should consider that this method may be called
multiple times, sometimes with seemingly conflicting data: the same index may be
observed at different times, or multiple indices may be observed at the same time.
"""
raise NotImplementedError

Expand Down Expand Up @@ -222,8 +224,13 @@ def get_max_index(self, dt: datetime) -> int:

@override
def update_alignment(self, dt: datetime, index: int) -> None:
if dt < self._alignment_date:
# we only care about the most recent report
if dt < self._alignment_date or index < self._alignment_index:
# We only care about the most recent report and index.
# Multiple calls to this method may be made with
# possibly conflicting data, so we just ignore
# anything that seems to go backwards in time or index.
# Saving the newest data is at least likely to be stable
# over multiple fetches.
return

logger.info("Updating alignment based on report observed at index %i", index)
Expand Down
12 changes: 5 additions & 7 deletions findmy/reports/reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ async def _fetch_accessory_report(
# state variables
cur_keys_primary: set[str] = set()
cur_keys_secondary: set[str] = set()
cur_index = accessory.get_min_index(start_date)
cur_index = accessory.get_max_index(start_date)
ret: set[LocationReport] = set()

async def _fetch() -> set[LocationReport]:
Expand All @@ -446,17 +446,15 @@ async def _fetch() -> set[LocationReport]:
report.decrypt(key)

# update alignment data on every report
# if a key maps to multiple indices, only feed it the maximum index,
# since apple only returns the latest reports per request.
# This makes the value more likely to be stable.
accessory.update_alignment(report.timestamp, max(key_to_ind[key]))
for i in key_to_ind[key]:
accessory.update_alignment(report.timestamp, i)

cur_keys_primary.clear()
cur_keys_secondary.clear()

return set(new_reports)

while cur_index <= accessory.get_max_index(end_date):
while cur_index >= accessory.get_min_index(end_date):
key_batch = accessory.keys_at(cur_index)

# split into primary and secondary keys
Expand All @@ -483,7 +481,7 @@ async def _fetch() -> set[LocationReport]:
cur_keys_primary |= new_keys_primary
cur_keys_secondary |= new_keys_secondary

cur_index += 1
cur_index -= 1

if cur_keys_primary or cur_keys_secondary:
# fetch remaining keys
Expand Down