Open tljstewart opened 1 year ago
I think I found it, you need to call server.update_value(service_uuid, char_uuid)
to notify, I would of suspected a callback similar to read_request_func
, write_request_func
... I'd recommend an api such as on_read
, on_write
, on_notify
.
Currently, it seems a bit strange to set the characteristic.value
then call server.update_value(service_uuid, char_uuid)
to notify.
Perhaps when characteristic.value
is set it should call server.update_value
if notify
property is set and has subscribers? Just some thoughts, as I use the library
If there is a readthedocs or a readme, I'd love to read over it. Thanks
Great library, and thank you for making it MIT licensed.
I second the need for some documentation and a notify example! Hesitant to use this without notify being easily usable
This works for me, modified from the gattserver.py
example. It's not very elegant, but may serve as an example. The asyncio
usage in the examples is a little bit outdated, but I didn't change it here:
"""
Example for a BLE 4.0 Notify Server using a GATT dictionary of services and
characteristics
"""
import logging
import asyncio
from typing import Any, Dict
from bless import ( # type: ignore
BlessServer,
BlessGATTCharacteristic,
GATTCharacteristicProperties,
GATTAttributePermissions
)
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name=__name__)
def write_request(
characteristic: BlessGATTCharacteristic,
value: Any,
**kwargs
):
characteristic.value = value
logger.debug(f"Char value set to {characteristic.value}")
# if characteristic.value == b'\x0f':
# logger.debug("Nice")
# trigger.set()
def notify(server, value):
server.get_characteristic(
YOUR_NOTIFY_UUID,
).value = value
server.update_value(
YOUR_SERVICE_UUID",
YOUR_NOTIFY_UUID"
)
async def run(loop):
# Instantiate the server
gatt: Dict = {
YOUR_SERVICE_UUID: {
YOUR_NOTIFY_UUID: {
"Properties": GATTCharacteristicProperties.notify,
"Permissions": GATTAttributePermissions.readable,
"Value": None
},
"YOUR_WRITE_UUID: { # This is not required, I need it for my case
"Properties": (GATTCharacteristicProperties.write |
GATTCharacteristicProperties.write_without_response),
"Permissions": GATTAttributePermissions.writeable,
"Value": None
},
}
}
server_name = "MY_NOTIFY_SERVER"
server = BlessServer(name=server_name, loop=loop, name_overwrite=True)
server.write_request_func = write_request # not required if we don't have a write characteristic
await server.add_gatt(gatt)
await server.start()
logger.debug("Waiting for someone to subscribe")
while not await server.is_connected(): # The name of this method is slightly misleading
await asyncio.sleep(0.1)
logger.debug("Someone has subscribed.")
notify(server, b'Welcome')
# This is the actual notifying loop:
while True:
a = input("Value: ")
if a == "quit":
break
else:
notify(server, a.encode())
await asyncio.sleep(0.5)
logger.debug("Stopping")
await server.stop()
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
@MarkusPiotrowski Thx for your example. I used it with added values for YOUR_SERVICE_UUID, YOUR_NOTIFY_UUID, YOUR_WRITE_UUID from https://bleid.netlify.app
For debugging I used NRF Connect App on iOS. However, Im getting spammed with Bluetooth Pairing requests by iOS. Does it have to do with wrong UUID for my service and iOS is getting confused what service is it connecting to? Or some pairing handling is needed on the script side?
In between pairing requests I tapped subscribe button and send 1,2 ,3 via terminal running script on my Raspberry Pi. These values were received, but popup still keep on showing up 🤔
Any help is appreciated :)
Edit:
Solution was found here in my case: https://github.com/ukBaz/python-bluezero/issues/335
After tapping pair once, pairing requests are not shown anymore on iOS
One cause of this is that Linux tries to read the battery state from the iPhone, which triggers the pairing request. You can configure bluez to prevent this. One of my colleagues at Ditto wrote some docs to fix it, which the forum won't let me link directly, but I will copy-paste the main instructions here.
To disable auto Battery reading
Open the bluetooth service file /usr/lib/systemd/system/bluetooth.service, or /etc/systemd/system/bluetooth.target.wants/bluetooth.service in a text editor. You may need sudo permission to write to this file.
Add -P battery to the end of the ExecStart line to disable the Battery feature in bluetoothd. Your ExecStart should look something like ExecStart=/usr/lib/bluetooth/bluetoothd -P battery now. Save the file.
3.Run systemctl daemon-reload and systemctl restart bluetooth to apply the changes to the Bluetooth service
Great library, was pointed here by @dlech on
bleak
repo looking for a BLE server. Successfully added read and write callback, but notify callback appears to be missing in the api, is it possible to notify once thecharacteristic.value
is updated?