[Fixed in 3.562] AirPods battery display breaks onto two lines

How fancy are you getting? :stuck_out_tongue: Just noticed that Catalina has this sweet menu when connected to Airpods Pro.

10_D0ycYQ

1 Like

I DEFINITELY want to support switching noise cancelling modes :smile:

1 Like

While I was tweaking the AirPods widgets, I realized the game controller icon is really out of date. I made a new one using the controller icon from Apple Arcade :slight_smile: I'm also adding xbox and DualShock controller support to the game controller connect button!

New icon for downloading:

game-controller

Also, I'm pretty sure I fixed the number display issue:

I'll work on adding the more compact display from the other AirPods thread once I've got everything working the way I want :slight_smile:

2 Likes

A pretty easy workaround could be just adding "& return &" after the return for L I actually had to do that anyway.

This is already done actually. But since Catalina, the script doesn't put out 2 values anymore, but 4, in a way I just don't get for now. Didn't manage yet to break it down on two lines or to retail's only lines containing a "%" to display. Don't know, maybe it will be easier just to read out the menu item from the Bluetooth Dropdown, would be way less smart though. Added to my post exam list.

could we text-edit the output and delete the two extra outputs with ApSc? Bandaid fix i know but well do we have anything else?

oh and I have no way of implementing that myself because I don’t have airpods and thus can’t get the glitched output :grimacing:

1 Like

This is what I was thinking about. Won't have time to check this out 'till next weekend, but then I'll have a look on it. It's way too annoying :roll_eyes:

Output (copy-paste from the Script Editor) looks like this:

19

94%

8

88%

The Script
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
		return BatteryLevel
	end if
	
end checkBattery

--thanks to @yyuuiko for the base of the code!

1 Like

So the desired output is the 94% and 88% right?

1 Like

Yupp. :+1:t4:

1 Like

I fixed this in my script by setting the variable to word 2 of the output and adding the percent symbol back in after the fact. :slight_smile:

1 Like

Gonna check this out right after my exam!!! Thanks for having looked into it!!!

PROBLEM SOLVED


If you already downloaded the AirPods Widget before, you just need to replace it by the AirPods Widget (Catalina Version). If this is the first time you install the Widget, please download and install the Reset AirPods Widget Trigger as well!

  1. AirPods (Catalina Version).json (67.9 KB)
  2. Reset AirPods Widget.json (1.8 KB)

Solved it indeed just by following @GoldenChaos's hint :+1:t4: The Widget is also integrated into my brand-new PHoeNiX preset :wink:


Important Reminder

  • If you use the "classic" name of the AirPods (like Caliguvara's AirPods) please do not type the name in the Window when asked! Instead, go to System Preferences… → Bluetooth select the device and copy the name there in order to paste it in BTT when asked. The name looks like it contains a simple ' but it seems to be some other character, so your AirPods won't be found if you type it.
  • If your AirPods have any other name (like AirMusic) just go ahead and type their name.

Here is the code of the new widget, for those who wonder

AirPods Battery Level Script
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 word 2 of OUTPUT2 & "%" & "
" & word 2 of OUTPUT1 & "%"

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!

Basically all that changed is the line

set BatteryLevel to word 2 of OUTPUT2 & "%" & "
" & word 2 of OUTPUT1 & "%"

which had been

set BatteryLevel OUTPUT2 & "
" & OUTPUT1

before :wink:

2 Likes

The AirPod battery indicator is cut off https://jepto.link/bF8qrB

@GoldenChaos this looks like your preset :man_shrugging:t4:

Is there a better place to lodge this bug for @GoldenChaos ?

Moved this thread to my preset's subforum (edit: actually merged with duplicate thread!) :slight_smile:

This has actually been fixed for a while in my internal build, but I'm still rewriting my bluetooth connect widgets. I'll post here when the new version has been uploaded!

1 Like

The only thing I changed with GoldenChaos' original script for AirPods Battery is add two variables and setting them to word 3 of batteryPercentLeft and batteryPercent Right. Then returning the values of these two variables. At first I had it set to word 2, but it seems the script returns 6 values total, 3 for left AirPods and 3 for right AirPods. I was wondering that no matter what the charge level was, it was returning the same two percentage levels. The correct battery percentage are word 3 of both left and right shell scripts.

So underneath the two battery percentage scripts I added:
set Output1 to word 3 of batteryPercentLeft & "%"
set Output2 to word 3 of batteryPercentRight & "%"

Then

return "L: " & Output1 & " " & "R: " & Output2

This correctly shows on the Touch Bar as "L: xx% R: xx%"

1 Like

Here are the updated battery widgets since I've been late getting the new version out the door! These are the same as the fixes posted by @Caliguvara and @Archenemy, just with the full widget code.

AirPods:

use framework "Foundation"
use framework "IOBluetooth"
use scripting additions

set pairedNames to ((current application's IOBluetoothDevice's pairedDevices())'s valueForKey:"nameOrAddress") as list
set connectedValue to ((current application's IOBluetoothDevice's pairedDevices())'s valueForKey:"connected") as list
set btInfo to {}

set i to 0
repeat with i from 1 to count pairedNames
	set btInfo to btInfo & (item i of pairedNames & ", " & item i of connectedValue) as list
end repeat

set i to 0
set deviceConnected to false
repeat with i from 1 to count btInfo
	if item i of btInfo contains "AirPods" and item i of btInfo does not contain "Pro" and item i of btInfo contains ", 1" then
		set deviceConnected to true
	else if item i of btInfo contains "The Temmie Flakes" and item i of btInfo contains ", 1" then
		set deviceConnected to true
	end if
end repeat

if deviceConnected is true then
	set batteryLevelLeft to do shell script "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=(\"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}\" ]] && OUTPUT=\"${OUTPUT}$(awk <<<\"${I}\")${!I}%\"; done; printf \"%s\" \"${OUTPUT}\"; else printf \"%s Not Connected\" \"${OUTPUT}\"; fi"
	set batteryLevelRight to do shell script "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=(\"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}\" ]] && OUTPUT=\"${OUTPUT}$(awk <<<\"${I}\")${!I}%\"; done; printf \"%s\" \"${OUTPUT}\"; else printf \"%s Not Connected\" \"${OUTPUT}\"; fi"
	set batteryPercentLeft to word 2 of batteryLevelLeft
	set batteryPercentRight to word 2 of batteryLevelRight
	return "L: " & batteryPercentLeft & "%  " & "R: " & batteryPercentRight & "%"
else
	return ""
end if

Beats:

use framework "Foundation"
use framework "IOBluetooth"
use scripting additions

set pairedNames to ((current application's IOBluetoothDevice's pairedDevices())'s valueForKey:"nameOrAddress") as list
set connectedValue to ((current application's IOBluetoothDevice's pairedDevices())'s valueForKey:"connected") as list
set btInfo to {}

set i to 0
repeat with i from 1 to count pairedNames
	set btInfo to btInfo & (item i of pairedNames & ", " & item i of connectedValue) as list
end repeat

set i to 0
set deviceConnected to false
repeat with i from 1 to count btInfo
	if item i of btInfo contains "Beats" and item i of btInfo contains ", 1" then
		set deviceConnected to true
	end if
end repeat

if deviceConnected is true then
	set batteryLevel to do shell script "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=(\"BatteryPercentSingle\"); 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}\" ]] && OUTPUT=\"${OUTPUT}$(awk <<<\"${I}\")${!I}%\"; done; printf \"%s\" \"${OUTPUT}\"; else printf \"%s Not Connected\" \"${OUTPUT}\"; fi"
	set batteryPercentage to word 2 of batteryLevel
	return "Battery: " & batteryPercentage & "%"
else
	return ""
end if

Hi,

Your code work good. I tried to put the "\n" to have left and right on 2 Lines, and it works too.
I would like to have your help for 2 thing, if possible, as I don't really know how to write a script.
Could you share how to alternate the icon please ? and also, is it possible to have the battery level of the case ?

Thank you for your help

This is now officially fixed in GC-BTT 3.562 :grinning_face_with_smiling_eyes: release notes and download:

Imprint | Privacy Policy