RkBlog

Hardware, programming and astronomy tutorials and reviews.

Bluetooth w Pythonie

Opis bibliotek umożliwiających wykorzystanie urządzeń Bluetooth z poziomu Pythona

Programowanie funkcjonalności opartych o protokół Bluetooth w Pythonie jest dość łatwe. Do dyspozycji mamy kilka rozwiązań: pybluez dla Linuksa (stos BlueZ) i MS Windows (tylko stos Windowsa), LightBlue dla Linuksa, Mac OS X i Symbiana S60, czy też obexftp posiadającymi API dla Pythona.

Bluetooth to protokół komunikacji radiowej stworzony jako zastępstwo dla "kabli". Za jego pomocą łączą się obecnie różne urządzenia jak telefony komórkowe, komputery, drukarki, słuchawki itp. Za pomocą Bluetooth można przesyłać pliki, czy też np. dane audio-video. Można też udostępniać połączenie sieciowe (np. z telefonu do laptopa).

Wykrywanie urządzeń Bluetooth i dostępnych usług

W LightBlue wygląda to następująco:
import lightblue

devices = lightblue.finddevices()
for dev in devices:
	print dev
	services = lightblue.findservices(dev[0])
	for s in services:
		print s
	print
	print
A w PyBlueZ:
import bluetooth
devices = bluetooth.discover_devices()
for dev in devices:
	print '%s: %s' % (dev, bluetooth.lookup_name(dev))
	services = bluetooth.find_service(address=dev)
	for i in services:
		print i
	print

RFCOMM (Radio Frequency Communication)

Protokół podobny do TCP, stosowany m.in. przez OBEX do przesyłania plików. Przykładowy serwer i klient w PyBluez:
import bluetooth

server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )

port = 1
server_sock.bind(("",port))
server_sock.listen(1)

client_sock,address = server_sock.accept()
print "Accepted connection from ",address

data = client_sock.recv(1024)
print "received [%s]" % data

client_sock.close()
server_sock.close()
import bluetooth

#klient
# przykładowy adres urządzenia
bd_addr = "01:23:45:67:89:AB"

port = 1

sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))

sock.send("hello!!")

sock.close()
Dla LightBlue:
# client socket
s = lightblue.socket()
s.connect(("00:12:2c:45:8a:7b", 5))
s.send("hello")
s.close()
#############
# server socket
s = lightblue.socket()
s.bind(("", 0))  # bind to 0 to bind to dynamically assigned port 
s.listen(1)
lightblue.advertise("My RFCOMM Service", s, lightblue.RFCOMM)
conn, addr = s.accept()
print "Connected by", addr
conn.recv(1024)
conn.close()
s.close()

L2CAP (Logical Link Control and Adaptation Protocol)

Niejako podstawowy protokół komunikowania się urządzeń Bluetooth. Przykładowy serwer i klient w PyBluez:
import bluetooth

server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP )

port = 0x1001
server_sock.bind(("",port))
server_sock.listen(1)

client_sock,address = server_sock.accept()
print "Accepted connection from ",address

data = client_sock.recv(1024)
print "received [%s]" % data

client_sock.close()
server_sock.close()
# klient
import bluetooth

sock=bluetooth.BluetoothSocket(bluetooth.L2CAP)

bd_addr = "01:23:45:67:89:AB"
port = 0x1001

sock.connect((bd_addr, port))

sock.send("hello!!")

sock.close()

OBEX

Transter plików za pomocą obexftp jest podobny do protokołu FTP. Oto przykład wykorzystujący Pythonowe API obexftp:
import obexftp

cli = obexftp.client(obexftp.BLUETOOTH)

devs = cli.discover()
print devs;
# dla przykładu pierwsze urządzenie
dev = devs[0]
print "Using %s" % dev

print cli.connect(dev, 10)

print cli.list("/")

#print cli.list("/images")

# pobieranie danych
#data = cli.get("/images/some.jpg")
#file = open('downloaded.jpg', 'wb')
#file.write(data)

print cli.disconnect()

cli.delete
Można także skorzystać z API LightBlue:
# send a file (can pass file name or file object)
lightblue.obex.sendfile("00:12:2c:45:8a:7b", 10, "MyFile.txt")

#######################
# receive a file and save it as MyFile.txt
s = lightblue.socket()
s.bind(("", 0))
lightblue.advertise("My OBEX Service", s, lightblue.OBEX)
lightblue.obex.recvfile(s, "MyFile.txt")  # or pass file object instead
s.close()
Jeżeli komunikujemy się z jakimś urządzeniem, np. telefonem komórkowym, to oba urządzenia Bluetooth muszą być zparowane - oba urządzenia muszą mieć wprowadzony ten sam numer PIN uwierzytelniający komunikację między urządzeniami. Proste urządzenia jak słuchawki mają proste fabryczne PINy typu "0000", czy "1111".
RkBlog

18 December 2008;

Comment article