or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-structures.mddevice-discovery.mdexception-handling.mdgatt-client.mdindex.mduuid-utilities.md

uuid-utilities.mddocs/

0

# UUID Utilities and Constants

1

2

Bleak provides comprehensive utilities for UUID normalization, conversion, and lookup of Bluetooth assigned numbers. These utilities handle the conversion between different UUID formats and provide human-readable descriptions for standard Bluetooth services and characteristics.

3

4

## Capabilities

5

6

### UUID Normalization Functions

7

8

Convert UUIDs between different formats and normalize them to Bleak's standard 128-bit lowercase format.

9

10

```python { .api }

11

def normalize_uuid_str(uuid: str) -> str:

12

"""

13

Normalize a UUID string to Bleak's standard format.

14

15

Converts UUID to lowercase and expands 16-bit and 32-bit UUIDs to 128-bit format.

16

17

Args:

18

uuid: UUID string in 16-bit, 32-bit, or 128-bit format

19

20

Returns:

21

128-bit UUID string in lowercase format

22

23

Examples:

24

normalize_uuid_str("1234") -> "00001234-0000-1000-8000-00805f9b34fb"

25

normalize_uuid_str("12345678") -> "12345678-0000-1000-8000-00805f9b34fb"

26

normalize_uuid_str("12345678-0000-1234-1234-1234567890ABC") ->

27

"12345678-0000-1234-1234-1234567890abc"

28

29

Note: Function normalizes according to Bluetooth Core Specification Version 5.4 | Vol 3, Part B - Section 2.5.1

30

"""

31

32

def normalize_uuid_16(uuid: int) -> str:

33

"""

34

Normalizes a 16-bit integer UUID to Bleak's standard format.

35

36

Args:

37

uuid: 16-bit integer UUID

38

39

Returns:

40

128-bit UUID string with format "0000xxxx-0000-1000-8000-00805f9b34fb"

41

42

Example:

43

normalize_uuid_16(0x1234) -> "00001234-0000-1000-8000-00805f9b34fb"

44

"""

45

46

def normalize_uuid_32(uuid: int) -> str:

47

"""

48

Normalizes a 32-bit integer UUID to Bleak's standard format.

49

50

Args:

51

uuid: 32-bit integer UUID

52

53

Returns:

54

128-bit UUID string with format "xxxxxxxx-0000-1000-8000-00805f9b34fb"

55

56

Example:

57

normalize_uuid_32(0x12345678) -> "12345678-0000-1000-8000-00805f9b34fb"

58

"""

59

```

60

61

### UUID Description Lookup

62

63

Convert UUIDs to human-readable descriptions using Bluetooth assigned numbers.

64

65

```python { .api }

66

def uuidstr_to_str(uuid_: str) -> str:

67

"""

68

Convert UUID string to human-readable description.

69

70

Looks up the UUID in the assigned numbers database and returns

71

a descriptive name if found.

72

73

Args:

74

uuid_: UUID string to look up

75

76

Returns:

77

Human-readable description or "Unknown" if not found

78

79

Examples:

80

uuidstr_to_str("0000180f-0000-1000-8000-00805f9b34fb") -> "Battery Service"

81

uuidstr_to_str("00002a19-0000-1000-8000-00805f9b34fb") -> "Battery Level"

82

"""

83

84

def register_uuids(uuids_to_descriptions: dict[str, str]) -> None:

85

"""

86

Register custom UUID to description mappings.

87

88

Adds or modifies the mapping of 128-bit UUIDs to descriptions

89

for application-specific or vendor-specific UUIDs.

90

91

Args:

92

uuids_to_descriptions: Dictionary mapping UUID strings to descriptions

93

94

Example:

95

register_uuids({

96

"12345678-1234-5678-9012-123456789abc": "My Custom Service",

97

"87654321-4321-8765-2109-cba987654321": "My Custom Characteristic"

98

})

99

"""

100

```

101

102

### UUID Assigned Numbers Constants

103

104

Comprehensive dictionaries containing Bluetooth SIG assigned numbers for services, characteristics, and descriptors.

105

106

