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?