Pycom Wipy 3.0 read PROP_NOTIFY

Hi Everyone. Thanks in advance to any help you can give me.

I just received my Wipy 3.0 and Track on Friday. I watched Chris’ awesome videos Saturday morning and got lat long and modified the class to give me atomic clock time within a couple of hours, awesome! Connected to a BLE device and read out the services and characteristics in an hour, great!

I’ve got stuck though, trying to read the value of a notify property. I can detect that the property exists and get it’s UUID, properties, instance. But can’t read the actual value of the data. I can connect with a BLE scanner on my phone and with an arduino+HM10 and read the value so know the device is working.

It is giving me this error: OSError: the requested operation failed

Here is my code:

from network import Bluetooth
import binascii
import time
bt = Bluetooth()
#bt.start_scan(-1)
bt.stop_scan()
bt.start_scan(-1)

while True:
    adv = bt.get_adv()
    if adv:
        mfg_data = bt.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA)

        if bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'earconnect':
            print('connected to: {}'.format(bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)))
            conn = bt.connect(adv.mac)
            services = conn.services()
            for service in services:
                time.sleep(0.050)
                if type(service.uuid()) == bytes:
                    print('Reading bytes from service: {}'.format(service.uuid()))
                else:
                    print('Reading chars from service: %x' % service.uuid())
                chars = service.characteristics()
                for char in chars:
                    #if ((char.properties()) & (Bluetooth.PROP_READ or Bluetooth.PROP_INDICATE or Bluetooth.PROP_NOTIFY)):
                    if ((char.properties()) & (Bluetooth.PROP_NOTIFY)):
                        print('char uuid: {}'.format(char.uuid()))
                        print('char instance: {}'.format(char.instance()))
                        print('char properties: {}'.format(char.properties()))
                        #line below fails with error: OSError: the requested operation failed
                        print('char read: {}'.format(char.read()))
            conn.disconnect()
            break
    else:
        #print('ADV does not exist')
        time.sleep(0.050)

Hi Luke!

I may be wrong, but I think that you cannot read the value of a Notify. Notifications are a message type that your device is sending, like a request. You may not be able to read the notification request you are sending. This could just be out of the supported bluetooth operations on Pycom. They say on in their documentation that they only support “Basic BLE functionality” at this time. Perhaps that just isn’t supported yet.

Let me know if you find a solution!

1 Like

Thanks @Stephen. Hmmm, I’ve using it as a central and connecting to a peripheral. THat’s a bugger since the characteristic I’m interested in is a notify type and the Wipy can’t read it. I’ll keep digging.

Cheers Luke

2 Likes

I ended up finding a ‘legacy’ characteristic that contained some of the data that I could process/decode and use.

Luke,

I’d like to know how you did it! Would you mind sharing your code?

Sure, I’m tidying it into a class, then will share. But basically I printed out every characteristic, looked for ones that had varying output, then used an ascii/hex.dec conversion table to see if it fitted what I was looking for.

1 Like

Hi Stephen,

I got this sorted properly, here’s the code. I’ve added a Bluetooth.CHAR_NOTIFY_EVENT which calls char_notify_callback when the peripheral updates the notify characteristic:

from network import Bluetooth
import binascii
import time
bt = Bluetooth()
#bt.start_scan(-1)
bt.stop_scan()
bt.start_scan(-1)

def char_notify_callback(char):
    char_value = (char.value())
    print("Got new char: {} value: {}".format(char.uuid(), char_value))

while True:
    adv = bt.get_adv()
    if adv:
        mfg_data = bt.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA)
        your_device_name = "something here"

        if bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == your_device_name:
            print('connected to: {}'.format(bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL)))
            conn = bt.connect(adv.mac)
            services = conn.services()
            for service in services:
                time.sleep(0.050)
                if type(service.uuid()) == bytes:
                    print('Reading bytes from service: {}'.format(service.uuid()))
                else:
                    print('Reading chars from service: %x' % service.uuid())
                chars = service.characteristics()
                for char in chars:
                    if ((char.properties()) & (Bluetooth.PROP_NOTIFY)):
                        characteristic.callback(trigger=Bluetooth.CHAR_NOTIFY_EVENT,
                                                handler=char_notify_callback,
                                                arg=None)
            conn.disconnect()
            break
    else:
        #print('ADV does not exist')
        time.sleep(0.050)
2 Likes