Skip to content

Conversation

@limpkin
Copy link

@limpkin limpkin commented Dec 31, 2025

Summary by CodeRabbit

  • New Features

    • Added WRGB (White-Red-Green-Blue) light preset for 4-channel fixtures.
  • Improvements

    • Drivers now handle a dedicated white channel and correct WRGB channel mapping.
    • Improved LED handling across configurations so white channel position is respected during updates.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 31, 2025

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'review', 'context'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

Adds a WRGB light preset and propagates four-channel (channelsPerLight=4) WRGB mapping through DriverNode, VirtualLayer, and the parallel LED driver so the white channel offset is tracked and used alongside RGB offsets.

Changes

Cohort / File(s) Summary
Light preset enum & handling
src/MoonBase/Nodes.h, src/MoonBase/Nodes.cpp
Added lightPreset_WRGB to LightPresetsEnum and implemented handling in DriverNode::onUpdate to set channelsPerLight = 4 with offsets white=0, red=1, green=2, blue=3 when WRGB is selected.
Virtual layer RGB/White writes
src/MoonLight/Layers/VirtualLayer.h
Replaced white-position check with channelsPerLight == 4 for RGBW behavior: setRGB and setWhite now treat 4-channel lights consistently (white at offset 3 for internal buffer or configured offset for non-RGBW).
Parallel LED driver integration
src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h
Extended logging and updated calls to initled(...) and updateDriver(...) to pass the additional offsetWhite parameter so driver init/update use the white-channel offset.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant UI as DriverNode (config)
    participant VL as VirtualLayer
    participant D as ParallelLEDDriver
    note right of UI `#DDEEFF`: onUpdate for WRGB preset
    UI->>VL: set channelsPerLight=4, offsets {W=0,R=1,G=2,B=3}
    VL-->>D: initled(channelsPerLight, offsetR, offsetG, offsetB, offsetWhite)
    D-->>VL: driver initialized
    note right of UI `#E8F5E9`: runtime updates
    UI->>VL: write RGB/White values
    VL->>D: updateDriver(buffer, offsets..., offsetWhite)
    D-->>VL: DMA/LED buffer updated
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Board presets p4 #74 — Modifies the same lighting preset handling and related VirtualLayer/Nodes code paths (enum, preset mapping, RGBW handling).

Poem

🐰 Four tiny channels hop in a line,
White first, then red, green, blue align,
A WRGB tune hums through driver and layer,
I mapped their offsets with careful-care-er! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding support for WS2814 LED strips with white channel first (WRGB), which is implemented via the new lightPreset_WRGB across multiple files.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 117088b and d940ec7.

📒 Files selected for processing (1)
  • src/MoonLight/Layers/VirtualLayer.h
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/MoonLight/Layers/VirtualLayer.h

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/MoonLight/Layers/VirtualLayer.h (1)

114-117: The special-case logic works for current presets but may be fragile for future ones.

The condition offsetWhite == 0 && channelsPerLight == 4 specifically handles WRGB, but a hypothetical future 4-channel preset with offsetWhite at position 1 or 2 would incorrectly write to that physical offset rather than the internal white position (3).

Consider generalizing to always write to position 3 for all 4-channel configurations, since the internal format is RGBW regardless of physical ordering:

🔎 Suggested alternative (optional)
  void setWhite(const uint16_t indexV, const uint8_t value) {
-   if (layerP->lights.header.offsetWhite == 0 && layerP->lights.header.channelsPerLight == 4) setLight(indexV, &value, 3, sizeof(value));
-   else if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value));
+   if (layerP->lights.header.channelsPerLight == 4 && layerP->lights.header.offsetWhite != UINT8_MAX) {
+     setLight(indexV, &value, 3, sizeof(value));  // Internal RGBW format: white always at position 3
+   } else if (layerP->lights.header.offsetWhite != UINT8_MAX) {
+     setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value));
+   }
  }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6746a3 and 117088b.

📒 Files selected for processing (4)
  • src/MoonBase/Nodes.cpp
  • src/MoonBase/Nodes.h
  • src/MoonLight/Layers/VirtualLayer.h
  • src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h
🧰 Additional context used
🧬 Code graph analysis (1)
src/MoonLight/Layers/VirtualLayer.h (1)
src/MoonLight/Layers/VirtualLayer.cpp (2)
  • setLight (126-162)
  • setLight (126-126)
🔇 Additional comments (6)
src/MoonBase/Nodes.cpp (2)

356-356: LGTM!

The WRGB control value is added in the correct position matching the enum order in Nodes.h.


462-468: LGTM!

The WRGB preset correctly configures the 4-channel layout with white at position 0, matching WS2814 LED strip specifications.

src/MoonBase/Nodes.h (1)

30-30: LGTM!

The lightPreset_WRGB enum value is correctly positioned after lightPreset_GRBW, maintaining backward compatibility with existing preset indices.

src/MoonLight/Layers/VirtualLayer.h (1)

100-111: LGTM!

The removal of the offsetWhite == offsetRGB + 3 constraint is correct. This allows WRGB (where white is at offset 0) to properly trigger the 4-channel RGBW path. The internal rgbw array maintains standard RGBW order, with reordering to physical layout handled downstream by reOrderAndDimRGBW.

src/MoonLight/Nodes/Drivers/D_ParallelLEDDriver.h (2)

133-134: LGTM!

The update path mirrors the initialization path, consistently passing offsetWhite to updateDriver() for runtime preset changes.


120-121: LGTM, pending external dependency verification.

The initialization and update paths consistently log and pass offsetWhite to both initled() and updateDriver() methods, enabling white channel offset mapping. However, the method signatures for I2SClocklessLedDriver::initled() and updateDriver() cannot be verified as this is an external dependency not present in the repository. Confirm with the I2SClocklessLedDriver library that both methods accept the offsetWhite parameter in their current signatures.

void setWhite(const uint16_t indexV, const uint8_t value) {
if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value));
if (layerP->lights.header.offsetWhite == 0 && layerP->lights.header.channelsPerLight == 4) setLight(indexV, &value, 3, sizeof(value));
else if (layerP->lights.header.offsetWhite != UINT8_MAX) setLight(indexV, &value, layerP->lights.header.offsetWhite, sizeof(value));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this can be combined into :

If offsetWhite != UINT8_MAX {
If (channelsPerLight is 4) assign to position 3; // for rgbw lights
Else assign to offsetWhite position; // for moving heads

}


void setRGB(const uint16_t indexV, CRGB color) {
if (layerP->lights.header.offsetWhite != UINT8_MAX && layerP->lights.header.offsetWhite == layerP->lights.header.offsetRGB + 3) { // W set and after RGB
if (layerP->lights.header.offsetWhite != UINT8_MAX) { // W set
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should add && channelsPerLight == 4 here to avoid problems with moving heads

@ewowi
Copy link
Collaborator

ewowi commented Dec 31, 2025

the complicating matter here is that the channels array always stores RGB(W) in the order of RGB(W), not GRB(W) etc, even if the lights are GRB(W) etc. In the reOrderAndDimRGBW() this is set right for the specific LED type.

There is a 'revolutionary' idea to store the color order already in the channels array during setRGB. This simplifies a number of things, like the checks I proposed above (if channels per light == 4) are not needed. But for now this is the best compromise

@limpkin
Copy link
Author

limpkin commented Dec 31, 2025

@ewowi PR updated :)

@ewowi ewowi merged commit 48bc65e into MoonModules:main Dec 31, 2025
1 check passed
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