Files
btd700linux/btd700/worker.py
T
Justin dd0809e877
Tests / unit (de, 3.10) (push) Has been cancelled
Tests / unit (de, 3.14) (push) Has been cancelled
Tests / unit (en, 3.14) (push) Has been cancelled
Tests / unit (en, 3.10) (push) Has been cancelled
Add English localization and MIT-licensed public release documentation
2026-09-05 21:02:14 +02:00

69 lines
2.8 KiB
Python

"""One thread owns the USB handle; the GTK main loop never waits for USB."""
from .i18n import tr
import queue
import threading
from gi.repository import GLib
from .controller import Controller
from .transport import DeviceError, Hidraw, discover
class Worker(threading.Thread):
def __init__(self, callback, *, device_path=None, demo=False):
super().__init__(name='btd700-usb', daemon=True)
self.callback = callback
self.device_path = device_path
self.demo = demo
self.commands = queue.Queue()
self.stopping = threading.Event()
self.controller = None
self.transport = None
def submit(self, method, args, kwargs):
self.commands.put((method, args, kwargs))
def stop(self):
self.stopping.set()
self.commands.put(None)
def run(self):
try:
while not self.stopping.is_set():
try:
action = self.commands.get(timeout=2)
except queue.Empty:
action = None
if self.stopping.is_set():
break
error = ''
try:
if self.controller is None:
if self.demo:
from .demo import DemoTransport
self.transport = DemoTransport()
else:
devices = discover()
if self.device_path:
devices = [d for d in devices if d.path == self.device_path]
if not devices:
raise DeviceError(tr('Kein BTD 700 gefunden. Bitte den Dongle einstecken.'))
if len(devices) > 1:
raise DeviceError(tr('Mehrere BTD 700 gefunden. Mit --device /dev/hidrawN auswählen.'))
self.transport = Hidraw(devices[0])
self.controller = Controller(self.transport)
if action:
method, args, kwargs = action
try:
getattr(self.controller, method)(*args, **kwargs)
except (ValueError, DeviceError, TimeoutError) as exc:
error = str(exc)
status = self.controller.snapshot()
GLib.idle_add(self.callback, status, error, bool(action))
except Exception as exc:
if self.transport:
self.transport.close()
self.transport = self.controller = None
GLib.idle_add(self.callback, None, error or str(exc), bool(action))
finally:
if self.transport:
self.transport.close()