Closed ZaoTX closed 2 years ago
I am not sure I understand your question about UUID. There is is no requirement to use the UUID library as BlueZ (the library underneath Bluezero) expects the UUIDs in string format. If you can clarify your question I will try to answer it. Is something not doing what you are expecting? Are you trying to create a UUID for a custom service? You can do like the following:
pi@raspberry:~ $ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uuid
>>> str(uuid.uuid4())
'7a2e8776-a11f-49c4-85f7-3dce19cf010f'`
Bluetooth always sends bytes in little endian format. Most things can be done with the struct library https://docs.python.org/3/library/struct.html If you can share what the data is your getting (and what you are sending/expecting) I can take a look to see how it could be unpacked.
Thank you very much for your quick answer.
Using examples/heartrate_monitor_peripheral.py as an instance, I want to firstly create a writeable characteristic with name like "send message". Here I want to change the uuid so that it can show a desired characteristic name.
Then, I want to read a string sent from iPhone to the peripheral (here I used lightBlue). I rewrite the function write_control_point in
def write_control_point(value, options):
print(value)
But I got a list of integers when I send the text via lightBlue. Is that possible to convert this list of integers back into string?
Maybe the ble_uart.py
is a better example for you to start from for what you want to do.
The RX_CHARACTERISTIC
can be written to and it has a callback to convert the list of integers to text:
Here in my test code based on your examples:
from gi.repository import GLib
from bluezero import adapter
from bluezero import peripheral
from bluezero import device
HRM_SRV = '0000180D-0000-1000-8000-00805f9b34fb'
HR_CTRL_PT_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
def write_control_point(value,option):
"""
Called when a central writes to our write characteristic.
:param value: data sent by the central
:param options:
"""
print('raw bytes:', value)
print('With options:', options)
print('Text value:', bytes(value).decode('utf-8'))
#print(option)
adapter_address = list(adapter.Adapter.available())[0].address
# Create peripheral
hr_monitor = peripheral.Peripheral(adapter_address,
local_name='SendMeText',
appearance=0x0340)
# Add service
hr_monitor.add_service(srv_id=1, uuid=HRM_SRV, primary=True)
# Add characteristics
hr_monitor.add_characteristic(srv_id=1, chr_id=1, uuid=HR_CTRL_PT_UUID,
value="", notifying=False,
flags=['write'],
read_callback=None,
write_callback=write_control_point,
notify_callback=None
)
# Publish peripheral and start event loop
hr_monitor.publish()
The line print('Text value:', bytes(value).decode('utf-8')) is not working but print('raw bytes:', value) does. Can you tell me what could be missing here?
What I did is send a string "Test" to the peripheral. However, I only got the [84,101,115,116] as output. Is that possible to translate that back to "Test"?
Those raw byte values seem like they should do what you want.
This is my experiment:
>>> value = [84, 101, 115, 116]
>>> bytes(value)
b'Test'
>>> bytes(value).decode('utf-8')
'Test'
When you say:
The line print('Text value:', bytes(value).decode('utf-8')) is not working
What does that mean? Are you getting an error message? Can you share that message?
Hi ukBaz, Your experiment code works. But somehow there is no message printed from that line. The photo I took is the only message I got
Hi ukBaz, I don't know why when I delete the code from my demo
print('raw bytes:', value)
print('With options:', options)
It works again. Seems it only fits only one line print
Hi ukBaz, Thank you for answering my question before. My last question is how you can label the characteristics in peripheral? Is that because of the uuid? If so, I don't know how to create the uuid so that I can name that whatever I want.
There isn't really the ability to label the characteristic. As you suspect, there are some known UUIDs used in Bluetooth that are published by the Bluetooth SIG. See the 16-bit UUIDs document on their website for the full list.
There is also the following article with guidance on how to choose a UUID: https://www.novelbits.io/uuid-for-custom-services-and-characteristics/
Thank you very much! I think I found one suitable for my case! You feel free to close the issue. Have a nice day!
Dear all,
I read through the code in examples/heartrate_monitor_peripheral.py Here you defined a uuid HR_CTRL_PT_UUID = '00002a39-0000-1000-8000-00805f9b34fb' which means "Heart Rate Control Point" I would like to ask how you managed to generate such uuid from string? There is a package called uuid. I don't know which one should I use for this translation. https://docs.python.org/3/library/uuid.html
And if I send a message in string (from phone to the peripheral). It returns numbers in little endian format. How can I translate the little endian numbers into string again?