Python 基础脚本:使用 Bleak 列出 BLE 设备
此脚本使用 Python 的 Bleak 库列出蓝牙低功耗 (BLE) 设备。目前,RSSI 和服务列表不起作用。
list_ble_devices.py
#!/usr/bin/env python3
"""
BLE 设备扫描器
此脚本扫描并列出附近所有可用的蓝牙低功耗 (BLE) 设备。
它显示设备信息,包括名称、地址和 RSSI。
要求:
- bleak 库:pip install bleak
用法:
python list_ble_devices.py
"""
import asyncio
import sys
from bleak import BleakScanner
from datetime import datetime
async def scan_ble_devices(scan_time=10):
"""
扫描 BLE 设备并返回已发现设备的列表。
参数:
scan_time (int): 扫描持续时间(秒)(默认:10)
返回:
list: BleakDevice 对象列表
"""
print(f"Scanning for BLE devices for {scan_time} seconds...")
print("=" * 50)
try:
devices = await BleakScanner.discover(timeout=scan_time)
return devices
except Exception as e:
print(f"Error during scanning: {e}")
return []
def display_devices(devices):
"""
以格式化表格显示已发现的 BLE 设备。
参数:
devices (list): BleakDevice 对象列表
"""
if not devices:
print("No BLE devices found.")
return
print(f"Found {len(devices)} BLE device(s):")
print("-" * 80)
print(f"{'Name':<25} {'Address':<20} {'RSSI':<6} {'Services'}")
print("-" * 80)
for device in devices:
name = device.name if device.name else "<Unknown>"
address = device.address
rssi = "N/A"
if hasattr(device, 'metadata') and 'rssi' in device.metadata:
rssi_val = device.metadata['rssi']
rssi = f"{rssi_val} dBm" if rssi_val is not None else "N/A"
# 如果可用,获取服务 UUID
services = ""
if hasattr(device, 'metadata') and 'uuids' in device.metadata:
services = ', '.join(device.metadata['uuids'][:2]) # 显示前 2 个 UUID
if len(device.metadata['uuids']) > 2:
services += "..."
print(f"{name:<25} {address:<20} {rssi:<6} {services}")
async def main():
"""
运行 BLE 设备扫描器的主函数。
"""
print("BLE Device Scanner")
print(f"Scan started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
# 检查是否提供了扫描时间作为命令行参数
scan_time = 10
if len(sys.argv) > 1:
try:
scan_time = int(sys.argv[1])
if scan_time <= 0:
raise ValueError("Scan time must be positive")
except ValueError as e:
print(f"Invalid scan time: {e}")
print("Using default scan time of 10 seconds")
scan_time = 10
# 执行扫描
devices = await scan_ble_devices(scan_time)
# 显示结果
print()
display_devices(devices)
# 附加设备详情
if devices:
print()
print("Additional device information:")
print("-" * 50)
for i, device in enumerate(devices, 1):
print(f"{i}. {device.name or '<Unknown>'} ({device.address})")
metadata = getattr(device, 'metadata', None)
if metadata:
for key, value in metadata.items():
if key != 'uuids': # uuids 已在上面显示
print(f" {key}: {value}")
print()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nScan interrupted by user.")
except Exception as e:
print(f"An error occurred: {e}")
sys.exit(1)If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow