Compact AirPods widget with User-Friendly Setup

I'm having the same problem.

Please try this: go to system Settings → Bluetooth and copy your AirPods' Name there. Then paste it in BTT. There is some issue from macOS with the apostrophe in the name.

I've tried copying and pasting this code into the Apple Script button several times and can't get it to work. I'm not an experienced coder guy, admittedly. I can't figure out if I need to change something to my AirPods name, and if I do, where I do it.

After I compile and Run Script, I keep getting " " as a result.

Could I get a little help?

Plenty of stuff. The "original" widget didn't work? :confused:

No. When i pasted the original in the output after compiling and running was only: “ “

When i looked for where it came from, it appears to be bc some part of the code doesn’t return “yeet”

I haven't been following this closely, just a little note:

BTT 3.216 Alpha adds a few bluetooth predefined actions:

  • Connect Bluetooth Device
  • Disconnect Bluetooth Device
  • Toggle Bluetooth Device

These allow to connect to arbitrary bluetooth devices including the Airpods. Might be faster than the apple script solution.

I also added a dynamic variable that let's you know about the current connection state:
It starts with BluetoothConnectionState- and then takes either the bluetooth address (xx-xx-xx-xx-xx-xx) or the name of the device (wildcards * are allowed)

tell application "BetterTouchTool"
	get_number_variable "BluetoothConnectionState-*Pods*"
end tell
4 Likes

I hate you for the work it gives me, but love you for the possibilities you give us!! I'm definitely gonna check this out on a closer look!!!!! Thanks a lot!!!!

This is awesome! Will be redoing my bluetooth connect widgets now :smiley:

@Andreas_Hegenberg

Is there a variable for the list of bluetooth devices? A bluetooth picker in the TouchBar would be great

1 Like

currently not, but would be possible (for that I should add something like a "get_list_variable" function)

@Andreas_Hegenberg

also not related but kinda: could we have these bluetooth actions but for airplay?

I have a little something I'm having trouble getting to work:

@Andreas_Hegenberg This is a great addition and works great. This is a big improvement, just finished re coding my AirPod menu widgets. Great work, thanks for listening to us.

2 Likes

Can you share it!?

Hi!

I have made a couple of images for the AirPods Pro.

Grab them if you want :slight_smile:

Few others for you... They all look like a hair dryer to me...

AirPod Pro Case

If anyone is interested, here's a battery-checking code I wrote that is much easier to read, and it works for me.

use framework "IOBluetooth"
use scripting additions

