Skip to main content

Python driver for the SOOMFON Stream Controller SE and compatible Mirabox / Ajazz AKP03 devices

Project description

soomfon

Python driver for the SOOMFON Stream Controller SE and compatible devices (Mirabox N3/N4, Ajazz AKP03 and variants).

Compatible devices

Device VID:PID
SOOMFON Stream Controller SE 1500:3001
Mirabox Stream Controller N3 rev.2, N4 1500:3001
Ajazz AKP03E/R rev.2 1500:3001
Mars Gaming MSD-TWO, TreasLin N3, Redragon SS-551 1500:3001

All share the same firmware (V25.CN002.01.005) and mirajazz v3 protocol.

Hardware layout

  • Keys 0–5 — LCD macro buttons with 60×60 pixel displays
  • Keys 6–8 — plain buttons (no display)
  • Keys 9–11 — encoder press events (knob 0 / 1 / 2)
  • Encoders 0–2 — rotary knobs, fire on_encoder(enc, delta) on twist

Installation

pip install soomfon

Device permissions (Linux)

Without a udev rule the device is only accessible as root. Run once after install:

soomfon udev | sudo tee /etc/udev/rules.d/99-soomfon.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

Then re-plug the device. The rule file is also included at udev/99-soomfon.rules in the source tree.

Quickstart

from soomfon import Soomfon
from PIL import Image

with Soomfon() as deck:
    deck.set_brightness(70)
    deck.set_key_image(0, Image.open("icon.png"))
    deck.set_key_color(1, 255, 80, 0)          # solid orange

    @deck.on_key
    def on_key(key: int, pressed: bool):
        print(f"key {key} {'↓' if pressed else '↑'}")

    @deck.on_encoder
    def on_encoder(enc: int, delta: int):
        print(f"encoder {enc}  {'→' if delta > 0 else '←'}")

    deck.run_forever()                          # blocks; Ctrl-C exits cleanly

API

Soomfon()

Opens the first connected device and runs the initialization sequence. Raises RuntimeError if no device is found.

Use as a context manager (with Soomfon() as deck) for automatic cleanup, or call deck.close() manually.

Display

Method Description
set_brightness(pct) Screen brightness, 0–100
set_key_image(key, image) Upload a PIL Image to an LCD key (0–5). Images are resized to 60×60 and JPEG-encoded automatically.
set_key_color(key, r, g, b) Fill an LCD key with a solid colour
clear_key(key) Clear one key
clear_all() Clear all keys at once
sleep() Put the device into standby

Events

Register callbacks before calling start() or run_forever().

@deck.on_key
def handler(key: int, pressed: bool): ...
@deck.on_encoder
def handler(enc: int, delta: int): ...   # delta is always ±1

Both decorators return the callback unchanged, so they compose with other decorators.

Lifecycle

Method Description
start() Start background reader + dispatcher threads (non-blocking)
run_forever() start() then block until KeyboardInterrupt
stop() Stop threads
close() Stop threads and close the HID device

CLI

soomfon info              show device info and firmware version
soomfon brightness PCT    set brightness (0–100)
soomfon udev              print udev rules to stdout
soomfon --version

Development

git clone ...
cd soomfon
uv sync
uv run python examples/demo.py

The two-thread architecture keeps the HID reader loop unblocked by user callbacks: a dedicated reader thread enqueues raw reports as fast as the OS delivers them; a dispatcher thread drains the queue and calls on_key / on_encoder. Slow callbacks (e.g. image uploads triggered by key presses) never cause encoder events to be dropped.

Protocol notes

The device uses the mirajazz v3 protocol (reference):

  • All OUT reports are 1025 bytes (0x00 report-ID + 1024 data)
  • Commands begin with the CRT magic: 00 43 52 54 00 00
  • Images are sent as: BAT header → JPEG chunks → STP commit
  • IN reports are 512 bytes, prefixed with ACK (41 43 4B); byte 9 is the event code, byte 10 is the state

Image rotation

The driver rotates images 270° before encoding. This was determined empirically on a SOOMFON Stream Controller SE — other hardware revisions or firmware versions may display images differently. If your keys appear rotated, change _IMG_ROT in src/soomfon/_device.py to 0, 90, or 180.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

soomfon-0.1.1.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

soomfon-0.1.1-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file soomfon-0.1.1.tar.gz.

File metadata

  • Download URL: soomfon-0.1.1.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for soomfon-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4f8ad37473ae91eda1400323ba90f93aa26abc7d24a76f19cf3198d9309ae6c6
MD5 1e459bfcc47b1ea68c5ae321f65e5cf5
BLAKE2b-256 9a9282c71611f89c848922e7dd6aeee821943738f84b7641d348121eab706e20

See more details on using hashes here.

File details

Details for the file soomfon-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: soomfon-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for soomfon-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b223a831af7c037af7940e2e57096d3f94fac17f22be490c936d72ed05716ae6
MD5 60187f85936739e4cbcd53b19101d9cf
BLAKE2b-256 007436a82239808059ef08c60b2334cf77baa498954ae411d268cbe40068e5be

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page