Skip to content

Commit 20ad969

Browse files
feat: Add RGBW support to LedDeviceUdpE131
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.
1 parent 26fd6d8 commit 20ad969

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

libsrc/leddevice/dev_net/LedDeviceUdpE131.cpp

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ const int DMX_MAX = 512; // 512 usable slots
3939

4040
LedDeviceUdpE131::LedDeviceUdpE131(const QJsonObject &deviceConfig)
4141
: ProviderUdp(deviceConfig)
42+
, _whiteAlgorithm(RGBW::WhiteAlgorithm::INVALID)
43+
, _ledRGBWCount(0)
4244
{
4345
}
4446

@@ -61,6 +63,28 @@ bool LedDeviceUdpE131::init(const QJsonObject &deviceConfig)
6163
_e131_source_name = deviceConfig["source-name"].toString("hyperion on "+QHostInfo::localHostName());
6264
QString _json_cid = deviceConfig["cid"].toString("");
6365

66+
// Initialize white algorithm
67+
QString whiteAlgorithmStr = deviceConfig["whiteAlgorithm"].toString("white_off");
68+
_whiteAlgorithm = RGBW::stringToWhiteAlgorithm(whiteAlgorithmStr);
69+
if (_whiteAlgorithm == RGBW::WhiteAlgorithm::INVALID)
70+
{
71+
QString errortext = QString("unknown whiteAlgorithm: %1").arg(whiteAlgorithmStr);
72+
this->setInError(errortext);
73+
return false;
74+
}
75+
Debug(_log, "whiteAlgorithm : %s", QSTRING_CSTR(whiteAlgorithmStr));
76+
77+
// Calculate RGBW count
78+
if (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF)
79+
{
80+
_ledRGBWCount = _ledCount * 3;
81+
}
82+
else
83+
{
84+
_ledRGBWCount = _ledCount * 4;
85+
}
86+
87+
6488
if (_json_cid.isEmpty())
6589
{
6690
_e131_cid = QUuid::createUuid();
@@ -138,10 +162,32 @@ void LedDeviceUdpE131::prepare(unsigned this_universe, unsigned this_dmxChannelC
138162

139163
int LedDeviceUdpE131::write(const std::vector<ColorRgb> &ledValues)
140164
{
141-
int retVal = 0;
165+
int retVal = 0;
142166
int thisChannelCount = 0;
143-
int dmxChannelCount = _ledRGBCount;
144-
const uint8_t * rawdata = reinterpret_cast<const uint8_t *>(ledValues.data());
167+
int dmxChannelCount = _ledRGBWCount; // Use _ledRGBWCount
168+
169+
// Create a temporary buffer for RGB or RGBW data
170+
std::vector<uint8_t> tempBuffer(dmxChannelCount);
171+
uint8_t* rawDataPtr = tempBuffer.data();
172+
173+
int currentChannel = 0;
174+
for (const ColorRgb& color : ledValues)
175+
{
176+
if (_whiteAlgorithm == RGBW::WhiteAlgorithm::WHITE_OFF)
177+
{
178+
rawDataPtr[currentChannel++] = color.red;
179+
rawDataPtr[currentChannel++] = color.green;
180+
rawDataPtr[currentChannel++] = color.blue;
181+
}
182+
else
183+
{
184+
RGBW::Rgb_to_Rgbw(color, &_temp_rgbw, _whiteAlgorithm);
185+
rawDataPtr[currentChannel++] = _temp_rgbw.red;
186+
rawDataPtr[currentChannel++] = _temp_rgbw.green;
187+
rawDataPtr[currentChannel++] = _temp_rgbw.blue;
188+
rawDataPtr[currentChannel++] = _temp_rgbw.white;
189+
}
190+
}
145191

146192
_e131_seq++;
147193

@@ -150,16 +196,16 @@ int LedDeviceUdpE131::write(const std::vector<ColorRgb> &ledValues)
150196
if (rawIdx % DMX_MAX == 0) // start of new packet
151197
{
152198
thisChannelCount = (dmxChannelCount - rawIdx < DMX_MAX) ? dmxChannelCount % DMX_MAX : DMX_MAX;
153-
// is this the last packet? ? ^^ last packet : ^^ earlier packets
199+
// is this the last packet? ? ^^ last packet : ^^ earlier packets
154200

155201
prepare(_e131_universe + rawIdx / DMX_MAX, thisChannelCount);
156202
e131_packet.sequence_number = _e131_seq;
157203
}
158204

159-
e131_packet.property_values[1 + rawIdx%DMX_MAX] = rawdata[rawIdx];
205+
e131_packet.property_values[1 + rawIdx % DMX_MAX] = rawDataPtr[rawIdx];
160206

161-
// is this the last byte of last packet || last byte of other packets
162-
if ( (rawIdx == dmxChannelCount-1) || (rawIdx %DMX_MAX == DMX_MAX-1) )
207+
// is this the last byte of last packet || last byte of other packets
208+
if ((rawIdx == dmxChannelCount - 1) || (rawIdx % DMX_MAX == DMX_MAX - 1))
163209
{
164210
#undef e131debug
165211
#if e131debug

libsrc/leddevice/dev_net/LedDeviceUdpE131.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
// hyperion includes
55
#include "ProviderUdp.h"
6+
#include "utils/ColorRgbw.h"
7+
#include "utils/RgbToRgbw.h"
68

79
#include <QUuid>
810

@@ -142,6 +144,11 @@ class LedDeviceUdpE131 : public ProviderUdp
142144
uint8_t _acn_id[12] = {0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
143145
QString _e131_source_name;
144146
QUuid _e131_cid;
147+
148+
// RGBW specific members
149+
RGBW::WhiteAlgorithm _whiteAlgorithm;
150+
int _ledRGBWCount;
151+
ColorRgbw _temp_rgbw;
145152
};
146153

147154
#endif // LEDEVICEUDPE131_H

libsrc/leddevice/schemas/schema-e131.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@
3636
"type": "string",
3737
"title": "edt_dev_spec_cid_title",
3838
"propertyOrder": 5
39+
},
40+
"whiteAlgorithm": {
41+
"type": "string",
42+
"title": "edt_dev_spec_white_algorithm_title",
43+
"enum": [
44+
"white_off",
45+
"subtractive",
46+
"additive"
47+
],
48+
"default": "white_off",
49+
"propertyOrder": 6,
50+
"options": {
51+
"enum_titles": [
52+
"edt_dev_spec_white_algorithm_white_off",
53+
"edt_dev_spec_white_algorithm_subtractive",
54+
"edt_dev_spec_white_algorithm_additive"
55+
]
56+
}
3957
}
4058
},
4159
"additionalProperties": true

0 commit comments

Comments
 (0)