This started as a fork of https://github.com/ApolloAutomation/PixelMagicTool but I was not satisfied with the result of the image. While searching for solutions to the compression, I stumbled on https://github.com/zak-45/WLEDVideoSync and decided to leverage a DDP stream instead.
- Loads an image from a URL or local path
- Resizes it to your matrix dimensions
- Converts it to RGB24
- Sends it to a WLED device over DDP (UDP port 4048)
- Go to HACS
- Click the three dots menu (⋮) in the top right corner
- Select "Custom repositories"
- Add this repository URL:
https://github.com/iamjoshk/ha_ddp2wled - Select "Integration" as the category
- Click "Add"
- Search for "HA DDP2WLED" in HACS and install it
- Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration
- Search for "HA DDP2WLED" and add it (name-only config flow)
- Copy
custom_components/ha_ddp2wledinto your Home Assistantcustom_componentsfolder - Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration
- Search for "HA DDP2WLED" and add it (name-only config flow)
Sends an image to WLED device via DDP protocol with optional WLEDVideoSync-compatible image processing.
Image URLorImage Path(both templatable)WLED Host: IP address or hostname of the WLED deviceWidth: Target width in pixels for the matrix displayHeight: Target height in pixels for the matrix display
Brightness: Display brightness (0-255, default 255) — templatableSegment ID: WLED segment to target (default 0)Timeout: Network timeout in seconds (default 10)Keepalive Seconds: Duration to keep re-sending the frame (default 0 = send once)Keepalive Interval: Seconds between keepalive sends (default 1)
Auto Image Adjustment: Enable automatic image adjustment (true/false, default true)Auto Clipping Percentage: Histogram clipping percentage for auto image adjustment (0.0-50.0, default 0.0)Saturation: Color saturation multiplier (0.0-2.0, default 1.0)Contrast: Contrast adjustment (0.5-2.0, default 1.0)Sharpen: Sharpening intensity (0.0-2.0, default 0.0)Gamma Correction: Gamma correction (0.1-3.0, default 1.0)Red Balance: Red channel color balance (1.0 = no change, 0.0 = no red, 2.0 = enhanced red)Green Balance: Green channel color balance (1.0 = no change, 0.0 = no green, 2.0 = enhanced green)Blue Balance: Blue channel color balance (1.0 = no change, 0.0 = no blue, 2.0 = enhanced blue)
service: ha_ddp2wled.send_to_wled_ddp
data:
image_url: "{{ state_attr('media_player.spotify', 'entity_picture') }}"
wled_host: "192.168.1.100"
width: 32
height: 32
brightness: 200service: ha_ddp2wled.send_to_wled_ddp
data:
image_url: "https://example.com/album-cover.jpg"
wled_host: "192.168.1.100"
width: 32
height: 32
brightness: "{{ states('input_number.display_brightness') | int }}"
saturation: 1.2
contrast: 1.1
sharpening: 0.5
auto_brightness: true
keepalive_seconds: 300- Time-based dimming:
brightness: "{{ 10 if now().hour <= 8 or now().hour >= 22 else 128 }}" - Slider control:
brightness: "{{ states('input_number.display_brightness') | int }}" - Conditional brightness:
brightness: "{{ 50 if is_state('sun.sun', 'below_horizon') else 200 }}"
Stops any active keepalive stream to the specified WLED device.
wled_host: IP address or hostname of the WLED device to stop streaming to
service: ha_ddp2wled.stop_ddp_stream
data:
wled_host: "192.168.1.100"This integration is derived from the upstream zak-45/WLEDVideoSync project. The relevant pieces there include:
src/net/ddp_queue.py:DDPDevicehandles UDP socket creation, queuing, retry logic, and packetizing RGB data into DDP-compliant packets.src/cst/media.py:CASTMediaprepares and streams media sources (images, videos, USB cameras) to DDP devices, using queues to avoid latency and supporting previews.src/gui/videoplayer.py: GUI helpers for uploading GIFs and wiring UI actions to the media/DDP sending backend.WLEDVideoSync.py: Entry point that wires configuration, NiceGUI UI, and background tasks together.README: Documents configuration such as FPS, scaling, and device IP settings for DDP targets.
Overall flow: media sources are prepared by CASTMedia, packetized by DDPDevice, and streamed over DDP to WLED devices.
See LICENSE.