Skip to main content

OpenLamp Engine

The core layer of the OpenLamp family: instant, 100% local control of smart LED lamps (WLED recommended, Tuya also supported), exposed through a stable command contract — OpenLamp State (OLS), a WLED-compatible JSON state patch (see OLS.md).

PyPI — openlamp-lamp

Part of the OpenLamp family:

Layer Repo Role
Engine (this repo) openlamp/engine drivers + dispatcher + local API + daemon + CLI (Python reference)
Engine, JS port engine-js same contract on Node/tuyapi — for JS-first environments
Stream Deck frontend lumideck keys, dials, live status on an Elgato Stream Deck
MIDI frontend openlamp-midi stage control from physical MIDI controllers

Install the lamp CLI (PyPI)

The one-shot command-line frontend is published as openlamp-lamp on PyPI:

pip install openlamp-lamp

lamp rouge            # set colour (keeps brightness)
lamp bri:60           # brightness 1-100
lamp veilleuse        # a brightness preset (lueur/veilleuse/tamise/moyen/fort/max)
lamp on | off

It finds your lamp config (with local keys) from $LUMIDECK_LAMPS, else ~/.config/openlamp/tuya-lamps.json (template at the bottom of this README). If the LumiDeck plugin/daemon is running, the CLI routes through its local API (127.0.0.1:8377) for instant response; otherwise it drives the lamps directly.

Only the CLI (lamp.py) ships on PyPI. The engine + headless daemon stay in this repo (they couple to a local file layout — a clean engine package is a follow-up).

What's inside

  • engine.py — the engine: one thread per lamp with a persistent connection (sub-200 ms commands), the OLS dispatcher, groups, snapshots, animations (cycle/flash/tempo), connect-time sync, a rainbow welcome sweep, and the local API on 127.0.0.1:8377 (/cmd, /status, /syntax, plus the optional WLED-compat /json/state). Frontend-agnostic: its only upward link is an on_change hook.
  • daemon.py — headless host: runs the engine without any frontend app.
  • run-headless.sh — one command to switch to CLI/MIDI-only mode.
  • lamp-doctor.sh (macOS) — one-command diagnosis of "lamps unreachable", testing the three causes in order: Mac on the wrong Wi-Fi / router down / lamp powered off or radio-napping. Never trust the router's web panel (it renders from service-worker cache even with the router dead) — this script is the ground truth.
  • lamp.py — the CLI (also Bome-callable): lamp.py vert, lamp.py bri:40… Routes through the local API when a host runs, drives lamps directly otherwise.
  • bin/lamp-bench.py — a small bench for WLED tinkerers: firmware/hardware info, command latency (the round-trip a press pays), and — opt-in — the command ceiling (--ceiling) the lamp sustains before dropping commands. stdlib only. lamp-bench.py <ip>.
  • com.openlamp.lumideck-daemon.plist — launchd autostart for the daemon.
  • OLS.md — the OpenLamp State contract. TUYA-KEYS.md — how to get your lamps' local keys (official Tuya cloud API, one-time).

One host at a time — the rule

Every host binds port 8377 (and a Tuya lamp additionally accepts only one local connection). So run either the Stream Deck plugin (it embeds this engine in-process) or daemon.py — never both. Deck sessions → plugin; CLI/MIDI-only sessions → daemon.

Why 8-bit values (0–255)

OLS uses 8-bit for brightness and per-channel color, for three reasons:

  1. WLED compatibility — WLED's JSON API is 8-bit; OLS is a compatible patch.
  2. It matches the hardware — RGB LEDs are driven 8 bits per channel (16.7 M colors); Tuya's internal 0–1000 scale adds no perceptible precision.
  3. It matches perception — ~1 % brightness steps are at the threshold of what the eye distinguishes; 256 levels cover that. MIDI frontends (7-bit, 0–127) scale up ×2 — plenty for stage cues.

Config

You can point the engine at an external, synced folder (Google Drive/Dropbox) that holds lamp.py + tuya-lamps.json by setting OPENLAMP_LAMPS_DIR to that path; otherwise tuya-lamps.json sits next to lamp.py (never committed — it contains your local keys). Template:

{
  "lamps": [
    {"name": "L1", "mac": "aa:bb:cc:dd:ee:ff", "device_id": "…", "local_key": "…",
     "ips": {"192.168.1": "192.168.1.50"}}
  ],
  "groups": {"front": ["L1"]},
  "sync": {"enabled": true, "state": {"on": true, "col": [0, 100, 200], "bri": 153}}
}

Test hardware (budget setup)

The engine and LumiDeck are developed and tested on this cheap, off-the-shelf rig — reproduce it for well under €40 for a two-lamp stereo stage:

  • Bulbs — Athom WLED 7 W Color Bulb (E27, ESP32-C3, RGB + tunable white, WLED-preflashed, ~€13 each). WLED ships already flashed — put the bulb on Wi-Fi and it's auto-discovered. This is the reference bulb every timing figure is measured on (~45 ms/command, the latency-comp floor beatsync uses).
  • Socket / holder — TobeBright E27 corded lamp holder with inline switch (up to 100 W, a few € on Amazon). Turns a bare bulb into a standalone plug-in stage lamp — no fixture required, just screw the bulb in and plug it to mains.

Publishing to PyPI (maintainer)

openlamp-lamp publishes via Trusted Publishing (OIDC) — no token in the repo. .github/workflows/publish.yml builds + publishes on each GitHub Release. One-time:

  1. PyPI → Add a pending publisher (https://pypi.org → Publishing): project openlamp-lamp, owner openlamp, repo engine, workflow publish.yml, environment pypi.
  2. GitHub → Settings → Environments → New → pypi.
  3. Bump version in pyproject.toml, commit, cut a GitHub Release (tag v0.1.0) → the workflow builds and publishes. Then pip install openlamp-lamp works everywhere.

Credits

Made by @Beennnn (OpenLamp) with the help of Claude. WLED is the recommended, tested path (validated on Athom RGBCW bulbs, ~45 ms/command). Feedback: open an issue on lumideck.

Metadata

Release files for openlamp-lamp 0.1.2

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

Source distribution (sdist)

Source distribution for openlamp-lamp 0.1.2
File Size Uploaded Provenance
openlamp_lamp-0.1.2.tar.gz 22.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for openlamp-lamp 0.1.2
File Interpreter ABI Platform
openlamp_lamp-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 41.1 kB

Release files / openlamp_lamp-0.1.2.tar.gz

Download URL openlamp_lamp-0.1.2.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3c78b8b9abbfbfd12fc378b3a5d3210473127b7cb41c4392e3fc5281968f4b91
BLAKE2b-256 checksum
How to use checksums
cedfbbea02d5bef8edcc53475320d2ceb5117b2c5826956cf1fa69bf4d54586c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 14, 2026.

Transparency log

Release files / openlamp_lamp-0.1.2-py3-none-any.whl

Download URL openlamp_lamp-0.1.2-py3-none-any.whl
Size 18.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aa04a15c4ee6676a2f17f56f49b4438fed8fa339a942f50d51d3cb45ab99fe2b
BLAKE2b-256 checksum
How to use checksums
8c81a1ab27118c2dbac30328a6de0169567162b1942e4e683500dd101dda1232
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 14, 2026.

Transparency log

Security for openlamp-lamp 0.1.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openlamp_lamp-0.1.2.tar.gz

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 Jul 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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