Android Bluetooth Low Energy¶
Python interface to Android Bluetooth Low Energy API.
| Code repository: | |
|---|---|
| https://github.com/b3b/able | |
| Documentation: | https://herethere.me/able |
| Changelog: | https://github.com/b3b/able/blob/master/CHANGELOG.rst |
Quick start development environment¶
able is included in PythonHere app, together with the Jupyter Notebook it could be used as a development environment.
Usage example: https://herethere.me/pythonhere/examples/ble.html
Build¶
The following instructions are for building app with buildozer tool.
able_recipe recipe should be added to buildozer.spec requirements:
requirements = python3,kivy,android,able_recipe
Bluetooth permissions should be requested in buildozer.spec:
android.permissions = BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE, ACCESS_FINE_LOCATION
App configuration example: buildozer.spec
Build with a local version¶
To build app with a local (modified) version of able,
path to able recipes directory should be set in buildozer.spec:
p4a.local_recipes = /path/to/cloned/repo/recipes
Contributors¶
Thanks,
| andfmart |
| andreamerello |
| datmaniac95 |
| dgatf |
| dwmoffatt |
| Enkumicahel |
| hailesir |
| HelaFaye |
| jacklinquan |
| juasiepo |
| PapoKarlo |
| RoberWare |
| Rowataro |
| robgar2001 |
| sodef |
| sooko_io |
Usage Examples¶
Change MTU¶
Scan settings¶
from able import BluetoothDispatcher
from able.scan_settings import ScanSettingsBuilder, ScanSettings
# Use faster detection (more power usage) mode
settings = ScanSettingsBuilder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
BluetoothDispatcher().start_scan(settings=settings)
Scan filters¶
from able import BluetoothDispatcher
from able.filters import (
DeviceAddressFilter,
DeviceNameFilter,
ManufacturerDataFilter,
ServiceDataFilter,
ServiceUUIDFilter
)
ble = BluetoothDispatcher()
# Start scanning with the condition that device has one of names: "Device1" or "Device2"
ble.start_scan(filters=[DeviceNameFilter("Device1"), DeviceNameFilter("Device2")])
ble.stop_scan()
# Start scanning with the condition that
# device advertises "180f" service and one of names: "Device1" or "Device2"
ble.start_scan(filters=[
ServiceUUIDFilter('0000180f-0000-1000-8000-00805f9b34fb') & DeviceNameFilter("Device1"),
ServiceUUIDFilter('0000180f-0000-1000-8000-00805f9b34fb') & DeviceNameFilter("Device2")
])
Adapter state¶
Advertising¶
Advertise with data and additional (scannable) data¶
from able import BluetoothDispatcher
from able.advertising import (
Advertiser,
AdvertiseData,
ManufacturerData,
Interval,
ServiceUUID,
ServiceData,
TXPower,
)
advertiser = Advertiser(
ble=BluetoothDispatcher(),
data=AdvertiseData(ServiceUUID("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")),
scan_data=AdvertiseData(ManufacturerData(id=0xAABB, data=b"some data")),
interval=Interval.MEDIUM,
tx_power=TXPower.MEDIUM,
)
advertiser.start()
Set and advertise device name¶
from able import BluetoothDispatcher
from able.advertising import Advertiser, AdvertiseData, DeviceName
ble = BluetoothDispatcher()
ble.name = "New test device name"
# There must be a wait and check, it takes time for new name to take effect
print(f"New device name is set: {ble.name}")
Advertiser(
ble=ble,
data=AdvertiseData(DeviceName())
)
Battery service data¶
Use iBeacon advertising format¶
import uuid
from able import BluetoothDispatcher
from able.advertising import Advertiser, AdvertiseData, ManufacturerData
data = AdvertiseData(
ManufacturerData(
0x4C, # Apple Manufacturer ID
bytes([
0x2, # SubType: Custom Manufacturer Data
0x15 # Subtype lenth
]) +
uuid.uuid4().bytes + # UUID of beacon
bytes([
0, 15, # Major value
0, 1, # Minor value
10 # RSSI, dBm at 1m
]))
)
Advertiser(BluetoothDispatcher(), data).start()
Android Services¶
Connect to multiple devices¶
Full example code: multi_devices