Skip to main content

gicisky-296-bwry

Tag running the Tux example

A small Python library and BLE driver for the Gicisky/PICKSMART 2.9" 296x128 BWRY (black/white/red/yellow) e-paper display (device type 0x002E).

Install

pip install -e .

Usage

import asyncio
from PIL import Image
from gicisky_296_bwry import GiciskyTag


async def main():
    image = Image.open("status.png")  # must be 296x128 RGB

    async with GiciskyTag("AA:BB:CC:DD:EE:FF") as tag:
        await tag.display(image)


asyncio.run(main())

See examples/display_test_image.py for a runnable four-colour test pattern, examples/display_tux.py for a Tux (examples/assets/tux.png) sample that tiles the mascot three times across the panel, or examples/display_photo.py to fit/quantize any arbitrary photo onto the panel.

Error handling

Failures raise GiciskyError subclasses (GiciskyConnectionError, GiciskyProtocolError, GiciskyTransferError); a failed or cancelled upload() disconnects, so call connect() again before retrying.

Timeouts and retry limits are configurable via GiciskyTag keyword arguments, e.g. GiciskyTag(address, transfer_timeout=60, max_retries=5).

Finding your tag's BLE address

Each tag advertises over BLE and has its address printed on a label next to a barcode near the connector edge (the last four octets, e.g. 92.83.37.21, are printed there):

Address label on the tag

To find the full address (XX:XX:92:83:37:21) for use with this library, scan for nearby BLE devices:

bluetoothctl scan on

Look for a device named like NEMR92833721 (the digits match the ones printed on the label). Press Ctrl+C or run bluetoothctl scan off once you've found it, then use the full XX:XX:XX:XX:XX:XX address with GiciskyTag(...).

Layout

src/gicisky_296_bwry/
├── __init__.py   # public API: GiciskyTag, encode, WIDTH, HEIGHT
├── device.py     # BLE connection + vendor GATT protocol
├── encoder.py    # Pillow image -> 296x128 BWRY framebuffer bytes
└── exceptions.py # GiciskyError and subclasses

Protocol notes

The tag exposes two GATT characteristics:

  • fef1: command characteristic (write + notify)
  • fef2: image data characteristic (write + notify)

Upload flow:

0x01            -> request block size
0x02 + size      -> announce upcoming image write
0x03            -> request start of transfer
0x05 + block#... -> send framebuffer in blocks until tag replies 0x08 (done)

The framebuffer is a 2-bit-per-pixel packed image (4 pixels/byte) with codes 00=black, 01=white, 10=yellow, 11=red, rotated 90 degrees relative to the logical 296x128 image (matches the hass-gicisky device profile for this device type).

Acknowledgements

The BLE protocol and colour/rotation profile for this device type were reverse-engineered with reference to eigger/hass-gicisky, a Home Assistant integration for Gicisky BLE e-paper labels.

Development

pip install -e ".[dev]"
pytest
ruff check .
ruff format .

License

MIT

Metadata

Release files for gicisky-296-bwry 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gicisky-296-bwry 0.1.0
File Size Uploaded
gicisky_296_bwry-0.1.0.tar.gz 286.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gicisky-296-bwry 0.1.0
File Interpreter ABI Platform
gicisky_296_bwry-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 296.5 kB

Release files / gicisky_296_bwry-0.1.0.tar.gz

Download URL gicisky_296_bwry-0.1.0.tar.gz
Size 286.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1acca35556ef6071c5333c361a9db7e2cb5ff8f4a80339e551f28d9a257d414e
BLAKE2b-256 checksum
How to use checksums
9869551458e714562981786a1aaa0168409fed92b99d6995871bd9e37e41eedc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release files / gicisky_296_bwry-0.1.0-py3-none-any.whl

Download URL gicisky_296_bwry-0.1.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0f15a298a082e9436317b664c018a7195104c2c984019903f387206f84a42dbc
BLAKE2b-256 checksum
How to use checksums
b3aff9bdc8c5945611e8f91f9d19cc8898ff71dabcf842293bd30233632e99ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page