Skip to main content

led_ticker — Python library & CLI for the LED Ticker

led_ticker speaks the same BLE service as the companion mobile app, so you can drive the device — or build your own tools — from any machine with Bluetooth. The device advertises as LED-Ticker-XXXX.

Install

pip install led-ticker      # or: uv add led-ticker

This installs the importable led_ticker package and the led command.

Running the CLI

How you invoke the CLI depends on how it was installed:

led <cmd>                   # pip install into an active venv → on PATH
uv run led <cmd>            # uv add led-ticker → script is in .venv/bin, not on PATH
uv run tools/led.py <cmd>   # from a checkout of this repo → uses ./src directly

The examples below use led; prefix with uv run if you installed via uv add.

Library

from led_ticker import LedTicker, scan

# Scan for available devices (returns DeviceInfo with name, address, rssi):
for d in scan():
    print(d.name, d.address, d.rssi)

# Reuse one connection for several operations:
with LedTicker(pin="482913") as d:
    d.set_tickers(["AAPL", "MSFT"])
    d.set_status("BUSY", minutes=30)
    print(d.get_version())          # -> "0.7.0"
    s = d.get_status()              # -> Status(text="BUSY", seconds=1800)

# Or a one-shot for a single call (opens and closes its own connection):
import led_ticker
led_ticker.set_mode(["stocks", "weather"])

LedTicker(select=None, address=None, name_prefix="LED-Ticker", scan_timeout=4.0, timeout=15.0, pin=None). By default the first LED-Ticker-* in range is used; if several are in range it raises AmbiguousDeviceError (whose .candidates is a list of DeviceInfo). Pass select= to choose a specific unit (see Selecting a device), or address= to target a known address directly (skips the scan). Methods raise ValidationError, AuthError, DeviceNotFoundError, AmbiguousDeviceError, or ProtocolError (all subclasses of LedTickerError).

pin=None does not mean "no auth" — it falls back to the same resolution the CLI uses (LED_TICKER_PIN env var, then the ~/.config/led-ticker/pin cache), so a saved PIN is picked up automatically. Pass pin="482913" to override.

Selecting a device

With more than one LED-Ticker in range, list them and target one explicitly:

led devices                 # list units: name, address, signal
led --device A1B2 status "BUSY" 30   # target by name suffix

--device matches a unit by its name suffix (the XXXX in LED-Ticker-XXXX), its full name, or its Bluetooth address. If you run a command with several units in range and no --device, an interactive terminal prompts you to choose; in a script (no TTY) it lists the candidates and exits non-zero so you can re-run with --device.

CLI

# Sign mode
led status "BUSY" 30      # show for 30 min, then auto-clear
led status "ON AIR"       # indefinite
led status clear

# Timer mode (countdown sign — random animation at zero, then resumes ambient)
led timer 10              # 10-minute countdown
led timer cancel

# Ambient mode (subset of stocks/weather/clock, 'all', or 'none' for sign-only)
led mode stocks weather
led mode clock
led mode all
led mode none

# Power (volatile — power cycle returns to on)
led power on
led power off

# Display settings (persisted on the device)
led display                  # show current brightness + scroll speed
led display brightness 8     # brightness 0-15
led display speed 50         # scroll ms/step 20-500 (lower = faster)
led display 8 50             # both at once

# Timezone (persisted; POSIX TZ string — companion apps have a friendly picker)
led timezone                              # show current
led timezone "EST5EDT,M3.2.0,M11.1.0"     # US Eastern

# Data
led tickers AAPL TSLA NVDA SPY
led locations "47.61,-122.33,Seattle"   # lat,lon,label (look up coords online)
led apikey your-finnhub-key
led wifi My Network Name password

# Inspect
led get version           # firmware version on the device
led get wifi|apikey|tickers|status|locations|mode|power|display|timezone|version  # read other settings

# Auth
led pin 482913            # save the device's PIN locally (~/.config/led-ticker/pin)
led pin clear             # forget the saved PIN
led --pin 482913 status "BUSY" 30   # use a PIN for one call, without saving it
led pin-enforce on        # device: require PIN for writes (default after a fresh flash)
led pin-enforce off       # device: stop requiring PIN (escape hatch)

# Maintenance
led reload                # force stock refresh
led reset                 # wipe NVS, rotate PIN, revert to config.h defaults

Save once, every platform: run led pin <6 digits> a single time and it's replayed on each connection automatically — no per-command --pin, on Linux, Windows, and macOS alike. (Companion mobile apps instead use OS-level Bluetooth bonding — the phone prompts for the PIN once and the OS remembers it; the CLI never bonds.)

PIN resolution: every command (and the library) looks for the PIN in this order — --pin XXXXXX flag → LED_TICKER_PIN env var → the saved cache file (~/.config/led-ticker/pin). The env var suits CI or anyone who'd rather not write the PIN to disk. If none is found and the device has enforcement on, writes fail with a clear AuthError.

Stale-PIN safety: every write probes the device after sending the PIN and exits with a clear error if the PIN was rotated by a factory reset — a write never fails silently because of an out-of-date local PIN.

License

Apache-2.0 — free to use, including commercially, with attribution. (The firmware in the parent repo is also Apache-2.0; the hardware design files are CC BY 4.0 — see the repo root.)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

led_ticker-0.3.1.tar.gz (74.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

led_ticker-0.3.1-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file led_ticker-0.3.1.tar.gz.

File metadata

  • Download URL: led_ticker-0.3.1.tar.gz
  • Upload date:
  • Size: 74.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for led_ticker-0.3.1.tar.gz
Algorithm Hash digest
SHA256 2755d10168ee6e857775a8ef535b72c1de70a28a385cb66b3965717e54814c33
MD5 e302a98be5221bd50105f1451a0b5ad7
BLAKE2b-256 fc6ad79e8c1ed709d925af11f6f210db85feb598ebdbebc8c0bd3da1328cd9c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for led_ticker-0.3.1.tar.gz:

Publisher: publish.yml on ssayala/led-ticker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file led_ticker-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: led_ticker-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for led_ticker-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 802da562cfaf6dbfe7a087d385ad089ea71a3fe3f40788d3e101e3eedd867613
MD5 3c66fa25d4238d35fc3c1f71f95bda2c
BLAKE2b-256 45b8c0da45ded154b6f307aa678d25abcb6ea4923c55ad31d197b1739e78e637

See more details on using hashes here.

Provenance

The following attestation bundles were made for led_ticker-0.3.1-py3-none-any.whl:

Publisher: publish.yml on ssayala/led-ticker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 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