Skip to main content

WLED (ESP LED Controller)

Local control of LED strips driven by WLED firmware on ESP8266 / ESP32 boards (QuinLED, Athom, Dig-Quad, custom). Uses the on-device HTTP/JSON API — no cloud account, no MQTT broker, no Home Assistant in the middle.

Prerequisites

  • WLED 0.13 or newer recommended. Older builds work but lack a few segment fields.
  • Device on the same LAN as GEM. Static DHCP reservation strongly recommended — WLED defaults to DHCP and the IP can drift.
  • Verify the API with http://<wled-ip>/json/info in a browser; you should see firmware version, mac, and LED count.

Setup steps

  1. Find the WLED device IP from your router or the WLED iOS/Android app.
  2. Add a Device row in System → Devices with driver wled and the IP. Port stays at 80.
  3. If you've turned on Settings → Security → API access token in WLED, set the api_key attribute on the device row. Reads are unauthenticated by design; writes will include the token in the X-WLED-Token header.
  4. Add one Zone per WLED segment you want to control independently. zone.address is the integer segment id (0 for the main / only segment; most installs only have one).
  5. Use the set_color, set_effect, set_palette, and set_preset commands directly or wire them into scene macros.

Attribute reference

ScopeAttributeDirectionNotes
deviceiprequiredLAN IP or mDNS hostname.
deviceportoptionalDefault 80.
deviceapi_keyoptional, secureWLED API token (only set if Security is enabled).
devicestatus_intervaloptionalPoll cadence in ms. Default 10000. Set to 0 to disable polling and rely on write-only command flow.
devicetransitionoptionalDefault fade time sent on every write, in 100ms units. WLED default is 7 (~700 ms).
devicefirmware_versionread-onlyCaptured on connect.
devicedevice_nameread-onlyFriendly name set in WLED.
devicemacread-onlyController MAC.
deviceled_countread-onlyNumber of LEDs the controller is driving.
zonestateread-onlyon / off.
zonelevelread-onlyBrightness 0-100 (mapped from WLED's 0-255).
zonecolorread-onlyLast-reported foreground color in RRGGBB (or RRGGBBWW) hex.
zoneeffectread-onlyEffect id active on this segment.
zonepaletteread-onlyPalette id active on this segment.
zonepresetread-onlyActive preset id, if any.

Zone address format

Integer segment id. WLED supports multiple software-defined segments per physical strip (set up in the WLED Web UI under Segments). Address 0 = the first segment. If you only have one continuous strip you only need one zone with address 0.

If you omit zone.address the driver will default to segment 0 for commands.

Commands

  • on / off / toggle — per-segment power.
  • set_level — brightness 0-100, mapped to WLED's bri 0-255.
  • set_color — RRGGBB hex (ff8800) or RRGGBBWW hex (ffaa00ff) for RGBW strips.
  • set_effect — effect id (integer). Use get_effects to list the names supported by the connected firmware.
  • set_palette — palette id (integer). Use get_palettes to list.
  • set_speed / set_intensity — fx parameters 0-255.
  • set_preset — activate a stored preset by id (whole device).
  • get_info, get_state, get_effects, get_palettes — diagnostic reads.

Known limitations

  • Effect / palette ids are firmware-version specific. WLED 0.14 ships ~187 effects; older 0.10 had ~118. The driver passes the id through; the controller is the source of truth. The recommended pattern is to call get_effects once during integration and pick the id you want.
  • Live audio sync (Sound Reactive) and 2D matrix effects are not separately modeled — they're just effect ids that WLED reports. Choose them via set_effect like any other.
  • DDP / E1.31 streaming is out of scope — for ArtNet / sACN flows use a dedicated lighting console rather than the JSON API.
  • Per-segment color order and mapping is set in the WLED UI, not via this driver. If colors look swapped, fix the RGB order in WLED Settings → LED Preferences.

Troubleshooting

SymptomLikely cause
Writes return 401 / nothing happensAPI security token enabled on the controller but api_key not set on the device row (or wrong value).
Polling silent, never reports statestatus_interval set to 0 (write-only mode) or no zones created yet — the driver leaves device-level state populated but doesn't fan out per segment.
Brightness "snaps" instead of fadingtransition attribute set to 0. Default WLED behavior is ~700 ms; set it to 7 (or higher) to restore the fade.
set_color returns "invalid color"Color string must be 6 or 8 hex characters (RRGGBB or RRGGBBWW). Leading # is accepted; spaces / parentheses / decimal are not.
Colors look wrong (red vs. green swapped)LED color order misconfigured in WLED itself — fix under Settings → LED Preferences → Color Order, not here.