This Node port stopped tracking the Python engine on 2026-07-11. Five commits landed upstream after that date, including WLED WebSocket real-state feedback and 14-bit high-resolution CC ingestion. It is no longer interchangeable with openlamp-engine-python, and the claim below that a frontend cannot tell which engine is serving it has not been true since.
Kept readable as a reference implementation of the OLS contract; not maintained.
A faithful Node.js port of openlamp/engine (the Python reference implementation), for environments that prefer JS over Python β e.g. Stream Deck plugins packaged on the official Node SDK, or any npm-based stack.
Same contract, same behavior: OpenLamp State
patches + legacy aliases, persistent per-lamp connections (tuyapi, protocol 3.5),
acked multi-DP sets, groups, snapshots, animations (paced β€4 cmd/s), connect-time
sync, rainbow welcome sweep, and the identical local API on 127.0.0.1:8377
(/cmd, /status, /syntax, WLED-compat /json/state). Frontends cannot tell
which engine is serving them β the two are interchangeable behind the API.
- β
Offline-validated: 25 assertions on mocked devices (
npm test). - β
Live-validated on real Tuya lamps (2026-07-04): protocol 3.5 session
negotiation, connect + rainbow greet + sync writes, color commands acked
(
ok:true), auto-deauth integration β both lamps held concurrently. - β One fix pending live confirmation: state readback now uses a plain DPS query
(
get({})) βget({schema:true})made the 3.5 firmware drop the session.
npm install
node engine.js # headless daemon; config = tuya-lamps.json next to engine.js
npm test # offline mock test (port 18377)One host at a time: never run this alongside the Python engine host (Stream Deck plugin or daemon.py) β every host binds port 8377 (and Tuya lamps additionally accept only one local connection).
Part of the OpenLamp family. Made by BenLab with the help of Claude.