```python { .api }

107

# 16-bit UUID assignments

108

uuid16_dict: dict[int, str] = {

109

0x1800: "Generic Access Profile",

110

0x1801: "Generic Attribute Profile",

111

0x1802: "Immediate Alert",

112

0x180A: "Device Information",

113

0x180F: "Battery Service",

114

0x1812: "Human Interface Device",

115

# ... (complete mapping with hundreds of entries)

116

}

117

118

# 128-bit UUID assignments (vendor-specific and custom services)

119

uuid128_dict: dict[str, str] = {

120

"6e400001-b5a3-f393-e0a9-e50e24dcca9e": "Nordic UART Service",

121

"6e400002-b5a3-f393-e0a9-e50e24dcca9e": "Nordic UART RX",

122

"6e400003-b5a3-f393-e0a9-e50e24dcca9e": "Nordic UART TX",

123

# ... (complete mapping with custom and vendor UUIDs)

124

}

125

```

126

127

### Advertisement Data Type Constants

128

129

Enumeration of Generic Access Profile advertisement data types.

130

131

```python { .api }

132

class AdvertisementDataType(IntEnum):

133

"""Generic Access Profile advertisement data types."""

134

135

FLAGS = 0x01

136

INCOMPLETE_LIST_SERVICE_UUID16 = 0x02

137

COMPLETE_LIST_SERVICE_UUID16 = 0x03

138

INCOMPLETE_LIST_SERVICE_UUID32 = 0x04

139

COMPLETE_LIST_SERVICE_UUID32 = 0x05

140

INCOMPLETE_LIST_SERVICE_UUID128 = 0x06

141

COMPLETE_LIST_SERVICE_UUID128 = 0x07

142

SHORTENED_LOCAL_NAME = 0x08

143

COMPLETE_LOCAL_NAME = 0x09

144

TX_POWER_LEVEL = 0x0A

145

CLASS_OF_DEVICE = 0x0D

146

SERVICE_DATA_UUID16 = 0x16

147

SERVICE_DATA_UUID32 = 0x20

148

SERVICE_DATA_UUID128 = 0x21

149

MANUFACTURER_SPECIFIC_DATA = 0xFF

150

```

151

152

### Characteristic Properties

153

154

Constants and utilities for GATT characteristic properties.

155

156

```python { .api }

157

CharacteristicPropertyName = Literal[

158

"broadcast",

159

"read",

160

"write-without-response",

161

"write",

162

"notify",

163

"indicate",

164

"authenticated-signed-writes",

165

"extended-properties",

166

"reliable-write",

167

"writable-auxiliaries",

168

"encrypt-read",

169

"encrypt-write",

170

"encrypt-authenticated-read",

171

"encrypt-authenticated-write",

172

"authorize",

173

]

174

175

CHARACTERISTIC_PROPERTIES: dict[int, CharacteristicPropertyName] = {

176

0x1: "broadcast",

177

0x2: "read",

178

0x4: "write-without-response",

179

0x8: "write",

180

0x10: "notify",

181

0x20: "indicate",

182

0x40: "authenticated-signed-writes",

183

0x80: "extended-properties",

184

0x100: "reliable-write",

185

0x200: "writable-auxiliaries",

186

}

187

188

def gatt_char_props_to_strs(props: int) -> frozenset[CharacteristicPropertyName]:

189

"""

190

Convert GATT characteristic properties bitmask to set of property names.

191

192

Args:

193

props: Characteristic properties bitmask

194

195

Returns:

196

Frozenset of property name strings

197

"""

198

```

199

200

## Usage Examples

201

202

### UUID Normalization and Conversion

203

204

```python

205

from bleak.uuids import normalize_uuid_str, normalize_uuid_16, normalize_uuid_32

206

207

def demonstrate_uuid_normalization():

208

# Normalize different UUID formats

209

uuid_16bit = normalize_uuid_str("180F") # Battery Service

210

print(f"16-bit UUID: {uuid_16bit}")

211

# Output: 0000180f-0000-1000-8000-00805f9b34fb

212

213

uuid_32bit = normalize_uuid_str("12345678")

214

print(f"32-bit UUID: {uuid_32bit}")

215

# Output: 12345678-0000-1000-8000-00805f9b34fb

216

217

uuid_128bit = normalize_uuid_str("12345678-1234-5678-9012-123456789ABC")

218

print(f"128-bit UUID: {uuid_128bit}")

219

# Output: 12345678-1234-5678-9012-123456789abc

220

221

# Normalize from integers

222

from_int_16 = normalize_uuid_16(0x180F)

223

print(f"From 16-bit int: {from_int_16}")

224

225

from_int_32 = normalize_uuid_32(0x12345678)

226

print(f"From 32-bit int: {from_int_32}")

227

228

demonstrate_uuid_normalization()

229

```

230

231

### UUID Description Lookup

232

233

```python

234

from bleak.uuids import uuidstr_to_str

235

236

def demonstrate_uuid_lookup():

237

# Look up standard Bluetooth services

238

gap_service = uuidstr_to_str("00001800-0000-1000-8000-00805f9b34fb")

239

print(f"GAP Service: {gap_service}")

240

# Output: Generic Access Profile

241

242

battery_service = uuidstr_to_str("0000180f-0000-1000-8000-00805f9b34fb")

243

print(f"Battery Service: {battery_service}")

244

# Output: Battery Service

245

246

# Look up standard characteristics

247

device_name = uuidstr_to_str("00002a00-0000-1000-8000-00805f9b34fb")

248

print(f"Device Name: {device_name}")

249

# Output: Device Name

250

251

battery_level = uuidstr_to_str("00002a19-0000-1000-8000-00805f9b34fb")

252

print(f"Battery Level: {battery_level}")

253

# Output: Battery Level

254

255

# Look up vendor-specific UUID

256

nordic_uart = uuidstr_to_str("6e400001-b5a3-f393-e0a9-e50e24dcca9e")

257

print(f"Nordic UART: {nordic_uart}")

258

# Output: Nordic UART Service

259

260

# Unknown UUID

261

unknown = uuidstr_to_str("12345678-1234-5678-9012-123456789abc")

262

print(f"Unknown UUID: {unknown}")

263

# Output: Unknown

264

265

demonstrate_uuid_lookup()

266

```

267

268

### Registering Custom UUIDs

269

270

```python

271

from bleak.uuids import register_uuids, uuidstr_to_str

272

273

def demonstrate_custom_uuids():

274

# Register custom UUID mappings

275

custom_uuids = {

276

"12345678-1234-5678-9012-123456789abc": "My IoT Device Service",

277

"87654321-4321-8765-2109-cba987654321": "Temperature Sensor Characteristic",

278

"11111111-2222-3333-4444-555555555555": "Custom Control Point"

279

}

280

281

register_uuids(custom_uuids)

282

283

# Now lookup returns custom descriptions

284

service_desc = uuidstr_to_str("12345678-1234-5678-9012-123456789abc")

285

print(f"Custom Service: {service_desc}")

286

# Output: My IoT Device Service

287

288

char_desc = uuidstr_to_str("87654321-4321-8765-2109-cba987654321")

289

print(f"Custom Characteristic: {char_desc}")

290

# Output: Temperature Sensor Characteristic

291

292

demonstrate_custom_uuids()

293

```

294

295

### Working with Characteristic Properties

296

297

```python

298

from bleak.assigned_numbers import gatt_char_props_to_strs, CHARACTERISTIC_PROPERTIES

299

300

def demonstrate_characteristic_properties():

301

# Example properties bitmask (read + write + notify)

302

props_mask = 0x1A # 0x02 (read) + 0x08 (write) + 0x10 (notify)

303

304

# Convert to property names

305

properties = gatt_char_props_to_strs(props_mask)

306

print(f"Properties: {properties}")

307

# Output: frozenset({'read', 'write', 'notify'})

308

309

# Check individual properties

310

if "read" in properties:

311

print("Characteristic supports reading")

312

313

if "write" in properties:

314

print("Characteristic supports write-with-response")

315

316

if "notify" in properties:

317

print("Characteristic supports notifications")

318

319

if "write-without-response" not in properties:

320

print("Characteristic does not support write-without-response")

321

322

# Show all available property mappings

323

print("\nAll property mappings:")

324

for bit, name in CHARACTERISTIC_PROPERTIES.items():

325

print(f" 0x{bit:02X}: {name}")

326

327

demonstrate_characteristic_properties()

328

```

329

330

### Practical UUID Usage in BLE Operations

331

332

