hass-gicisky

Gicisky BLE Label Home Assistant Integration
🚚 This project has moved — repository archived
Development continues in eigger/hass-ble-esl — one integration for BLE e-paper shelf labels covering Gicisky (PickSmart) as well as Zhsunyco (WOLINK / easyTag) and other brands. Everything here (all models, services, examples) is supported there, and the payload format is unchanged.
This repository is archived and will not receive further updates. Existing gicisky installs keep working for now, but new features and fixes land only in hass-ble-esl.
To migrate: the integration domain changes (gicisky → ble_esl), so devices must be re-added and actions renamed (gicisky.write → ble_esl.write). See the migration guide and release 5.5.1.
Gallery
| Size |
Example |
| 2.1" (250×128) |
 |
| 2.9" (296×128) |
 |
| 10.2" (960×640) |
 |
What is an electronic label?
An electronic label (electronic shelf label, ESL) is a small e-paper display that keeps showing content without continuous power. This integration targets labels manufactured by Gicisky.
They work well for information that should stay visible, changes infrequently, and lives where mains power is impractical — not only retail price tags.
Feedback & Support
- Stash — self-hosted home inventory manager. Track and restock items with barcode scanning, and print labels to Gicisky devices via Home Assistant.
Supported Models
| Type |
Size |
Resolution |
Colors |
| TFT |
2.1" |
250 × 132 |
BW |
| EPD |
2.1" |
250 × 128 |
BWR |
| EPD |
2.9" |
296 × 128 |
BW |
| EPD |
2.9" |
296 × 128 |
BWR |
| EPD |
2.9" |
296 × 128 |
BWRY |
| EPD |
3.7" |
240 × 416 |
BWR |
| EPD |
4.2" |
400 × 300 |
BWR |
| EPD |
7.5" |
800 × 480 |
BWR |
| EPD |
10.2" |
960 × 640 |
BWR |
Where to Buy
Availability varies by country. Official Gicisky listings on AliExpress:
Installation
- Install with HACS (custom repository required), or copy this repo into
custom_components/gicisky.
- Restart Home Assistant.
- Add the integration via Settings → Integrations → Gicisky and select your device.
Important Notice
Use a Bluetooth proxy instead of a built-in adapter when possible — especially with multiple BLE devices nearby.
Keep the proxy scan interval at its default. bluetooth_proxy must have active: true.
esp32_ble_tracker:
scan_parameters:
active: true
bluetooth_proxy:
active: true
Options
Configure via Settings → Devices & Services → Gicisky → Configure:
| Option |
Default |
Range |
Description |
| Retry Count |
3 |
1–10 |
Retries when a BLE write fails |
| Write Delay (ms) |
0 |
0–1000 |
Pause between BLE write packets |
| Prevent Duplicate Send |
false |
on/off |
Skip sending when image data is unchanged |
| Debounce Delay (ms) |
0 |
0–120000 |
Wait before writing; new requests cancel pending ones (0 = immediate) |
Unstable writes: try Write Delay 50–100 ms. Frequent automations: enable Prevent Duplicate Send and/or Debounce Delay to save battery and reduce BLE traffic.
Payload & rendering (imagespec)
From version 5.0.0, labels are rendered with imagespec — a declarative YAML/JSON list of drawing elements packed and sent to the e-paper panel.
Documentation (maintained in imagespec, not duplicated here):
Gicisky-specific behaviour:
- Resolution:
width and height come from the device profile, not the service call.
- Palette: auto-selected per tag — BW, BWR (
black/white/red), or BWRY (+ yellow). Off-palette colors are quantized to the nearest supported color.
- Rotation:
rotate: 90/180/270 uses canvas mode — the fixed panel rotates; output size stays the device resolution.
- Default font:
NotoSansKR-Regular.ttf in custom_components/gicisky/fonts/. Custom fonts also work from www/fonts/.
plot element: reads history from Home Assistant Recorder.
dlimg: local file paths under /config/... are allowed (HTTP/HTTPS and data URIs too).
- Dithering: not a service option. Put
dither on photos and charts in the payload — dlimg, pie, diagram, plot, sparkline, progress_bar, gauge — when they use off-palette colors. Leave text without dither. See dithering.md.
- Layout: prefer
row / column / stack over hand-placed coordinates.
- Image entities: each tag exposes Last Updated Content (last image sent) and Preview Content (
dry_run renders).
- Battery: the advertised voltage (0.1 V steps) is mapped linearly over 2.5–2.9 V to Battery (%), and a Battery binary sensor (low battery) turns on at 2.5 V or below — below that, e-paper refresh becomes unreliable even though BLE still works.
Services
gicisky.write
Renders the payload and sends it to the tag (unless dry_run: true).
| Parameter |
Required |
Default |
Description |
payload |
yes |
— |
List of imagespec elements |
rotate |
no |
0 |
0, 90, 180, or 270 |
background |
no |
white |
white, black, red, or yellow |
dry_run |
no |
false |
Render only; updates Preview Content image entity without BLE send |
Basic example:
action: gicisky.write
target:
device_id: <your device>
data:
payload:
- type: text
value: Hello World!
x: 10
y: 10
size: 40
Per-element dither (photos / charts)
Do not dither the whole panel. Add dither on chart/media elements that use
off-palette colors (dlimg, pie, diagram, plot, sparkline,
progress_bar, gauge):
action: gicisky.write
target:
device_id: <your device>
data:
payload:
- type: text
value: Living room
x: 10
y: 8
size: 28
- type: dlimg
url: "/config/www/photo.jpg"
x: 10
y: 40
xsize: 120
ysize: 90
dither: floyd
- type: pie
x: 150
y: 40
radius: 40
values: "A,40,orange;B,60,blue"
dither: atkinson
- type: diagram
x: 250
y: 40
width: 130
height: 90
bars:
values: "Mon,10;Tue,25;Wed,15;Thu,30"
color: orange
dither: bayer8
Rotation and background:
action: gicisky.write
target:
device_id: <your device>
data:
rotate: 90
background: black
payload:
- type: text
value: Rotated!
x: 10
y: 10
size: 30
color: white
Preview without sending (dry_run updates the tag’s Preview Content image entity):
action: gicisky.write
target:
device_id: <your device>
data:
dry_run: true
payload:
- type: text
value: Preview Test
x: 10
y: 10
size: 30
Use the Gicisky Payload Editor to design layouts in the browser and paste the generated YAML.
Combined dashboard-style example:
action: gicisky.write
target:
device_id: <your device>
data:
background: white
payload:
- type: text
value: "Home Status"
x: 10
y: 5
size: 24
font: "fonts/NotoSansKR-Bold.ttf"
- type: line
x_start: 0
x_end: 250
y_start: 35
y_end: 35
fill: black
width: 1
- type: icon
value: thermometer
x: 10
y: 45
size: 24
- type: text
value: "{{ states('sensor.temperature') }}°C"
x: 40
y: 48
size: 20
- type: progress_bar
x_start: 10
y_start: 80
x_end: 240
y_end: 95
progress: "{{ states('sensor.humidity') | int }}"
fill: black
show_percentage: true
- type: qrcode
data: "https://www.home-assistant.io"
x: 180
y: 40
width: 60
height: 60
gicisky.write_guarded
Same rendering as gicisky.write, with guards before BLE transmission:
- duplicate image skip (when Prevent Duplicate Send is enabled)
- write lock check
- debounce scheduling (Debounce Delay option, overridable per call)
| Parameter |
Required |
Default |
Description |
payload |
yes |
— |
Same as gicisky.write |
rotate, background, dry_run |
no |
— |
Same as gicisky.write |
debounce_override_ms |
no |
option value |
Override debounce for this call (0 = write immediately) |
action: gicisky.write_guarded
target:
device_id: <your device>
data:
payload:
- type: text
value: Guarded Write
x: 10
y: 10
size: 36
Immediate write (skip debounce once):
action: gicisky.write_guarded
target:
device_id: <your device>
data:
debounce_override_ms: 0
payload:
- type: text
value: Immediate
x: 10
y: 10
size: 36
| Service |
When to use |
gicisky.write |
Always send (except explicit dry_run) |
gicisky.write_guarded |
Automations that fire often; skip duplicates and coalesce rapid updates |
Fonts
The default font is fonts/NotoSansKR-Regular.ttf. The integration checks custom_components/gicisky/fonts/ first, then config/www/fonts/.
Built-in fonts
| Family |
Files |
| CookieRun |
CookieRunRegular.ttf, CookieRunBold.ttf, CookieRunBlack.ttf |
| Gmarket Sans |
GmarketSansTTFLight.ttf, GmarketSansTTFMedium.ttf, GmarketSansTTFBold.ttf |
| Noto Sans KR |
Thin through Black weights (NotoSansKR-*.ttf) |
| OwnglyphParkDaHyun |
OwnglyphParkDaHyun.ttf |
Custom font example:
- type: text
value: "Custom Font"
x: 10
y: 10
size: 30
font: "MyCustomFont.ttf"
Place MyCustomFont.ttf in config/www/fonts/.
Examples
Appendix
T-Map integration
# https://openapi.sk.com/products/detail?linkMenuSeq=46
rest_command:
request_tmap_routes:
url: https://apis.openapi.sk.com/tmap/routes?version=1
method: POST
headers:
appKey: !secret tmap_api_key
accept: "application/json, text/html"
content_type: "application/json; charset=utf-8"
payload: >-
{
"startX": {{ startX }},
"startY": {{ startY }},
"endX": {{ endX }},
"endY": {{ endY }},
"searchOption": {{ searchOption }},
"totalValue": 2,
"trafficInfo ": "Y",
"mainRoadInfo": "Y"
}
See 2.1-tmap-time.yaml for a full label example.
Google Calendar
Add a remote calendar: Settings → Devices & Services → Calendar → add Google *.ics URL.
Third-party custom components
References
评论