I've been trying to get a bluetooth LE IoT set up to work with multiple bluetooth LE devices that periodically turn on and transmit. I'm using code similar to https://engineersportal.com/raspberry-pi-ble-code to manage the connections:
from bluepy import btle
import struct, os
from concurrent import futures
import time
addr_var = ['d8:a9:8b:b0:d0:49', 'd8:a9:8b:b0:da:dd']
class MyDelegate(btle.DefaultDelegate):
def __init__(self,params):
btle.DefaultDelegate.__init__(self)
def handleNotification(self,cHandle,data):
global addr_var
global delegate_global
print('got data: ', data)
try:
data_decoded = struct.unpack("b",data)
print("Address: "+addr_var[ii])
print(data_decoded)
return
except:
pass
def perif_loop(perif):
try:
if perif.waitForNotifications(8.0):
print("waiting for notifications...")
except Exception as e:
pass
finally:
print('disconnecting!')
try:
perif.disconnect()
time.sleep(4)
except Exception as e:
print('failed to disconnect!', e)
pass
def establish_connection(addr):
while True:
try:
print("Attempting to connect with "+addr)
p = btle.Peripheral(addr)
p_delegate = MyDelegate(addr)
p.withDelegate(p_delegate)
print("Connected to "+addr)
perif_loop(p)
except Exception as e:
print("failed to connect to "+addr, e)
time.sleep(1.0)
continue
ex = futures.ProcessPoolExecutor(max_workers = os.cpu_count())
results = ex.map(establish_connection,addr_var)
This works for a bit, but throws connection errors (Failed to connect to peripheral d8:a9:8b:b0:da:dd, addr type: public), and eventually gets into bad state where no device will connect and bluetooth has to be restarted with sudo systemctl stop bluetooth, sudo systemctl start bluetooth.
Looking further with strace, the error received is "Connection refused (111)" in the bluepy-helper executable.
Has anyone managed to get this or something similar working in a reliable manner (does not miss broadcasts) for long periods of time?