set deviceList to current application's IOBluetoothDevice's pairedDevices()
set devNames to (deviceList's valueForKey:"name") as list
set devStatus to (deviceList's valueForKey:"connected") as list
set devAddress to (deviceList's valueForKey:"addressString") as list

tell application "BetterTouchTool" to set AirPodsName to get_string_variable "AirPodsWg_DevceName"

if devNames contains AirPodsName then
	--Device is found
	repeat with i from 1 to count devNames
		if (item i of devNames) = AirPodsName then
			--Get index of AirPods in the list and save connection status and MAC address value
			set connectValue to item i of devStatus
			set MAC_addr to item i of devAddress
			
			if connectValue = 1 then
				--Connected, get battery info using built-in tool "PlistBuddy"
				set BatteryLeft to do shell script "/usr/libexec/PlistBuddy -c \"print :DeviceCache:" & MAC_addr & ":BatteryPercentLeft\" /Library/Preferences/com.apple.Bluetooth.plist"
				set BatteryRight to do shell script "/usr/libexec/PlistBuddy -c \"print :DeviceCache:" & MAC_addr & ":BatteryPercentRight\" /Library/Preferences/com.apple.Bluetooth.plist"
				
				return BatteryLeft & "%
" & BatteryRight & "%"
			else
				--Not connected
				return "NC"
			end if
		end if
	end repeat
else
	--Device not found
	return "NC"
end if

There is a line in the previously published code that could cause some bugs:

set AppleScript's text item delimiters to "name:"

We should always save old delimiters first, and reset the delimiters when we finish, otherwise, you might get unexpected results, such as in set a to List as text.

1 Like

Late to the game, just got airpods :confused: Could you post your changes? I like how clean yours looks and seems to be the most up-to-date.

1 Like

@K2DesignLab, @Noon_Chen

If you could post an isolated preset with your presets widgets I can put them for download up the top page.

Who has the best one tho? :wink:
Is it possible to make the icon automatically change for the different types? Again, I don't own AirPods of any kind so it's a little hard for me to test this stuff.

Do you mean upload .bttpreset file?

As for automatically change airpods icon based on the model, it's possible!!

There is a key-value pair in com.apple.Bluetooth.plist called ProductID, which uniquely identifies the product. The screenshot below shows all the information you can get, VendorID and ProductID uniquely determines a product, in my case, 76 stands for Apple, and 8206 stands for AirPods Pro.

Below shows an example code, you can do all the artwork or optimizations.

use framework "IOBluetooth"
use scripting additions

set deviceList to current application's IOBluetoothDevice's pairedDevices()
set devNames to (deviceList's valueForKey:"name") as list
set devStatus to (deviceList's valueForKey:"connected") as list
set devAddress to (deviceList's valueForKey:"addressString") as list

--Add AirPods base64 iconData here, add new line if newer model is released.
set airpods_iconData to "emmm"
set airpods_pro_iconData to "emmm_pro"

--Set default icon and battery info to make the code more tidy
set batteryText to formatValue("0", "🅛") & "
" & formatValue("0", "🅡")
set currentModelIcon to airpods_iconData

tell application "BetterTouchTool" to set AirPodsName to get_string_variable "AirPodsWg_DevceName"

if devNames contains AirPodsName then
	--Device is found
	repeat with i from 1 to count devNames
		if (item i of devNames) = AirPodsName then
			--Get index of AirPods in the list and save connection status and MAC address value
			set connectValue to item i of devStatus
			set MAC_addr to item i of devAddress
			
			if connectValue = 1 then
				--Connected, update battery info using built-in tool "PlistBuddy"
				set BatteryLeft to do shell script "/usr/libexec/PlistBuddy -c \"print :DeviceCache:" & MAC_addr & ":BatteryPercentLeft\" /Library/Preferences/com.apple.Bluetooth.plist"
				set BatteryRight to do shell script "/usr/libexec/PlistBuddy -c \"print :DeviceCache:" & MAC_addr & ":BatteryPercentRight\" /Library/Preferences/com.apple.Bluetooth.plist"
				set ProductID to do shell script "/usr/libexec/PlistBuddy -c \"print :DeviceCache:" & MAC_addr & ":ProductID\" /Library/Preferences/com.apple.Bluetooth.plist"
				
				set batteryText to formatValue(BatteryLeft, "🅛") & "
" & formatValue(BatteryRight, "🅡")
				
				--set corresponding icon based on product id, I ignored vendorID for simplicity
				if ProductID = "8206" then
					--AirPods Pro
					set currentModelIcon to airpods_pro_iconData
					--else if ProductID = "xxxx" then --Add product ID of new model here
					--set currentModelIcon to newModel_iconData
				else
					--Default model: AirPods
					set currentModelIcon to airpods_iconData
				end if
			end if
			
			--return to break repeat loop
			return jsonData(currentModelIcon, batteryText)
		end if
	end repeat
else
	--Device not found, return default data
	return jsonData(currentModelIcon, batteryText)
end if

--Adding utf icon and % character
on formatValue(BatteryLevel, prefix)
	if BatteryLevel = "0" then
		--If one of AirPods is in the case, battery would be 0
		return prefix & "NC"
	else
		return prefix & BatteryLevel & "%"
	end if
end formatValue

--Format into json data that BTT can recognize
on jsonData(icon, batteryInfo)
	return "{\"text\":\"" & batteryInfo & "\", \"icon_data\": \"" & icon & "\", \"background_color\": \"47,55,65,255\"}"
end jsonData

For the battery of the case, you can actually get the data from that plist, but it is only available when you open the case and it became 0 if the case is closed. My thought is to create another button to display the case battery, and we must update the case battery manually by long-press or whatever.
@K2DesignLab Can you share your thoughts?

Would be great if you two could get some .bttpreset up! :smiley: