What I want to do:
I want to connect my Raspberry Pi 2 to a Bluetooth Smart Weight Scale (Medisana BS440) and receive my Data.
What I know:
There is just one interesting Primary Service with 5 Characteristics:
- handle: 0x001a
- properties: 0x20 (Indication), char value handle: 0x1b uuid:00008a21-0000-1000-8000-00805f9b34fb
- handle: 0x001d
- properties: 0x20 (Indication), char value handle: 0x1e uuid:00008a22-0000-1000-8000-00805f9b34fb
- handle: 0x0020
- properties: 0x02 (Read-Only), char value handle: 0x21 uuid:00008a20-00..
- handle: 0x0022
- properties: 0x08 (Write-Only), char value handle: 0x23 uuid:00008a81-00..
- handle: 0x0024
- properties: 0x20 (Indication), char value handle: 0x25 uuid:00008a82-00..
I used the HCI-Snoop-Developer-Funktion of my Android-Phone, to see how the corresponding app communicates to my scale.
after step 4. there is the first Indication (handle 0x25) which give me the stored personal data of me (my height, gender, age etc)
after step 5. there are some Indications (handle 0x1b and handle 0x1e) which should transfer my measured data. (Didn't analyze the hex-values at this time)
What I did:
I installed bluez.5.32 on my raspi (kernel 4.1.13), and did step 1 - 5 with gatttool and everything works fine till step 5. I don't get any Indication-messages from handle 0x1b and 0x1e) Nothing happens after step 5.
gatttool -t random -b DE:70:4A:XX:XX:XX -I
char-write-cmd 0x1f 0200
char-read-hnd 0x21 (37fb)
char-write-cmd 0x1c 0200
char-write-cmd 0x26 0200
char-write-cmd 0x23 0000000000
(I even do the thing with unix-timestamp-for 1975.. doesnt worked out)
After billions of hours I was getting bluetoothctl work on my raspi (there was a dbus-problem) and I tried the same with bluetoothctl. I enabled all Indications and write 0000000000 to hnd=0x23. Switched to handle 0x1a and it worked! I receive many hex-values that should be the data I'm searching for.
So whats the problem? I want to use gatttool for my purpose or at least I want to understand, why it doesnt worked out with gatttool
When I use bluetoothctl, I just can select and watch one attribute, and after receiving the data, my scale automatically disconnects to my raspberry. So when I select characteristic 0x1a, I cant see the indication-messages of characteristic 0x01d et vice versa.
Is there another connection between my Pi and my Scale when I'm using gatttool or when I'm using bluetoothctl? Or is there a difference in the way, how they communicate to my scale?
The scale appears to be connectable just for a short period of time after the weight etc. has been measured I used the non-interactive mode of gatttool in a bash script like this:
gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001f -n 0200
gatttool -t random -b F1:37:57:XX:XX:XX --char-read --handle 0x0021
gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001c -n 0200
gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x0026 -n 0200
gatttool -t random -b F1:37:57:XX:XX:XX --char-write-req --handle 0x0023 -n 0000000000 --listen
Info was taken from Pratik Sinha here. To get the response displayed the --listen explicitly needed to be given after which some 25 lines of data are received (alternating 1b and 1e responses). Thanks for your info, saved me days of work!
Happy New Year!
EDIT:
Using Python and the pygatt module this boils down to:
import pygatt.backends
from binascii import hexlify
def printIndication(handle, value):
print('Indication received {} : {}'.format(hex(handle), hexlify(str(value))))
adapter = pygatt.backends.GATTToolBackend()
adapter.start()
# wait for someone to step on the scale
while True:
try:
device = adapter.connect('f1:37:57:xx:xx:xx', 5, 'random')
break
except pygatt.exceptions.NotConnectedError:
print('Waiting...')
device.subscribe('00008a22-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
device.subscribe('00008a21-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
device.subscribe('00008a82-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
try:
device.char_write_handle(0x23, [02,00,00,00,00], True)
except pygatt.exceptions.NotificationTimeout:
pass
device.disconnect()
adapter.stop()
NOTES: