Request- response scenario using BLE (python)

Viewed 66

I am building a mechanism for syncing data between two sqlite instances (master on Raspberry and slave on mobile). I want to do this over BLE using dedicated Characteristic and combination of Write and Notification. What I want to do: after receiving the value from the client (mobile application) I read the passed value and trigger a one-time notification with the response.

  • From the test application (BlueSee on my Mac) I can Write value and this value is visible on the peripheral (RPI) - the method WriteValue (print ('DEBUG WriteValue received:' + str (val))) is called on the device

  • When I subscribe to notifications from the test application, the StartNotify method is called on the device and the test application receives subsequent values ​​at 500 ms intervals (counter)

  • What I wanted to do (code commented out) is to trigger a one-time notification in response to the value received to the WriteValue method (assuming that the test application subscribes to it). I assume the notification trigger is self.PropertiesChanged (GATT_CHRC_IFACE, {"Value": value}, []). I don't know if I'm doing it right because it didn't work :) Does it have something to do with callback - here I don't quite know how it works.

import dbus

from advertisement import Advertisement
from service import Application, Service, Characteristic, Descriptor

GATT_CHRC_IFACE = "org.bluez.GattCharacteristic1"
NOTIFY_TIMEOUT = 500

class MyAdvertisement(Advertisement):
    def __init__(self, index):
        Advertisement.__init__(self, index, "peripheral")
        self.add_local_name("Instinct BLE")
        self.include_tx_power = True


class MyService(Service):
    MY_SVC_UUID = "00000001-710e-4a5b-8d75-3e5b444bc3cf"

    def __init__(self, index):

        Service.__init__(self, index, self.MY_SVC_UUID, True)
        self.add_characteristic(MyCharacteristic(self))

class MyCharacteristic(Characteristic):
    counter = 0
    MY_CHARACTERISTIC_UUID = "00000002-710e-4a5b-8d75-3e5b444bc3cf"

    def __init__(self, service):
        self.notifying = False

        Characteristic.__init__(
            self, self.MY_CHARACTERISTIC_UUID,
            ["notify", "read", "write"], service)
        self.add_descriptor(MyDescriptor(self))

    def get_response(self):
        value = []

        strresponse = str(self.counter)
        self.counter = self.counter +1
        print('DEBUG ReadValue value to be send back: '+str(self.counter))
        for c in strresponse:
            value.append(dbus.Byte(c.encode()))
        return value

    def set_response_callback(self):
        if self.notifying:
            value = self.get_response()
            self.PropertiesChanged(GATT_CHRC_IFACE, {"Value": value}, [])

        return self.notifying

    def StartNotify(self):
        print('DEBUG StartNotify')
        if self.notifying:
            return

        self.notifying = True
        value = self.get_response()
        print ('DEBUG StartNotify')
        self.PropertiesChanged(GATT_CHRC_IFACE, {"Value": value}, [])
        self.add_timeout(NOTIFY_TIMEOUT, self.set_response_callback)

    def StopNotify(self):
        print('DEBUG StopNotify')
        self.notifying = False

    def ReadValue(self, options):
        print('DEBUG ReadValue start')
        value = self.get_response()
        print('DEBUG ReadValue stop')
        return value

    def WriteValue(self, value, options):
        print('DEBUG WriteValue start')
        bit_c = 0
        val =''
        for bit in value:
            bit_v = str(value[bit_c])
            val = val +str(value[bit_c])
            bit_c = bit_c +1
        print('DEBUG WriteValue received: '+str(val))
        # self.notifying = True
        # print('self.notifying: ' + str(self.notifying))
        # print('DEBUG before PropertiesChanged : '+str(val))
        # self.PropertiesChanged(GATT_CHRC_IFACE, {"Value": value}, [])
        # print('DEBUG after PropertiesChanged : ' + str(val))

        print('DEBUG WriteValue stop')

class MyDescriptor(Descriptor):
    TEMP_DESCRIPTOR_UUID = "2901"
    TEMP_DESCRIPTOR_VALUE = "CPU Temperature"

    def __init__(self, characteristic):
        Descriptor.__init__(
            self, self.TEMP_DESCRIPTOR_UUID,
            ["read"],
            characteristic)

    def ReadValue(self, options):
        value = []
        desc = self.TEMP_DESCRIPTOR_VALUE

        for c in desc:
            value.append(dbus.Byte(c.encode()))
        return value

app = Application()
app.add_service(MyService(0))
app.register()

adv = MyAdvertisement(0)
adv.register()

try:
    app.run()
except KeyboardInterrupt:
    app.quit()
0 Answers
Related