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

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:

Hi there!

Thanks for your amazing job!

If we wanted to have the percentage in multiple (2) lines, how can we do it? Seems better to me and more compact to see 2 lines in one button.

Thanks