0
# Device Operations
1
2
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.
3
4
## Capabilities
5
6
### Connection Management
7
8
Manage device connection state, bonding, and signal strength monitoring.
9
10
```python { .api }
11
def bond(self, permanent: bool = False):
12
"""
13
Create a bonded (encrypted) connection with the device.
14
15
Args:
16
permanent: Store bond permanently for future connections
17
18
Raises:
19
BLEError: Bonding failed or not supported
20
NotConnectedError: Device not connected
21
"""
22
23
def disconnect(self):
24
"""
25
Disconnect from the device.
26
27
After calling this method, the BLEDevice instance becomes unusable.
28
Must call BLEBackend.connect() again to establish a new connection.
29
"""
30
31
def get_rssi(self) -> int:
32
"""
33
Get the Received Signal Strength Indicator (RSSI) from the device.
34
35
Returns:
36
int: RSSI value in dBm, or None if unavailable
37
"""
38
```
39
40
**Usage Example:**
41
42
```python
43
import pygatt
44
45
adapter = pygatt.BGAPIBackend()
46
adapter.start()
47
device = adapter.connect('01:23:45:67:89:ab')
48
49
# Create encrypted connection
50
device.bond(permanent=True)
51
52
# Monitor signal strength
53
rssi = device.get_rssi()
54
if rssi:
55
print(f"Signal strength: {rssi} dBm")
56
57
# Clean disconnect
58
device.disconnect()
59
```
60
61
### Characteristic Reading
62
63
Read data from BLE characteristics using UUID or handle-based access with support for both standard and long reads.
64
65
```python { .api }
66
def char_read(self, uuid: str) -> bytearray:
67
"""
68
Read a characteristic value by UUID.
69
70
Args:
71
uuid: Characteristic UUID as string (e.g., 'a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b')
72
73
Returns:
74
bytearray: Characteristic value data
75
76
Raises:
77
BLEError: Characteristic not found or read failed
78
NotConnectedError: Device not connected
79
"""
80
81
def char_read_handle(self, handle: int) -> bytearray:
82
"""
83
Read a characteristic value by handle.
84
85
Args:
86
handle: Characteristic handle as integer
87
88
Returns:
89
bytearray: Characteristic value data
90
"""
91
92
def char_read_long(self, uuid: str) -> bytearray:
93
"""
94
Read a long characteristic value by UUID.
95
96
Used for characteristics longer than MTU size.
97
Note: Only supported by BGAPI backend.
98
99
Args:
100
uuid: Characteristic UUID as string
101
102
Returns:
103
bytearray: Complete characteristic value data
104
"""
105
106
def char_read_long_handle(self, handle: int) -> bytearray:
107
"""
108
Read a long characteristic value by handle.
109
110
Args:
111
handle: Characteristic handle as integer
112
113
Returns:
114
bytearray: Complete characteristic value data
115
"""
116
```
117
118
**Usage Example:**
119
120
```python
121
import pygatt
122
123
adapter = pygatt.BGAPIBackend()
124
adapter.start()
125
device = adapter.connect('01:23:45:67:89:ab')
126
127
# Read by UUID
128
battery_level = device.char_read('00002a19-0000-1000-8000-00805f9b34fb')
129
print(f"Battery level: {battery_level[0]}%")
130
131
# Read by handle (if known)
132
value = device.char_read_handle(42)
133
134
# Read long characteristic (BGAPI only)
135
long_data = device.char_read_long('custom-long-uuid')
136
```
137
138
### Characteristic Writing
139
140
Write data to BLE characteristics with configurable response handling and support for both standard and long writes.
141
142
```python { .api }
143
def char_write(self, uuid: str, value: bytearray, wait_for_response: bool = True):
144
"""
145
Write data to a characteristic by UUID.
146
147
Args:
148
uuid: Characteristic UUID as string
149
value: Data to write as bytearray
150
wait_for_response: Wait for write confirmation (default: True)
151
False uses GATT "command" (no acknowledgment)
152
153
Raises:
154
BLEError: Write failed or characteristic not found
155
NotConnectedError: Device not connected
156
"""
157
158
def char_write_handle(self, handle: int, value: bytearray, wait_for_response: bool = True):
159
"""
160
Write data to a characteristic by handle.
161
162
Args:
163
handle: Characteristic handle as integer
164
value: Data to write as bytearray
165
wait_for_response: Wait for write confirmation
166
"""
167
168
def char_write_long(self, uuid: str, value: bytearray, wait_for_response: bool = False):
169
"""
170
Write long data to a characteristic by UUID.
171
172
Used for data longer than MTU size.
173
Note: Only supported by BGAPI backend.
174
175
Args:
176
uuid: Characteristic UUID as string
177
value: Data to write as bytearray
178
wait_for_response: Wait for write confirmation
179
"""
180
181
def char_write_long_handle(self, handle: int, value: bytearray, wait_for_response: bool = False):
182
"""
183
Write long data to a characteristic by handle.
184
185
Args:
186
handle: Characteristic handle as integer
187
value: Data to write as bytearray
188
wait_for_response: Wait for write confirmation
189
"""
190
```
191
192
**Usage Example:**
193
194
```python
195
import pygatt
196
197
adapter = pygatt.GATTToolBackend()
198
adapter.start()
199
device = adapter.connect('01:23:45:67:89:ab')
200
201
# Write command to device
202
device.char_write('a1e8f5b1-696b-4e4c-87c6-69dfe0b0093b',
203
bytearray([0x01, 0x02, 0x03]))
204
205
# Fast write without waiting for response
206
device.char_write('command-uuid',
207
bytearray([0xFF]),
208
wait_for_response=False)
209
210
# Write configuration to handle
211
device.char_write_handle(45, bytearray([0x01, 0x00]))
212
```
213
214
### Notifications and Indications
215
216
Subscribe to characteristic changes for real-time data streaming with callback-based event handling.
217
218
```python { .api }
219
def subscribe(self, uuid: str, callback=None, indication: bool = False, wait_for_response: bool = True):
220
"""
221
Subscribe to notifications or indications for a characteristic.
222
223
Args:
224
uuid: Characteristic UUID as string
225
callback: Function called when data received: callback(handle, value)
226
handle: int, characteristic handle
227
value: bytearray, notification data
228
indication: Use indications (ACKed) instead of notifications
229
More reliable but slower
230
wait_for_response: Wait for subscription confirmation
231
232
Raises:
233
BLEError: Subscription failed or characteristic not found
234
"""
235
236
def unsubscribe(self, uuid: str, wait_for_response: bool = True):
237
"""
238
Unsubscribe from notifications for a characteristic.
239
240
Args:
241
uuid: Characteristic UUID as string
242
wait_for_response: Wait for unsubscription confirmation
243
"""
244
245
def subscribe_handle(self, handle: int, callback=None, indication: bool = False, wait_for_response: bool = True):
246
"""
247
Subscribe to notifications using characteristic handle.
248
249
Args:
250
handle: Characteristic handle as integer
251
callback: Notification callback function
252
indication: Use indications instead of notifications
253
wait_for_response: Wait for subscription confirmation
254
"""
255
256
def unsubscribe_handle(self, handle: int, wait_for_response: bool = True):
257
"""
258
Unsubscribe from notifications using characteristic handle.
259
260
Args:
261
handle: Characteristic handle as integer
262
wait_for_response: Wait for unsubscription confirmation
263
"""
264
265
def resubscribe_all(self):
266
"""
267
Reenable all previous subscriptions after reconnection.
268
269
Must be called after connection loss and subsequent reconnect
270
to restore notification subscriptions.
271
"""
272
```
273
274
**Usage Example:**
275
276
```python
277
import pygatt
278
import time
279
from binascii import hexlify
280
281
adapter = pygatt.GATTToolBackend()
282
283
def sensor_callback(handle, value):
284
"""Handle sensor data notifications"""
285
print(f"Sensor data on handle {handle}: {hexlify(value)}")
286
# Parse sensor data based on your device protocol
287
if len(value) >= 4:
288
temperature = int.from_bytes(value[:2], 'little') / 100.0
289
humidity = int.from_bytes(value[2:4], 'little') / 100.0
290
print(f"Temperature: {temperature}°C, Humidity: {humidity}%")
291
292
try:
293
adapter.start()
294
device = adapter.connect('01:23:45:67:89:ab')
295
296
# Subscribe to sensor notifications
297
device.subscribe('environmental-sensor-uuid',
298
callback=sensor_callback,
299
indication=False)
300
301
# Keep program running to receive notifications
302
print("Listening for notifications... Press Ctrl+C to stop")
303
while True:
304
time.sleep(1)
305
306
except KeyboardInterrupt:
307
print("Stopping...")
308
finally:
309
adapter.stop()
310
```
311
312
### Characteristic Discovery
313
314
Discover and map available characteristics on the connected device.
315
316
```python { .api }
317
def get_handle(self, char_uuid: str) -> int:
318
"""
319
Look up and return the handle for a characteristic by UUID.
320
321
Automatically discovers characteristics if not already cached.
322
323
Args:
324
char_uuid: Characteristic UUID as string
325
326
Returns:
327
int: Characteristic handle
328
329
Raises:
330
BLEError: Characteristic not found
331
"""
332
333
def discover_characteristics(self) -> dict:
334
"""
335
Discover all characteristics available on the device.
336
337
Returns:
338
dict: Mapping of UUID to Characteristic objects
339
{UUID('uuid-string'): Characteristic(uuid, handle)}
340
"""
341
```
342
343
**Usage Example:**
344
345
```python
346
import pygatt
347
348
adapter = pygatt.BGAPIBackend()
349
adapter.start()
350
device = adapter.connect('01:23:45:67:89:ab')
351
352
# Discover all characteristics
353
characteristics = device.discover_characteristics()
354
for uuid, char in characteristics.items():
355
print(f"Characteristic {uuid}: handle={char.handle}")
356
357
# Get specific handle
358
battery_handle = device.get_handle('00002a19-0000-1000-8000-00805f9b34fb')
359
print(f"Battery service handle: {battery_handle}")
360
```
361
362
### MTU Exchange
363
364
Negotiate Maximum Transmission Unit size for larger data transfers.
365
366
```python { .api }
367
def exchange_mtu(self, mtu: int) -> int:
368
"""
369
Request MTU (Maximum Transmission Unit) exchange with device.
370
371
Args:
372
mtu: Requested MTU size in bytes
373
374
Returns:
375
int: Negotiated MTU size as accepted by device
376
377
Raises:
378
BLEError: MTU exchange failed
379
NotImplementedError: Backend doesn't support MTU exchange
380
"""
381
```
382
383
**Usage Example:**
384
385
```python
386
# Request larger MTU for bigger data transfers
387
new_mtu = device.exchange_mtu(512)
388
print(f"Negotiated MTU: {new_mtu} bytes")
389
```
390
391
## Error Handling
392
393
Common device operation errors:
394
395
- **NotConnectedError**: Device disconnected during operation
396
- **BLEError**: Characteristic not found, operation not supported
397
- **NotificationTimeout**: Notification subscription timeout
398
- **BGAPIError**: BGAPI protocol-specific errors