Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Gicisky/PICKSMART BLE ESL Uploader

English | Беларуская | Русский

A Python-based CLI tool for automated image uploading to Gicisky/PICKSMART Electronic Shelf Labels (ESL) via Bluetooth Low Energy (BLE).

Features

  • End-to-End Automation: Fully scriptable replacement for the browser-based Web Bluetooth uploader.
  • Optimized for 2.9" BWR: Pre-configured for 296×128 Red/White/Black ESL tags.
  • Advanced Image Pipeline:
    • Automatic alpha-channel flattening (composite onto white background).
    • Smart resizing & centering.
    • Mandatory 90° matrix rotation for the 0x0033 device profile.
  • Robust BLE Transport:
    • MTU negotiation (up to 247 bytes).
    • Explicit Write Requests for connection stability.
    • Built-in 50ms inter-block delay to prevent tag buffer overflows.
    • RAW HEX mode for low-level protocol debugging.

Requirements

  • Python: 3.12 or 3.13
  • OS: Linux (tested on Ubuntu/Pop!_OS) with BlueZ stack
  • Hardware: BLE-compatible adapter
  • Permissions: User access to the Bluetooth subsystem

Installation

  1. Clone the repository:
    git clone https://github.com/51n1au5k1/PICKSMART-BLE-ESL-Uploader.git
    cd PICKSMART-BLE-ESL-Uploader

Setup

Create a virtual environment and install dependencies:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

(Linux only) Grant Bluetooth permissions to avoid using sudo:

sudo usermod -aG bluetooth $USER
# Log out and back in, or reboot to apply

Usage

Basic Upload

Automatically scans for devices named NEMR...:

python main.py --image assets/your_label.png --verbose

Target Specific MAC Address

Skip auto-scan and connect directly:

python main.py --address FF:FF:92:99:04:78 --image assets/test.png

Diagnostic Mode (RAW HEX)

Send a pre-recorded 9472-byte payload for low-level debugging:

python main.py --address FF:FF:92:99:04:78 --raw-hex debug/dump.txt

Technical Details

Component Value / Description
GATT Service 0xFEF0
Control Characteristic (0xFEF1) 0x01 (Block Size), 0x02 (Screen Info), 0x03 (Start Transfer)
Data Characteristic (0xFEF2) Receives image blocks. Format: [Block Index (4B LE)] + [Data (240B)]
Total Payload Size 9472 bytes
Plane 1 (B/W) 4736 bytes (1 bpp, 0 = black, 1 = white)
Plane 2 (Red) 4736 bytes (1 bpp, 1 = red)

Troubleshooting

MTU stuck at 23 bytes

Some tags ignore MTU negotiation.

Fix: manually connect via bluetoothctl before running the script:

bluetoothctl connect FF:FF:92:99:04:78

TimeoutError / Upload fails

ESL tags process data slowly.

Fix: the script already includes a 50 ms inter-block delay. If issues persist, increase BLOCK_DELAY in app/transport/bleak_backend.py.

Permission denied on BLE

Ensure your user is in the bluetooth group and that you have fully logged out and back in after running usermod.

Project Structure

├── main.py                 # CLI entry point & argument parsing
├── app/
│   ├── image_codec.py      # Image processing & BWR bitstream generation
│   ├── protocol.py         # GATT command construction & payload formatting
│   └── transport/
│       └── bleak_backend.py # BLE communication logic (bleak-based)
└── requirements.txt

Contributing and License

Pull requests are welcome. Please follow the existing code style and ensure compatibility with Python 3.12+.

Licensed under the MIT License.

About

CLI tool for uploading images to Gicisky/PICKSMART BLE electronic shelf labels (ESL) from Linux.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages