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!
- AirPods (Catalina Version).json (67.9 KB)
- Reset AirPods Widget.json (1.8 KB)
Solved it indeed just by following @GoldenChaos's hint
The Widget is also integrated into my brand-new PHoeNiX preset
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
The AirPod battery indicator is cut off https://jepto.link/bF8qrB
@GoldenChaos this looks like your preset
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!)
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!
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%"
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 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