Skip to content

Conversation

@lougovsk
Copy link

@lougovsk lougovsk commented Jun 30, 2025

Summary
This PR primarily focuses on extending current implementation of e1.31 led device to not only support RGB data but also RGBW and hence partially covers #446 feature request for network based led device. Having RGBW implementation for e1.31 will allow in the future to extend wled led device to use not only DDP and RAW but also e1.31 and hence provide native RGBW support. During implementation I've also encountered a problem that some e1.31 (e.g. RGB WLED) doesn't use 512 DMX channels but less (510 = 170 leds*3channels) and hence current e1.31 led device implementation doesn't work correctly with WLED for >170 leds. To address this I've replaced the hardcoded value with a configurable option (see webui changes before/after).I've tested code with my WLED setup using both RGB (white_off) and RGBW (cold/neutral white).

I've started working on this with intension of vibe coding but in the end gave up and put a couple of manual commits. So some of the code has been AI generated, but was reviewed by me.

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Docs
  • Build-related changes
  • Other, please describe:

If changing the UI of web configuration, please provide the before/after screenshot:
before
before
after
after

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

If yes, please describe the impact and migration path for existing setups:

The PR fulfills these requirements:

  • When resolving a specific issue, it's referenced in the PR's body (e.g. Fixes: #xxx[,#xxx], where "xxx" is the issue number)

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature
  • Related documents have been updated (docs/docs/en)
  • Related tests have been updated

PLEASE DON'T FORGET TO ADD YOUR CHANGES TO CHANGELOG.MD

  • Yes, CHANGELOG.md is also updated

To avoid wasting your time, it's best to open a feature request issue first and wait for approval before working on it.

Other information:

google-labs-jules bot and others added 3 commits June 29, 2025 15:42
This commit introduces RGBW (Red, Green, Blue, White) data handling
for the E1.31 UDP LED device.

Key changes:

1.  **LedDeviceUdpE131.h modifications:**
    *   Included `utils/ColorRgbw.h` and `utils/RgbToRgbw.h`.
    *   Added private member variables:
        *   `_whiteAlgorithm` (RGBW::WhiteAlgorithm) to store the selected white calibration mode.
        *   `_ledRGBWCount` (int) to store the total number of channels (3 for RGB, 4 for RGBW).
        *   `_temp_rgbw` (ColorRgbw) as a temporary variable for color conversion.

2.  **LedDeviceUdpE131.cpp modifications:**
    *   Constructor now initializes `_whiteAlgorithm` to `INVALID` and `_ledRGBWCount` to 0.
    *   `init()` method:
        *   Reads `whiteAlgorithm` from the device configuration (defaults to "white_off").
        *   Converts the string to `RGBW::WhiteAlgorithm`.
        *   Sets `_ledRGBWCount` based on `_ledCount` and whether a white channel is active (3 * _ledCount for RGB, 4 * _ledCount for RGBW).
    *   `write()` method:
        *   Uses `_ledRGBWCount` for `dmxChannelCount`.
        *   Creates a temporary buffer for pixel data.
        *   If `_whiteAlgorithm` is `WHITE_OFF`, copies RGB data directly.
        *   Otherwise, converts RGB to RGBW using `RGBW::Rgb_to_Rgbw` and copies R,G,B,W data.
        *   Populates E1.31 packet properties using the new (potentially RGBW) data buffer.

3.  **JSON Schema Update (libsrc/leddevice/schemas/schema-e131.json):**
    *   Added a `whiteAlgorithm` property to the E1.31 device schema.
    *   This allows users to select the white channel calibration method ("white_off", "subtractive", "additive").
    *   Includes a default value of "white_off".

**Compilation Status:**

The project successfully configures with CMake after installing numerous dependencies (Qt6, libudev, XCB libs, ALSA, CEC, libp8-platform, libusb).
However, the `make` process consistently times out after approximately 6 minutes and 40 seconds, regardless of the number of parallel jobs (`-j nproc`, `-j 2`, `-j 1`) or if a specific target (`hyperiond`) is built.

This suggests a potential hang or an extremely long compilation step for a particular file/module within the project, which could not be identified due to lack of verbose output during the timeout.

Further investigation or environment adjustments are needed to complete the full build.
   ledRGB(W)Count variable from LedDevice instead of creating a new
   locally
2. Fixed the problem where DMX Max channel count was hardcoded to 512.
   WLED e.g. in MultiRGB mode relies on 510 (3*170) channels. On other
   hand for MultiRGBW it expect 512 (4*128) channels. So obviously it
   has to be a parameter.
3. Updated corresponding configuration for WebUI
@lougovsk lougovsk changed the title Feature/rgbw e131 support rgbw e131 support Jun 30, 2025
@lougovsk lougovsk marked this pull request as ready for review June 30, 2025 13:47
Copy link
Collaborator

@Lord-Grey Lord-Grey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-cli /review

@Lord-Grey Lord-Grey requested a review from Copilot October 27, 2025 17:34
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR extends the e1.31 LED device implementation to support RGBW (Red-Green-Blue-White) color formats in addition to the existing RGB support. The change addresses issue #446 for network-based LED devices and resolves a compatibility problem where some e1.31 implementations (like WLED) use fewer than 512 DMX channels.

Key Changes:

  • Added RGBW white algorithm configuration with multiple white LED control modes
  • Introduced configurable DMX channel maximum (replacing hardcoded 512 value)
  • Implemented RGB-to-RGBW color conversion in the write method

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
libsrc/leddevice/schemas/schema-e131.json Added schema definitions for dmx-max and whiteAlgorithm configuration options
libsrc/leddevice/dev_net/LedDeviceUdpE131.h Added RGBW-related member variables and includes for color conversion utilities
libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp Implemented RGBW color conversion logic and replaced hardcoded DMX_MAX with configurable value
assets/webconfig/i18n/en.json Added English translation for DMX max channels configuration field
CHANGELOG.md Documented the new RGBW support feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

int dmxChannelCount = (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) ? _ledRGBCount : _ledRGBWCount; // if white_off we expect 3 channels per LED otherwise 4

// Create a temporary buffer for RGB or RGBW data
std::vector<uint8_t> tempBuffer(dmxChannelCount);
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tempBuffer is allocated on every write() call. Consider making this a member variable (like _temp_rgbw) and resizing it only when needed, to avoid repeated allocations for every frame.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

@Lord-Grey Lord-Grey Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might have a look at libsrc/leddevice/dev_ftdi/LedDeviceWs2812_ftdi.cpp
where an _ledBuffer is prepared durting init

@Lord-Grey Lord-Grey self-assigned this Oct 27, 2025
_port = deviceConfig[CONFIG_PORT].toInt(E131_DEFAULT_PORT);

_e131_universe = deviceConfig["universe"].toInt(1);
_e131_dmx_max = deviceConfig["dmx-max"].toInt(DMX_MAX);
Copy link
Collaborator

@Lord-Grey Lord-Grey Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that _e131_dmx_max must be always <= DMX_MAX?
The ensure that _e131_dmx_max = DMX_MAX, if greater

Suggested change
_e131_dmx_max = deviceConfig["dmx-max"].toInt(DMX_MAX);
_e131_dmx_max = deviceConfig["dmx-max"].toInt(DMX_MAX);
if (_e131_dmx_max > DMX_MAX)
{
_e131_dmx_max > DMX_MAX);
Warning(_log, "Maximum channels configured [%d] cannot exceed maximum channels defined by the E1.31 protocol. Corrected to %d channels.", _e131_dmx_max, DMX_MAX)
}

