Apple's original AirTag still tracks effectively, and you can get a 4-pack for its best price ever
Back to Tutorials
techTutorialintermediate

Apple's original AirTag still tracks effectively, and you can get a 4-pack for its best price ever

April 17, 20263 views5 min read

Learn to detect and analyze Apple AirTag devices using Python and Bluetooth scanning techniques, understanding how the original Gen 1 model still functions effectively for tracking.

Introduction

In this tutorial, you'll learn how to work with Apple's AirTag technology using Python and the Bluetooth protocol to understand how these tracking devices function. While the original AirTag (Gen 1) may be outdated, it still offers reliable tracking capabilities that can be explored programmatically. We'll create a Python script that can detect and analyze AirTag devices in your vicinity using Bluetooth scanning techniques.

Prerequisites

  • Python 3.7 or higher installed on your system
  • Bluetooth adapter compatible with your operating system
  • Basic understanding of Python programming concepts
  • Access to a macOS or Linux system (Windows support limited for Bluetooth scanning)
  • Install required Python packages: bleak, pyobjc (macOS only)

Step-by-Step Instructions

1. Set Up Your Development Environment

First, we need to install the required Python packages to work with Bluetooth devices. The bleak library is essential for Bluetooth Low Energy (BLE) communication on multiple platforms.

pip install bleak

Why this step? The bleak library provides a cross-platform way to interact with BLE devices, which is exactly what AirTags use for communication. It handles the low-level Bluetooth operations and provides a clean Python interface.

2. Create the Main Script Structure

Let's create the foundation of our AirTag detection script:

import asyncio
import time
from bleak import BleakScanner

async def scan_airtags():
    print("Scanning for AirTags...")
    devices = await BleakScanner.discover()
    
    airtags = []
    for device in devices:
        # Check if device is an AirTag based on name or service data
        if 'AirTag' in device.name:
            airtags.append(device)
            print(f"Found AirTag: {device.name} - {device.address}")
    
    return airtags

async def main():
    airtags = await scan_airtags()
    print(f"Total AirTags found: {len(airtags)}")

if __name__ == "__main__":
    asyncio.run(main())

Why this step? This sets up the basic structure for scanning Bluetooth devices. The BleakScanner.discover() function scans for all nearby BLE devices and returns a list of devices that we can then filter for AirTags.

3. Enhance Device Detection with Service Data Analysis

AirTags use specific service data that we can analyze to identify them more accurately. Let's modify our script to examine the service data:

import asyncio
import time
from bleak import BleakScanner
from bleak.uuids import uuid16_dict

async def analyze_airtag_service_data(device):
    """Analyze service data to identify AirTag characteristics"""
    service_data = device.metadata.get('service_data', {})
    
    for uuid, data in service_data.items():
        # Apple's AirTag uses specific service UUIDs
        if uuid in ['0000180a-0000-1000-8000-00805f9b34fb', '0000180f-0000-1000-8000-00805f9b34fb']:
            print(f"Service UUID {uuid} found in {device.name}")
            return True
    return False

async def scan_airtags_advanced():
    print("Scanning for AirTags with advanced detection...")
    devices = await BleakScanner.discover()
    
    airtags = []
    for device in devices:
        # Check name first
        if 'AirTag' in device.name:
            airtags.append(device)
            print(f"Found AirTag (name): {device.name} - {device.address}")
        
        # Then check service data
        elif await analyze_airtag_service_data(device):
            airtags.append(device)
            print(f"Found AirTag (service data): {device.name} - {device.address}")
    
    return airtags

Why this step? AirTags broadcast specific service data that includes Apple's proprietary identifiers. By examining this data, we can more reliably detect AirTags even if they're not advertising their names clearly.

4. Add RSSI and Distance Estimation

Let's enhance our script to include signal strength information that helps estimate distance:

import asyncio
import time
from bleak import BleakScanner

