Skip to content

Silverquark/waybar-airpods-module

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

AirPods Waybar Module

A Waybar custom module that shows AirPods battery levels (left, right, case) with click-to-connect/disconnect.

Uses Apple's AAP (Apple Accessory Protocol) over a BlueZ Profile1 L2CAP socket to read battery notifications directly from the AirPods — no polling, no hacks.

Disconnected Connecting Connected
disconnected connecting connected

Features

  • Real-time battery for left bud, right bud, and case
  • Charging indicator (⚡) in tooltip
  • Click to connect/disconnect with visual "connecting" feedback
  • Duplicate click prevention while connecting
  • Auto-reconnects when AirPods come back in range

Requirements

  • Linux with BlueZ 5
  • Python 3 with PyGObject (gi — GLib/Gio bindings)
  • Waybar
  • bluetoothctl and rfkill (for click-to-toggle)

Install dependencies

Arch:

sudo pacman -S python-gobject bluez bluez-utils

Debian/Ubuntu:

sudo apt install python3-gi gir1.2-glib-2.0 bluez

Fedora:

sudo dnf install python3-gobject bluez

Setup

1. Find your AirPods MAC address

Pair your AirPods via your desktop's Bluetooth settings or bluetoothctl, then find the MAC:

bluetoothctl devices | grep -i airpods

Output looks like:

Device AA:BB:CC:DD:EE:FF XXXX's AirPods

2. Copy the script

cp airpods.py ~/.config/waybar/airpods.py
chmod +x ~/.config/waybar/airpods.py

3. Add the Waybar module

Add "custom/airpods" to your bar's module list in ~/.config/waybar/config.jsonc:

"modules-right": ["custom/airpods", "bluetooth", "network", "pulseaudio", "battery"],

Then add the module config (replace the MAC with yours):

"custom/airpods": {
    "exec": "~/.config/waybar/airpods.py AA:BB:CC:DD:EE:FF",
    "return-type": "json",
    "format": "{icon} ",
    "format-icons": {
        "connected": "󱡒",
        "disconnected": "󱡑",
        "connecting": "󱘖"
    },
    "on-click": "pkill -USR1 -f 'airpods\\.py'",
    "tooltip": true
}

Alternatively, set the MAC via environment variable and omit it from the exec line:

export AIRPODS_MAC="AA:BB:CC:DD:EE:FF"

4. Add styles

Add to ~/.config/waybar/style.css:

#custom-airpods {
    margin-right: 17px;
}

#custom-airpods.disconnected {
    opacity: 0.4;
}

#custom-airpods.connecting {
    opacity: 0.6;
}

#custom-airpods.warning {
    color: #f9e2af;
}

#custom-airpods.critical {
    color: #f38ba8;
}

5. Restart Waybar

killall waybar && waybar &

How it works

  1. The script registers a BlueZ Profile1 for the AAP UUID (74ec2172-0bad-4d01-8f77-997b2be0722a)
  2. When AirPods connect, BlueZ hands over an L2CAP file descriptor via NewConnection
  3. The script sends a handshake + notification request over the socket
  4. AirPods respond with battery packets containing left/right/case levels and charging status
  5. The script parses these and outputs JSON to stdout for Waybar
  6. D-Bus PropertiesChanged signals detect connect/disconnect events
  7. Clicking the module sends SIGUSR1 to toggle the connection

Battery states

Class Meaning
disconnected AirPods not connected
connecting Connection in progress
good Battery > 40%
warning Battery 21-40%
critical Battery ≤ 20%

Credits

AAP protocol based on Bluetooth-Battery-Meter by maniacx.

Disclaimer

This has only been tested with Airpods 2nd Gen, but others should work.

Full transparency: This project was built with heavy AI assistance. I provided the direction and requirements, but AI did most of the heavy lifting on implementation.

About

A simple waybar module to quickly connect airpods and see battery info

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages