简体   繁体   中英

Python - Connect a BLE device

As the title indicates I have a BLE device that I wish to connect to via a python script. I am using a Raspberry Pi and have the newest version of Bluez installed.

I have connected to a different BLE device using Bluepy, unfortunately I am unable to retrieve any data using this method with the current BLE that I have, which is why I want to connect to it in a different way.

I have connected to the new device using GATTTool and have successfully obtained data, I am aware that there are libraries that facilitate a connection with GATTTool within a python script. I have tried pexpect and pygatt but neither seem to work due to it timing out before a connection is made.

Here is a piece of code that I found online;

import pygatt.backends
from binascii import hexlify

def printIndication(handle, value):
    print('Indication received {} : {}'.format(hex(handle), hexlify(str(value))))

adapter = pygatt.backends.GATTToolBackend()
adapter.start()
while True:  
 try:
    device = adapter.connect('00:38:40:0A:00:04', 5)
    break
 except pygatt.exceptions.NotConnectedError:
    print('Waiting...')

device.subscribe('0002021-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
device.subscribe('00002022-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
device.subscribe('00002a19-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)


device.disconnect()
adapter.stop()

When I execute the code I get the following output:

Traceback (most recent call last):
  File "./test.py", line 10, in <module>
    adapter.start()
  File "/usr/local/lib/python2.7/dist-packages/pygatt/backends/gatttool/gatttool.py", line 90, in start
   self._con.expect(r'\[LE\]>', timeout=1)
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1418, in expect
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1433, in expect_list
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/dist-packages/pexpect/__init__.py", line 1535, in expect_loop
    raise TIMEOUT(str(err) + '\n' + str(self))
pexpect.TIMEOUT: Timeout exceeded.
<pexpect.spawn object at 0x76737730>
version: 3.2
command: /usr/bin/gatttool
args: ['/usr/bin/gatttool', '-i', 'hci0', '-I']
searcher: <pexpect.searcher_re object at 0x76737770>
buffer (last 100 chars): ''
before (last 100 chars): ''
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 5062
child_fd: 3
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

I have also tried the following code:

import pygatt.backends

# The BGAPI backend will attemt to auto-discover the serial device name of the
# attached BGAPI-compatible USB adapter.
adapter = pygatt.backends.GATTToolBackend()
adapter.start()
device = adapter.connect('01:23:45:67:89:ab')
value = device.char_read("a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b")

After executing this code I got the exact same error. I have tried changing the Timeout but it doesn't seem to make a difference, all that happens is that it waits the allocated time and the same output will be displayed.

What am I missing? Is there a better way to do this?

Thanks, in advance for any help given.

Probably it's too late now, but if anyone has the same doubt, you can use the pexpect library. I'll leave some example code that works with me (i can read some data sent from a PSOC 4200 ble device).

import pexpect
DEVICE = "00:A0:50:CF:62:CD"   # address of your device
if len(sys.argv) == 2:
  DEVICE = str(sys.argv[1])
# Run gatttool interactively.
child = pexpect.spawn("gatttool -I")

# Connect to the device.
print("Connecting to:"),
print(DEVICE)
NOF_REMAINING_RETRY = 3
while True:
  try:
    child.sendline("connect {0}".format(DEVICE))
    child.expect("Connection successful", timeout=5)
  except pexpect.TIMEOUT:
    NOF_REMAINING_RETRY = NOF_REMAINING_RETRY-1
    if (NOF_REMAINING_RETRY>0):
      print "timeout, retry..."
      continue
    else:
      print "timeout, giving up."
      break
  else:
    print("Connected!")
    break

And then to read something just do this:

# Presence Sensor
  child.sendline("char-read-hnd 0x16") # put the handle you want to read
  child.expect("Characteristic value/descriptor: ", timeout=5)
  child.expect("\r\n", timeout=5)
  print("Presence Sensor:  "),
  print(child.before),
  print(chr(int(child.before[0:2],16)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM