or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backend-management.mdbgapi-backend.mddevice-operations.mderror-handling.mdgatttool-backend.mdindex.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Utility functions and classes for UUID conversion, device discovery, and USB serial device management. These utilities provide helper functionality for common BLE development tasks and hardware integration.

3

4

## Capabilities

5

6

### UUID Conversion

7

8

Convert between different UUID formats commonly used in BLE applications.

9

10

```python { .api }

11

def uuid16_to_uuid(uuid16: int) -> UUID:

12

"""

13

Convert 16-bit UUID to full 128-bit UUID format.

14

15

Converts Bluetooth SIG assigned 16-bit UUIDs to their full 128-bit

16

representation using the Bluetooth base UUID.

17

18

Args:

19

uuid16: 16-bit UUID as integer (e.g., 0x180F for Battery Service)

20

21

Returns:

22

UUID: Full 128-bit UUID object

23

24

Example:

25

Battery Service UUID 0x180F becomes:

26

0000180F-0000-1000-8000-00805F9B34FB

27

"""

28

```

29

30

**Usage Example:**

31

32

```python

33

import pygatt

34

from pygatt.util import uuid16_to_uuid

35

36

# Convert standard Bluetooth service UUIDs

37

battery_service = uuid16_to_uuid(0x180F)

38

print(battery_service) # 0000180f-0000-1000-8000-00805f9b34fb

39

40

device_info_service = uuid16_to_uuid(0x180A)

41

print(device_info_service) # 0000180a-0000-1000-8000-00805f9b34fb

42

43

# Use converted UUID with pygatt

44

adapter = pygatt.BGAPIBackend()

45

adapter.start()

46

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

47

48

# Read battery level using converted UUID

49

battery_level = device.char_read(str(battery_service))

50

```

51

52

### USB Device Discovery

53

54

Discover and enumerate USB serial devices for BGAPI backend configuration.

55

56

```python { .api }

57

def find_usb_serial_devices(vendor_id: int = None, product_id: int = None) -> list:

58

"""

59

Discover USB serial devices matching optional vendor/product ID filters.

60

61

Args:

62

vendor_id: USB vendor ID to filter by (e.g., 0x2458 for Silicon Labs)

63

product_id: USB product ID to filter by (e.g., 0x0001 for BLED112)

64

65

Returns:

66

list: List of USBSerialDeviceInfo objects for matching devices

67

68

Raises:

69

ImportError: If required USB enumeration libraries not available

70

"""

71

72

def extract_vid_pid(info_string: str) -> tuple:

73

"""

74

Extract vendor ID and product ID from USB device info string.

75

76

Args:

77

info_string: USB device information string from system

78

79

Returns:

80

tuple: (vendor_id: int, product_id: int) or (None, None) if not found

81

"""

82

```

83

84

**Usage Example:**

85

86

```python

87

import pygatt

88

from pygatt.backends.bgapi.util import find_usb_serial_devices, extract_vid_pid

89

90

# Find all USB serial devices

91

all_devices = find_usb_serial_devices()

92

for device in all_devices:

93

print(f"Device: {device.device_name}")

94

print(f"Port: {device.port_name}")

95

print(f"VID: 0x{device.vendor_id:04X}, PID: 0x{device.product_id:04X}")

96

97

# Find BLED112 devices specifically

98

bled112_devices = find_usb_serial_devices(

99

vendor_id=0x2458, # Silicon Labs

100

product_id=0x0001 # BLED112

101

)

102

103

if bled112_devices:

104

# Use first BLED112 found

105

device = bled112_devices[0]

106

adapter = pygatt.BGAPIBackend(serial_port=device.port_name)

107

print(f"Using BLED112 on {device.port_name}")

108

else:

109

print("No BLED112 devices found")

110

111

# Parse device info manually

112

info = "USB\\VID_2458&PID_0001\\12345"

113

vid, pid = extract_vid_pid(info)

114

if vid and pid:

115

print(f"Found device: VID=0x{vid:04X}, PID=0x{pid:04X}")

116

```

117

118

### USB Device Information

119

120

Container class for USB serial device metadata and connection details.

121

122

```python { .api }

123

class USBSerialDeviceInfo:

124

"""

125

Container for USB serial device information.

126

127

Attributes:

128

device_name: Human-readable device name

129

port_name: System port name for serial connection

130

vendor_id: USB vendor ID as integer

131

product_id: USB product ID as integer

132

"""

133

def __init__(self, device_name: str, port_name: str, vendor_id: int, product_id: int):

134

self.device_name = device_name

135

self.port_name = port_name

136

self.vendor_id = vendor_id

137

self.product_id = product_id

138

```

139

140

**Usage Example:**

141

142

```python

143

from pygatt.backends.bgapi.util import USBSerialDeviceInfo

144

145

# Create device info manually

146

device_info = USBSerialDeviceInfo(

147

device_name="Silicon Labs BLED112",

148

port_name="COM9", # Windows

149

vendor_id=0x2458,

150

product_id=0x0001

151

)

152

153

print(f"Device: {device_info.device_name}")

154

print(f"Connect via: {device_info.port_name}")

155

156

# Use with BGAPI backend

157

adapter = pygatt.BGAPIBackend(serial_port=device_info.port_name)

158

```

159

160

## BGAPI Hardware Constants

161

162

Predefined constants for common BGAPI-compatible hardware identification.

163

164

```python { .api }

165

# Silicon Labs BLED112 USB BLE adapter

166

BLED112_VENDOR_ID = 0x2458

167

BLED112_PRODUCT_ID = 0x0001

168

169

# Usage in device discovery

170

from pygatt.backends.bgapi.constants import BLED112_VENDOR_ID, BLED112_PRODUCT_ID

171

172

bled112_devices = find_usb_serial_devices(

173

vendor_id=BLED112_VENDOR_ID,

174

product_id=BLED112_PRODUCT_ID

175

)

176

```

177

178

## Platform-Specific Utilities

179

180

Handle cross-platform differences in USB device enumeration and serial port naming.

181

182

### Windows COM Port Discovery

183

184

```python

185

import pygatt

186

from pygatt.backends.bgapi.util import find_usb_serial_devices

187

188

# Windows-specific COM port handling

189

devices = find_usb_serial_devices()

190

for device in devices:

191

if device.port_name.startswith('COM'):

192

print(f"Windows COM port: {device.port_name}")

193

194

# Handle COM ports > 9 (Windows limitation)

195

if int(device.port_name[3:]) > 9:

196

print("Warning: COM ports >9 may require special handling")

197

```

198

199

### Linux/macOS Device Path Discovery

200

201

```python

202

import pygatt

203

from pygatt.backends.bgapi.util import find_usb_serial_devices

204

205

# Unix-style device path handling

206

devices = find_usb_serial_devices()

207

for device in devices:

208

if device.port_name.startswith('/dev/'):

209

print(f"Unix device path: {device.port_name}")

210

211

# Common Linux patterns

212

if 'ttyACM' in device.port_name:

213

print("USB CDC ACM device (typical for BGAPI)")

214

elif 'ttyUSB' in device.port_name:

215

print("USB serial converter device")

216

elif 'cu.usbmodem' in device.port_name:

217

print("macOS USB modem device")

218

```

219

220

## Automated Device Selection

221

222

Implement intelligent device selection for robust applications.

223

224

```python

225

import pygatt

226

from pygatt.backends.bgapi.util import find_usb_serial_devices

227

from pygatt.backends.bgapi.constants import BLED112_VENDOR_ID, BLED112_PRODUCT_ID

228

229

def auto_select_bgapi_device():

230

"""

231

Automatically select best BGAPI device available.

232

233

Returns:

234

str: Serial port name for selected device

235

236

Raises:

237

pygatt.BGAPIError: No suitable devices found

238

"""

239

# First, look for known BGAPI devices

240

bgapi_devices = find_usb_serial_devices(

241

vendor_id=BLED112_VENDOR_ID,

242

product_id=BLED112_PRODUCT_ID

243

)

244

245

if bgapi_devices:

246

device = bgapi_devices[0] # Use first BLED112

247

print(f"Selected BLED112: {device.port_name}")

248

return device.port_name

249

250

# Fallback: look for any Silicon Labs device

251

siliconlabs_devices = find_usb_serial_devices(vendor_id=0x2458)

252

if siliconlabs_devices:

253

device = siliconlabs_devices[0]

254

print(f"Selected Silicon Labs device: {device.port_name}")

255

return device.port_name

256

257

# Last resort: let BGAPI backend auto-discover

258

print("No specific devices found, using auto-discovery")

259

return None

260

261

# Usage

262

try:

263

port = auto_select_bgapi_device()

264

adapter = pygatt.BGAPIBackend(serial_port=port)

265

adapter.start()

266

print("BGAPI backend initialized successfully")

267

268

except pygatt.BGAPIError as e:

269

print(f"Failed to initialize BGAPI: {e}")

270

print("Check USB connections and drivers")

271

```

272

273

## Device Health Monitoring

274

275

Monitor USB device health and connection stability.

276

277

```python

278

import time

279

import threading

280

from pygatt.backends.bgapi.util import find_usb_serial_devices

281

282

class BGAPIDeviceMonitor:

283

"""

284

Monitor BGAPI device availability and health.

285

"""

286

287

def __init__(self, vendor_id=0x2458, product_id=0x0001):

288

self.vendor_id = vendor_id

289

self.product_id = product_id

290

self.monitoring = False

291

self.last_seen_devices = set()

292

293

def start_monitoring(self, callback=None):

294

"""

295

Start monitoring device availability.

296

297

Args:

298

callback: Function called on device changes: callback(added, removed)

299

"""

300

self.monitoring = True

301

302

def monitor_loop():

303

while self.monitoring:

304

current_devices = set()

305

306

try:

307

devices = find_usb_serial_devices(

308

vendor_id=self.vendor_id,

309

product_id=self.product_id

310

)

311

current_devices = {d.port_name for d in devices}

312

313

if current_devices != self.last_seen_devices:

314

added = current_devices - self.last_seen_devices

315

removed = self.last_seen_devices - current_devices

316

317

if callback:

318

callback(added, removed)

319

320

if added:

321

print(f"BGAPI devices added: {added}")

322

if removed:

323

print(f"BGAPI devices removed: {removed}")

324

325

self.last_seen_devices = current_devices

326

327

except Exception as e:

328

print(f"Device monitoring error: {e}")

329

330

time.sleep(2) # Check every 2 seconds

331

332

threading.Thread(target=monitor_loop, daemon=True).start()

333

334

def stop_monitoring(self):

335

self.monitoring = False

336

337

# Usage

338

def device_change_handler(added, removed):

339

if removed:

340

print("BGAPI device disconnected - applications may need restart")

341

if added:

342

print("New BGAPI device available")

343

344

monitor = BGAPIDeviceMonitor()

345

monitor.start_monitoring(callback=device_change_handler)

346

347

# Run for 30 seconds

348

time.sleep(30)

349

monitor.stop_monitoring()

350

```

351

352

## Error Handling for Utilities

353

354

Handle common issues in device discovery and USB enumeration.

355

356

```python

357

import pygatt

358

from pygatt.backends.bgapi.util import find_usb_serial_devices

359

360

def safe_device_discovery():

361

"""

362

Safely discover USB devices with comprehensive error handling.

363

"""

364

try:

365

devices = find_usb_serial_devices()

366

return devices

367

368

except ImportError as e:

369

print(f"USB enumeration not available: {e}")

370

print("Install: pip install pyusb or pip install pyserial")

371

return []

372

373

except PermissionError:

374

print("Permission denied accessing USB devices")

375

print("Try running with elevated privileges")

376

return []

377

378

except Exception as e:

379

print(f"Unexpected error in device discovery: {e}")

380

return []

381

382

# Usage with fallback

383

devices = safe_device_discovery()

384

if devices:

385

print(f"Found {len(devices)} USB serial devices")

386

else:

387

print("No devices found or discovery failed")

388

print("Specify serial port manually:")

389

print("adapter = pygatt.BGAPIBackend(serial_port='COM9')")

390

```