kopia lustrzana https://github.com/micropython/micropython-lib
aioble/server.py: Add data arg for indicate.
In micropython/micropython#11239 we added support for passing data to gatts_indicate (to make it match gatts_notify). This adds the same to aioble. Also update the documentation to mention this (and fix some mistakes and add a few more examples). This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>pull/729/head
rodzic
55d1d23d6f
commit
e5ba864470
|
@ -1,4 +1,4 @@
|
||||||
metadata(version="0.3.0")
|
metadata(version="0.4.0")
|
||||||
|
|
||||||
require("aioble-core")
|
require("aioble-core")
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ Alternatively, install the `aioble` package, which will install everything.
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Passive scan for nearby devices for 5 seconds: (Observer)
|
#### Passive scan for nearby devices for 5 seconds: (Observer)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
async with aioble.scan(duration_ms=5000) as scanner:
|
async with aioble.scan(duration_ms=5000) as scanner:
|
||||||
|
@ -87,7 +87,7 @@ async with aioble.scan(duration_ms=5000, interval_us=30000, window_us=30000, act
|
||||||
print(result, result.name(), result.rssi, result.services())
|
print(result, result.name(), result.rssi, result.services())
|
||||||
```
|
```
|
||||||
|
|
||||||
Connect to a peripheral device: (Central)
|
#### Connect to a peripheral device: (Central)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
# Either from scan result
|
# Either from scan result
|
||||||
|
@ -101,7 +101,7 @@ except asyncio.TimeoutError:
|
||||||
print('Timeout')
|
print('Timeout')
|
||||||
```
|
```
|
||||||
|
|
||||||
Register services and wait for connection: (Peripheral, Server)
|
#### Register services and wait for connection: (Peripheral, Server)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
|
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
|
||||||
|
@ -126,30 +126,95 @@ while True:
|
||||||
print("Connection from", device)
|
print("Connection from", device)
|
||||||
```
|
```
|
||||||
|
|
||||||
Update characteristic value: (Server)
|
#### Update characteristic value: (Server)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
# Write the local value.
|
||||||
temp_char.write(b'data')
|
temp_char.write(b'data')
|
||||||
|
|
||||||
temp_char.notify(b'optional data')
|
|
||||||
|
|
||||||
await temp_char.indicate(timeout_ms=2000)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Query the value of a characteristic: (Client)
|
```py
|
||||||
|
# Write the local value and notify/indicate subscribers.
|
||||||
|
temp_char.write(b'data', send_update=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Send notifications: (Server)
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Notify with the current value.
|
||||||
|
temp_char.notify(connection)
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Notify with a custom value.
|
||||||
|
temp_char.notify(connection, b'optional data')
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Send indications: (Server)
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Indicate with current value.
|
||||||
|
await temp_char.indicate(connection, timeout_ms=2000)
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Indicate with custom value.
|
||||||
|
await temp_char.indicate(connection, b'optional data', timeout_ms=2000)
|
||||||
|
```
|
||||||
|
|
||||||
|
This will raise `GattError` if the indication is not acknowledged.
|
||||||
|
|
||||||
|
#### Wait for a write from the client: (Server)
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Normal characteristic, returns the connection that did the write.
|
||||||
|
connection = await char.written(timeout_ms=2000)
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Characteristic with capture enabled, also returns the value.
|
||||||
|
char = Characteristic(..., capture=True)
|
||||||
|
connection, data = await char.written(timeout_ms=2000)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Query the value of a characteristic: (Client)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
temp_service = await connection.service(_ENV_SENSE_UUID)
|
temp_service = await connection.service(_ENV_SENSE_UUID)
|
||||||
temp_char = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)
|
temp_char = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)
|
||||||
|
|
||||||
data = await temp_char.read(timeout_ms=1000)
|
data = await temp_char.read(timeout_ms=1000)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Wait for a notification/indication: (Client)
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Notification
|
||||||
|
data = await temp_char.notified(timeout_ms=1000)
|
||||||
|
```
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Indication
|
||||||
|
data = await temp_char.indicated(timeout_ms=1000)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Subscribe to a characteristic: (Client)
|
||||||
|
|
||||||
|
```py
|
||||||
|
# Subscribe for notification.
|
||||||
await temp_char.subscribe(notify=True)
|
await temp_char.subscribe(notify=True)
|
||||||
while True:
|
while True:
|
||||||
data = await temp_char.notified()
|
data = await temp_char.notified()
|
||||||
```
|
```
|
||||||
|
|
||||||
Open L2CAP channels: (Listener)
|
```py
|
||||||
|
# Subscribe for indication.
|
||||||
|
await temp_char.subscribe(indicate=True)
|
||||||
|
while True:
|
||||||
|
data = await temp_char.indicated()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Open L2CAP channels: (Listener)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
channel = await connection.l2cap_accept(_L2CAP_PSN, _L2CAP_MTU)
|
channel = await connection.l2cap_accept(_L2CAP_PSN, _L2CAP_MTU)
|
||||||
|
@ -158,7 +223,7 @@ n = channel.recvinto(buf)
|
||||||
channel.send(b'response')
|
channel.send(b'response')
|
||||||
```
|
```
|
||||||
|
|
||||||
Open L2CAP channels: (Initiator)
|
#### Open L2CAP channels: (Initiator)
|
||||||
|
|
||||||
```py
|
```py
|
||||||
channel = await connection.l2cap_connect(_L2CAP_PSN, _L2CAP_MTU)
|
channel = await connection.l2cap_connect(_L2CAP_PSN, _L2CAP_MTU)
|
||||||
|
|
|
@ -257,7 +257,7 @@ class Characteristic(BaseCharacteristic):
|
||||||
raise ValueError("Not supported")
|
raise ValueError("Not supported")
|
||||||
ble.gatts_notify(connection._conn_handle, self._value_handle, data)
|
ble.gatts_notify(connection._conn_handle, self._value_handle, data)
|
||||||
|
|
||||||
async def indicate(self, connection, timeout_ms=1000):
|
async def indicate(self, connection, data=None, timeout_ms=1000):
|
||||||
if not (self.flags & _FLAG_INDICATE):
|
if not (self.flags & _FLAG_INDICATE):
|
||||||
raise ValueError("Not supported")
|
raise ValueError("Not supported")
|
||||||
if self._indicate_connection is not None:
|
if self._indicate_connection is not None:
|
||||||
|
@ -270,7 +270,7 @@ class Characteristic(BaseCharacteristic):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with connection.timeout(timeout_ms):
|
with connection.timeout(timeout_ms):
|
||||||
ble.gatts_indicate(connection._conn_handle, self._value_handle)
|
ble.gatts_indicate(connection._conn_handle, self._value_handle, data)
|
||||||
await self._indicate_event.wait()
|
await self._indicate_event.wait()
|
||||||
if self._indicate_status != 0:
|
if self._indicate_status != 0:
|
||||||
raise GattError(self._indicate_status)
|
raise GattError(self._indicate_status)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# code. This allows (for development purposes) all the files to live in the
|
# code. This allows (for development purposes) all the files to live in the
|
||||||
# one directory.
|
# one directory.
|
||||||
|
|
||||||
metadata(version="0.3.1")
|
metadata(version="0.4.0")
|
||||||
|
|
||||||
# Default installation gives you everything. Install the individual
|
# Default installation gives you everything. Install the individual
|
||||||
# components (or a combination of them) if you want a more minimal install.
|
# components (or a combination of them) if you want a more minimal install.
|
||||||
|
|
Ładowanie…
Reference in New Issue