maniacx / Airpod-Battery-Monitor

A Gnome extension for monitoring battery level of AirPods and Beats Bluetooth headset
https://extensions.gnome.org/extension/6778/airpod-battery-monitor/
GNU General Public License v3.0
36 stars 8 forks source link

Scanning but airpods not detected #7

Open maniacx opened 7 months ago

maniacx commented 7 months ago

Hey @maniacx,

First off, thanks for creating this extension man. Super exciting to have this functionality in Linux!

I am having an issue using Manjaro with Gnome 45.x and my AirPods Pros (1st Gen). I followed the steps in the documentation, but it still appears to be 'scanning' and not giving me any battery life details. I left the computer on for 10-15 mins, and still no battery information.

Is this normal? If not, can I send some logs or something to help troubleshoot what the root issue may be?

Thanks in advance for all of your time and help, it is greatly appreciated!

@a4orce84 moving your post here.

Disable the extension Run this script test.js . https://maniacx.github.io/Airpod-Battery-Monitor/bugs-feature-request#script

This will script will scan nearby all airpods and return the manufacturer data model and other battery info. I may take some may be a minute or more to post the output.

Post the result here

a4orce84 commented 7 months ago

Hey @maniacx,

For some reason, I did not get any output. Here is a screenshot with my AirPods connected and the script running: https://i.imgur.com/8xXq5fZ.jpeg

If you need any additional details, please let me know. Thank you for the help!

maniacx commented 7 months ago

Strange. Ok let try this manually.

keep extension disabled. Make sure the airpods are ON and connected.

in terminal/console start bluetoothctl

Then type scan le This will start discovery and show RSSI (signal strength) all bluetooth devices nearby. Some bluetooth device is airpods will also advertise ManufacturerKey and Data. When you see one or more Manufacturer data post the results here.

I will look something like this.

Screenshot from 2024-02-27 12-07-58

Btw, you can attach pictures and files here. no need to upload them on imgur

Edit: After you get manufacturerdata you can stop discovery by typing scan off and exit bluetoothctl.

Some explaination: 0x04C (76) are apple devices such as iphone, airpods etc/ manufacturerdata starting with 0719 and 0713 are airpods and fake airpods (as per CApod android app developer)

a4orce84 commented 7 months ago

Strange. Ok let try this manually.

keep extension disabled. Make sure the airpods are ON and connected.

in terminal/console start bluetoothctl

Then type scan le This will start discovery and show RSSI (signal strength) all bluetooth devices nearby. Some bluetooth device is airpods will also advertise ManufacturerKey and Data. When you see one or more Manufacturer data post the results here.

I will look something like this.

Screenshot from 2024-02-27 12-07-58

Btw, you can attach pictures and files here. no need to upload them on imgur

Edit: After you get manufacturerdata you can stop discovery by typing scan off and exit bluetoothctl.

Some explaination: 0x04C (76) are apple devices such as iphone, airpods etc/ manufacturerdata starting with 0719 and 0713 are airpods and fake airpods (as per CApod android app developer)

Output: wugiSmy

Hmm, maybe some other issue is going on? When I run the 'devices' command, I can see my Airpods: nYvTA9W

Let me know what else I should try if you need more details. Thanks!

maniacx commented 7 months ago

For some reason you discorvry doest start becuase it is already in progress. Disable the extension Airpod battery Monitor. If you have opened any windows for GNOME settings > Bluetooth, close it.

Then follow the steps.

Screencast from 2024-02-27 13-51-52.webm

If it doesnt scan any device, restart the system and try again. Also are you running any python script, such as AirStatus . May need to stop them.

a4orce84 commented 7 months ago

Thanks for the video @maniacx. For some reason, I am still getting that, "Failed to start discovery: org.bluez.Error.InProgress" error message. I made sure that the Battery Monitor extension is disabled and even did a restart, but as soon as I try the "scan le" command, I get the error message.

Not sure what's going on, I'll do some googling to see if I can find anything out. Please let me know if I can provide anymore details to assist in the troubleshooting process.

Thanks maniacx!

maniacx commented 7 months ago

Did you try to stop discovery before start

bluetoothctl scan off scan le

or try scan on bluetoothctl scan off scan on

I think you may have some other scripts or apps running that always keep discovery on

a4orce84 commented 7 months ago

Looks like 'scan on' started, but 'scan le' is still not working.

Screenshots: 21V3fo6 uKQOhST

Please let me know if 'scan on' gets us any closer. I'll look at my other extensions + scripts again if there's anything bluetooth related.

Thanks!

maniacx commented 7 months ago

Ok. Let me explain. scan on is to scan all type of device. scan le is to only scan ble devices, which is way faster and shorter list.

try only scan on and wait to see if airpods manufacturerdata appears.

bluetoothctl scan off scan on

then monitor for a minute and see if any device adbertise manufacturerdata

maniacx commented 7 months ago

also try with root

sudo bluetoothctl scan off scan le

And you bluez vesion bluetoothctl --version .

a4orce84 commented 7 months ago

Still no luck. Latest output below:

Screenshot: hIOpjEV

Let me know if there's another set of commands you'd like me to try. Thank you again for your help!

maniacx commented 7 months ago

Post output of

cat /etc/bluetooth/main.conf
a4orce84 commented 7 months ago

Output:

[General]

# Default adapter name
# Defaults to 'BlueZ X.YZ'
#Name = BlueZ

# Default device class. Only the major and minor device class bits are
# considered. Defaults to '0x000000'.
#Class = 0x000100

# How long to stay in discoverable mode before going back to non-discoverable
# The value is in seconds. Default is 180, i.e. 3 minutes.
# 0 = disable timer, i.e. stay discoverable forever
#DiscoverableTimeout = 0

# Always allow pairing even if there are no agent registered
# Possible values: true, false
# Default: false
#AlwaysPairable = false

# How long to stay in pairable mode before going back to non-discoverable
# The value is in seconds. Default is 0.
# 0 = disable timer, i.e. stay pairable forever
#PairableTimeout = 0

# Use vendor id source (assigner), vendor, product and version information for
# DID profile support. The values are separated by ":" and assigner, VID, PID
# and version.
# Possible vendor id source values: bluetooth, usb (default) or false (disabled)
#DeviceID = bluetooth:1234:5678:abcd

# Do reverse service discovery for previously unknown devices that connect to
# us. For BR/EDR this option is really only needed for qualification since the
# BITE tester doesn't like us doing reverse SDP for some test cases, for LE
# this disables the GATT client functionally so it can be used in system which
# can only operate as peripheral.
# Defaults to 'true'.
#ReverseServiceDiscovery = true

# Enable name resolving after inquiry. Set it to 'false' if you don't need
# remote devices name and want shorter discovery cycle. Defaults to 'true'.
#NameResolving = true

# Enable runtime persistency of debug link keys. Default is false which
# makes debug link keys valid only for the duration of the connection
# that they were created for.
#DebugKeys = false

# Restricts all controllers to the specified transport. Default value
# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
# Possible values: "dual", "bredr", "le"
ControllerMode = bredr

# Maximum number of controllers allowed to be exposed to the system.
# Default=0 (unlimited)
#MaxControllers=0

# Enables Multi Profile Specification support. This allows to specify if
# system supports only Multiple Profiles Single Device (MPSD) configuration
# or both Multiple Profiles Single Device (MPSD) and Multiple Profiles Multiple
# Devices (MPMD) configurations.
# Possible values: "off", "single", "multiple"
#MultiProfile = off

# Permanently enables the Fast Connectable setting for adapters that
# support it. When enabled other devices can connect faster to us,
# however the tradeoff is increased power consumptions. This feature
# will fully work only on kernel version 4.1 and newer. Defaults to
# 'false'.
#FastConnectable = false

# Default privacy setting.
# Enables use of private address.
# Possible values for LE mode: "off", "network/on", "device"
# Possible values for Dual mode: "off", "network/on", "device",
# "limited-network", "limited-device"
#
# - off: Local privacy disabled.
#
# - network/on: A device will only accept advertising packets from peer
# devices that contain private addresses. It may not be compatible with some
# legacy devices since it requires the use of RPA(s) all the time.
#
# - device: A device in device privacy mode is only concerned about the
# privacy of the device and will accept advertising packets from peer devices
# that contain their Identity Address as well as ones that contain a private
# address, even if the peer device has distributed its IRK in the past.

