CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pygatt

Python Bluetooth LE (Low Energy) and GATT Library providing cross-platform BLE operations with multiple backends

Pending
Overview
Eval results
Files

device-operations.mddocs/

Device Operations

Core BLE device connection operations including characteristic reading, writing, and subscription management. The BLEDevice class provides the interface for all device-level operations once a connection is established.

Capabilities

Connection Management

Manage device connection state, bonding, and signal strength monitoring.

def bond(self, permanent: bool = False):
    """
    Create a bonded (encrypted) connection with the device.
    
    Args:
        permanent: Store bond permanently for future connections
    
    Raises:
        BLEError: Bonding failed or not supported
        NotConnectedError: Device not connected
    """

def disconnect(self):
    """
    Disconnect from the device.
    
    After calling this method, the BLEDevice instance becomes unusable.
    Must call BLEBackend.connect() again to establish a new connection.
    """

def get_rssi(self) -> int:
    """
    Get the Received Signal Strength Indicator (RSSI) from the device.
    
    Returns:
        int: RSSI value in dBm, or None if unavailable
    """

Usage Example:

import pygatt

adapter = pygatt.BGAPIBackend()
adapter.start()
device = adapter.connect('01:23:45:67:89:ab')

# Create encrypted connection
device.bond(permanent=True)

# Monitor signal strength
rssi = device.get_rssi()
if rssi:
    print(f"Signal strength: {rssi} dBm")

# Clean disconnect
device.disconnect()

Characteristic Reading

Read data from BLE characteristics using UUID or handle-based access with support for both standard and long reads.

def char_read(self, uuid: str) -> bytearray:
    """
    Read a characteristic value by UUID.
    
    Args:
        uuid: Characteristic UUID as string (e.g., 'a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b')
    
    Returns:
        bytearray: Characteristic value data
    
    Raises:
        BLEError: Characteristic not found or read failed
        NotConnectedError: Device not connected
    """

def char_read_handle(self, handle: int) -> bytearray:
    """
    Read a characteristic value by handle.
    
    Args:
        handle: Characteristic handle as integer
    
    Returns:
        bytearray: Characteristic value data
    """

def char_read_long(self, uuid: str) -> bytearray:
    """
    Read a long characteristic value by UUID.
    
    Used for characteristics longer than MTU size.
    Note: Only supported by BGAPI backend.
    
    Args:
        uuid: Characteristic UUID as string
    
    Returns:
        bytearray: Complete characteristic value data
    """

def char_read_long_handle(self, handle: int) -> bytearray:
    """
    Read a long characteristic value by handle.
    
    Args:
        handle: Characteristic handle as integer
    
    Returns:
        bytearray: Complete characteristic value data
    """

Usage Example:

import pygatt

adapter = pygatt.BGAPIBackend()
adapter.start()
device = adapter.connect('01:23:45:67:89:ab')

# Read by UUID
battery_level = device.char_read('00002a19-0000-1000-8000-00805f9b34fb')
print(f"Battery level: {battery_level[0]}%")

# Read by handle (if known)
value = device.char_read_handle(42)

# Read long characteristic (BGAPI only)
long_data = device.char_read_long('custom-long-uuid')

Characteristic Writing

Write data to BLE characteristics with configurable response handling and support for both standard and long writes.

def char_write(self, uuid: str, value: bytearray, wait_for_response: bool = True):
    """
    Write data to a characteristic by UUID.
    
    Args:
        uuid: Characteristic UUID as string
        value: Data to write as bytearray
        wait_for_response: Wait for write confirmation (default: True)
                          False uses GATT "command" (no acknowledgment)
    
    Raises:
        BLEError: Write failed or characteristic not found
        NotConnectedError: Device not connected
    """

def char_write_handle(self, handle: int, value: bytearray, wait_for_response: bool = True):
    """
    Write data to a characteristic by handle.
    
    Args:
        handle: Characteristic handle as integer
        value: Data to write as bytearray
        wait_for_response: Wait for write confirmation
    """

def char_write_long(self, uuid: str, value: bytearray, wait_for_response: bool = False):
    """
    Write long data to a characteristic by UUID.
    
    Used for data longer than MTU size.
    Note: Only supported by BGAPI backend.
    
    Args:
        uuid: Characteristic UUID as string
        value: Data to write as bytearray
        wait_for_response: Wait for write confirmation
    """

def char_write_long_handle(self, handle: int, value: bytearray, wait_for_response: bool = False):
    """
    Write long data to a characteristic by handle.
    
    Args:
        handle: Characteristic handle as integer
        value: Data to write as bytearray
        wait_for_response: Wait for write confirmation
    """

Usage Example:

import pygatt

adapter = pygatt.GATTToolBackend()
adapter.start()
device = adapter.connect('01:23:45:67:89:ab')

# Write command to device
device.char_write('a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b', 
                  bytearray([0x01, 0x02, 0x03]))

# Fast write without waiting for response
device.char_write('command-uuid', 
                  bytearray([0xFF]), 
                  wait_for_response=False)

