Repository: icepick3000/AirtagAlex Branch: main Commit: 008c18f1a2cf Files: 2 Total size: 6.5 KB Directory structure: gitextract_zckfl_z8/ ├── AirtagAlex.sh └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: AirtagAlex.sh ================================================ #!/bin/bash ITEMS_FILE="./Items.data" CSV_FILE="./Airtags.csv" CSV_HEADER="datetime,name,serialnumber,producttype,productindentifier,vendoridentifier,antennapower,systemversion,batterystatus,locationpositiontype,locationlatitude,locationlongitude,locationtimestamp,locationverticalaccuracy,locationhorizontalaccuracy,locationfloorlevel,locationaltitude,locationisinaccurate,locationisold,locationfinished,addresslabel,addressstreetaddress,addresscountrycode,addressstatecode,addressadministrativearea,addressstreetname,addresslocality,addresscountry,addressareaofinteresta,addressareaofinterestb" copy_items_data() { echo "Creating a copy of Items.data to prevent potential file corruption" if ! cp -p ~/Library/Caches/com.apple.findmy.fmipcore/Items.data "$ITEMS_FILE"; then echo "Failed to copy Items.data file. Please ensure Terminal has 'Full Disk Access' in the 'Privacy & Security' section in macOS Preferences" >&2 exit 1 fi } create_csv_file() { echo "Checking if $CSV_FILE exists" if [ ! -f "$CSV_FILE" ]; then echo "$CSV_FILE does not exist, creating one" if ! echo "$CSV_HEADER" >> "$CSV_FILE"; then echo "Failed to create $CSV_FILE. Please ensure the destination directory is writable." >&2 exit 1 fi fi } while true; do copy_items_data create_csv_file echo "Checking number of Airtags to process" airtagsnumber=$(jq ".[].serialNumber" "$ITEMS_FILE" | wc -l) echo "Number of Airtags to process: $airtagsnumber" airtagsnumber=$((airtagsnumber-1)) for j in $(seq 0 "$airtagsnumber"); do echo "Processing airtag number $j" datetime=$(date +"%Y-%m-%d %T") serialnumber=$(jq ".[$j].serialNumber" "$ITEMS_FILE") name=$(jq ".[$j].name" "$ITEMS_FILE") producttype=$(jq ".[$j].productType.type" "$ITEMS_FILE") productindentifier=$(jq ".[$j].productType.productInformation.productIdentifier" "$ITEMS_FILE") vendoridentifier=$(jq ".[$j].productType.productInformation.vendorIdentifier" "$ITEMS_FILE") antennapower=$(jq ".[$j].productType.productInformation.antennaPower" "$ITEMS_FILE") systemversion=$(jq ".[$j].systemVersion" "$ITEMS_FILE") batterystatus=$(jq ".[$j].batteryStatus" "$ITEMS_FILE") locationpositiontype=$(jq ".[$j].location.positionType" "$ITEMS_FILE") locationlatitude=$(jq ".[$j].location.latitude" "$ITEMS_FILE") locationlongitude=$(jq ".[$j].location.longitude" "$ITEMS_FILE") locationtimestamp=$(jq ".[$j].location.timeStamp" "$ITEMS_FILE") locationverticalaccuracy=$(jq ".[$j].location.verticalAccuracy // 0" "$ITEMS_FILE") locationhorizontalaccuracy=$(jq ".[$j].location.horizontalAccuracy // 0" "$ITEMS_FILE") locationfloorlevel=$(jq ".[$j].location.floorlevel // 0" "$ITEMS_FILE") locationaltitude=$(jq ".[$j].location.altitude // 0" "$ITEMS_FILE") locationisinaccurate=$(jq ".[$j].location.isInaccurate" "$ITEMS_FILE" | awk '{ print "\""$0"\"" }') locationisold=$(jq ".[$j].location.isOld" "$ITEMS_FILE" | awk '{ print "\""$0"\"" }' ) locationfinished=$(jq ".[$j].location.locationFinished" "$ITEMS_FILE" | awk '{ print "\""$0"\"" }' ) addresslabel=$(jq ".[$j].address.label // \"\"" "$ITEMS_FILE") addressstreetaddress=$(jq ".[$j].address.streetAddress // \"\"" "$ITEMS_FILE") addresscountrycode=$(jq ".[$j].address.countryCode // \"\"" "$ITEMS_FILE") addressstatecode=$(jq ".[$j].address.stateCode // \"\"" "$ITEMS_FILE") addressadministrativearea=$(jq ".[$j].address.administrativeArea // \"\"" "$ITEMS_FILE") addressstreetname=$(jq ".[$j].address.streetName // \"\"" "$ITEMS_FILE") addresslocality=$(jq ".[$j].address.locality // \"\"" "$ITEMS_FILE") addresscountry=$(jq ".[$j].address.country // \"\"" "$ITEMS_FILE") addressareaofinteresta=$(jq ".[$j].address.areaOfInterest[0] // \"\"" "$ITEMS_FILE") addressareaofinterestb=$(jq ".[$j].address.areaOfInterest[1] // \"\"" "$ITEMS_FILE") echo "Writing data to $CSV_FILE" echo "$datetime","$name","$serialnumber","$producttype","$productindentifier","$vendoridentifier","$antennapower","$systemversion","$batterystatus","$locationpositiontype","$locationlatitude","$locationlongitude","$locationtimestamp","$locationverticalaccuracy","$locationhorizontalaccuracy","$locationfloorlevel","$locationaltitude","$locationisinaccurate","$locationisold","$locationfinished","$addresslabel","$addressstreetaddress","$addresscountrycode","$addressstatecode","$addressadministrativearea","$addressstreetname","$addresslocality","$addresscountry","$addressareaofinteresta","$addressareaofinterestb" >> "$CSV_FILE" done echo -e "Checking again in 1 minute...\n" sleep 60 done ================================================ FILE: README.md ================================================ # AirtagAlex !!This script will NOT work on MAC's that have a Sonoma version thats newer then 14.3.1. Apple started encrypting the data after this version!! Get all metadata from the Airtags (lat, lon, geocoding information, precision range, battery status). This script is a very basic script to write the data to a CSV for processing in Excel or Numbers. I am sure many rewrites will be done by other folks but anyone with some programming experience will have a good starting point with this script. Click below to see the youtube video and a step by step guide; [![Click here for the youtube video](https://img.youtube.com/vi/9VQ-_ztG9aM/0.jpg)](https://www.youtube.com/watch?v=9VQ-_ztG9aM) ## Instructions * Install brew (https://brew.sh/) * Install the jq utility (`brew install jq`) * Clone this repo by typing `git clone https://github.com/icepick3000/AirtagAlex.git` * Make the shell file executable by typing `chmod 700 AirtagAlex.sh` You can start the script by typing: `./AirtagAlex.sh` The output will look something like this: ``` Create a copy of the Items.data file to prevent changes while the script is running Check if Airtags.csv exists Check how many Airtags to process Number of Airtags to process: 4 Processing airtag number 0 Write the data to the Airtags.csv file Processing airtag number 1 Write the data to the Airtags.csv file Processing airtag number 2 Write the data to the Airtags.csv file Processing airtag number 3 Write the data to the Airtags.csv file Sleep for 1 minute (60 seconds) ``` The results in CSV format can be found in the same directory! To see all my Airtag adventures check out my channel at https://www.youtube.com/c/AirtagAlex If this script was of use to you a referal in your video or project would be highly appreciated. ## Troubleshooting If you receive an `operation not permitted` error when running the script, please ensure that `Terminal` has `Full Disk Access` in the `Privacy & Security` settings in macOS. This is because of the file permissions on the `Items.data` file. Please propose an alternative or better way to do this if it's possible.