# - limited-network: Apply Limited Discoverable Mode to advertising, which
# follows the same policy as to BR/EDR that publishes the identity address when
# discoverable, and Network Privacy Mode for scanning.
#
# - limited-device: Apply Limited Discoverable Mode to advertising, which
# follows the same policy as to BR/EDR that publishes the identity address when
# discoverable, and Device Privacy Mode for scanning.
#
# Defaults to "off"
#Privacy = off

# Specify the policy to the JUST-WORKS repairing initiated by peer
# Possible values: "never", "confirm", "always"
# Defaults to "never"
#JustWorksRepairing = never

# How long to keep temporary devices around
# The value is in seconds. Default is 30.
# 0 = disable timer, i.e. never keep temporary devices
#TemporaryTimeout = 30

# Enables the device to issue an SDP request to update known services when
# profile is connected. Defaults to true.
#RefreshDiscovery = true

# Enables D-Bus experimental interfaces
# Possible values: true or false
#Experimental = false

# Enables kernel experimental features, alternatively a list of UUIDs
# can be given.
# Possible values: true,false,<UUID List>
# Possible UUIDS:
# d4992530-b9ec-469f-ab01-6c481c47da1c (BlueZ Experimental Debug)
# 671b10b5-42c0-4696-9227-eb28d1b049d6 (BlueZ Experimental Simultaneous Central and Peripheral)
# 15c0a148-c273-11ea-b3de-0242ac130004 (BlueZ Experimental LL privacy)
# 330859bc-7506-492d-9370-9a6f0614037f (BlueZ Experimental Bluetooth Quality Report)
# a6695ace-ee7f-4fb9-881a-5fac66c629af (BlueZ Experimental Offload Codecs)
# 6fbaf188-05e0-496a-9885-d6ddfdb4e03e (BlueZ Experimental ISO socket)
# Defaults to false.
#KernelExperimental = false

# The duration to avoid retrying to resolve a peer's name, if the previous
# try failed.
# The value is in seconds. Default is 300, i.e. 5 minutes.
#RemoteNameRequestRetryDelay = 300

[BR]
# The following values are used to load default adapter parameters for BR/EDR.
# BlueZ loads the values into the kernel before the adapter is powered if the
# kernel supports the MGMT_LOAD_DEFAULT_PARAMETERS command. If a value isn't
# provided, the kernel will be initialized to it's default value.  The actual
# value will vary based on the kernel version and thus aren't provided here.
# The Bluetooth Core Specification should be consulted for the meaning and valid
# domain of each of these values.

# BR/EDR Page scan activity configuration
#PageScanType=
#PageScanInterval=
#PageScanWindow=

# BR/EDR Inquiry scan activity configuration
#InquiryScanType=
#InquiryScanInterval=
#InquiryScanWindow=

# BR/EDR Link supervision timeout
#LinkSupervisionTimeout=

# BR/EDR Page Timeout
#PageTimeout=

# BR/EDR Sniff Intervals
#MinSniffInterval=
#MaxSniffInterval=

[LE]
# The following values are used to load default adapter parameters for LE.
# BlueZ loads the values into the kernel before the adapter is powered if the
# kernel supports the MGMT_LOAD_DEFAULT_PARAMETERS command. If a value isn't
# provided, the kernel will be initialized to it's default value.  The actual
# value will vary based on the kernel version and thus aren't provided here.
# The Bluetooth Core Specification should be consulted for the meaning and valid
# domain of each of these values.
# LE advertisement interval (used for legacy advertisement interface only)
#MinAdvertisementInterval=
#MaxAdvertisementInterval=
#MultiAdvertisementRotationInterval=

# LE scanning parameters used for passive scanning supporting auto connect
# scenarios
#ScanIntervalAutoConnect=
#ScanWindowAutoConnect=

# LE scanning parameters used for passive scanning supporting wake from suspend
# scenarios
#ScanIntervalSuspend=
#ScanWindowSuspend=

# LE scanning parameters used for active scanning supporting discovery
# proceedure
#ScanIntervalDiscovery=
#ScanWindowDiscovery=

# LE scanning parameters used for passive scanning supporting the advertisement
# monitor Apis
#ScanIntervalAdvMonitor=
#ScanWindowAdvMonitor=

# LE scanning parameters used for connection establishment.
#ScanIntervalConnect=
#ScanWindowConnect=

