# Sound Tower Controller A small, unofficial desktop remote for Samsung Sound Tower speakers. Control EQ, bass, lighting, RGB color, volume, mute, playback, and source selection through Bluetooth Low Energy. Verified interactively on one **Samsung MX-T40 with Windows**. Other models and operating systems have not been verified. No firmware flashing, Samsung account, or bundled vendor software is required. ## Run with uv Use Windows Python for a Windows Bluetooth adapter. From WSL, invoke `uv.exe` so Bluetooth runs on Windows rather than inside WSL. ```powershell uv run soundtower --address YOUR_SPEAKER_MAC ``` For WSL: ```bash uv.exe run soundtower --address YOUR_SPEAKER_MAC ``` Replace `YOUR_SPEAKER_MAC` with the Bluetooth address of your speaker. Keep it powered on, close the phone app, and click **Connect**. The address can also be entered in the window. `uv run python -m controller` remains supported, as does the earlier `--with-requirements requirements.txt` launch command. Python 3.11 or newer is required; physical device testing used Windows Python 3.14. The interpreter needs Tcl/Tk. If the interpreter provided by uv lacks Tk, use a Windows Python installation with Tk support, for example: ```powershell uv run --python C:\Path\To\Python\python.exe soundtower --address YOUR_SPEAKER_MAC ``` ## Controls - EQ: Party, Standard, Hip-hop, EDM, Rock, Latin, House, Reggae. - Bass boost, volume up/down, mute, play/pause, and audio source. - Lighting: Off, Ambient, Party, Dance, Thunder, Star, Lover, Color. - RGB color picker; lighting mode is queried after a color change. - Readable activity log with optional raw packet display. A command acknowledgment means the packet was received. A later status report confirms the reported setting; the log distinguishes the two. Choosing an RGB color switches the tested speaker to COLOR mode. A play/pause event does not reveal the absolute playback state. The source menu includes protocol options that may not exist on every model. The tested MX-T40 reports Bluetooth, USB 1, AUX 1, and AUX 2. ## Audio versus control This app opens the BLE remote-control connection. Windows establishes the separate audio playback connection. Neither a BLE connection nor Windows' word “Connected” guarantees an audio output is available. If the speaker disappears from Windows' output list, disconnect/reconnect it through Windows and select it as the sound output. Both connection orders have worked in testing; no fixed startup order is established. Once playback works, the BLE controller can operate alongside it. The older RFCOMM/COM path is experimental and was unreliable on this MX-T40: `--transport rfcomm` selects it. BLE is the default. ## Development ```bash uv run --group dev python -m unittest discover -s tests -v uv run --group dev ruff check controller tests scripts uv run --group dev ruff format --check controller tests scripts uv build ``` The first online `uv run` resolves dependencies and creates `uv.lock`; commit that lockfile after resolving it for the project. A lockfile is not yet bundled because dependency resolution was unavailable in the offline development shell. The tests use captured packet fixtures and fake transports; they do not need a speaker, Tk, or a display. They do not replace physical compatibility tests. The optional GitHub Actions workflow runs headless tests on Windows/Linux and Python 3.11/3.14. The same commands can be used in Gitea CI. See [architecture](docs/ARCHITECTURE.md), [protocol](docs/PROTOCOL.md), [feature research](docs/FEATURES.md), and [contributing](CONTRIBUTING.md). ## Diagnostics List the MX-T40's advertised BLE/GATT endpoints without sending controls: ```powershell uv run python -m controller.ble_probe ``` Experimental Windows RFCOMM discovery: ```powershell uv run --extra diagnostics python -m controller.probe --channel 1 ``` ## Preparing a repository This development folder also contains private research inputs. Export only the controller, tests, and original documentation into a **new, empty directory**: ```bash python scripts/export_project.py dist/soundtower-controller ``` The export uses an explicit allowlist. Firmware, APKs, extracted vendor files, decompiled Java, environment files, and caches are excluded. Initialize Git in that exported directory before adding a GitHub or Gitea remote. No remote is configured and nothing is uploaded automatically. ## Project status This is an independent interoperability project, not an official Samsung or Qualcomm product. It contains original controller code and protocol notes, not redistributed firmware or application code. A project license has not yet been selected; no open-source license grant is currently declared.