I have a PyQt/PySide application where I use threads to process commands from a queue. In one thread, I need to use Bleak to work with BLE devices. Bleak is based on asyncio, and I am having trouble integrating these asynchronous functions into a synchronous thread. Here is a sample of my code:
import os
from pathlib import Path
import sys
from PySide6.QtCore import QObject, Slot, Signal
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtWidgets import QApplication
from workerCore import CoreWorker
from queue import Queue
from threading import Thread
import queueCmds as qc
class AppWindow(QObject):
sigPairingPopUp = Signal()
def __init__(self):
super().__init__(None)
self.queueCore = Queue()
self.workerCore = CoreWorker(self)
x = Thread(target=self.workerCore.run)
x.start()
@Slot()
def scanBLE(self):
sd = qc.QueueData()
sd.cmd = qc.CoreQC.SCAN_BLE
self.queueCore.put(sd)
if __name__ == "__main__":
main = QApplication(sys.argv)
engine = QQmlApplicationEngine()
appWin = AppWindow()
engine.rootContext().setContextProperty("backend", appWin)
engine.load(os.fspath(Path(__file__).resolve().parent / "qml/main.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(main.exec())
workerCore.py
import queueCmds as qc
from threading import Thread
import asyncio
from bleak import BleakScanner, BleakClient
CHARACTERISTIC_UUID = "...."
class CoreWorker(Thread):
def __init__(self, app, parent=None):
super(CoreWorker, self).__init__(parent)
self.app = app
def run(self):
while True:
rxd = self.app.queueCore.get()
if rxd.cmd == qc.CoreQC.SCAN_BLE:
asyncio.run(self.scan_devices())
async def scan_devices(self):
devices = await BleakScanner.discover()
for i, device in enumerate(devices):
print(f"{i}: {device.name} ({device.address})")
return devices
async def connect_and_read(self, device_address):
async with BleakClient(device_address) as client:
print(f"Connected to {device_address}")
value = await client.read_gatt_char(CHARACTERISTIC_UUID)
print(f"Read value: {value}")
Problem:
How can I correctly integrate asynchronous Bleak functions into a synchronous thread?
At a minimum, it seems strange to combine asyncio with threading. Either way, my call to scan_devices is not working. What is the best way to solve this?
Thank you!