# LE default connection parameters.  These values are superceeded by any
# specific values provided via the Load Connection Parameters interface
#MinConnectionInterval=
#MaxConnectionInterval=
#ConnectionLatency=
#ConnectionSupervisionTimeout=
#Autoconnecttimeout=

# Scan duration during interleaving scan. Only used when scanning for ADV
# monitors. The units are msec.
# Default: 300
#AdvMonAllowlistScanDuration=
# Default: 500
#AdvMonNoFilterScanDuration=

# Enable/Disable Advertisement Monitor interleave scan for power saving.
# 0: disable
# 1: enable
# Defaults to 1
#EnableAdvMonInterleaveScan=

[GATT]
# GATT attribute cache.
# Possible values:
# always: Always cache attributes even for devices not paired, this is
# recommended as it is best for interoperability, with more consistent
# reconnection times and enables proper tracking of notifications for all
# devices.
# yes: Only cache attributes of paired devices.
# no: Never cache attributes
# Default: always
#Cache = always

# Minimum required Encryption Key Size for accessing secured characteristics.
# Possible values: 0 and 7-16. 0 means don't care.
# Defaults to 0
#KeySize = 0

# Exchange MTU size.
# Possible values: 23-517
# Defaults to 517
#ExchangeMTU = 517

# Number of ATT channels
# Possible values: 1-5 (1 disables EATT)
# Default to 3
#Channels = 3

[AVDTP]
# AVDTP L2CAP Signalling Channel Mode.
# Possible values:
# basic: Use L2CAP Basic Mode
# ertm: Use L2CAP Enhanced Retransmission Mode
#SessionMode = basic

# AVDTP L2CAP Transport Channel Mode.
# Possible values:
# basic: Use L2CAP Basic Mode
# streaming: Use L2CAP Streaming Mode
#StreamMode = basic

[Policy]
#
# The ReconnectUUIDs defines the set of remote services that should try
# to be reconnected to in case of a link loss (link supervision
# timeout). The policy plugin should contain a sane set of values by
# default, but this list can be overridden here. By setting the list to
# empty the reconnection feature gets disabled.
#ReconnectUUIDs=00001112-0000-1000-8000-00805f9b34fb,0000111f-0000-1000-8000-00805f9b34fb,0000110a-0000-1000-8000-00805f9b34fb,0000110b-0000-1000-8000-00805f9b34fb

# ReconnectAttempts define the number of attempts to reconnect after a link
# lost. Setting the value to 0 disables reconnecting feature.
#ReconnectAttempts=7

# ReconnectIntervals define the set of intervals in seconds to use in between
# attempts.
# If the number of attempts defined in ReconnectAttempts is bigger than the
# set of intervals the last interval is repeated until the last attempt.
#ReconnectIntervals=1,2,4,8,16,32,64

# AutoEnable defines option to enable all controllers when they are found.
# This includes adapters present on start as well as adapters that are plugged
# in later on. Defaults to 'true'.
# A.Ahmad 4-27-2023: Setting AutoEnable to false.
AutoEnable=false

# Audio devices that were disconnected due to suspend will be reconnected on
# resume. ResumeDelay determines the delay between when the controller
# resumes from suspend and a connection attempt is made. A longer delay is
# better for better co-existence with Wi-Fi.
# The value is in seconds.
# Default: 2
#ResumeDelay = 2

[AdvMon]
# Default RSSI Sampling Period. This is used when a client registers an
# advertisement monitor and leaves the RSSISamplingPeriod unset.
# Possible values:
# 0x00       Report all advertisements
# N = 0xXX   Report advertisements every N x 100 msec (range: 0x01 to 0xFE)
# 0xFF       Report only one advertisement per device during monitoring period
# Default: 0xFF
#RSSISamplingPeriod=0xFF

If you need anything else, please let me know!

maniacx commented 7 months ago

Set

ControllerMode = dual

Use any file editor with root to change.

Example

sudo nano /etc/Bluetooth/main.conf

Make changes

Ctrl+X, Y, ENTER

Then restart Bluetooth service

sudo systemctl restart Bluetooth

Disable and re-enable extension. Reconnect airpods

a4orce84 commented 7 months ago

Sounds good, will make the change and report back. Can you elaborate on what the "ControllerMode" option does? As far as I know this is the 'stock' configuration that comes with Manjaro Gnome.

Just trying to learn more about what I'm doing! Thank you!

maniacx commented 7 months ago

Oh it is stock configuration? I was under the assumption that you changed it. As there are many post that mentions to get airpods working on linux to switch ControllerMode to bredr

On Ubuntu and Fedora the default value is commented and assumed to be dual. #ControllerMode = dual

However a lot of users got airpod working by switching it to bredr https://gist.github.com/aidos-dev/b49078c1d8c6bb1621e4ac199d18213b

Some users mentioned that just remove the comment # got the airpods working. ControllerMode = dual

BR/EDR devices classic bluetooth device that often use transmit continuous data like streaming audio. BLE device is low energy devices like smart bulb, heartrate monitor, airtags, that often transmit data in interval, hence are battery saving can run for long time.

ControllerMode = dual > support both type ControllerMode = bredr > support classic only ControllerMode = le > support ble only

Airpod stream audio data in classic mode, but advertise the battery info in le mode. So in ControllerMode = bredr the battery monitoring wont work.

Just try dual mode. verify the change you made in main.conf using cat command in previous post. Restart bluetooth service. See if you can connect and play airpods See if the extension works One user mentioned that when extension is enabled, is distortes audio playback. Check for that too. Try restarting the system too, if it doesnt work. If connecting or playback doesnt work, you can switch back to bredr

maniacx commented 7 months ago

Also incase you cannot connect/pair to airpods using ControllerMode = dual mode Keep the airpods out of case and open. and run the script.

https://maniacx.github.io/Airpod-Battery-Monitor/bugs-feature-request#script-for-getting-manufactorerdata

a4orce84 commented 7 months ago

Hey @maniacx - The ControllerMode setting worked! I am able to finally see my battery life and everything looks correct so far. Let me spend some time over the weekend to see if I get any distortion with audio, but I can happily report that the extension is working correctly now.

Thank you again for all of your time and help, it is greatly appreciated. I will keep you updated on the distortion issue.

Thanks, Asif

maniacx commented 7 months ago

Great! Thank for testing and reporting. I have added this to the readme.

thapa-sabin commented 5 months ago

Mine is also not working. Scanning with bluetoothctl does work, and shows that I have an Apple device, but running test.js does not do anything. I also have mine in ControllerMode = dualmode.

I have the Airpods 2nd gen.

test.js output: gjs-console test.js

Gjs-Message: 18:11:38.923: JS LOG: StartDiscoveryAsync Gjs-Message: 18:11:49.653: JS LOG: Scanning Bluetooth devices... Gjs-Message: 18:11:49.653: JS LOG: No information about objects was obtained. Gjs-Message: 18:11:54.640: JS LOG: StopDiscoveryAsync Gjs-Message: 18:12:04.639: JS LOG: StartDiscoveryAsync Gjs-Message: 18:12:19.649: JS LOG: Scanning Bluetooth devices... Gjs-Message: 18:12:19.649: JS LOG: No information about objects was obtained. Gjs-Message: 18:12:24.641: JS LOG: StopDiscoveryAsync Gjs-Message: 18:12:34.640: JS LOG: StartDiscoveryAsync Gjs-Message: 18:12:49.648: JS LOG: Scanning Bluetooth devices... Gjs-Message: 18:12:49.649: JS LOG: No information about objects was obtained. Gjs-Message: 18:12:54.641: JS LOG: StopDiscoveryAsync Gjs-Message: 18:13:04.641: JS LOG: StartDiscoveryAsync Gjs-Message: 18:13:19.651: JS LOG: Scanning Bluetooth devices... Gjs-Message: 18:13:19.651: JS LOG: No information about objects was obtained. Gjs-Message: 18:13:24.641: JS LOG: StopDiscoveryAsync Gjs-Message: 18:13:34.642: JS LOG: StartDiscoveryAsync Gjs-Message: 18:13:49.644: JS LOG: Scanning Bluetooth devices... Gjs-Message: 18:13:49.645: JS LOG: No information about objects was obtained. Gjs-Message: 18:13:54.640: JS LOG: StopDiscoveryAsync Gjs-Message: 18:14:04.643: JS LOG: StartDiscoveryAsync

thapa-sabin commented 5 months ago

It seems to work flawlessly on Gnome 43.9. I didn't have to fiddle around anywhere, I was able to just install the extension. Thanks! image