ble2wled.wled - WLED Device Communication
WLED LED controller implementations.
This module provides abstract and concrete LED controller classes for communicating with WLED devices via HTTP and UDP protocols.
- Protocols:
HTTP: JSON-based API, slower but more reliable
UDP: DRGB protocol, real-time updates with low latency
Example
Create and use an LED controller:
from ble2wled.wled import WLEDUDPController
controller = WLEDUDPController('wled.local', led_count=60, port=21324)
leds = [[255, 0, 0] for _ in range(60)] # All red
controller.update(leds)
- class ble2wled.wled.LEDController(host: str, led_count: int)[source]
Bases:
ABCAbstract base class for LED controllers.
Defines the interface that all LED controller implementations must follow.
- class ble2wled.wled.WLEDHTTPController(host: str, led_count: int, max_retries: int = 3)[source]
Bases:
LEDControllerWLED controller using HTTP API.
Sends LED updates via WLED’s JSON HTTP API. Slower than UDP but more reliable and easier to debug.
Implements automatic retry logic for handling temporary connection failures and timeouts.
Example
Use HTTP controller:
controller = WLEDHTTPController('192.168.1.100', led_count=60) leds = [[255, 100, 50] for _ in range(60)] controller.update(leds)
- update(leds: List[List[int]]) None[source]
Send LED update via HTTP POST with retry logic.
Sends LED data to WLED device using the /json/state endpoint. Automatically retries on timeout errors to handle temporary connection issues.
- Parameters:
leds (list) – List of RGB color values [R, G, B] 0-255.
Example
Update LEDs via HTTP:
leds = [[255, 0, 0] for _ in range(60)] # All red controller.update(leds)
- class ble2wled.wled.WLEDUDPController(host: str, led_count: int, port: int = 21324)[source]
Bases:
LEDControllerWLED controller using UDP DRGB protocol.
Sends LED updates via UDP using the DRGB protocol for real-time updates with minimal latency. Requires WLED to have UDP realtime protocol enabled.
- The DRGB protocol is simple:
Header: ‘DRGB’ (4 bytes)
Data: RGB triplets (3 bytes per LED)
Example
Use UDP controller for real-time updates:
controller = WLEDUDPController('wled.local', led_count=60, port=21324) leds = [[0, 255, 0] for _ in range(60)] # All green controller.update(leds)
- __init__(host: str, led_count: int, port: int = 21324)[source]
Initialize UDP controller.
- Parameters:
Example
Create UDP controller with custom port:
controller = WLEDUDPController('wled.local', 60, port=21325)
- update(leds: List[List[int]]) None[source]
Send LED update via UDP DRGB protocol.
Constructs DRGB packet with header and RGB data, sends via UDP. No response is expected or required.
- Parameters:
leds (list) – List of RGB color values [R, G, B] 0-255.
Example
Update LEDs via UDP:
leds = [[255, 0, 255] for _ in range(60)] # All magenta controller.update(leds)
Overview
The wled module provides controllers for communicating with WLED devices via HTTP and UDP protocols. It handles:
HTTP requests with automatic retry logic
UDP DRGB protocol for fast updates
Graceful error handling and recovery
Quick Example
from ble2wled.wled import WLEDUDPController, WLEDHTTPController
# UDP is faster and doesn't require connection setup
controller = WLEDUDPController(
host='192.168.1.100',
led_count=60
)
# HTTP is slower but more reliable for some networks
controller = WLEDHTTPController(
host='192.168.1.100',
led_count=60,
timeout=1.0,
max_retries=3
)
# Send LED data
leds = [[255, 0, 0]] * 60 # All red
controller.update(leds)
Classes
WLEDUDPController
Fast UDP-based communication using DRGB protocol.
Attributes:
host(str) - WLED device hostname or IPled_count(int) - Number of LEDs in stripport(int, default 21324) - UDP port
Methods:
update(leds: List[List[int]])- Send LED data to device
Advantages:
Faster (no connection overhead)
Fire-and-forget (no waiting for response)
Works with most WLED devices
Disadvantages:
No error handling (packets can be lost)
No acknowledgment
Example:
from ble2wled.wled import WLEDUDPController
controller = WLEDUDPController('192.168.1.100', 60)
# Send all red
leds = [[255, 0, 0] for _ in range(60)]
controller.update(leds)
# Send gradient
leds = [[i * 4, 0, 255 - i * 4] for i in range(60)]
controller.update(leds)
WLEDHTTPController
Reliable HTTP-based communication with automatic retry logic.
Attributes:
host(str) - WLED device hostname or IPled_count(int) - Number of LEDs in striptimeout(float, default 1.0) - HTTP request timeout in secondsmax_retries(int, default 3) - Number of retry attempts on timeoutport(int, default 80) - HTTP port
Methods:
update(leds: List[List[int]])- Send LED data to device
Advantages:
HTTP retries on timeout (automatic recovery)
Error handling and logging
Works with unreliable networks
Disadvantages:
Slower (HTTP overhead)
Connection setup time
Example:
from ble2wled.wled import WLEDHTTPController
# Standard configuration
controller = WLEDHTTPController(
host='192.168.1.100',
led_count=60,
timeout=1.0,
max_retries=3
)
# For unreliable networks
controller = WLEDHTTPController(
host='192.168.1.100',
led_count=60,
timeout=2.0, # Longer timeout
max_retries=5 # More retries
)
# For fast networks
controller = WLEDHTTPController(
host='192.168.1.100',
led_count=60,
timeout=0.5, # Shorter timeout
max_retries=1 # Fewer retries
)
# Send update
leds = [[255, 0, 0]] * 60
controller.update(leds)
LED Data Format
Both controllers accept LED data as a list of RGB tuples:
# List of [R, G, B] values for each LED
# Each value is 0-255
leds = [
[255, 0, 0], # LED 0: Red
[0, 255, 0], # LED 1: Green
[0, 0, 255], # LED 2: Blue
[255, 255, 255], # LED 3: White
# ... 56 more LEDs for 60-LED strip
]
controller.update(leds)
Requirements:
List length must equal
led_countEach element must be a list/tuple of [R, G, B]
Each value must be 0-255
Examples
Basic LED Updates
from ble2wled.wled import WLEDUDPController
controller = WLEDUDPController('192.168.1.100', 60)
# All red
leds = [[255, 0, 0]] * 60
controller.update(leds)
# Rainbow gradient
leds = [
[int(255 * (i / 60)), int(255 * (1 - i / 60)), 0]
for i in range(60)
]
controller.update(leds)
# Off
leds = [[0, 0, 0]] * 60
controller.update(leds)
With Animation Loop
from ble2wled.wled import WLEDUDPController
import time
controller = WLEDUDPController('192.168.1.100', 60)
# Simple animation: moving red dot
for iteration in range(100):
position = iteration % 60
leds = [[0, 0, 0]] * 60
leds[position] = [255, 0, 0]
controller.update(leds)
time.sleep(0.05) # 20fps
HTTP with Retry Handling
from ble2wled.wled import WLEDHTTPController
import logging
# Enable logging to see retries
logging.basicConfig(level=logging.INFO)
controller = WLEDHTTPController(
host='192.168.1.100',
led_count=60,
max_retries=3
)
# Try to update
leds = [[255, 0, 0]] * 60
controller.update(leds)
# If device times out, will automatically retry
# Logs will show retry attempts
Choosing Between UDP and HTTP
Use UDP when:
WLED device is on stable local network
Speed is critical
You want fire-and-forget behavior
from ble2wled.wled import WLEDUDPController
controller = WLEDUDPController('wled.local', 60)
Use HTTP when:
Network is unreliable or WiFi
You need automatic recovery from timeouts
Device is temporarily unreachable
from ble2wled.wled import WLEDHTTPController
controller = WLEDHTTPController('wled.local', 60)
Use HTTP with more retries on bad networks:
from ble2wled.wled import WLEDHTTPController
controller = WLEDHTTPController(
'wled.local',
60,
timeout=2.0,
max_retries=5
)
Error Handling
HTTP Errors
Handled automatically with retry logic:
from ble2wled.wled import WLEDHTTPController
controller = WLEDHTTPController('192.168.1.100', 60)
# These errors are retried automatically:
# - ReadTimeout
# - Timeout
# - ConnectionError
# Logs will show retry attempts:
# "HTTP timeout on attempt 1/3 for 192.168.1.100, retrying..."
# If all retries fail: "HTTP request failed after 3 attempts for 192.168.1.100..."
leds = [[255, 0, 0]] * 60
controller.update(leds) # May log timeout messages but continues
UDP Errors
UDP doesn’t wait for responses, so no timeouts. Packets may be lost:
from ble2wled.wled import WLEDUDPController
controller = WLEDUDPController('192.168.1.100', 60)
# UDP doesn't throw exceptions for lost packets
# If device unreachable, packets are silently dropped
leds = [[255, 0, 0]] * 60
controller.update(leds)
Debugging
Check Device Connectivity
# Test HTTP connection
curl http://192.168.1.100/json/state
# Test UDP with netcat (Linux/Mac)
echo "test" | nc -u 192.168.1.100 21324
See WLED Logs
Access WLED web interface at http://192.168.1.100 and check logs.
Performance Tips
UDP is ~10x faster than HTTP
HTTP adds network overhead but handles errors
Update interval of 0.05s (20fps) is good balance
Longer trails require more color calculations
See Also
ble2wled.animation - Animation Loop - Animation loop using controllers
HTTP Retry Logic - HTTP retry documentation
Configuration - Configure WLED parameters