http://lightblue.sourceforge.net
Bea Lam <blammit@gmail.com>
This project is no longer maintained.
LightBlue is a cross-platform Bluetooth API for Python which provides simple access to Bluetooth operations. It is available for Mac OS X, GNU/Linux and Nokia's Python for Series 60 platform for mobile phones.
Downloads are available below, or see the sourceforge project page for the full list of downloads.
LightBlue provides simple access to:
See the online API documentation for more details.
The Mac OS X implementation also introduces LightAquaBlue, an Objective-C framework that enables the implementation of custom OBEX clients and servers. See the LightAquaBlue documentation for more details.
LightBlue is released under the GPL v3 License.
Comments, suggestions, questions, etc. are most welcome and appreciated.
15 February, 09: Version 0.4 is out:
16 August, 08: Version 0.3.3 is out. This includes the following fixes:
March 21, 08: Version 0.3.2 is out. This includes some major bug fixes:
February 17, 08: Version 0.3.1 is out:
February 3, '08: Version 0.3 is out! The major features of this release are:
October 16, '07: Version 0.2.3 is out:
August 21, '07: Version 0.2.2 is out:
March 22, '07: Version 0.2.1 (intended to fix PyS60 build issues, but didn't)
March 6, '07: Version 0.2 has been released! The changes for this version are:
Requires Python 2.3 or later, and at least Xcode 2.1 and Mac OS 10.4 for building the included LightAquaBlue .xcodeproj package. (For Xcode 1.5 and Mac OS 10.3 you can create a .xcode project yourself and build that; see the readme for some tips.)
To install:
python setup.py install
Or, if you need to run with root access, use sudo python setup.py install
instead.
Along with installing the LightBlue python library, this also installs the LightAquaBlue Objective-C framework into /Library/Frameworks/
.
For Mac OS 10.6 users:
Some things to note:
finddevices()
, recvfile()
and finddevicename()
take a while to complete, and if they are called within a PyObjC app, the Cocoa UI will freeze until the method returns. If you want the normal Cocoa asynchronous behaviour that doesn't freeze, use the LightAquaBlue framework and Apple's IOBluetooth framework through PyObjC instead.Requires Python 2.3 or later, with the BlueZ bluetooth stack and development libraries. (Tkinter must be included with Python to call selectdevice() and selectservice().)
To install:
python setup.py install
(or with root access, sudo python setup.py install
)Requires Python for Series 60 to be installed on your phone. If you have a newer phone based on Series 60 3rd Edition FP1 or later, download it from the garage: Python for Series 60 project. Otherwise, get an older version from the Nokia PyS60 opensource page.
(If you don't know which S60 edition, Feature Pack etc. is the right one for your phone, see the wikipedia S60 entry.)
If you have Python for Series 60 1.9.x:
If you have Python for Series 60 1.4.x or earlier:
Please let me know if there are any problems with these builds, because it's impossible to test them for all the different editions.
If you're interested, the LightBlue source files (tar.gz or zip) include the python and C++ extensions source code as well as MMP files etc. for recompiling everything. For the 1.9.x builds, the files aren't in the tar/zip packages, but can be found in the svn repository.
Here are some examples of using the LightBlue API. Obviously, for the sake of simplicity, they assume lightblue has already been imported, like this:
import lightblue
So to discover nearby devices and available services:
>>> lightblue.finddevices() [('00:0E:6D:71:A2:0B', u'My6600', 5243396), ('00:0D:93:19:C8:68', u'pantherbox', 1057028)] >>> lightblue.findservices('00:0D:93:19:C8:68') [('00:0D:93:19:C8:68', 10, 'OBEX Object Push'), ('00:0D:93:19:C8:68', 15, 'OBEX File Transfer'), ('00:0D:93:19:C8:68', 1, 'Bluetooth-PDA-Sync'), ('00:0D:93:19:C8:68', 3, 'Palm Serial Port')]
To ask the end user to select a device or service:
>>> lightblue.selectdevice() # brings up a device-selection GUI ('00:0E:6D:71:A2:0B', u'My6600', 5243396) >>> lightblue.selectservice() # brings up a service-selection GUI ('00:0E:6D:71:A2:0B', 2, u'Bluetooth Serial Port')
To use RFCOMM socket objects:
# client socket >>> s = lightblue.socket() >>> s.connect(("00:12:2c:45:8a:7b", 5)) >>> s.send("hello") 5 >>> 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 Connected by ('00:0D:93:19:C8:68', 5) >>> conn.recv(1024) "hello" >>> conn.close() >>> s.close()
To send and receive files over OBEX:
# 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()
To run OBEX client sessions:
# send a business card (vCard) to an Object Push service >>> client = lightblue.obex.OBEXClient("00:12:2c:45:8a:7b", 10) >>> client.connect() <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}> >>> client.put({"name": "MyBusinessCard.vcf"}, file("MyBusinessCard.vcf", "r")) <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}> >>> client.disconnect() <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}> # get a directory listing from a File Transfer service # (see examples/obex_ftp_client.py for a basic File Transfer client implementation) >>> client = lightblue.obex.OBEXClient("00:12:2c:45:8a:7b", 15) >>> ftp_target_uuid = '\xf9\xec{\xc4\x95<\x11\xd2\x98NRT\x00\xdc\x9e\t' >>> client.connect({"target": ftp_target_uuid}) <OBEXResponse reason='OK' code=0x20 (0xa0) headers={'connection-id': 327258, 'who': '\xf9\xec{\xc4\x95<\x11\xd2\x98NRT\x00\xdc\x9e\t'}> >>> import StringIO >>> dirlist = StringIO.StringIO() >>> client.get({'type': 'x-obex/folder-listing'}, dirlist) <OBEXResponse reason='OK' code=0x20 (0xa0) headers={'length': 292}> >>> dirlist.getvalue() '<?xml version="1.0"?>\n<!DOCTYPE folder-listing SYSTEM "obex-folder-listing.dtd"\n [ <!ATTLIST folder mem-type CDATA #IMPLIED>\n <!ATTLIST folder label CDATA #IMPLIED> ]>\n<folder-listing version="1.0">\n <folder name="C:" user-perm="RW" mem-type="DEV" label="Phone memory"/>\n</folder-listing>' >>> client.disconnect() <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
To read local device information:
>>> lightblue.gethostaddr() '00:0F:3D:5F:20:F0' >>> lightblue.finddevicename(lightblue.gethostaddr()) # get local device name u'susebox' >>> lightblue.gethostclass() # class of device 3670276
LightBlue's implementation uses native and third-party libraries on the three platforms, including:
findservices()
and selectservice()
on Python For Series 60 returns only RFCOMM and OBEX servicesfileno()
raises NotImplementedError
on Mac OS X and Python For Series 60settimeout()
raises NotImplementedError
, gettimeout()
returns None
send()
and recv
but not accept()
or connect()
recv
) have no effect