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()