Welcome to Bluezero’s documentation!¶
Overview¶

Overview¶
Bluetooth¶
Bluetooth is a standard set of binary protocols for short-range wireless communication between devices.
- Bluetooth “Classic” (BR/EDR) supports speeds up to about 24Mbps.
- Bluetooth 4.0 introduces a low energy mode, “Bluetooth Low Energy” (BLE or LE, also known as “Bluetooth Smart”), that operates at 1Mbps. This mode allows devices to leave their transmitters off most of the time. As a result it is “Low Energy”.
BLE functionality is dominated by key/value pairs that create a Generic Attribute Profile (GATT).
BLE defines multiple roles that devices can play:
- The Broadcaster (beacon) is a transmitter only application.
- The Observer (scanner) is for receiver only applications.
- Devices acting in the Peripheral role can receive connections.
- Devices acting in the Central role can connect to Peripheral devices.
BlueZ¶
BlueZ is a Bluetooth stack for the Linux family of operating systems. Support for BlueZ can be found in many Linux distributions available.
The highest level of API on BlueZ is the DBus API which can be daunting to
users unfamiliar with such APIs. python-bluezero
offers users a more gentle
learning curve to using Bluetooth functionality on Linux.
Bluezero API Complexity¶
This section gives guidelines about the complexity of different
python-bluezero
APIs. We will use the terms Level 1, 10 and 100. A new user
would start at Level 1 as this should offer the least friction. If at a later
stage a greater level of control is needed then the user can progress on to the
other levels. As the user becomes more experienced they may not need Bluezero
and will use BlueZ on its own. The numbers for the API levels represent the
steps in code and knowledge required with each step.
Level 1¶
- At this level the interface will be pythonic.
- The API will not assume knowledge of Bluetooth, DBus or event loops.
- For something to exist at this level there will need to be a public Bluetooth Profile in existence so that users does not need to enter UUIDs etc.
- This might be specific hardware such as the BBC micro:bit or it could be more generalised hardware such as Heart Rate Monitors.
Level 10¶
- At this level the API will be pythonic.
- The API will require some knowledge of Bluetooth such as UUIDs of services and characteristics for selecting required services.
- The API will not expose DBus terminology and will simplify event loops.
Level 100¶
- At this level the interface is expecting the user to know Bluetooth, DBus and event loops.
- DBus function names are not Pythonic and may be exposed at the level.
- This level will be very specific to the Linux kernel and so it will be difficult to port this to other operating systems that do not have the BlueZ Daemon running.
- The previous more abstracted API levels should be easier to port to any hardware.
Summary of Bluezero Files¶
Level 1 | Level 10 | Level 100 | shared |
---|---|---|---|
microbit.py | broadcaster.py | adapter.py | tools.py |
eddystone_beacon.py | central.py | advertisement.py | constants.py |
observer.py | device.py | dbus_tools.py | |
peripheral.py | GATT.py | async_tools.py | |
localGATT.py |
Examples¶
Examples¶
An example can often speed things up when you are trying to get started with a library so there are few below. There is also a Getting Started workshop using a Raspberry Pi and a BBC micro:bit
Adapter¶
This example prints out the status of the Bluetooth device on your Linux computer. It also checks to see if it is enabled (powered) before scanning for nearby Bluetooth devices:
from bluezero import adapter
import logging
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
def main():
dongles = adapter.list_adapters()
print('dongles available: ', dongles)
dongle = adapter.Adapter(dongles[0])
print('address: ', dongle.address)
print('name: ', dongle.name)
print('alias: ', dongle.alias)
print('powered: ', dongle.powered)
print('pairable: ', dongle.pairable)
print('pairable timeout: ', dongle.pairabletimeout)
print('discoverable: ', dongle.discoverable)
print('discoverable timeout: ', dongle.discoverabletimeout)
print('discovering: ', dongle.discovering)
print('Powered: ', dongle.powered)
if not dongle.powered:
dongle.powered = True
print('Now powered: ', dongle.powered)
print('Start discovering')
dongle.nearby_discovery()
# dongle.powered = False
if __name__ == '__main__':
print(__name__)
logger = logging.getLogger('adapter')
logger.setLevel(logging.DEBUG)
logger.addHandler(NullHandler())
main()
Central Role¶
This example uses the micro:bit API that has been written in Bluezero to interact with the micro:bit
import time
from bluezero import microbit
ubit = microbit.Microbit(adapter_addr='B8:27:EB:22:57:E0',
device_addr='E3:AC:D2:F8:EB:B9',
accelerometer_service=True,
button_service=True,
led_service=True,
magnetometer_service=False,
pin_service=False,
temperature_service=True)
ubit.connect()
assert ubit.pixels == [0b01110,
0b10000,
0b10000,
0b10000,
0b01110]
ubit.scroll_delay = 20
delay = ubit.scroll_delay
ubit.text = 'Scroll speed {}'.format(delay)
time.sleep(5)
ubit.text = 'This is a really long string '
time.sleep(5)
while not ubit.button_a:
ubit.pixels = [0b00000,
0b01000,
0b11111,
0b01000,
0b00000]
time.sleep(0.5)
ubit.clear_display()
while not ubit.button_b:
ubit.pixels = [0b00000,
0b00010,
0b11111,
0b00010,
0b00000]
time.sleep(0.5)
ubit.clear_display()
ubit.clear_display()
ubit.scroll_delay = 120
ubit.text = '{0}'.format(ubit.temperature)
time.sleep(5)
ubit.text = '{0}'.format(ubit.accelerometer)
time.sleep(5)
ubit.disconnect()
Scanner: Eddystone¶
This example scans for beacons in the Eddystone format. It will report on UID beacons <https://github.com/google/eddystone/tree/master/eddystone-uid> and URL beacons <https://github.com/google/eddystone/tree/master/eddystone-url>.
This uses the aioblescan Python library which requires your code to be run with sudo
from bluezero import observer
def print_eddystone_values(data):
"""
:param data:
:return:
"""
expected_keys = {'name space': 'hex_format',
'instance': 'hex_format',
'url': 'string_format',
'mac address': 'string_format',
'tx_power': 'int_format',
'rssi': 'int_format'}
endian = 'big'
print('New Eddystone data:')
for prop in data:
if prop in expected_keys:
if expected_keys[prop] == 'string_format':
print('\t{} = {}'.format(prop, data[prop]))
if expected_keys[prop] == 'hex_format':
print('\t{} = 0x{:X}'.format(prop,
int.from_bytes(data[prop],
endian)))
if expected_keys[prop] == 'int_format':
print('\t{} = {}'.format(prop, int(data[prop])))
if __name__ == '__main__':
observer.scan_eddystone(on_data=print_eddystone_values)
Beacon: Eddystone URL¶
This example broadcasts a given URL in a format for the Physical Web: You will need to put the BlueZ bluetoothd into experimental mode for this one.
from bluezero import eddystone_beacon
eddystone_beacon.EddystoneURL('https://github.com/ukBaz')
Peripheral Role¶
This example transmits the temperature of the CPU over the single characteristic. If your hardware does not support the vcgencmd then change the get_cpu_temperature() function to use the randomly generated temperature. Values are only updated when notification are switched on. You will need to have BlueZ in experimental mode and have modified the DBus configuration file to open the permissions for ‘ukBaz.bluezero’
# Standard modules
import os
import dbus
try:
from gi.repository import GObject
except ImportError:
import gobject as GObject
# Bluezero modules
from bluezero import constants
from bluezero import adapter
from bluezero import advertisement
from bluezero import localGATT
from bluezero import GATT
# constants
CPU_TMP_SRVC = '12341000-1234-1234-1234-123456789abc'
CPU_TMP_CHRC = '2A6E'
CPU_FMT_DSCP = '2904'
def get_cpu_temperature():
# return random.randrange(3200, 5310, 10) / 100
cpu_temp = os.popen('vcgencmd measure_temp').readline()
return float(cpu_temp.replace('temp=', '').replace("'C\n", ''))
def sint16(value):
return int(value * 100).to_bytes(2, byteorder='little', signed=True)
def cpu_temp_sint16(value):
answer = []
value_int16 = sint16(value[0])
for bytes in value_int16:
answer.append(dbus.Byte(bytes))
return answer
class TemperatureChrc(localGATT.Characteristic):
def __init__(self, service):
localGATT.Characteristic.__init__(self,
1,
CPU_TMP_CHRC,
service,
[get_cpu_temperature()],
False,
['read', 'notify'])
def temperature_cb(self):
reading = [get_cpu_temperature()]
print('Getting new temperature',
reading,
self.props[constants.GATT_CHRC_IFACE]['Notifying'])
self.props[constants.GATT_CHRC_IFACE]['Value'] = reading
self.PropertiesChanged(constants.GATT_CHRC_IFACE,
{'Value': dbus.Array(cpu_temp_sint16(reading))},
[])
print('Array value: ', cpu_temp_sint16(reading))
return self.props[constants.GATT_CHRC_IFACE]['Notifying']
def _update_temp_value(self):
if not self.props[constants.GATT_CHRC_IFACE]['Notifying']:
return
print('Starting timer event')
GObject.timeout_add(500, self.temperature_cb)
def ReadValue(self, options):
reading = [get_cpu_temperature()]
self.props[constants.GATT_CHRC_IFACE]['Value'] = reading
return dbus.Array(
cpu_temp_sint16(self.props[constants.GATT_CHRC_IFACE]['Value'])
)
def StartNotify(self):
if self.props[constants.GATT_CHRC_IFACE]['Notifying']:
print('Already notifying, nothing to do')
return
print('Notifying on')
self.props[constants.GATT_CHRC_IFACE]['Notifying'] = True
self._update_temp_value()
def StopNotify(self):
if not self.props[constants.GATT_CHRC_IFACE]['Notifying']:
print('Not notifying, nothing to do')
return
print('Notifying off')
self.props[constants.GATT_CHRC_IFACE]['Notifying'] = False
self._update_temp_value()
class ble:
def __init__(self):
self.bus = dbus.SystemBus()
self.app = localGATT.Application()
self.srv = localGATT.Service(1, CPU_TMP_SRVC, True)
self.charc = TemperatureChrc(self.srv)
self.charc.service = self.srv.path
cpu_format_value = dbus.Array([dbus.Byte(0x0E),
dbus.Byte(0xFE),
dbus.Byte(0x2F),
dbus.Byte(0x27),
dbus.Byte(0x01),
dbus.Byte(0x00),
dbus.Byte(0x00)])
self.cpu_format = localGATT.Descriptor(4,
CPU_FMT_DSCP,
self.charc,
cpu_format_value,
['read'])
self.app.add_managed_object(self.srv)
self.app.add_managed_object(self.charc)
self.app.add_managed_object(self.cpu_format)
self.srv_mng = GATT.GattManager(adapter.list_adapters()[0])
self.srv_mng.register_application(self.app, {})
self.dongle = adapter.Adapter(adapter.list_adapters()[0])
advert = advertisement.Advertisement(1, 'peripheral')
advert.service_UUIDs = [CPU_TMP_SRVC]
# eddystone_data = tools.url_to_advert(WEB_BLINKT, 0x10, TX_POWER)
# advert.service_data = {EDDYSTONE: eddystone_data}
if not self.dongle.powered:
self.dongle.powered = True
ad_manager = advertisement.AdvertisingManager(self.dongle.address)
ad_manager.register_advertisement(advert, {})
def add_call_back(self, callback):
self.charc.PropertiesChanged = callback
def start_bt(self):
# self.light.StartNotify()
self.app.start()
if __name__ == '__main__':
print('CPU temperature is {}C'.format(get_cpu_temperature()))
print(sint16(get_cpu_temperature()))
pi_cpu_monitor = ble()
pi_cpu_monitor.start_bt()
Peripheral - Nordic UART Service¶
This service simulates a basic UART connection over two lines, TXD and RXD.
It is based on a proprietary UART service specification by Nordic Semiconductors. Data sent to and from this service can be viewed using the nRF UART apps from Nordic Semiconductors for Android and iOS.
It uses the Bluezero peripheral file (level 10) so should be easier than the previous CPU Temperature example that was a level 100.
from gi.repository import GLib
from evdev import InputDevice, categorize, ecodes
# Bluezero modules
from bluezero import peripheral
# constants
UART_SERIVCE = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
RX_CHARACTERISTIC = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
TX_CHARACTERISTIC = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
class UartService:
def __init__(self):
self.app = peripheral.Application()
self.ble_uart = peripheral.Service(UART_SERIVCE,
True)
self.rx_uart = peripheral.Characteristic(RX_CHARACTERISTIC,
['write',
'write-without-response'],
self.ble_uart)
self.tx_uart = peripheral.Characteristic(TX_CHARACTERISTIC,
['notify'],
self.ble_uart)
self.rx_uart.add_write_event(self.uart_print)
self.tx_uart.add_notify_event(print)
self.tx_uart.StartNotify()
self.ble_uart.add_characteristic(self.rx_uart)
self.ble_uart.add_characteristic(self.tx_uart)
self.app.add_service(self.ble_uart)
@staticmethod
def _from_bytes(data):
return ''.join(chr(letter) for letter in data)
@staticmethod
def _to_bytes(word):
return [ord(x) for x in word]
def uart_print(self, value):
print(self._from_bytes(value))
def start(self):
self.app.start()
def stop(self):
self.app.stop()
def detect_keys(dev_loop):
event = dev.read_one()
if event is not None:
if event.code == ecodes.KEY_DOWN and event.value == 1:
dev_loop.tx_uart.send_notify_event('down')
elif event.code == ecodes.KEY_UP and event.value == 1:
dev_loop.tx_uart.send_notify_event('up')
elif event.code == ecodes.KEY_LEFT and event.value == 1:
dev_loop.tx_uart.send_notify_event('left')
elif event.code == ecodes.KEY_RIGHT and event.value == 1:
dev_loop.tx_uart.send_notify_event('right')
elif event.code == ecodes.KEY_ENTER and event.value == 1:
dev_loop.disconnect()
dev_loop.stop()
return True
if __name__ == '__main__':
dev = InputDevice('/dev/input/event0')
uart = UartService()
uart.app.dongle.alias = 'RPi_UART'
GLib.idle_add(detect_keys, uart)
uart.start()
Set-up¶
System Setup¶
Overview¶
Bluezero relies on the dbus interface of BlueZ. This version of Bluezero is tested wtih BlueZ version 5.43. As the BlueZ DBus API is undergoing changes between versions it is best to aim for that version when working with Bluezero. BlueZ 5.43 was chosen as the version to align with as this is the default version of BlueZ in Debian Stretch which was the latest/popular version at the time of release. This means it is likely that the Linux version you have installed will have the correct version. To check the version use bluetoothctl and type version:
$ bluetoothctl -v
5.43
More instructions are available in the Getting Started workshop using a Raspberry Pi and a BBC micro:bit
Using Bluezero for a Peripheral role or beacon¶
The BlueZ DBus API functionality associated with Bluetooth advertising requires the Bluetooth daemon to be run with the experimental flag. Advertising is used for Beacons and Peripheral role. Experimental mode can be switched on by default in the bluetooth.service file
Edit bluetooth.service file to add –experimental flag e.g:
sudo sed -i '/^ExecStart.*bluetoothd\s*$/ s/$/ --experimental/' /lib/systemd/system/bluetooth.service
Restart bluetoothd in experimental mode¶
You will need to either, reboot or run:
sudo systemctl daemon-reload
sudo service bluetooth restart
The bluetoothd should now be set to run with the experimental flag by default.
To check the bluetoothd is running with the experimental flag:
service bluetooth status
Change DBus permissions for Bluezero¶
An application that is in the role of a Peripheral will be registered on the System
DBus. This requires for some modification of permissions so Bluezero will be using
the bus name of ukBaz.bluezero
. An example dbus configuration file is provided
and will need to be copied to the correct location:
sudo cp examples/ukBaz.bluezero.conf /etc/dbus-1/system.d/.
Notes for getting debug information¶
Log of the bluetoothd¶
Stop bluetooth service:
service bluetooth stop
Kill the process (use ‘service bluetooth status’ to get the pid) the launch daemon with debug:
sudo /usr/libexec/bluetooth/bluetoothd -nEd |& tee ~/bluetoothd.log
Manually run bluetoothd with experimental mode with debug:
/usr/libexec/bluetooth/bluetoothd -nEd
python-bluezero modules¶
python-bluezero Modules¶
Level 1¶
micro:bit¶
-
class
bluezero.microbit.
Microbit
(device_addr, adapter_addr=None, accelerometer_service=True, button_service=True, led_service=True, magnetometer_service=False, pin_service=False, temperature_service=True, uart_service=False)¶ Class to simplify interacting with a micro:bit over Bluetooth Low Energy
-
accelerometer
¶ Read the values of the accelerometer on the microbit :return: return a list in the order of x, y & z
-
bearing
¶ Compass bearing in degrees from North. :return: degrees in integer
Read the state of button A on a micro:bit 3 button states are defined and represented by a simple numeric enumeration: 0 = not pressed, 1 = pressed, 2 = long press. :return: integer representing button value
Read the state of button B on a micro:bit 3 button states are defined and represented by a simple numeric enumeration: 0 = not pressed, 1 = pressed, 2 = long press. :return: integer representing button value
-
calibrate
()¶ Request a calibration of the magnetometer
-
clear_display
()¶ Clear the LED display on the microbit
-
connect
()¶ Connect to the specified micro:bit for this instance
-
connected
¶ Indicate whether the remote device is currently connected.
-
disconnect
()¶ Disconnect from the micro:bit
-
magnetometer
¶ Exposes magnetometer data. A magnetometer measures a magnetic field such as the earth’s magnetic field in 3 axes. :return: List of x, y & z value
-
pin_values
¶ Get the values of all the pins that are set as inputs :return: Dictionary (keys are pins)
-
pixels
¶ Returns a list of 5 binary numbers. Each number represents a row from top to bottom :return: Example [0b01110, 0b01000, 0b10000, 0b10000, 0b01110]
-
quit_async
()¶ Stops asynchronose mode :return:
-
run_async
()¶ Puts the code into asynchronous mode :return:
-
scroll_delay
¶ Specifies a millisecond delay to wait for in between showing each character on the display.
-
set_pin
(pin_number, pin_input, pin_analogue)¶ For a given pin, set the direction and type for the microbit pin.
Parameters: - pin_number – Pin number of the microbit
- pin_input – False for output, True for input
- pin_analogue – False for digital, True for analogue
Returns:
Execute user_callback on Button A being press on micro:bit :param user_callback: User callback method receiving the button state :return:
Execute user_callback on Button B being press on micro:bit :param user_callback: User callback method receiving the button state :return:
-
subscribe_calibrate
(user_callback)¶ Execute user_callback when calibration of magnetometer is complete :param user_callback: :return:
-
subscribe_pins
(user_callback)¶ Execute user_callback on input pin being changed on micro:bit :param user_callback: :return:
-
subscribe_uart
(user_callback)¶ Execute user_callback on data being received on UART service
Parameters: user_callback – Returns:
-
temperature
¶ Temperature from sensors in micro:bit processors :return: Integer of temperature in Celsius
-
text
¶ Specify text to be displayed. Limit of 20 characters. The content will be restricted to that number of characters. :param words:
-
uart
¶ Write string to micro:bit UART service. To read from UART, use
Returns:
-
-
class
bluezero.microbit.
MIpower
(device_addr, adapter_addr=None, accelerometer_service=True, button_service=True, led_service=True, magnetometer_service=False, pin_service=False, temperature_service=True)¶ -
beep
(duration=1)¶ If a buzzer is attached to pin 0 then a beep will be played :param duration: time in seconds
-
-
class
bluezero.microbit.
BitBot
(device_addr, adapter_addr=None, accelerometer_service=False, button_service=True, led_service=True, magnetometer_service=False, pin_service=True, temperature_service=False)¶ Class to simplify interacting with a microbit attached to a bit:bot over Bluetooth Low Energy The bit:bot is a micro:bit robot available from 4tronix.co.uk
-
buzzer_off
()¶ Stop the buzzer
-
buzzer_on
()¶ Play the buzzer
-
clean_up
()¶ Stop bitbot and turn buzzer is off :return:
-
connect
()¶ Connect to the bit:bot
-
connected
¶ Returns true if bit:bot is connected
-
disconnect
()¶ Disconnect from the bit:bot
-
drive
(left=100, right=100)¶ Set the drive power of both wheels at same time :param left: percentage of power (negative numbers are reverse) :param right: percentage of power (negative numbers are reverse)
-
forward
()¶ Spin both wheels forward
-
left_light_sensor
¶ Get the value of the left light sensor
-
left_line_senor
¶ Value ofthe left line sensor :return: False = No line True = Line
-
line_sensors
¶ Get the value of both line sensors :return: (left, right)
-
reverse
()¶ Spin both wheels backwards
-
right_light_sensor
¶ Get the value of the left light sensor
-
right_line_sensor
¶ Value of the right line sensor :return: False = No line True = Line
-
spin_left
()¶ Spin left wheel forward and right wheel backwards so bit:bot spins
-
spin_right
()¶ Spin right wheel forward and left wheel backwards so bit:bot spins
-
stop
()¶ Stop both wheels of the bit:bot
-
Eddystone¶
-
class
bluezero.eddystone_beacon.
EddystoneURL
(url, tx_power=8)¶ Create and start broadcasting a Eddystone URL beacon
The Eddystone-URL frame broadcasts a URL using a compressed encoding format in order to fit more within the limited advertisement packet. :Example:
>>> from bluezero import eddystone_beacon >>> eddystone_beacon.EddystoneURL('https://github.com/ukBaz')
Parameters: - url – String containing URL e.g. (‘http://camjam.me’)
- tx_power – Value of Tx Power of advertisement (Not implemented)
Level 10¶
Broadcaster¶
The level 10 file for creating beacons This requires BlueZ to have the experimental flag set
-
class
bluezero.broadcaster.
Beacon
(adapter_addr=None)¶ Create a non-connectable Bluetooth instance advertising information
-
add_manufacturer_data
(manufacturer, data)¶ Add manufacturer information to be used in beacon message :param manufacturer: Use numbers from Bluetooth SIG https://www.bluetooth.com/specifications/assigned-numbers/16-bit-UUIDs-for-Members :param data: Data to be sent (Limit of ??)
-
add_service_data
(service, data)¶ Add service and service data to be used in beacon message :param service: Valid service UUID :param data: Data to be sent (Limit of ??)
-
include_tx_power
(show_power=None)¶ Use to include TX power in advertisement. This is different to the TX power in specific beacon format (e.g. Eddystone) :param show_power: boolean value :return:
-
start_beacon
()¶ Start beacon advertising
-
Central¶
Classes that represent the GATT features of a remote device.
-
class
bluezero.central.
Central
(device_addr, adapter_addr=None)¶ Create a BLE instance taking the Central role.
-
add_characteristic
(srv_uuid, chrc_uuid)¶ Specify a characteristic of interest on the remote device by using the GATT Service UUID and Characteristic UUID :param srv_uuid: 128 bit UUID :param chrc_uuid: 128 bit UUID :return:
-
connect
(profile=None)¶ Initiate a connection to the remote device and load GATT database once resolved
Parameters: profile – (optional) profile to use for the connection.
-
connected
¶ Indicate whether the remote device is currently connected.
-
disconnect
()¶ Disconnect from the remote device.
-
load_gatt
()¶ Once the remote device has been connected to and the GATT database has been resolved then it needs to be loaded. :return:
-
Observer¶
-
bluezero.observer.
scan_eddystone
(on_data=None)¶ Provide a callback for ‘on_data’. The callback will be run whenever an Eddystone packet is detected.
Parameters: on_data – A function to be called on Eddystone packet Returns: None
Peripheral¶
Classes required to create a Bluetooth Peripheral.
Current classes include:
- Application – Root class
- Service – Bluetooth Service
- Characteristic – Bluetooth Characteristic
- Descriptor – Bluetooth Descriptor
- Advertisement – Bluetooth Advertisement
This requires BlueZ to have the experimental flag to be enabled
-
bluezero.peripheral.
register_ad_cb
()¶ Advertisement registration callback.
-
bluezero.peripheral.
register_ad_error_cb
(error)¶ Advertisement registration error callback.
-
bluezero.peripheral.
register_service_cb
()¶ Service registration callback.
-
bluezero.peripheral.
register_service_error_cb
(error)¶ Service registration error callback.
Level 100¶
Adapter¶
Class and methods that represent a Bluetooth Adapter.
-
class
bluezero.adapter.
Adapter
(adapter_addr=None)¶ Bluetooth Adapter Class.
This class instantiates an object that interacts with the physical Bluetooth device.
Example: >>> from bluezero import adapter >>> dongle = adapter.Adapter() >>> dongle.powered = True
-
address
¶ Return the adapter MAC address.
-
alias
¶ Return the adapter alias.
Parameters: new_alias – the new alias of the adapter.
-
bt_class
¶ Return the Bluetooth class of device.
-
discoverable
¶ Discoverable state of the Adapter.
-
discoverabletimeout
¶ Discoverable timeout of the Adapter.
-
discovering
¶ Return whether the adapter is discovering.
-
get_all
()¶ Return dictionary of all the Adapter attributes.
-
name
¶ Return the adapter name.
-
nearby_discovery
(timeout=10)¶ Start discovery of nearby Bluetooth devices.
-
pairable
¶ pairable state of the Adapter.
Parameters: new_state – boolean.
-
pairabletimeout
¶ The pairable timeout of the Adapter.
-
powered
¶ power state of the Adapter.
Parameters: new_state – boolean.
-
quit
()¶ Stop the EventLoop for async operations
-
run
()¶ Start the EventLoop for async operations
-
start_discovery
()¶ Start discovery of nearby Bluetooth devices.
Returns: True on success otherwise False
-
stop_discovery
()¶ Stop scanning of nearby Bluetooth devices.
-
uuids
¶ List of 128-bit UUIDs that represent available remote services.
-
-
exception
bluezero.adapter.
AdapterError
¶
-
bluezero.adapter.
list_adapters
()¶ Return list of adapters address available on system.
Device¶
Class and methods that represent a remote Bluetooth Device.
Classes:
- Device – Remote Bluetooth Device Class
-
class
bluezero.device.
Device
(adapter_addr, device_addr)¶ Remote Bluetooth Device Class.
This class instantiates an object that interacts with a remote Bluetooth device.
-
RSSI
¶ Received Signal Strength Indicator of the remote device.
(This is inquiry or advertising RSSI).
-
adapter
¶ The object path of the adapter the device belongs to.
-
address
¶ Return the remote device address.
-
alias
¶ remote device alias
-
appearance
¶ External appearance of device, as found on GAP service.
-
blocked
¶ Indicate whether the remote device is seen as blocked.
-
bt_class
¶ The Bluetooth class of device of the remote device.
-
cancel_pairing
()¶ This method can be used to cancel a pairing operation initiated by the pair method
-
connect
(profile=None)¶ Initiate a connection to the remote device.
Parameters: profile – (optional) profile to use for the connection.
-
connected
¶ Indicate whether the remote device is currently connected.
-
disconnect
()¶ Disconnect from the remote device.
-
icon
¶ Proposed icon name.
This is set according to the freedesktop.org icon naming specification.
-
legacy_pairing
¶ Indicate the legacy pairing status.
Set to true if the device only supports the pre-2.1 pairing mechanism.
-
manufacturer_data
¶ Manufacturer specific advertisement data.
Keys are 16 bits Manufacturer ID followed by its byte array value.
-
modalias
¶ Remote Device ID information in modalias format.
Used by the kernel and udev.
-
name
¶ Return the remote device name.
-
pair
()¶ Pair the device
-
paired
¶ Indicate whether the remote device is paired.
-
service_data
¶ Service advertisement data.
Keys are the UUIDs in string format followed by its byte array value.
-
services_resolved
¶ Indicate whether or not service discovery has been resolved.
-
trusted
¶ Indicate whether the remote device is seen as trusted.
-
tx_power
¶ Advertised transmitted power level (inquiry or advertising).
-
uuids
¶ List of 128-bit UUIDs that represent available remote services.
-
Advertisement¶
Class and methods that represent LE Advertising. This class requires BlueZ to have the experimental flag enabled
Classes:
- Advertisement – Specifies the Advertisement Data to be broadcast
- AdvertisingManager – register Advertisement Data which should be broadcast to devices
-
class
bluezero.advertisement.
AdvertisingManager
(adapter_addr=None)¶ Associate the advertisement to an adapter. If no adapter specified then first adapter in list is used
-
register_advertisement
(advertisement, options=<MagicMock name='mock()' id='139827728598464'>)¶ Registers an advertisement object to be sent over the LE Advertising channel :param advertisement: Advertisement object :param options: :return:
-
unregister_advertisement
(advertisement)¶ - This unregisters the services that has been
- previously registered. The advertisement object must match the value that was used on registration
Parameters: advertisement – Returns:
-
-
bluezero.advertisement.
register_ad_cb
()¶ Advertisement registration callback.
-
bluezero.advertisement.
register_ad_error_cb
(error)¶ Advertisement registration error callback.
Remote Device GATT¶
Classes that represent the GATT features of a remote device.
-
class
bluezero.GATT.
Characteristic
(adapter_addr, device_addr, srv_uuid, chrc_uuid)¶ Remote GATT Characteristic.
-
UUID
¶ Return the value of the Characteristic UUID for this path.
Returns: string example ‘00002a00-0000-1000-8000-00805f9b34fb’
-
add_characteristic_cb
(callback=None)¶ Add a callback for this characteristic.
Parameters: callback – callback function to be added.
-
flags
¶ Return a list of how this characteristic’s value can be used.
Returns: list example [‘read’, ‘write’, ‘notify’]
-
notifying
¶ Return whether this characteristic has notifications enabled.
Returns: Boolean
-
props_changed_cb
(iface, changed_props, invalidated_props)¶ Callback indicating that properties have changed.
Parameters: - iface – Interface associated with the callback.
- changed_props – Properties changed that triggered the callback.
- invalidated_props – Unused.
-
read_raw_value
(flags='')¶ Return this characteristic’s value (if allowed).
Parameters: flags – “offset”: Start offset “device”: Device path (Server only) Returns: - Possible Errors: org.bluez.Error.Failed
- org.bluez.Error.InProgress org.bluez.Error.NotPermitted org.bluez.Error.InvalidValueLength org.bluez.Error.NotAuthorized org.bluez.Error.NotSupported
-
resolve_gatt
()¶ Get the methods and properties for the discovered characteristics :return: Boolean of if characteristics have been resolved
-
service
¶ Return the DBus object for this characteristic’s service.
Returns: DBus object of device
-
start_notify
()¶ Initialise notifications for this characteristic.
-
start_notify_cb
()¶ Callback associated with enabling notifications.
-
stop_notify
()¶ Stop notifications for this characteristic.
-
stop_notify_cb
()¶ Callback associated with disabling notifications.
-
value
¶ The cached value of the characteristic.
This property gets updated only after a successful read request and when a notification or indication is received, upon which a PropertiesChanged signal will be emitted.
Returns: DBus byte array
-
write_value
(value, flags='')¶ Write a new value to the characteristic.
Parameters: - value –
- flags –
Returns:
-
-
class
bluezero.GATT.
Descriptor
(adapter_addr, device_addr, srv_uuid, chrc_uuid, dscr_uuid)¶ Remote GATT Descriptor.
-
UUID
¶ Return the value of the Descriptor UUID for this path.
Returns: string example ‘00002a00-0000-1000-8000-00805f9b34fb’
-
characteristic
¶ Object path of the GATT characteristic’s descriptor.
Returns: DBus object
-
flags
¶ Return a list of how this descriptor value can be used.
Returns: list example [‘read’, ‘write’]
-
read_raw_value
(flags='')¶ Issue a request to read the value of the descriptor.
Returns the value if the operation was successful.
Parameters: flags – “offset”: Start offset “device”: Device path (Server only) Returns: dbus byte array
-
resolve_gatt
()¶ Get the methods and properties for the discovered Descriptors :return:
-
value
¶ The cached value of the descriptor.
This property gets updated only after a successful read request, upon which a PropertiesChanged signal will be emitted.
Returns: DBus byte array
-
write_value
(value, flags='')¶ Issue a request to write the value of the descriptor.
Parameters: - value – DBus byte array
- flags – “offset”: Start offset “device”: Device path (Server only)
Returns:
-
-
class
bluezero.GATT.
GattManager
(adapter_addr)¶ GATT Manager.
-
register_application
(application, options)¶ Register an application with the GATT Manager.
Parameters: - application – Application object.
- options –
Returns:
-
unregister_application
(application)¶ Unregister an application with the GATT Manager.
Parameters: application – Application object. Returns:
-
-
class
bluezero.GATT.
Profile
(adapter_addr, device_addr, profile_uuid)¶ Remote GATT Profile.
-
UUIDs
¶ 128-bit GATT service UUIDs to auto connect.
Returns: list of UUIDs
-
release
()¶ Release the profile.
Returns:
-
-
class
bluezero.GATT.
Service
(adapter_addr, device_addr, srv_uuid)¶ Remote GATT Service.
-
UUID
¶ Return the value of the Service UUID for this path.
Returns: string for example ‘00001800-0000-1000-8000-00805f9b34fb’
-
device
¶ Return the DBus object that this service belongs to.
Returns: DBus object of device
-
primary
¶ Return a boolean saying if this a primary service.
Returns: boolean
-
resolve_gatt
()¶ Get the methods and properties for the discovered Services :return:
-
-
bluezero.GATT.
generic_error_cb
(error)¶ Generic Error Callback function.
-
bluezero.GATT.
register_app_cb
()¶ Application registration callback.
-
bluezero.GATT.
register_app_error_cb
(error)¶ Application registration error callback.
Local Device GATT¶
Classes required to create a Bluetooth Peripheral.
Current classes include: - Service – Bluetooth Service - Characteristic – Bluetooth Characteristic - Descriptor – Bluetooth Descriptor
Developer Documentation¶
Developer Documentation¶
Developer Install¶
If you wish to help with the development of Bluezero then the recommended way of installing for edit is as follows:
git clone https://github.com/ukBaz/python-bluezero.git
cd python-bluezero
pip3 install -e .[dev]
Release Checklist¶
- Check Travis-tests are passing (run_local_tests.sh)
- Update version info (see Update Version Info)
- Build and publish PyPI package (see Build PyPI package)
- Check PyPI page for obvious errors
git tag
with version number- Check read the docs page
Update Version Info¶
Use bumpversion package to update all references at once. This library tries to use Semantic Versioning
Semantic version uses three numbers that represent major.minor.patch
.
The bumpversion command allows you to choose which to update. In the following example the version is being updated for a patch.
bumpversion patch setup.py
Build PyPI package¶
Update version information in setup.py.
To upload to PyPI:
python3 setup.py bdist_wheel sdist
twine upload dist/*
Test Build of Documentation¶
Do a test build of the documentation and then a visual inspection. To do a local build of the documentation:
cd docs
make clean
make html
- readthedocs gets update from GitHub
- readthedocs versions are based on GitHub version tags