mirror of
https://github.com/kawasaki/pyscrlink.git
synced 2025-09-05 17:20:20 +02:00
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.
This commit is contained in:
committed by
Shin'ichiro Kawasaki
parent
199b54f094
commit
ba8eba4800
@@ -22,6 +22,7 @@ from bluepy.btle import BTLEDisconnectError, BTLEManagementError
|
|||||||
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
import queue
|
||||||
|
|
||||||
logLevel = logging.INFO
|
logLevel = logging.INFO
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ class Session():
|
|||||||
self.websocket = websocket
|
self.websocket = websocket
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
self.lock = threading.RLock()
|
self.lock = threading.RLock()
|
||||||
self.notification = None
|
self.notification_queue = queue.Queue()
|
||||||
|
|
||||||
async def recv_request(self):
|
async def recv_request(self):
|
||||||
"""
|
"""
|
||||||
@@ -89,12 +90,17 @@ class Session():
|
|||||||
logger.debug("default end_request")
|
logger.debug("default end_request")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def notify(self, method, params):
|
def notify(self):
|
||||||
"""
|
"""
|
||||||
Notify BT/BLE device events to scratch.
|
Notify BT/BLE device events to scratch.
|
||||||
"""
|
"""
|
||||||
logger.debug("start to notify")
|
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 = { 'jsonrpc': "2.0", 'method': method }
|
||||||
jsonn['params'] = params
|
jsonn['params'] = params
|
||||||
notification = json.dumps(jsonn)
|
notification = json.dumps(jsonn)
|
||||||
@@ -337,7 +343,8 @@ class BLESession(Session):
|
|||||||
params = { 'rssi': d.rssi }
|
params = { 'rssi': d.rssi }
|
||||||
params['peripheralId'] = devices.index(d)
|
params['peripheralId'] = devices.index(d)
|
||||||
params['name'] = d.getValueText(0x9)
|
params['name'] = d.getValueText(0x9)
|
||||||
self.session.notify('didDiscoverPeripheral', params)
|
self.session.notification_queue.put(('didDiscoverPeripheral', params))
|
||||||
|
self.session.notify()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
elif self.session.status == self.session.CONNECTED:
|
elif self.session.status == self.session.CONNECTED:
|
||||||
logger.debug("in connected status:")
|
logger.debug("in connected status:")
|
||||||
@@ -381,11 +388,12 @@ class BLESession(Session):
|
|||||||
|
|
||||||
def handleNotification(self, handle, data):
|
def handleNotification(self, handle, data):
|
||||||
logger.debug(f"BLE notification: {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():
|
if not self.restart_notification_event.is_set():
|
||||||
return
|
return
|
||||||
params = self.handles[handle]
|
self.session.notify()
|
||||||
params['message'] = base64.standard_b64encode(data).decode('ascii')
|
|
||||||
self.session.notify('characteristicDidChange', params)
|
|
||||||
|
|
||||||
def __init__(self, websocket, loop):
|
def __init__(self, websocket, loop):
|
||||||
super().__init__(websocket, loop)
|
super().__init__(websocket, loop)
|
||||||
|
Reference in New Issue
Block a user