Repository navigation
Releases: deonspengler/akp02
Release list
v2.0.0
akp02 v2.0.0 Release Notes
Breaking Changes
- Orientation API replaced:
set_boot_orientation("horizontal"|"vertical")→orientation(Orientation.LANDSCAPE|PORTRAIT). Also renamed:SCREEN_WIDTH/SCREEN_HEIGHT→PANEL_LONG_SIDE/PANEL_SHORT_SIDE,PORTRAIT_X_ALIGN_*→SHORT_AXIS_ALIGN_*. keepalive=renamed tokeepalive_interval=(keyword-only; positional calls unaffected).AKP02.DeviceNotFoundErrormoved to module level → import asakp02.DeviceNotFoundError(now in__all__).
New Features
- Portrait orientation and inverted (upside-down) mounting support, with automatic rotation of both full frames and regions.
- Brightness is now tracked;
set_brightness(None)reads back the last requested value and is re-applied automatically afterscreen_on(device resets brightness on its own). - JPEG chroma subsampling is now configurable (
jpeg_subsampling); default changed to 4:4:4 for sharper small colored text, with default quality lowered from 85 → 80 to offset the size increase. AKP02now uses__slots__, so typos in attribute names (e.g.panel.invert) raiseAttributeErrorinstead of failing silently.- Automatic settling delays between region updates to prevent dropped/misplaced writes on rapid consecutive draws.
Bug Fixes
- Fixed color/position misalignment on regions — corrected target alignment residue (was landing 2px off).
- Oversized HID reports now raise a clear, descriptive error instead of an obscure
negative countfailure. - Fixed clock example crashing on systems without Liberation Mono (falls back to Pillow's default font).
- Fixed clock example skipping seconds after a slow
show()push.
Internal / Docs
- Various refactors (JPEG encoding extraction, shared region-rect logic, consolidated settle-delay constant), formatting cleanup, and documentation improvements (examples, coverage stats, README corrections).
1.1.0
Added
-
AKP02(keepalive=...)— entering the context manager now starts the
keepalive thread automatically (every 5s by default), so the panel no
longer goes blank for callers who forgotstart_keepalive(). Pass
keepalive=Noneto restore the previous behavior, or a float for a
different interval. -
akp02.__version__. The module is now the single source of truth for
the version;pyproject.tomldeclares it dynamic and hatchling reads
it from there at build time.
Changed
- A non-positive keepalive interval is now rejected with
ValueError,
by bothAKP02(keepalive=...)andstart_keepalive(interval_sec=...).
Previously such a value silently turned the keepalive loop into a
tight loop writing to the device as fast as USB allows, since
Event.wait()returns immediately for a timeout of 0 or less.
Unchanged
start_keepalive(),stop_keepalive()andheartbeat()remain
public, and behave as before for every valid argument (see Changed
above for the new interval check). Existing code that calls
start_keepalive()explicitly is unaffected — the call is a no-op
when the thread is already running.- No thread is started by
__init__; construction still has no
background side effects. Panels built without awithstatement get
no automatic keepalive.
Notes for downstream
- Code passing its own
dev=object inside awithblock will now see
CONNECTheartbeats it did not see before. If that matters (a test
double asserting on exact traffic, or one that isn't thread-safe),
passkeepalive=None. - To let the panel sleep while still holding the handle open, call
stop_keepalive()inside the block.
v1.0.0
First release.
Linux library for the Ajazz AKP02 9.2" USB secondary display,
reverse-engineered from the Windows-only official software.
Install: pip install akp02, or python-akp02 from the AUR on Arch.
Working and confirmed on real hardware: full-screen frames, partial
region updates with correct colour, brightness, screen on/off, clear,
firmware version query, boot/display orientation, and sustained
keepalive operation.
The protocol notes
document the HID protocol in full, including two behaviours that aren't
obvious and cost real time to find: region updates render with the wrong
colour unless the position satisfies portrait_x % 8 == 2, and a region
update immediately after a full-frame draw silently drops the full frame
without a short settling delay. The library handles both automatically.