You can find information on my terminal configuration here
Last active
November 2, 2024 03:12
-
-
Save Jahhein/45b8e8c9c36a0932189a5037f990bcdd to your computer and use it in GitHub Desktop.
Display Apple AirPods battery levels via Terminal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Airpods.sh | |
# Output connected Airpods battery levels via CLI | |
AIRPOD_ICON=$'\uF7CC' | |
BATTERY_INFO=( | |
"BatteryPercentCombined" | |
"HeadsetBattery" | |
"BatteryPercentSingle" | |
"BatteryPercentCase" | |
"BatteryPercentLeft" | |
"BatteryPercentRight" | |
) | |
BT_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth) | |
SYS_PROFILE=$(system_profiler SPBluetoothDataType 2>/dev/null) | |
MAC_ADDR=$(grep -b2 "Minor Type: Headphones"<<<"${SYS_PROFILE}"|awk '/Address/{print $3}') | |
CONNECTED=$(grep -ia6 "${MAC_ADDR}"<<<"${SYS_PROFILE}"|awk '/Connected: Yes/{print 1}') | |
BT_DATA=$(grep -ia6 '"'"${MAC_ADDR}"'"'<<<"${BT_DEFAULTS}") | |
if [[ "${CONNECTED}" ]]; then | |
for info in "${BATTERY_INFO[@]}"; do | |
declare -x "${info}"="$(awk -v pat="${info}" '$0~pat{gsub (";",""); print $3 }'<<<"${BT_DATA}")" | |
[[ ! -z "${!info}" ]] && OUTPUT="${OUTPUT} $(awk '/BatteryPercent/{print substr($0,15)": "}'<<<"${info}")${!info}%" | |
done | |
printf "%s\\n" "${AIRPOD_ICON} ${OUTPUT}" | |
else | |
printf "%s Not Connected\\n" "${OUTPUT}" | |
fi | |
exit 0 |
Instead of my hacky one-off solution, here's a more generalized solution. Though I'm sure there's a more elegant terser way of doing it.
Just replace the CONNECTED=$(...)
line with this:
CONNECTED=""
for m in ${MAC_ADDR} ; do
grep -ia6 "${m}"<<<"${SYS_PROFILE}"|awk '/Connected: Yes/{print 1}' | grep 1 && MAC_ADDR="$m" && CONNECTED=1 && break ;
done
That just checks if each mac address is connected, and when it finds a connected one, redefines MAC_ADDR
to just the value of the connected pair.
Edit: Put this in a fork available here: https://gist.github.com/varenc/6300183cc2be8a4d4a1dd941eb2f5766
Running the script returns "Not connected", although my Airpods Max are connected. Is this no longer working?
Running the script returns "Not connected", although my Airpods Max are connected. Is this no longer working?
Same problem with AirPods 2
The script here doesn't work for me, but this command does:
system_profiler SPBluetoothDataType 2>/dev/null | grep -o "Left Battery Level: [0-9]*%" | grep -o "[0-9]*%"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script is great! And shows me some advanced shell-fu.
Though there's an issue with it when you have multiple pairs of Headphone/AirPods that were at one point paired to your system.
For me, this line returns multiple mac addresses, all of ones previously connected along with the actually connected one:
MAC_ADDR=$(grep -b2 "Minor Type: Headphones"<<<"${SYS_PROFILE}"|awk '/Address/{print $3}')
That means that later when
$(awk -v pat="${info}" '$0~pat{gsub (";",""); print $3 }'<<<"${BT_DATA}")
is called, it somehow fetches old battery data for every pair of old headphones. And my output ends up looking like this. Only one of those battery values matches my currently in-use airpods, the rest must be old cached battery values...?My hacky fixes is just to limit the mac_addr fetch to the specific pair of airpods I actually use like this:
MAC_ADDR=$(grep -b2 "Minor Type: Headphones"<<<"${SYS_PROFILE}"|awk '/Address/{print $3}' | grep "<my airpods mac address>")
(I easily lookup the mac address for my airpods using the amazing
BluetoothConnector
util.)