```python

333

import asyncio

334

from bleak import BleakClient

335

from bleak.uuids import normalize_uuid_str, uuidstr_to_str

336

337

async def uuid_practical_usage():

338

address = "00:11:22:33:44:55" # Replace with actual device address

339

340

async with BleakClient(address) as client:

341

print(f"Connected to {client.name}")

342

343

# Use UUID utilities with service discovery

344

for service in client.services:

345

service_desc = uuidstr_to_str(service.uuid)

346

print(f"\nService: {service.uuid}")

347

print(f" Description: {service_desc}")

348

349

for char in service.characteristics:

350

char_desc = uuidstr_to_str(char.uuid)

351

print(f" Characteristic: {char.uuid}")

352

print(f" Description: {char_desc}")

353

print(f" Properties: {char.properties}")

354

355

# Demonstrate reading standard characteristics

356

if char.uuid == normalize_uuid_str("2A00"): # Device Name

357

try:

358

data = await client.read_gatt_char(char.uuid)

359

name = data.decode('utf-8')

360

print(f" Device Name: {name}")

361

except Exception as e:

362

print(f" Could not read device name: {e}")

363

364

elif char.uuid == normalize_uuid_str("2A19"): # Battery Level

365

try:

366

data = await client.read_gatt_char(char.uuid)

367

level = int.from_bytes(data, byteorder='little')

368

print(f" Battery Level: {level}%")

369

except Exception as e:

370

print(f" Could not read battery level: {e}")

371

372

# asyncio.run(uuid_practical_usage()) # Uncomment with real device

373

```

374

375

### Advertisement Data Type Usage

376

377

```python

378

from bleak.assigned_numbers import AdvertisementDataType

379

380

def process_advertisement_data(adv_data_raw):

381

"""Example of processing raw advertisement data using constants."""

382

383

# Parse advertisement data (simplified example)

384

pos = 0

385

while pos < len(adv_data_raw):

386

length = adv_data_raw[pos]

387

if length == 0:

388

break

389

390

ad_type = adv_data_raw[pos + 1]

391

data = adv_data_raw[pos + 2:pos + 1 + length]

392

393

# Use constants for readable code

394

if ad_type == AdvertisementDataType.COMPLETE_LOCAL_NAME:

395

device_name = data.decode('utf-8')

396

print(f"Device Name: {device_name}")

397

398

elif ad_type == AdvertisementDataType.COMPLETE_LIST_SERVICE_UUID16:

399

# Parse 16-bit service UUIDs

400

for i in range(0, len(data), 2):

401

uuid_16 = int.from_bytes(data[i:i+2], byteorder='little')

402

print(f"Service UUID: {uuid_16:04X}")

403

404

elif ad_type == AdvertisementDataType.TX_POWER_LEVEL:

405

tx_power = int.from_bytes(data, byteorder='little', signed=True)

406

print(f"TX Power: {tx_power} dBm")

407

408

elif ad_type == AdvertisementDataType.MANUFACTURER_SPECIFIC_DATA:

409

company_id = int.from_bytes(data[:2], byteorder='little')

410

mfg_data = data[2:]

411

print(f"Manufacturer {company_id:04X}: {mfg_data.hex()}")

412

413

pos += 1 + length

414

415

# Example usage with mock data

416

mock_adv_data = bytes([

417

0x05, 0x09, 0x54, 0x65, 0x73, 0x74, # Complete local name: "Test"

418

0x03, 0x03, 0x0F, 0x18, # Complete 16-bit service UUID: 0x180F

419

0x02, 0x0A, 0x00, # TX Power: 0 dBm

420

])

421

422

process_advertisement_data(mock_adv_data)

423

```

424

425

## Types

426

427

```python { .api }

428

# UUID dictionaries

429

uuid16_dict: dict[int, str]

430

uuid128_dict: dict[str, str]

431

432

# Characteristic property type

433

CharacteristicPropertyName = Literal[

434

"broadcast", "read", "write-without-response", "write",

435

"notify", "indicate", "authenticated-signed-writes",

436

"extended-properties", "reliable-write", "writable-auxiliaries",

437

"encrypt-read", "encrypt-write", "encrypt-authenticated-read",

438

"encrypt-authenticated-write", "authorize"

439

]

440

441

# Property mapping

442

CHARACTERISTIC_PROPERTIES: dict[int, CharacteristicPropertyName]

443

444

# Advertisement data types

445

class AdvertisementDataType(IntEnum): ...

446

```