From ba8eba48008b7de8bb96a6e515f15a305fb55978 Mon Sep 17 00:00:00 2001 From: MDE <59321583+mdevel1@users.noreply.github.com> Date: Sat, 8 Feb 2020 22:16:53 +0100 Subject: [PATCH] BLESession: Introduce notification queue During bluepy-scratch-link handles requests from Scratch, it throws away notifications from BLE devices. This loses those notifications. Not to lose the notifications, introduce a queue to keep notifications from BLE devices. Once request handling completes, flush the notifications kept in the queue. --- scratch_link.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/scratch_link.py b/scratch_link.py index 0e4efee..189f844 100755 --- a/scratch_link.py +++ b/scratch_link.py @@ -22,6 +22,7 @@ from bluepy.btle import BTLEDisconnectError, BTLEManagementError import threading import time +import queue logLevel = logging.INFO @@ -52,7 +53,7 @@ class Session(): self.websocket = websocket self.loop = loop self.lock = threading.RLock() - self.notification = None + self.notification_queue = queue.Queue() async def recv_request(self): """ @@ -89,12 +90,17 @@ class Session(): logger.debug("default end_request") return False - def notify(self, method, params): + def notify(self): """ Notify BT/BLE device events to scratch. """ logger.debug("start to notify") + # flush notification queue + while not self.notification_queue.empty(): + method, params = self.notification_queue.get() + self._send_notification(method, params) + def _send_notification(self, method, params): jsonn = { 'jsonrpc': "2.0", 'method': method } jsonn['params'] = params notification = json.dumps(jsonn) @@ -337,7 +343,8 @@ class BLESession(Session): params = { 'rssi': d.rssi } params['peripheralId'] = devices.index(d) params['name'] = d.getValueText(0x9) - self.session.notify('didDiscoverPeripheral', params) + self.session.notification_queue.put(('didDiscoverPeripheral', params)) + self.session.notify() time.sleep(1) elif self.session.status == self.session.CONNECTED: logger.debug("in connected status:") @@ -381,11 +388,12 @@ class BLESession(Session): def handleNotification(self, handle, data): logger.debug(f"BLE notification: {handle} {data}") + params = self.handles[handle].copy() + params['message'] = base64.standard_b64encode(data).decode('ascii') + self.session.notification_queue.put(('characteristicDidChange', params)) if not self.restart_notification_event.is_set(): return - params = self.handles[handle] - params['message'] = base64.standard_b64encode(data).decode('ascii') - self.session.notify('characteristicDidChange', params) + self.session.notify() def __init__(self, websocket, loop): super().__init__(websocket, loop)