Skip to main content

Pure-Python parser for Apple Continuity BLE proximity-pairing adverts (AirPods battery + Apple device presence)

Project description

Apple

apple-ble

CI PyPI Python License: MIT

Read AirPods battery (case / left / right + charging) and detect nearby Apple devices from Python, straight off the unencrypted Apple Continuity proximity-pairing BLE advertisement — no pairing, no connection.

This library powers the Apple BLE Home Assistant integration, but works standalone in any Python project (or straight from the command line). The parser is pure and dependency-free; bleak is only needed for the optional scanner CLI.

What works: AirPods broadcast their battery in an unencrypted Continuity advert when the lid is opened. What doesn't: Apple Watch / iPhone do not put battery in their adverts — BLE can only tell you an Apple device is nearby. Apple rotates the BLE MAC (~15 min), so there is no stable per-device id.

Features

  • 🔋 AirPods battery — case, left, and right levels plus per-pod and case charging flags, decoded from the manufacturer-0x004C proximity-pairing advert.
  • 🎧 Model detection — AirPods 1/2/3, Pro, Pro 2, Max.
  • 📡 Presence-friendly — exposes the Apple manufacturer id so callers can count nearby Apple devices.
  • 🧪 Pure parserparse_proximity_pairing(bytes) -> AirPodsData | None, no I/O, trivially unit-testable.
  • 🖥️ CLIapple-ble scans and prints any AirPods it sees (needs the cli extra).

Requirements

  • Python 3.12 or newer.
  • A Bluetooth LE adapter (built-in or USB) — only for live scanning; the parser itself needs nothing.

Installation

pip install apple-ble            # core (parsing only)
pip install "apple-ble[cli]"     # + bleak scanner CLI

CLI usage

apple-ble    # 15s BLE scan; open your AirPods lid nearby and watch the battery

Library usage

from apple_ble import parse_proximity_pairing, APPLE_MANUFACTURER_ID

# `payload` is manufacturer_data[76] from any BLE stack (bleak, Home Assistant, ...)
data = parse_proximity_pairing(payload)
if data:
    print(data.model, data.left_battery, data.right_battery, data.case_battery)
    print(data.left_charging, data.right_charging, data.case_charging)

parse_proximity_pairing returns None for anything that isn't a complete AirPods proximity-pairing advert, so it is safe to feed it every Apple advert you see and keep the non-None results.

API

Symbol Description
parse_proximity_pairing(data) Parse manufacturer_data[76] bytes into AirPodsData, or None if it isn't AirPods.
AirPodsData Frozen dataclass: model, left_battery, right_battery, case_battery (int % or None), left_charging, right_charging, case_charging.
decode_battery_nibble(nibble) Pure helper: a 0x00xF battery nibble to a percentage (None when not present).
APPLE_MANUFACTURER_ID 76 (0x004C) — Apple's Bluetooth company id.
MODEL_BY_CHAR Mapping of the model nibble to a human model name.

Credits

Continuity reverse-engineering: furiousMAC/continuity, kavishdevar/librepods, delphiki/AirStatus, d4rken-org/capod. Author @hudsonbrendon.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

apple_ble-0.1.1.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

apple_ble-0.1.1-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file apple_ble-0.1.1.tar.gz.

File metadata

  • Download URL: apple_ble-0.1.1.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for apple_ble-0.1.1.tar.gz
Algorithm Hash digest
SHA256 133ee2d389d1c05d65b166d0aea7a864e527e704fc42eea863c1d5762d00e345
MD5 ea525551836b161203d03b9200e0d6c9
BLAKE2b-256 d7b314eb4e8731d1d7945f602d8c65810ce720dd65d43d550174250575d59f70

See more details on using hashes here.

File details

Details for the file apple_ble-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: apple_ble-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for apple_ble-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 75fd4932583c658972f1cc4eb8bf7bebbceb9160be09a6493e1cbaf8a8c77cf3
MD5 9b5cdd327151b4bbcfb76cd7d4677a5f
BLAKE2b-256 7f47c0dcea13ac397e7593290edf2da8a2beaabbe2ffe69c762567e27b550429

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page