Minimales Python-Skript zum Auflisten & Lesen von BLE-Geräte-Charakteristiken mit Python (Bleak)
Dieses Skript listet Bluetooth Low Energy (BLE)-Geräte auf und liest deren Charakteristiken mit der Bleak-Bibliothek in Python. Es ist ein minimales Beispiel, um zu zeigen, wie man sich mit einem BLE-Gerät verbindet und dessen Charakteristiken liest.
connect_ble_device.py
#!/usr/bin/env python3
"""
BLE-Geräteverbindung und Service-Explorer
Dieses Skript verbindet sich mit einem bestimmten BLE-Gerät anhand der MAC-Adresse
und listet alle verfügbaren Services sowie deren Charakteristiken/Attribute auf.
Voraussetzungen:
- bleak-Bibliothek: pip install bleak
Verwendung:
python connect_ble_device.py [MAC_ADDRESS]
Beispiel:
python connect_ble_device.py 24:EC:4A:76:00:32
"""
import asyncio
import sys
import argparse
from bleak import BleakClient
from bleak.exc import BleakError
from datetime import datetime
async def explore_device_services(client, show_descriptors=False):
"""
Untersucht alle Services und Charakteristiken eines verbundenen BLE-Geräts.
Args:
client (BleakClient): Verbundener BLE-Client
"""
try:
# Alle Services als Liste abrufen
services = list(client.services)
if not services:
print("No services found on this device.")
return
print(f"Found {len(services)} service(s):")
print("=" * 80)
for service in services:
print(f"\nService: {service.uuid}")
print(f"Description: {service.description}")
print(f"Handle: {service.handle}")
# Charakteristiken für diesen Service abrufen
characteristics = service.characteristics
if characteristics:
print(f" Characteristics ({len(characteristics)}):")
print(" " + "-" * 76)
for char in characteristics:
print(f" UUID: {char.uuid}")
print(f" Description: {char.description}")
print(f" Handle: {char.handle}")
print(f" Properties: {', '.join(char.properties)}")
# Versuche, die Charakteristik zu lesen, wenn sie lesbar ist
if "read" in char.properties:
try:
value = await client.read_gatt_char(char.uuid)
# Versuche als String zu dekodieren, sonst als Hex anzeigen
try:
decoded_value = value.decode('utf-8')
print(f" Value (string): {decoded_value}")
except UnicodeDecodeError:
hex_value = ' '.join(f'{b:02x}' for b in value)
print(f" Value (hex): {hex_value}")
print(f" Value (raw bytes): {value}")
except Exception as e:
print(f" Value: <Could not read - {e}>")
# Deskriptoren nur anzeigen, wenn angefordert
if show_descriptors:
descriptors = char.descriptors
if descriptors:
print(f" Descriptors ({len(descriptors)}):")
for desc in descriptors:
print(f" UUID: {desc.uuid}")
print(f" Description: {desc.description}")
print(f" Handle: {desc.handle}")
# Versuche, den Deskriptor zu lesen, wenn möglich
try:
desc_value = await client.read_gatt_descriptor(desc.handle)
try:
decoded_desc = desc_value.decode('utf-8')
print(f" Value (string): {decoded_desc}")
except UnicodeDecodeError:
hex_desc = ' '.join(f'{b:02x}' for b in desc_value)
print(f" Value (hex): {hex_desc}")
except Exception as e:
print(f" Value: <Could not read - {e}>")
print() # Leerzeile zwischen Charakteristiken
else:
print()
else:
print(" No characteristics found for this service.")
print("-" * 80)
except Exception as e:
print(f"Error exploring services: {e}")
async def connect_and_explore(mac_address, show_descriptors=False):
"""
Verbindet sich mit einem BLE-Gerät und untersucht dessen Services.
Args:
mac_address (str): MAC-Adresse des Geräts, mit dem verbunden werden soll
scan_time (int): Dauer, nach der das Gerät gesucht wird
"""
print(f"\nAttempting to connect to {mac_address} ...")
try:
async with BleakClient(mac_address) as client:
if client.is_connected:
print(f"Successfully connected to {mac_address}")
print(f"Connected at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
# Alle Services und Charakteristiken untersuchen
await explore_device_services(client, show_descriptors=show_descriptors)
print(f"\nDisconnected from {mac_address}")
return True
else:
print(f"Failed to connect to {mac_address}")
return False
except BleakError as e:
print(f"Bluetooth error: {e}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
async def main():
"""
Hauptfunktion zum Ausführen des BLE-Geräteverbinders und -Explorers.
"""
print("BLE Device Connection and Service Explorer")
print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
parser = argparse.ArgumentParser(description="Connect to a BLE device and list all services and attributes.")
parser.add_argument("mac_address", nargs="?", default="24:EC:4A:76:00:32", help="MAC address of the BLE device (default: 24:EC:4A:76:00:32)")
parser.add_argument("-d", "--descriptors", action="store_true", help="Show individual descriptors for each characteristic")
args = parser.parse_args()
mac_address = args.mac_address
show_descriptors = args.descriptors
print(f"Using MAC address: {mac_address}")
if show_descriptors:
print("Descriptor display enabled.")
# MAC-Adressformat validieren (einfache Prüfung)
if len(mac_address.replace(":", "").replace("-", "")) != 12:
print(f"Invalid MAC address format: {mac_address}")
print("Expected format: XX:XX:XX:XX:XX:XX or XX-XX-XX-XX-XX-XX")
return
print()
# Mit dem Gerät verbinden und es untersuchen
success = await connect_and_explore(mac_address, show_descriptors=show_descriptors)
if success:
print("\nDevice exploration completed successfully.")
else:
print("\nDevice exploration failed.")
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nOperation interrupted by user.")
except Exception as e:
print(f"An error occurred: {e}")
sys.exit(1)Wenn dieser Beitrag dir geholfen hat, erwäge, mir einen Kaffee zu spendieren oder per PayPal zu spenden, um die Recherche und Veröffentlichung neuer Beiträge auf TechOverflow zu unterstützen