# Write configuration to handle
device.char_write_handle(45, bytearray([0x01, 0x00]))

Notifications and Indications

Subscribe to characteristic changes for real-time data streaming with callback-based event handling.

def subscribe(self, uuid: str, callback=None, indication: bool = False, wait_for_response: bool = True):
    """
    Subscribe to notifications or indications for a characteristic.
    
    Args:
        uuid: Characteristic UUID as string
        callback: Function called when data received: callback(handle, value)
                 handle: int, characteristic handle
                 value: bytearray, notification data
        indication: Use indications (ACKed) instead of notifications
                   More reliable but slower
        wait_for_response: Wait for subscription confirmation
    
    Raises:
        BLEError: Subscription failed or characteristic not found
    """

def unsubscribe(self, uuid: str, wait_for_response: bool = True):
    """
    Unsubscribe from notifications for a characteristic.
    
    Args:
        uuid: Characteristic UUID as string
        wait_for_response: Wait for unsubscription confirmation
    """

def subscribe_handle(self, handle: int, callback=None, indication: bool = False, wait_for_response: bool = True):
    """
    Subscribe to notifications using characteristic handle.
    
    Args:
        handle: Characteristic handle as integer
        callback: Notification callback function
        indication: Use indications instead of notifications
        wait_for_response: Wait for subscription confirmation
    """

def unsubscribe_handle(self, handle: int, wait_for_response: bool = True):
    """
    Unsubscribe from notifications using characteristic handle.
    
    Args:
        handle: Characteristic handle as integer
        wait_for_response: Wait for unsubscription confirmation
    """

def resubscribe_all(self):
    """
    Reenable all previous subscriptions after reconnection.
    
    Must be called after connection loss and subsequent reconnect
    to restore notification subscriptions.
    """

Usage Example:

import pygatt
import time
from binascii import hexlify

adapter = pygatt.GATTToolBackend()

def sensor_callback(handle, value):
    """Handle sensor data notifications"""
    print(f"Sensor data on handle {handle}: {hexlify(value)}")
    # Parse sensor data based on your device protocol
    if len(value) >= 4:
        temperature = int.from_bytes(value[:2], 'little') / 100.0
        humidity = int.from_bytes(value[2:4], 'little') / 100.0
        print(f"Temperature: {temperature}°C, Humidity: {humidity}%")

try:
    adapter.start()
    device = adapter.connect('01:23:45:67:89:ab')
    
    # Subscribe to sensor notifications
    device.subscribe('environmental-sensor-uuid', 
                    callback=sensor_callback,
                    indication=False)
    
    # Keep program running to receive notifications
    print("Listening for notifications... Press Ctrl+C to stop")
    while True:
        time.sleep(1)
        
except KeyboardInterrupt:
    print("Stopping...")
finally:
    adapter.stop()

Characteristic Discovery

Discover and map available characteristics on the connected device.

def get_handle(self, char_uuid: str) -> int:
    """
    Look up and return the handle for a characteristic by UUID.
    
    Automatically discovers characteristics if not already cached.
    
    Args:
        char_uuid: Characteristic UUID as string
    
    Returns:
        int: Characteristic handle
    
    Raises:
        BLEError: Characteristic not found
    """

def discover_characteristics(self) -> dict:
    """
    Discover all characteristics available on the device.
    
    Returns:
        dict: Mapping of UUID to Characteristic objects
            {UUID('uuid-string'): Characteristic(uuid, handle)}
    """

Usage Example:

import pygatt

adapter = pygatt.BGAPIBackend()
adapter.start()
device = adapter.connect('01:23:45:67:89:ab')

# Discover all characteristics
characteristics = device.discover_characteristics()
for uuid, char in characteristics.items():
    print(f"Characteristic {uuid}: handle={char.handle}")

# Get specific handle
battery_handle = device.get_handle('00002a19-0000-1000-8000-00805f9b34fb')
print(f"Battery service handle: {battery_handle}")

MTU Exchange

Negotiate Maximum Transmission Unit size for larger data transfers.

def exchange_mtu(self, mtu: int) -> int:
    """
    Request MTU (Maximum Transmission Unit) exchange with device.
    
    Args:
        mtu: Requested MTU size in bytes
    
    Returns:
        int: Negotiated MTU size as accepted by device
    
    Raises:
        BLEError: MTU exchange failed
        NotImplementedError: Backend doesn't support MTU exchange
    """

Usage Example:

# Request larger MTU for bigger data transfers
new_mtu = device.exchange_mtu(512)
print(f"Negotiated MTU: {new_mtu} bytes")

Error Handling

Common device operation errors:

  • NotConnectedError: Device disconnected during operation
  • BLEError: Characteristic not found, operation not supported
  • NotificationTimeout: Notification subscription timeout
  • BGAPIError: BGAPI protocol-specific errors

Install with Tessl CLI

npx tessl i tessl/pypi-pygatt

docs

backend-management.md

bgapi-backend.md

device-operations.md

error-handling.md

gatttool-backend.md

index.md

utilities.md

tile.json