int thisChannelCount = 0;
int dmxChannelCount = _ledRGBCount;
const uint8_t * rawdata = reinterpret_cast<const uint8_t *>(ledValues.data());
int dmxChannelCount = (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF) ? _ledRGBCount : _ledRGBWCount; // if white_off we expect 3 channels per LED otherwise 4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dmxChannelCount can be calculated once in init, next to allocating the vector

@Lord-Grey
Copy link
Collaborator

Lord-Grey commented Oct 27, 2025

@lougovsk Thank you very much for your contribution and issuing a pull request.
Apologies that a review took longer than normal, but too many things came into between.

I already pushed some small updates which are hopefully ok with you.

Please have a look at the additional comments and suggestion to improve the PR further.

Edit: I had some additional reading about the E1.31 protocol.

E1.31 transports lighting information in "Universes", which is a collection of up to 512 channels together. You can chose any universe number from 1-63999 and assign it to a block of channels in your sequencing software. While a Universe can contain up to 512 channels, it does not have to, and can be any number between 1-512 channels.

i.e. the number channels in one package defined for maximum number of LEDs, RGB = 170 LED, RGBW = 128 LED for one given universe, but must not exceed 512 channels.

-> There is not a need to define a new max channel parameter, but calculate the max channels by the number of LEDs and ensure it does not exceed 512 channels.
Does that sound right?

We might add some validation to the UI added that the number of LEDs does not exceed the maximum number of channels which is LED# multiplied by 3 or 4 colors for the given universe?

Many thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants