Compact AirPods widget with User-Friendly Setup

I use AirPods 1. I tried installing the files, and when I press the button it will help me toggle between connect/disconnect AirPods, however, it does not display the battery of each AirPod. So it only half works.

Did you install the trigger too? You might have to hold the widget once to set it up.

Yes, all installed. Held the button and copied + pasted AirPods name in, yet it still doesn't show battery. It does connect and disconnect when I press the button though

Sorry to interrupt, would you please do me a favor? I just want to check the ProductID of AirPods 1.

It's very simple, run defaults read /Library/Preferences/com.apple.Bluetooth in the Terminal, then press ⌘+F to search ProductID = 8194, see if there are any matches?

Yupp, there is a match @Noon_Chen :+1:t4:

What does the script return?

@Caliguvara Thanks! Now I can confirm the ProductID is related to the model of AirPods:
8206 stands for AirPods Pro
8207 stands for AirPods 2
8194 stands for AirPods 1.

@yuuiko AirPods Battery_auto icon.bttpreset (30.3 KB)
Here is my preset that can automatically change the icon based on the model and connection status. I only test with my airpods pro, it works, but I need other airpods users to help me test it.

(really need some sleep now...

2 Likes

I had same issue, renamed my airpods to remove all spaces and then it worked

ie: AirPod Pros > AirPod_Pros

Nothing. When the button is pressed, all that will happen is it will connect or disconnect from my airpods. When the airpods are connected, no battery level is displayed.

@Ryan_Mak You can copy the code in the widget and paste it into Script Editor (a mac built-in app), run the code to see if there's any error.

My guess is that the name of your airpods is not correct, because that's the reason why it didn't work for me at the 1st time :-/ Be ware of two different apostrophes: ' and ’.

Or you can run the following code in script editor to see the name of you airpods that stored in the bluetooth.plist

use framework "IOBluetooth"
use scripting additions

set deviceList to current application's IOBluetoothDevice's pairedDevices()
return (deviceList's valueForKey:"name") as list

Copy the airpods name in the result and try again.

BTW, Would you please to test the code that I uploaded for me?

1 Like

Thanks so much. It works now.

Regarding your AirPods widget, it seems to work (it shows the AirPods original icon)

@Noon_Chen Your preset works great! Just one question though: is it possible to make it so when it is connected or disconnected the icon itself doesn't move? So this would be making the icon be the same size and in the same space (the indicator of connected or not connected is just whether or not the icon is highlighted or not).
Thanks!

@Krieii The button length is changing because of the varied text length, you can check the following option in the Common setting to ensure the icon is not moving around.
image

@Noon_Chen Thanks for the suggestion, but I have tried that already!
Here is my settings:


Here is my touchbar with my AirPods connected:

And here is my touchbar with my AirPods not connected:

As you can see, even with the fixed width, the icon and text moves even with the button size remaining the same.

Thanks,
Krieii

I see, this is still due to the size change of the text, try “align left” in the font setting.

IF the above doesn’t work, you can @ admin and ask him how to align the icon to the left.

I get the battery script working, but the 1.2 version will not keep the AirPods name - always asks again for it

EDIT:
I could edit the catalina.json script and it connects and disconnects - but I don't get the icon. It shows shortly and than ist gone :-(( Please help

@Caliguvara?

(i feel pretty helpless without airpods.....)

Sorry for some reason I missed this post!

I have honestly no clue why this doesn't work out for @tosbsas! I just downloaded the 1.2 version again and it works fine here!

I changed the script a little bit with that version, maybe try to copy-paste the attached script and replace the one of your widget (the widget script itself, not the associated action):

return checkStatus()

on checkStatus()
	--GET STORED NAME
	tell application "BetterTouchTool"
		--attempt to get variable
		try
			set LclAirPodsName to get_string_variable "AirPodsWg_DevceName"
		end try
	end tell
	--END GET STORED NAME
	
	--set myString to button returned of (display dialog "Connected?" buttons {"Yes", "No"})
	--set myString to "name: DR-BT101 Connected: " & myString
	
	(*uncomment line below when done testing*)
	set myString to do shell script "system_profiler SPBluetoothDataType"
	
	--initial check if it's not even there
	if myString does not contain LclAirPodsName then
		return " "
	else
		
		--find out if connected/disconnected
		set AppleScript's text item delimiters to "name:"
		set myList to the text items of myString --each item of mylist is now one of the devices
		
		set numberOfDevices to count of myList
		set counter to 1
		repeat numberOfDevices times --loop through each devices checking for Connected string
			if item counter of myList contains LclAirPodsName then
				if item counter of myList contains "Connected: Yes" then
					return checkBattery()
				else if item counter of myList contains "Connected: No" then
					return " "
				else
					display dialog "Error Parsing" --this shouldn't happen
				end if
			end if
			set counter to counter + 1
		end repeat
	end if
end checkStatus

on checkBattery()
	set OUTPUT1 to do shell script "
OUTPUT1='';
BLUETOOTH_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth);
SYSTEM_PROFILER=$(system_profiler SPBluetoothDataType); 
MAC_ADDR=$(grep -b2 \"Minor Type: Headphones\"<<<\"${SYSTEM_PROFILER}\"|awk '/Address/{print $3}'); 
CONNECTED=$(grep -ia6 \"${MAC_ADDR}\"<<<\"${SYSTEM_PROFILER}\"|awk '/Connected: Yes/{print 1}'); 
BLUETOOTH_DATA=$(grep -ia6 '\"'\"${MAC_ADDR}\"'\"'<<<\"${BLUETOOTH_DEFAULTS}\"); 
BATTERY_LEVELS=(\"BatteryPercentCombined\" \"HeadsetBattery\" \"BatteryPercentSingle\" \"BatteryPercentRight\"); 

if [[ \"${CONNECTED}\" ]];
 then 
 for I in \"${BATTERY_LEVELS[@]}\";
  do 
  declare -x \"${I}\"=\"$(awk -v pat=\"${I}\" '$0~pat{gsub (\";\",\"\"); print $3}'<<<\"${BLUETOOTH_DATA}\")\";
   [[ ! -z \"${!I}\" ]] && 
   OUTPUT1=\"${OUTPUT}$(awk '/BatteryPercent/{print substr($0)}'<<<\"${I}\")${!I}%\";
    done;
    printf \"%s\" \"${OUTPUT1}\";
fi"
	
	set OUTPUT2 to do shell script "
OUTPUT2='';
BLUETOOTH_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth);
SYSTEM_PROFILER=$(system_profiler SPBluetoothDataType); 
MAC_ADDR=$(grep -b2 \"Minor Type: Headphones\"<<<\"${SYSTEM_PROFILER}\"|awk '/Address/{print $3}'); 
CONNECTED=$(grep -ia6 \"${MAC_ADDR}\"<<<\"${SYSTEM_PROFILER}\"|awk '/Connected: Yes/{print 1}'); 
BLUETOOTH_DATA=$(grep -ia6 '\"'\"${MAC_ADDR}\"'\"'<<<\"${BLUETOOTH_DEFAULTS}\"); 
BATTERY_LEVELS=(\"BatteryPercentCombined\" \"HeadsetBattery\" \"BatteryPercentSingle\" \"BatteryPercentLeft\"); 

if [[ \"${CONNECTED}\" ]];
 then 
 for I in \"${BATTERY_LEVELS[@]}\";
  do 
  declare -x \"${I}\"=\"$(awk -v pat=\"${I}\" '$0~pat{gsub (\";\",\"\"); print $3}'<<<\"${BLUETOOTH_DATA}\")\";
   [[ ! -z \"${!I}\" ]] && 
   OUTPUT2=\"${OUTPUT}$(awk '/BatteryPercent/{print substr($0)}'<<<\"${I}\")${!I}%\";
    done;
    printf \"%s\" \"${OUTPUT2}\";
fi"
	if OUTPUT2 is " " then
		return " "
	else
		set BatteryLevel to word 2 of OUTPUT2 & "%" & "
" & word 2 of OUTPUT1 & "%"
	end if
	if BatteryLevel is "" & "
" & "" then
		return " "
	else
		return BatteryLevel
	end if
	
end checkBattery

--thanks to @yyuuiko for the base of the code!
--thanks to @GoldenChaos for the great problemsolving idea for Catalina!

EDIT: I understand from the other thread that you use AirPods Pro. Not sure regarding compatibility. Maybe try this code for AirPods Pro, idk if it still works though that's why I didn't publish it yet (I wrote it months ago when I could get hands on a pair of AirPods Pro for an afternoon).

return checkStatus()

on checkStatus()
	--GET STORED NAME
	tell application "BetterTouchTool"
		--attempt to get variable
		try
			set LclAirPodsName to get_string_variable "AirPodsWg_DevceName"
		end try
	end tell
	--END GET STORED NAME
	
	--set myString to button returned of (display dialog "Connected?" buttons {"Yes", "No"})
	--set myString to "name: DR-BT101 Connected: " & myString
	
	(*uncomment line below when done testing*)
	set myString to do shell script "system_profiler SPBluetoothDataType"
	
	--initial check if it's not even there
	if myString does not contain LclAirPodsName then
		return " "
	else
		
		--find out if connected/disconnected
		set AppleScript's text item delimiters to "name:"
		set myList to the text items of myString --each item of mylist is now one of the devices
		
		set numberOfDevices to count of myList
		set counter to 1
		repeat numberOfDevices times --loop through each devices checking for Connected string
			if item counter of myList contains LclAirPodsName then
				if item counter of myList contains "Connected: Yes" then
					return checkBattery()
				else if item counter of myList contains "Connected: No" then
					return " "
				else
					display dialog "Error Parsing" --this shouldn't happen
				end if
			end if
			set counter to counter + 1
		end repeat
	end if
end checkStatus

on checkBattery()
	set OUTPUT1 to do shell script "
OUTPUT1='';
BLUETOOTH_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth);
SYSTEM_PROFILER=$(system_profiler SPBluetoothDataType); 
MAC_ADDR=$(grep -b2 \"Minor Type: Headphones\"<<<\"${SYSTEM_PROFILER}\"|awk '/Address/{print $3}'); 
CONNECTED=$(grep -ia6 \"${MAC_ADDR}\"<<<\"${SYSTEM_PROFILER}\"|awk '/Connected: Yes/{print 1}'); 
BLUETOOTH_DATA=$(grep -ia6 '\"'\"${MAC_ADDR}\"'\"'<<<\"${BLUETOOTH_DEFAULTS}\"); 
BATTERY_LEVELS=(\"BatteryPercentCombined\" \"HeadsetBattery\" \"BatteryPercentSingle\" \"BatteryPercentRight\"); 

if [[ \"${CONNECTED}\" ]];
 then 
 for I in \"${BATTERY_LEVELS[@]}\";
  do 
  declare -x \"${I}\"=\"$(awk -v pat=\"${I}\" '$0~pat{gsub (\";\",\"\"); print $3}'<<<\"${BLUETOOTH_DATA}\")\";
   [[ ! -z \"${!I}\" ]] && 
   OUTPUT1=\"${OUTPUT}$(awk '/BatteryPercent/{print substr($0)}'<<<\"${I}\")${!I}%\";
    done;
    printf \"%s\" \"${OUTPUT1}\";
fi"
	
	set OUTPUT2 to do shell script "
OUTPUT2='';
BLUETOOTH_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth);
SYSTEM_PROFILER=$(system_profiler SPBluetoothDataType); 
MAC_ADDR=$(grep -b2 \"Minor Type: Headphones\"<<<\"${SYSTEM_PROFILER}\"|awk '/Address/{print $3}'); 
CONNECTED=$(grep -ia6 \"${MAC_ADDR}\"<<<\"${SYSTEM_PROFILER}\"|awk '/Connected: Yes/{print 1}'); 
BLUETOOTH_DATA=$(grep -ia6 '\"'\"${MAC_ADDR}\"'\"'<<<\"${BLUETOOTH_DEFAULTS}\"); 
BATTERY_LEVELS=(\"BatteryPercentCombined\" \"HeadsetBattery\" \"BatteryPercentSingle\" \"BatteryPercentLeft\"); 

if [[ \"${CONNECTED}\" ]];
 then 
 for I in \"${BATTERY_LEVELS[@]}\";
  do 
  declare -x \"${I}\"=\"$(awk -v pat=\"${I}\" '$0~pat{gsub (\";\",\"\"); print $3}'<<<\"${BLUETOOTH_DATA}\")\";
   [[ ! -z \"${!I}\" ]] && 
   OUTPUT2=\"${OUTPUT}$(awk '/BatteryPercent/{print substr($0)}'<<<\"${I}\")${!I}%\";
    done;
    printf \"%s\" \"${OUTPUT2}\";
fi"
	
	set BatteryLevel to OUTPUT2 & "
" & OUTPUT1
	
	if BatteryLevel is "" & "
" & "" then
		return " "
	else
		if OUTPUT2 is " " then
			return " "
		else
			return OUTPUT2 & "
" & OUTPUT1
		end if
		
	end if
	
end checkBattery

--thanks to @yyuuiko for the base of the code!
--thanks to @GoldenChaos for the great problemsolving idea for Catalina!
1 Like

you are the man - the second script fixed it :-)) I get the icon and after changing the wording in the script I got it all as it should - yeah

One question remains - I don't see the icon on app specific touchbar settings - any way to accomplish that? Is there copy paste or something like that? (:-)) found that too

1 Like

If I remember correctly that's because the icons provided by @yuuiko are white (white on white has such a high contrast :wink:). Try these
AirPods Icon AirPods Icon_2