Extracting a streaming return variable in my class

Question:

I’m using bluepy and I have a base code to read values comming from an arduino now I have the problem that when I try to extrac the variable num or tum from def handleNotification I don’t have any succes in the code:

So I want to print the variable to use it in a formula in a while.

A second option will be asking how can I simplyfy my code to just connect and receive data?

This is my code:

from bluepy import btle

class MyDelegate(btle.DefaultDelegate):
    def __init__(self):
        btle.DefaultDelegate.__init__(self)
        # ... initialise here

    def handleNotification(self, cHandle, data):
        print("n- handleNotification -n")
        #print(data)
        num = list(data)[0]
        #print(num)
        tum = int.from_bytes(data, byteorder='big')
        #print(tum)
        #print(data.decode("utf-8"))#newline
        # ... perhaps check cHandle
        # ... process 'data'


# Initialisation  -------

p = btle.Peripheral("3a:dc:f3:6f:b1:dc")
p.setDelegate( MyDelegate() )

# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID("81c30e5c-1101-4f7d-a886-de3e90749161")
ch = svc.getCharacteristics("81c30e5c-2101-4f7d-a886-de3e90749161")[0]
#   ch.write( setup_data )

setup_data = b"x010"
p.writeCharacteristic(ch.valHandle+1, setup_data)

# Main loop --------

while True:
    if p.waitForNotifications(1.0):
        # handleNotification() was called
        continue

    print("Waiting...")
    # Perhaps do something else here
Asked By: Eduardomaker

||

Answers:

It is not clear from your question what you want to do with the number that you have read from the Arduino.

A typical structure might be to have the BLE code to only handle reading the code from the Arduino, turning it from bytes to some other structure before passing it along. Characteristic values will always be sent as bytes and may have a number of values packed into one notification.

One way to structure your could be to pass a function name to the MyDelegate and that be used when notifications happen. For example

from bluepy import btle


def my_main_code(new_value):
    print(new_value)


class MyDelegate(btle.DefaultDelegate):
    def __init__(self, callback):
        self.callback = callback
        btle.DefaultDelegate.__init__(self)
        # ... initialise here

    def handleNotification(self, cHandle, data):
        # Convert data to be easily consumed by callback
        tum = int.from_bytes(data, byteorder='big')
        self.callback(tum)


# Initialisation  -------
p = btle.Peripheral("3a:dc:f3:6f:b1:dc")
p.setDelegate( MyDelegate(my_main_code) )

# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID("81c30e5c-1101-4f7d-a886-de3e90749161")
ch = svc.getCharacteristics("81c30e5c-2101-4f7d-a886-de3e90749161")[0]

setup_data = b"x010"
p.writeCharacteristic(ch.valHandle+1, setup_data)

# Main loop --------

while True:
    if p.waitForNotifications(1.0):
        # handleNotification() was called
        continue

    print("Waiting...")

To respond to your "update 2" about the value from Bluetooth defining what gets sent over mqtt I’ve done the following.
There needs to be a a lot of disclaimers around this as I have no way of testing this.
I have tried to follow as closely as possible the structure in your question along with a few assumptions (that may be incorrect).
The structure of the code could be something like this:

from bluepy import btle
import paho.mqtt.publish as publish

hostname = "????????"


def publish_mqtt(new_value):
    print(new_value)
    if new_value == 1:
        publish.single("dance/lights", "on", hostname=hostname)
    else:
        publish.single("dance/lights", "off", hostname=hostname)


class MyDelegate(btle.DefaultDelegate):
    def __init__(self, callback):
        self.callback = callback
        btle.DefaultDelegate.__init__(self)
        # ... initialise here

    def handleNotification(self, cHandle, data):
        # Convert data to be easily consumed by callback
        tum = int.from_bytes(data, byteorder='big')
        self.callback(tum)


# Initialisation  -------
p = btle.Peripheral("3a:dc:f3:6f:b1:dc")
p.setDelegate(MyDelegate(publish_mqtt))

# Setup to turn notifications on, e.g.
svc = p.getServiceByUUID("81c30e5c-1101-4f7d-a886-de3e90749161")
ch = svc.getCharacteristics("81c30e5c-2101-4f7d-a886-de3e90749161")[0]

setup_data = b"x010"
p.writeCharacteristic(ch.valHandle+1, setup_data)

# Main loop --------

while True:
    if p.waitForNotifications(1.0):
        # handleNotification() was called
        continue

    print("Waiting...")

Answered By: ukBaz