Airpods Battery Level Script No Longer Works (Monterey?)

Hi,
The script to check Airpods battery level used to work. It's not working anymore.
image

Both scripts outputs 71 and 68 regardless of the battery level.

/usr/libexec/PlistBuddy \
-c "Print :DeviceCache:d0-65-44-b9-9b-bf:BatteryPercentLeft" \
-c "Print :DeviceCache:d0-65-44-b9-9b-bf:BatteryPercentRight" \
-c "Print :DeviceCache:d0-65-44-b9-9b-bf:BatteryPercentCase" \
/Library/Preferences/com.apple.Bluetooth.plist
# Left
defaults read /Library/Preferences/com.apple.Bluetooth  | grep BatteryPercentLeft | tr -d \; | awk '{print "Left: " $3 " "}'

# Right
defaults read /Library/Preferences/com.apple.Bluetooth | grep BatteryPercentRight | tr -d \; | awk '{print "Right: " $3}'

# Case
#defaults read /Library/Preferences/com.apple.Bluetooth | grep BatteryPercentCase | tr -d \; | awk '{print "Case:" $3}'

It maybe due to the Monterey update.

Does anyone have a working script? @appleianer?

Thanks!

1 Like

My Mac Mini reports that my keyboard is powered at 1%, which is obviously wrong; I charge it almost daily. Do you have a wireless keyboard or mouse? I don't have AirPods.

I never knew about this command! Cool!

I do. But I don't care too much about keyboard or mouse battery level. Airpods lasts only a couple of hours. I'm more concerned about its battery level.

I was just trying to diagnose your problem by checking if the problem is limited to the AirPods or to everything. Did you check?

Thanks.
I believe the numbers are not updated for all devices.

Airpods:

			BatteryPercentCase = 37;
			BatteryPercentLeft = 71;
			BatteryPercentRight = 68;

Trackpad:

			BatteryPercent = 0;

image

@martin I also tried this but gave up after I found on the app AirBuddy.
When I open the case of the AirPods I get on the desktop the current battery level

Left: AirPods
right: Case

is displayed. As soon as I plug in the AirPods, the display changes to the battery status of the individual AirPods.

Then I can call up the battery display on the desktop at any time via a shortcut.

2021_12_04_Support_3

A notification about an individual battery level is also on board. You can choose between macOS notification or the AirBuddy Dispaly display.

2021_12_04_Support_2

But you can also get the battery levels via a widget.

The advantage is that I get all my bluetooth devices displayed and that across all devices (sync - MBP & iMac).

The price of AirBuddy... fair :wink:

1 Like

Thanks! This app looks very nice.
I just found a free app on Github: GitHub - mohamed-arradi/AirpodsBattery-Monitor-For-Mac: Widget that show your AirPods / AirPods Pro / Airpods Max battery directly from your MacOS status bar. M1 Macbook and Intel Macbook Compatible

image

I'm gonna try this app out. If it does not work well, I'll consider AirBuddy then.

2 Likes

@martin danke für Deine Link :+1:

I was able to find this script in the GitHub documentation:

11)AirPods - Batterie levels <654D 211204T214705>.kmmacros (27,3 KB)

#!/usr/bin/env bash
# Airpods.sh
# Output connected Airpods battery levels via CLI

BT_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth)
SYS_PROFILE=$(system_profiler SPBluetoothDataType 2>/dev/null)
MAC_ADDR=$(grep -b2 "Minor Type: "<<<"${SYS_PROFILE}"|awk '/Address/{print $3}')
regex_connected="(Connected:.+Yes)"

if [[ $SYS_PROFILE =~ $regex_connected ]]
then

#this regex won't work because of PRCE not working with some bash version (Connected:.Yes).(Vendor ID:.0x004C.)(Product ID:.*(Case.+%).+(Firmware Version:.[A-Z-a-z-0-9]+))
patwithCase="(.+)(Connected:.Yes).(Vendor ID:.0x004C.)(Product ID.*(Case.+%).+(Firmware.+Version:.+))"
patwithoutCase="(.+)(Connected:.Yes).(Vendor ID:.0x004C.)(Product ID.*.+(Firmware.+Version:.+))"
replace="?"

comp=$(echo ${SYS_PROFILE}  | sed "s/Address:/$replace/g")

