Files
soundtower-controller/controller/link.py
T
lda Verified 038e152bbc
Checks / tests (ubuntu-latest, 3.11) (push) Canceled after 0s
Checks / tests (ubuntu-latest, 3.14) (push) Canceled after 0s
Checks / tests (windows-latest, 3.11) (push) Canceled after 0s
Checks / tests (windows-latest, 3.14) (push) Canceled after 0s
Checks / package (push) Canceled after 0s
Add MX-T40 BLE desktop controller and protocol documentation
2026-10-25 04:43:47 +07:00

56 lines
2.1 KiB
Python

"""Experimental RFCOMM/serial adapter for the shared Samsung session."""
import queue
import time
from controller.session import Session
from controller.transport import open_stream
from controller.worker import ConnectionWorker
class Link(ConnectionWorker):
def __init__(self, port, events, channel=1, prepare=False):
super().__init__(port, events)
self.channel = channel
self.prepare = prepare
def work(self):
self.events.put(("log", f"Opening {self.port} (direct RFCOMM uses channel {self.channel})"))
def report(text):
self.events.put(("status", text))
self.events.put(("log", text))
with open_stream(self.port, self.channel, self.prepare, report) as stream:
session = Session(strict_checksums=True)
def send(packet):
if stream.write(packet) != len(packet):
raise OSError("Incomplete Bluetooth write")
self.events.put(("log", "TX " + packet.hex(" ")))
report("Bluetooth connected; waiting for speaker handshake…")
send(session.start())
deadline = time.monotonic() + 10
last_sent = time.monotonic()
while not self.stopped.is_set():
chunk = stream.read(1024)
if chunk:
self.events.put(("log", "RX " + chunk.hex(" ")))
update = session.receive(chunk)
self.publish(update)
for packet in update.outgoing:
send(packet)
last_sent = time.monotonic()
if not session.ready and time.monotonic() > deadline:
raise TimeoutError(
"No completed speaker handshake. Close the phone app and check the TX/RX log."
)
if session.ready and time.monotonic() - last_sent >= 0.1:
try:
payload = self.commands.get_nowait()
except queue.Empty:
continue
send(session.command(payload))
last_sent = time.monotonic()