Description
Hi,
I was looking to deal with nearby
-state devices using the OfflineFindingScanner
from this library.
I seem to have trouble with the method NearbyOfflineFindingDevice.is_from(other_device: HasPublicKey | RollingKeyPairSource)
not returning true
when the parameter other_device
is filed with the output of FindMyAccessory.from_plist(f)
.
I see that FindMyAccessory
is a subclass of RollingKeyPairSource
, so I figured it must be a valid input to the scanner. But it appears that while the scanner finds payloads from my official AirTags, it can't manage to ALWAYS identify the payloads as belonging to those AirTags.
Note that in one random run I did, I realised that it actually does match the FindMyAccessory
instances sometimes.
Example Code to Reproduce
"Minimal" example to reproduce this goes as follows:
import logging
from pathlib import Path
import asyncio
from findmy import FindMyAccessory
from findmy.scanner import (
NearbyOfflineFindingDevice,
OfflineFindingScanner,
SeparatedOfflineFindingDevice,
)
# windows
PLIST_FILES = [
'C:\\somepath\\OwnedBeacons\\049BC649-8733-4FA1-B31D-5BBDDE97E398.plist',
'C:\\somepath\\OwnedBeacons\\0FB0AEAC-C083-405E-A979-4AA6A73F5C56.plist',
'C:\\somepath\\OwnedBeacons\\46E881A1-3CD9-4965-AEA9-2D95414661E7.plist',
'C:\\somepath\\OwnedBeacons\\6FDA3C09-5E99-4A5B-BFED-E9922403E960.plist',
'C:\\somepath\\OwnedBeacons\\B1CE4F0C-2489-486E-8295-45690FACF1E8.plist'
]
SCAN_FOR = 1000
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s %(pathname)s:%(lineno)d %(levelname)s: %(message)s'
)
logger = logging.getLogger(__name__)
def _print_nearby(device: NearbyOfflineFindingDevice) -> None:
print(f"NEARBY Device - {device.mac_address}")
print(f" Status byte: {device.status:x}")
print(" Extra data:")
for k, v in sorted(device.additional_data.items()):
print(f" {k:20}: {v}")
print()
def _print_separated(device: SeparatedOfflineFindingDevice) -> None:
print(f"SEPARATED Device - {device.mac_address}")
print(f" Public key: {device.adv_key_b64}")
print(f" Lookup key: {device.hashed_adv_key_b64}")
print(f" Status byte: {device.status:x}")
print(f" Hint byte: {device.hint:x}")
print(" Extra data:")
for k, v in sorted(device.additional_data.items()):
print(f" {k:20}: {v}")
print()
def main():
items: list[FindMyAccessory] = []
for plist_file in PLIST_FILES:
with Path(plist_file).open("rb") as f:
airtag = FindMyAccessory.from_plist(f)
items.append(airtag)
asyncio.run(do_scan_stuff(items))
async def do_scan_stuff(items: list[FindMyAccessory]):
scanner = await OfflineFindingScanner.create()
async for device in scanner.scan_for(SCAN_FOR, extend_timeout=True):
if isinstance(device, NearbyOfflineFindingDevice):
_print_nearby(device)
for airtag in items:
if device.is_from(airtag):
print("!! Found a device that belonged to an airtag!")
elif isinstance(device, SeparatedOfflineFindingDevice):
_print_separated(device)
else:
print(f"Unknown device: {device}")
print()
main()
Example Output
Here is the output of the script in my latest run, observe that there is ONE instance of !! Found a device that belonged to an airtag!
but 3 different NEARBY
device matches.
2025-03-19 19:53:42,443 C:\Users\parawanderer\git\testproj\reproduce_example.py:64 INFO: Extracting data from .plist files
2025-03-19 19:53:42,448 C:\Python312\Lib\asyncio\proactor_events.py:634 DEBUG: Using proactor: IocpProactor
2025-03-19 19:53:42,459 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\findmy\scanner\scanner.py:332 INFO: Starting BLE scanner
2025-03-19 19:53:42,611 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 7C:40:DE:A5:24:09: .
2025-03-19 19:53:42,615 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 7C:40:DE:A5:24:09: .
2025-03-19 19:53:42,615 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\findmy\scanner\scanner.py:102 DEBUG: Unsupported OF type: 16
2025-03-19 19:53:43,213 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received E2:6A:EF:0E:27:A9: .
NEARBY Device - E2:6A:EF:0E:27:A9
Status byte: 0
Extra data:
!! Found a device that belonged to an airtag!
2025-03-19 19:53:44,269 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 7C:40:DE:A5:24:09: .
2025-03-19 19:53:44,270 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\findmy\scanner\scanner.py:102 DEBUG: Unsupported OF type: 16
2025-03-19 19:53:44,639 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received CD:DE:70:5B:37:95: .
NEARBY Device - CD:DE:70:5B:37:95
Status byte: 10
Extra data:
2025-03-19 19:53:44,647 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received CD:DE:70:5B:37:95: .
2025-03-19 19:53:44,652 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received CE:72:6F:CA:B6:A8: .
NEARBY Device - CE:72:6F:CA:B6:A8
Status byte: 10
Extra data:
2025-03-19 19:53:44,660 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received CE:72:6F:CA:B6:A8: .
2025-03-19 19:53:44,874 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 71:B6:BD:8F:68:D4: .
2025-03-19 19:53:44,875 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 71:B6:BD:8F:68:D4: .
2025-03-19 19:53:45,225 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received E2:6A:EF:0E:27:A9: .
2025-03-19 19:53:46,514 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 71:B6:BD:8F:68:D4: .
2025-03-19 19:53:47,576 c:\Users\parawanderer\git\testproj\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py:117 DEBUG: Received 7C:40:DE:A5:24:09: .