Closed Owenber123 closed 3 years ago
Generally speaking, I advise people to avoid scanning for devices inside of their application. This adds lots of complexity for no benefit in most cases. Once you have done a scan and connected inside of bluetoothctl
then there shouldn't be a need to scan again.
If the device you wish to connect to is sometimes out of range, then handling the timeout on connection involves less complexity than scanning.
If you do really, really, really need scanning then you have two choices:
Let the discovery run for a period and then proceed. e.g.
adapter.nearby_discovery(timeout=discoveryTimeout)
The application of this is that when a new device is discovered it gets added to the list of devices.
on_device_found
:
https://github.com/ukBaz/python-bluezero/blob/06480a3430e55325a10d3854db509efbfc412ba4/bluezero/adapter.py#L90
If you are checking for the existence of a already discovered then a connection to the PropertiesChanged
signal would need to be done for the device similar to what has been done for the adapter.
https://github.com/ukBaz/python-bluezero/blob/master/bluezero/adapter.py#L99This has the benefit of you get a signal
that the device has been discovered or the RSSI has changed on a known device. but requires to program your application in asynchronous.
As you seem to be trying to do this synchronously I've had an attempt at how I would do this and have come up with the following:
from bluezero import adapter
from bluezero import device
ubit = 'E9:06:4D:45:FC:8D'
rpi = 'B8:27:EB:22:57:E0'
dongle = adapter.Adapter()
searching = True
def keep_trying(attempts):
fails = 0
while searching:
for dev in device.Device.available():
if dev.address == ubit:
remote = device.Device(rpi, ubit)
try:
remote.connect(timeout=2)
return remote
except:
pass
fails += 1
print(f'fails = {fails}')
if fails > attempts:
return None
dongle.nearby_discovery(3)
my_dev = keep_trying(10)
if my_dev:
print('Great, connected', my_dev.connected)
my_dev.disconnect()
while my_dev.connected:
print('Disconnecting...')
sleep(1)
else:
print('failed to connect')
ukBaz,
I gave this implementation a try. It works very similar to what I am doing above, I guess the device is found in the list. The application gets stuck during the remote.connect(). No exceptions are thrown during this function call. I have yet to debug beyond the Device object during the connect and am hoping you have some ideas with your great knowledge of bluezero. My device object is very similar and based off of the Microbit object and works for the majority of devices. I will be running hardware tests today in case its not software related.
Thanks in advanced, Owen
I'm struggling to understand what you are referring to when you say "get stuck during the remote.connect()". When it tries to connect to a device that isn't there, then it will be trying for 35 seconds before timing out. This can be changed n the above code by adding a shorter timeout to the connect statement. e.g.
remote.connect(timeout=2)
I've updated the example above to fail faster with the connect. Is this what you are referring to?
It is stuck in the:
while not self.rmt_device.services_resolved:
sleep(0.5)
This means we are connected but the characteristics cannot be resolved I believe. Any ideas?
You would need to narrow down if the issue is with remote device never resolving its services. Or if it is somewhere on the Linux side not getting the update.
To monitor D-Bus traffic use the following in a separate terminal:
sudo busctl monitor org.bluez
To monitor Bluetooth traffic:
sudo btmon
This are both very verbose, so not easy.
I was not able to solve the problem with the information gathered by those commands, however, the Central device was using a USB Ethernet Adapter in order to avoid WIFI interference. This was accidentally removed and the problem stopped occurring. I have no idea why but this is going to be my solution. Thanks
Thanks for letting me know. I'll close this ticket as I don't think there is anything else to do here.
Hello, I have been debugging my application for quite some time now and have never seen this problem. I am able to create a Device with a Central object but once I attempt to connect to it my application freezes. I do not get any timouts or exceptions. When I check the bluetoothctl device list I do not see the device but when run a quick scan I am able to see the device and connect to it just fine. I was convinced that the Central object checked for the devices presence during initialization. I have pushed this device to the side and am moving forward but do not know how to handle this if others follow suit. Any advise would be great. I added some snippets of the Device creation and connection. Thanks, Owen
IN MAIN
IN DEVICE