Skip to content

superdeee/pyajazz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pyajazz (Ajazz AKP HID Controller)

Python module for interfacing with Ajazz AKP devices (such as the AKP153E Desk Controller), enabling programmatic control over button images, callbacks, and device states.

Table of Contents

Installation

pip install pyajazz
# or
git clone https://github.com/superdeee/pyajazz
cd pyajazz
pip install .

⚠️ Note: This package relies on hidapi. You may need to install OS-specific dependencies before installing cython-hidapi. Refer to the cython-hidapi README for details.

Overview

This module provides an easy-to-use Python interface for controlling Ajazz AKP Devices. pyajazz module is primarily designed for the AKP153E Desk Controller. However, other models such as the AKP05, AKP03, and similar rebranded devices may also work (untested). The module handles all necessary requests, allowing full use of the device without relying on the Chinese OEM software.

Read the usage section carefully to avoid bricking your device!

Features

  • 🧠 Thread-safe read/write handling
  • 🧾 Queue-based events handling
  • 🔧 Easy event callbacks configuration
  • 🧯 Error handling
  • 🧰 Context-managed connection lifecycle

Supported Device Capabilities

  • Device state:
    • Initialize / Shut down
    • Sleep / Wake up
  • Set screen brightness
  • Set/Clear individual icon slots
  • Clear the whole screen
  • Set shutdown logo
  • Button press/release callbacks

Usage

Sample Code

from pyajazz import Device

jpeg_img_data = ... # load JPEG data from file or create image programmatically

with Device() as device:
    device.on_press(position=1, callback=lambda: print("Hello world!"))
    device.set_button_image(position=1, data=jpeg_img_data)

    while True:
        device.handle_pending_inputs()

Setting and Clearing Button Images

When setting button images, JPEG-encoded data must be provided via the data parameter. Images should have dimensions that are multiples of 16 (e.g., 16×N x 16×M) and contain minimal metadata. Ensure metadata is stripped to prevent issues, including possible device bricking. Attempting to set a logo image with extensive metadata (e.g., EXIF) may cause the device to become unresponsive. Always sanitize image files before sending. Images wider/longer than 96 pixels will overflow to adjacent buttons areas.

Note: The AKP153 display controller expects the screen to be rotated 90° clockwise relative to its physical orientation. Therefore, images must be rotated 90° counter-clockwise before sending to the device.

Each screen/button area is referred to as a position, numbered 1–18. The layout for AKP153 device is as follows:

+------+------+------+------+------+----+
|  13  |  10  |  7   |  4   |  1   | 16 |
+------+------+------+------+------+----+
|  14  |  11  |  8   |  5   |  2   | 17 |
+------+------+------+------+------+----+
|  15  |  12  |  9   |  6   |  3   | 18 |
+------+------+------+------+------+----+

Tip: Reading and encoding the images with opencv is a nice way of removing unnecessary metadata

image_data = cv2.imencode('.jpg', image, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

Setting Image

set_button_image(position, data)

  • position (int): ID of the screen area (1–18)
  • data (bytes | bytearray | list[int]): JPEG-encoded image (max ~10kB, no metadata)

Clearing Image

clear_button_image(position)

  • position (int): ID of the screen area (1-18)

Clear All Images

clear_all()

Configuring Button Actions (Callbacks)

The Ajazz AKP153 supports two types of button events - press and release - which can be configured independently. The device does not support key combinations.

Setting Button Press Callback

on_press(position, callback)

  • position (int): ID of the button (1-15)
  • callback (Callable): callable to run on press event

Setting Button Release Callback

on_release(position, callback)

  • position (int): ID of the button (1-15)
  • callback (Callable): callable to run on release event

Remove Callbacks

clear_callbacks(position)

  • position (Optional[int] = None): ID of the button (1-15) or None (clears all button callbacks)

Sleep Mode

The device supports sleep mode in which it handles any USB input requests (button images can be set while asleep). The first user interaction after entering the sleep mode wakes it up, but is not populated to the controlling software.

Entering Sleep Mode

sleep()

Waking Up (through software)

wakeup()

Brightness Control

set_brightness(brightness)

  • brightness (int): brightness level (0-100)

Setting Logo Image

While not connected to any software Ajazz devices display a logo which can be changed with the command below. Note that the display's physical resolution is 854x480, but due to the device's rotation, logo images must be 480x854 (portrait orientation). Make sure any redundant image metadata, such as EXIF, is removed prior to sending!

set_logo_image(data)

  • data (bytes | bytearray | list[int]): JPEG encoded image data with no metadata (512kB maximum)

Logo image can be sanitized with OpenCV using a following snippet:

def prep_logo(path):
    logo_img = cv2.imread(path)
    if logo_img is None:
        raise FileNotFoundError(f"Can't open: {path}")

    if logo_img.shape[0] < logo_img.shape[1]:
        logo_img = cv2.rotate(logo_img, cv2.ROTATE_90_COUNTERCLOCKWISE)
    
    if logo_img.shape != (854, 480, 3):
        print("Logo image resolution must be 854x480, resizing...")
        logo_img = cv2.resize(logo_img, (480, 854))

    success, encoded_image = cv2.imencode('.jpg', logo_img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

    if not success:
        raise ValueError("Can't encode as JPEG.")
    
    return encoded_image

About

A Python interface for a USB Ajazz stream controllers

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages