mohamed-arradi / AirpodsBattery-Monitor-For-Mac

Your AirPods Battery levels at your status bar | MacOS | Widget
MIT License
422 stars 29 forks source link

Broken #38

Closed makeSmartio closed 2 years ago

makeSmartio commented 2 years ago

This latest update appears to have broken everything for me - AirPods are no longer detected (versions 2 and 3.) I have not had time to troubleshoot yet. I will when I get time.

mohamed-arradi commented 2 years ago

Hi, I have updated the Oui.txt file which is responsible of testing if the device is an Apple device or not. In order to check take the 6 digits of your Airpods and check if you find it in the Oui.txt file. If yes it should be detected.

makeSmartio commented 2 years ago

Where in the code does it get the 6 digits - I can't find it! Edit: I found it: MAC_ADDR=$(grep -b2 "Minor Type: "<<<"${SYS_PROFILE}"|awk '/Address/{print $3}') but it isn't pulling up the MAC of my AirPods, it's pulling up my iPad MAC. What version of Monterey are you running? I just updated to 12.3

mohamed-arradi commented 2 years ago

So create a file named "something.sh" and fill inside a part of the script. which is this one below :

BT_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth)
SYS_PROFILE=$(system_profiler SPBluetoothDataType 2>/dev/null)
echo $SYS_PROFILE

Then execute it in a Terminal with the command (make sure to be on the correct folder path in the terminal):

sh something.sh

You should see all the Bluetooth devices connected . And you might see your Airpods Meta Data (MAC Address there).

You mention that it pulling up your iPad Mac. Does your iPad is connected via Bluetooth to your mac ?

Also in a second step (after doing the first one) order to debug completely, you can put the entire script below in the something.sh

#!/usr/bin/env bash
# Airpods.sh
# Output connected Airpods battery levels via CLI

BT_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth)
SYS_PROFILE=$(system_profiler SPBluetoothDataType 2>/dev/null)
MAC_ADDR=$(grep -b2 "Minor Type: "<<<"${SYS_PROFILE}"|awk '/Address/{print $3}')
regex_connected="(Connected:.+Yes)"

if [[ $SYS_PROFILE =~ $regex_connected ]]
then

#this regex won't work because of PRCE not working with some bash version (Connected:.Yes).(Vendor ID:.0x004C.)(Product ID:.*(Case.+%).+(Firmware Version:.[A-Z-a-z-0-9]+))
patwithCase="(.+)(Connected:.Yes).(Vendor ID:.0x004C.)(Product ID.*(Case.+%).+(Firmware.+Version:.+))"
patwithoutCase="(.+)(Connected:.Yes).(Vendor ID:.0x004C.)(Product ID.*.+(Firmware.+Version:.+))"
replace="?"

comp=$(echo ${SYS_PROFILE}  | sed "s/Address:/$replace/g")

set -f
IFS='?'
ary=($comp)
for key in "${!ary[@]}";
do
d=$(echo "${ary[$key]}")
data=""
macAddress=""
connectedStatus=""
vendorID=""
batteryLevel=""
firmwareVersion=""

if [[ $d =~ $patwithCase ]]
then
macAddress=$( echo "${BASH_REMATCH[1]}" | sed 's/ *$//g')
connectedStatus="${BASH_REMATCH[2]}"
vendorID="${BASH_REMATCH[3]}"
data="${BASH_REMATCH[4]}"
firmwareVersion=$(echo ${BASH_REMATCH[6]} | awk '{print $3}')

batterylevelregex="Case Battery Level: (.+%) Left Battery Level: (.+%) Right Battery Level: (.+%)"
batterySingleRegex="(BatteryPercentSingle) = ([0-9]+)"
if [[ $data =~ $batterylevelregex ]]
then
caseBattery="${BASH_REMATCH[1]}"
leftBattery="${BASH_REMATCH[2]}"
rightBattery="${BASH_REMATCH[3]}"
batteryLevel="${caseBattery} ${leftBattery} ${rightBattery}"
if [ -z "$batteryLevel" ]
then
echo ""
else
echo $macAddress"@@""$batteryLevel"
fi
elif [[ $data =~ $batterySingleRegex ]]
then
#IN PROGRESS - AIRPODS MAX (TO VERIFY)
batteryLevel=$macAddress"@@"${BASH_REMATCH[2]}
echo $batteryLevel
fi
elif [[ $d =~ $patwithoutCase ]]
then
macAddress=$( echo "${BASH_REMATCH[1]}" | sed 's/ *$//g')
connectedStatus="${BASH_REMATCH[2]}"
vendorID="${BASH_REMATCH[3]}"
data="${BASH_REMATCH[4]}"
firmwareVersion=$(echo ${BASH_REMATCH[6]} | awk '{print $3}')
batterylevelregex="Left Battery Level: (.+%) Right Battery Level: (.+%)"

if [[ $data =~ $batterylevelregex ]]
then
caseBattery="-1"
leftBattery="${BASH_REMATCH[1]}"
rightBattery="${BASH_REMATCH[2]}"
batteryLevel="${caseBattery} ${leftBattery} ${rightBattery}"
if [ -z "$batteryLevel" ]
then
echo ""
else
echo $macAddress"@@""$batteryLevel"
fi
fi
fi
done
else
echo "nc"
fi

And then run it with sh something.sh and see what you have printed on the console.

makeSmartio commented 2 years ago

Here is the string that macOS 12.3 returns:

Bluetooth: Bluetooth Controller: Address: 14:98:77:80:C1:33 State: On Chipset: BCM_4378 Discoverable: Off Firmware Version: 19.5.475.2668 Product ID: 0x0001 Supported services: 0x382039 < HFP AVRCP A2DP HID Braille AACP GATT Serial > Transport: PCIe 
Vendor ID: 0x004C (Apple) Connected: AirPods 3: Address: F8:4D:89:1B:12:0E Vendor ID: 0x004C Product ID: 0x2013 Case Battery Level: 62% Left Battery Level: 96% Right Battery Level: 92% Firmware Version: 4C170 Minor Type: Headphones RSSI: -62 Serial Number: xxxx Services: 0x1980019 < HFP AVRCP A2DP AACP GATT ACL SCO > 

Note the lack of "Yes" for connected

mohamed-arradi commented 2 years ago

Indeed that is exactly the issue. It seems that your Airpods 3 are not connected. Or at least recognized as connected from the system. Can you check if you can stream audio to it while having this script runner ?

On Mac OS sometimes the airpods battery can be retrieved by the system without being connected but I restricted the use to be when connected only.

that is because of this regex from the script : (.+)(Connected:.Yes).

makeSmartio commented 2 years ago

Yes, audio is working properly. I verified that this is the new string for the new MacOS update with no "Connected: Yes"

mohamed-arradi commented 2 years ago

@makeSmartio The issue should be solved now with the latest release.

Indeed I released it just before 12.3, therefore the new breaking changes was not applied. Can you confirm that it is working with the latest release (make sure to remove old ones from the login startup settings too).

PR linked to it: https://github.com/mohamed-arradi/AirpodsBattery-Monitor-For-Mac/pull/39

makeSmartio commented 2 years ago

Yes, it is working great for my AirPod 2's and 3's! Nice work! Thanks!