set -f
IFS='?'
ary=($comp)
for key in "${!ary[@]}";
do
d=$(echo "${ary[$key]}")
data=""
macAddress=""
connectedStatus=""
vendorID=""
batteryLevel=""
firmwareVersion=""

if [[ $d =~ $patwithCase ]]
then
macAddress=$( echo "${BASH_REMATCH[1]}" | sed 's/ *$//g')
connectedStatus="${BASH_REMATCH[2]}"
vendorID="${BASH_REMATCH[3]}"
data="${BASH_REMATCH[4]}"
firmwareVersion=$(echo ${BASH_REMATCH[6]} | awk '{print $3}')

batterylevelregex="Case Battery Level: (.+%) Left Battery Level: (.+%) Right Battery Level: (.+%)"
batterySingleRegex="(BatteryPercentSingle) = ([0-9]+)"
if [[ $data =~ $batterylevelregex ]]
then
caseBattery="${BASH_REMATCH[1]}"
leftBattery="${BASH_REMATCH[2]}"
rightBattery="${BASH_REMATCH[3]}"
batteryLevel="${caseBattery} ${leftBattery} ${rightBattery}"
if [ -z "$batteryLevel" ]
then
echo ""
else
echo $macAddress"@@""$batteryLevel"
fi
elif [[ $data =~ $batterySingleRegex ]]
then
#IN PROGRESS - AIRPODS MAX (TO VERIFY)
batteryLevel=$macAddress"@@"${BASH_REMATCH[2]}
echo $batteryLevel
fi
elif [[ $d =~ $patwithoutCase ]]
then
macAddress=$( echo "${BASH_REMATCH[1]}" | sed 's/ *$//g')
connectedStatus="${BASH_REMATCH[2]}"
vendorID="${BASH_REMATCH[3]}"
data="${BASH_REMATCH[4]}"
firmwareVersion=$(echo ${BASH_REMATCH[6]} | awk '{print $3}')
batterylevelregex="Left Battery Level: (.+%) Right Battery Level: (.+%)"

if [[ $data =~ $batterylevelregex ]]
then
caseBattery="-1"
leftBattery="${BASH_REMATCH[1]}"
rightBattery="${BASH_REMATCH[2]}"
batteryLevel="${caseBattery} ${leftBattery} ${rightBattery}"
if [ -z "$batteryLevel" ]
then
echo ""
else
echo $macAddress"@@""$batteryLevel"
fi
fi
fi
done
else
echo "nc"
fi
exit 0

Unfortunately my script knowledge is not sufficient to create the variables (Case, Left, Right) for a notification.
Maybe there is someone here who can do that.

2 Likes

Thank you so much.
Without editing the script, we just need a RegEx action to get them:

Click to see screenshot

image

Result:

Click to see screenshot

image

1 Like

@martin that Looks very good, but I always get an error message:

Could you please share your macro here so I can try it on myself.
Do you also use the AirPods Pro?

Yes.
Here is the macro:
Airpods Pro Battery Level.kmmacros (6.5 KB)

Click to see screenshot

You must have Airpods connected. Otherwise, the variable local__batteryLevel will be empty.

1 Like

@martin the AirPods Pro are connected. I get the error message even with your macro. For some reason it is going wrong.

2021_12_05_Support_2

That's interesting. For some reason, the returned string on your Mac has a space between the digits and the % sign.
Add a space to the RegEx and see if it can capture it.
Try this:
Airpods Pro Battery Level.kmmacros (6.5 KB)

Click to see screenshot

1 Like

@martin thank you for the new macro. Unfortunately, I also get the same error message with this one (with the space).
Somehow the worm is in there for me.
I have also restarted the MBP. Still the same error message. I will try tomorrow to find the error.

Thank you very much for your help :+1:

Ps. luckily I still have Air Buddy :rofl:

Sorry to hear that.
Can you paste the output string to the forum?
If the characters are not changed by browser or forum server, then we can see what are the characters in the string.

1 Like

Do you mean this issue?

This is what I get as results when I run your macro.

Yes. But I mean the string, not the screenshot.
Just copy and paste the string there.

From the screenshot, there is no space between \d+ and %:
image

My new macro should have a space between them:
image

CC:C9:5D:50:C9:86@@21 % 42 % 35 %

I was able to get the result from your string:

image

Notice that there is a space between \d+ and %:

(\d+ %) (\d+ %) (\d+ %)