async def scan_with_rssi():
    print("Scanning for AirTags with RSSI information...")
    devices = await BleakScanner.discover()
    
    airtags = []
    for device in devices:
        if 'AirTag' in device.name or await analyze_airtag_service_data(device):
            airtags.append(device)
            
            # Calculate estimated distance based on RSSI
            rssi = device.rssi
            if rssi:
                distance = calculate_distance(rssi)
                print(f"AirTag: {device.name} - {device.address} | RSSI: {rssi}dBm | Distance: {distance:.2f}m")
            else:
                print(f"AirTag: {device.name} - {device.address} | RSSI: Unknown")
    
    return airtags

def calculate_distance(rssi):
    """Simple distance calculation based on RSSI"""
    # This is a simplified approximation
    # Real calculation would require calibration
    if rssi >= -50:
        return 0.5
    elif rssi >= -60:
        return 1.0
    elif rssi >= -70:
        return 3.0
    elif rssi >= -80:
        return 10.0
    else:
        return 50.0  # Beyond range

Why this step? RSSI (Received Signal Strength Indicator) provides information about how strong the Bluetooth signal is, which correlates with distance. This helps users understand how close their AirTags are, making the tracking more useful.

5. Implement Continuous Scanning

For practical tracking, we'll create a continuous scanning function that can monitor AirTags over time:

async def continuous_scan(duration=60):
    """Continuously scan for AirTags for a specified duration"""
    start_time = time.time()
    print(f"Starting continuous scan for {duration} seconds...")
    
    while time.time() - start_time < duration:
        print(f"\n--- Scan at {time.strftime('%H:%M:%S')} ---")
        airtags = await scan_with_rssi()
        
        if airtags:
            print(f"Found {len(airtags)} AirTag(s) in range")
        else:
            print("No AirTags detected")
        
        await asyncio.sleep(5)  # Wait 5 seconds before next scan

async def main():
    # Run a single scan first
    await scan_airtags_advanced()
    
    # Then run continuous scan for 2 minutes
    await continuous_scan(120)

Why this step? Continuous scanning mimics real-world usage where users might want to monitor their AirTags over time. This is especially useful for understanding tracking patterns and reliability over extended periods.

6. Save Results to File

Let's add functionality to save scan results for later analysis:

import json
import datetime

async def save_scan_results(airtags, filename="airtag_scan_results.json"):
    """Save scan results to a JSON file"""
    results = {
        "timestamp": datetime.datetime.now().isoformat(),
        "airtags": []
    }
    
    for device in airtags:
        result = {
            "name": device.name,
            "address": device.address,
            "rssi": device.rssi,
            "distance_estimate": calculate_distance(device.rssi) if device.rssi else None
        }
        results["airtags"].append(result)
    
    with open(filename, 'w') as f:
        json.dump(results, f, indent=2)
    
    print(f"Results saved to {filename}")

async def main():
    airtags = await scan_airtags_advanced()
    
    # Save results
    await save_scan_results(airtags)
    
    # Run continuous scan
    await continuous_scan(60)

Why this step? Saving results allows you to analyze tracking patterns over time, which is valuable for understanding how the original AirTag technology performs in different environments and conditions.

Summary

In this tutorial, you've learned how to create a Python script that can detect and analyze Apple AirTag devices using Bluetooth scanning techniques. You've built a system that can:

  • Discover nearby AirTags using BLE scanning
  • Analyze service data to identify AirTag characteristics
  • Estimate distance based on RSSI values
  • Perform continuous monitoring over time
  • Save scan results for later analysis

This demonstrates how the original AirTag technology still functions effectively, even though it's no longer the latest model. The script provides insight into how AirTags communicate and can help you understand why they remain effective for tracking at a lower cost compared to newer models.

While this tutorial focuses on the technical aspects of AirTag detection, it's important to note that these devices are designed for legitimate tracking purposes and should be used ethically, respecting privacy laws and regulations in your area.

Source: ZDNet AI

Related Articles