Skip to content

improve bootup behaviour for boot presets#5686

Open
DedeHai wants to merge 3 commits into
wled:mainfrom
DedeHai:improve_bootup_colors
Open

improve bootup behaviour for boot presets#5686
DedeHai wants to merge 3 commits into
wled:mainfrom
DedeHai:improve_bootup_colors

Conversation

@DedeHai

@DedeHai DedeHai commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

changes made:

  • full refactor of the bootup behaviour regarding "bootup preset" and "turn on at boot" here is how it works now:

    • if turn on at boot is set, LEDs turn on unconditionally to the set default brightness
    • if no prest is applied, it still fades from black at the set default transition time instead of instantly turning on (same as it was in 0.14)
    • if a preset is applied it fades to that preset on all segments, starting off black
    • if any transition mode other than fade is set, LEDs start off at "default brightness" instead of fading from black (not acutally sure why on "fade" transition it starts off black but it works)
  • Segments created by a bootup presets no longer use the DEFAULT_COLOR but start out black: segments created within the first 5s after bootup default to black

  • DEFAULT_COLOR used for new segments is now the same as the bootup color (AA which is 170 changed to A0 which is 160)

TLDR;
no matter if "turn on at boot" is now set or not, boot up presets are applied correctly. If "turn on at boot" is set, LEDs always turn on.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Startup now prevents the first fade-in from starting at the default orange, bringing LEDs up from black.
  • Bug Fixes
    • Improved boot LED state setup, brightness initialization, and boot preset handling, including cases without a relay pin.
  • UI/UX
    • Renamed the “Power up” bootup brightness field label to “Bootup brightness”.
  • Style
    • Updated the default warm orange shade and adjusted initial stored primary color state to start from black.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

DEFAULT_COLOR hex value is corrected from 0xFFAA00 to 0xFFA000. colPri[] global initializer is zeroed. The Segment constructor gains a boot-time guard that forces colors[0] to BLACK while millis() is below a 5-second threshold. beginStrip() startup sequencing is restructured around relay presence and bootPreset. A UI label is renamed.

Changes

Boot-up LED color initialization

Layer / File(s) Summary
Color constants and initial global state
wled00/FX.h, wled00/wled.h
DEFAULT_COLOR updated to 0xFFA000; colPri[] global initializer changed from orange-like values to all zeros; Segment colors initializer gains a descriptive comment.
Segment constructor boot-time black enforcement
wled00/FX.h
Constructor computes bootTimeDelay (5000ms + optional WLED_BOOTUPDELAY) and forces colors[0] to BLACK while millis() is below that threshold, preventing fade-in from the default orange during early boot.
beginStrip() startup sequencing and UI label
wled00/wled.cpp, wled00/data/settings_leds.htm
strip.show() is called early when no relay pin is present; brightness initialization starts from zero then sets to briS when turnOnAtBoot is true; bootPreset > 0 handling is isolated into its own branch that applies the preset then forces active segments to BLACK; transitionDelayDefault restoration is now conditional on bootPreset == 0. Settings label for bootup brightness field renamed from "with brightness" to "Bootup brightness".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • wled/WLED#4827: Modifies the same startup initialization logic with overlapping colPri clearing and boot preset handling in wled00/wled.cpp and wled00/wled.h.
  • wled/WLED#5315: Modifies the same WLED::beginStrip() function with relay-presence–gated startup initialization logic, directly overlapping the refactored code path.

Suggested labels

enhancement, keep

Suggested reviewers

  • softhack007
  • willmmiles
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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 focus of the PR: improving bootup behavior specifically for boot presets, which is the central objective across all file changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

coderabbitai[bot]

This comment was marked as outdated.

@DedeHai

DedeHai commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai please check for any edge cases that may have a changed behaviour and come up with a test plan to verify this PR works as intended.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the PR diff
gh pr diff 5686 --repo wled/WLED

echo "===== wled.cpp segment ====="
gh api repos/wled/WLED/contents/wled00/wled.cpp?ref=refs/pull/5686/head --jq '.content' | base64 -d | grep -n "bootPreset\|turnOnAtBoot\|briS\|colPri\|transitionDelay\|beginStrip\|BLACK\|DEFAULT_COLOR\|bootTime\|CALL_MODE_INIT" -A2 -B2

echo "===== FX.h segment ====="
gh api repos/wled/WLED/contents/wled00/FX.h?ref=refs/pull/5686/head --jq '.content' | base64 -d | grep -n "DEFAULT_COLOR\|bootTime\|bootupDelay\|colors\[0\]\|BLACK\|WLED_BOOTUPDELAY" -A5 -B2

echo "===== wled.h colPri ====="
gh api repos/wled/WLED/contents/wled00/wled.h?ref=refs/pull/5686/head --jq '.content' | base64 -d | grep -n "colPri\|colSec" -A2 -B2

Length of output: 11599


🏁 Script executed:

#!/bin/bash
# Get full beginStrip function from PR branch
gh api repos/wled/WLED/contents/wled00/wled.cpp?ref=refs/pull/5686/head --jq '.content' | base64 -d | grep -n "beginStrip\|void WLED::begin" -A 80 | head -120

echo "=====FX.h Segment constructor====="
gh api repos/wled/WLED/contents/wled00/FX.h?ref=refs/pull/5686/head --jq '.content' | base64 -d | grep -n "Segment()\|Segment ::\|bootTime\|bootupDelay\|colors\[0\]" -A 10 -B 5 | head -80

Length of output: 9859



@DedeHai Here's a thorough edge-case analysis and test plan for this PR.


Edge Case Analysis

EC-1: turnOnAtBoot = true + bootPreset > 0 (New Combined Path)

Changed behavior: Previously these were separate branches. Now both execute sequentially: bri = briS, colPri set to orange, then immediately overwritten to {0,0,0,0} before applyPreset(). The net result is bri > 0 with the preset colors—which is the intended behavior—but the intermediate orange colPri is wasted work. More importantly, confirm the preset's own brightness (if any) wins over briS.

EC-2: turnOnAtBoot = false + bootPreset > 0

Changed behavior: bri stays 0. applyPreset() is called but whether LEDs turn on depends on whether applyPreset sets bri. If the preset doesn't embed a brightness value, LEDs remain off. Then handlePresets() in setup() re-applies the preset—double application may replay side-effects (playlists, random seeds, etc.).

EC-3: Transition not restored when bootPreset > 0

strip.setTransition(transitionDelayDefault) is now inside the else branch, so it is never called when a boot preset is set. colorUpdated(CALL_MODE_INIT) therefore runs with transition = 0. If a fade-in from black is desired for the boot preset path, the transitionDelayDefault needs to be restored before colorUpdated or the fade must come from handlePresets() in setup().

EC-4: briLast No Longer Set in beginStrip()

Old code: briLast = briS; bri = 0;. New code: briLast is never assigned in beginStrip(). The first power-toggle (button/API) will restore to whatever briLast was deserialized from config, which may be 0, causing "turn on" to appear broken.

EC-5: strip.fill(BLACK) Removed

Old code explicitly filled the strip with BLACK when turnOnAtBoot = false. New code relies on bri = 0 to keep LEDs visually dark. On hardware where setBrightness(0) isn't perfectly zero (PWM floor, etc.) or where a relay isn't used and stale frame buffer data exists, pixels might briefly flicker.

EC-6: strip.show() Called Before turnOnAtBoot Check (Relay Absent)

strip.show() at bri = 0 is now always called when rlyPin < 0, regardless of turnOnAtBoot. Previously it was only inside the turnOnAtBoot = false branch. This means on turnOnAtBoot = true + no relay, the strip is shown at bri = 0 first and then turned on. This is correct behavior but adds one redundant show call.

EC-7: 5-Second Boot Window Affects User-Created Segments

Any segment created within 5000ms + WLED_BOOTUPDELAY starts with colors[0] = BLACK. If a user reacts quickly and adds a segment via the UI within 5 seconds of boot, it silently starts black instead of the expected orange. With large WLED_BOOTUPDELAY values this window can extend significantly (e.g., 35 seconds with a 30s delay).

EC-8: Segment Copy Constructor Not Updated

The boot-time black logic is only in the default constructor body. The copy constructor (Segment(const Segment &orig)) and move constructor are not affected, so copied segments during transition setup retain the source's color, not black. This is probably fine but worth confirming that no boot-time segment copy occurs before beginStrip() completes.

EC-9: colors[1] / colors[2] Not Zeroed After Preset Application

After applyPreset(), the code forces colors[0] = BLACK for all active segments but leaves colors[1] and colors[2] as set by the preset. Effects using secondary/tertiary colors will not fade from black for those channels.

EC-10: First-Time Install (briS = 0)

bri = briS ? briS : 128 correctly handles this fallback. ✅

EC-11: Non-Fade Transition Mode

Per PR description, LEDs should start at default brightness immediately. Verify that when transitionDelayDefault > 0 but mode is not FADE, the segment shows the preset state directly without a black-to-color animation.

EC-12: Boot Preset Is a Playlist

handlePresets() in setup() calls handlePlaylist() after handlePresets(). Since applyPreset() is already called in beginStrip(), the playlist is started twice. Verify no duplicate timer registration or doubled first-entry playback.


Test Plan

Setup Matrix

Each test should be run with a fresh config (factory reset) and with a saved config unless noted.

# turnOnAtBoot bootPreset rlyPin transitionDelayDefault Notes
T-1 false 0 none 700ms (default) Baseline: all off at boot
T-2 true 0 none 700ms LEDs on at briS, fade from black
T-3 true 0 none 0 Instant on, no fade
T-4 false N (valid preset) none 700ms Preset applied, LEDs may be off
T-5 true N (valid preset) none 700ms LEDs on + preset fades in from black
T-6 true N (valid preset) none 0 Instant preset, no fade
T-7 true 0 configured 700ms Relay controls on/off, then fade
T-8 false N configured 700ms Relay stays off, preset applied silently
T-9 true N (playlist preset) none 700ms Playlist boot preset
T-10 true 0 none 700ms briS = 0 (first install fallback)

Test Cases

T-1: All Off at Boot

  1. Set turnOnAtBoot = false, bootPreset = 0.
  2. Power cycle.
  3. Expected: All LEDs remain off. No flicker on first frame.
  4. Check: bri = 0, no relay command issued, strip dark.

T-2: Turn-On Fade from Black

  1. Set turnOnAtBoot = true, bootPreset = 0, default orange color saved, transitionDelayDefault = 700ms.
  2. Power cycle.
  3. Expected: LEDs fade from black to briS brightness in orange over ~700ms.
  4. Check: No flash of orange before fade starts; brightness reaches briS exactly.

T-3: Instant Turn-On (No Fade)

  1. Set turnOnAtBoot = true, bootPreset = 0, transitionDelayDefault = 0.
  2. Power cycle.
  3. Expected: LEDs turn on instantly at briS, no fade transition.
  4. Check: No visible ramp-up from zero.

T-4: Boot Preset Only (LEDs Stay Off?)

  1. Set turnOnAtBoot = false, bootPreset = N (preset with explicit brightness embedded).
  2. Power cycle.
  3. Expected (verify): Does the preset turn on the LEDs if it has a bri field? Or do LEDs stay off because bri = 0?
  4. Check: bri value after boot; compare with and without brightness saved in the preset.

T-5: Turn-On + Boot Preset Fade

  1. Set turnOnAtBoot = true, bootPreset = N, transitionDelayDefault = 700ms.
  2. Power cycle.
  3. Expected: LEDs start black, fade to the preset's colors at briS brightness over 700ms.
  4. Check: No orange flash before fade; all segment channels (col0, col1, col2) fade correctly; briS is respected vs. preset brightness.

T-6: Turn-On + Boot Preset Instant (No Fade)

  1. Set turnOnAtBoot = true, bootPreset = N, transitionDelayDefault = 0.
  2. Power cycle.
  3. Expected: Preset applied immediately at briS with no fade.
  4. Check: Same as T-5 but instantaneous.

T-7: Relay + Turn-On + Boot Preset

  1. Configure relay pin, set turnOnAtBoot = true, bootPreset = N.
  2. Power cycle.
  3. Expected: Relay fires, LEDs turn on after relay delay, preset fades in.
  4. Check: strip.show() is NOT called before relay activates; no premature LED output.

T-8: Power Toggle After Boot (briLast regression)

  1. Any configuration.
  2. Power cycle, wait for boot to complete.
  3. Toggle LEDs off via button or API.
  4. Toggle LEDs back on.
  5. Expected: LEDs restore to the expected brightness (briS or preset brightness).
  6. Check: Confirm briLast holds the correct value—not 0—after boot.

T-9: Boot Playlist Preset

  1. Set bootPreset = N where N is a playlist preset.
  2. Power cycle.
  3. Expected: Playlist starts, advances entries correctly, no duplicate first-entry playback.
  4. Check: Playlist timing is correct; first entry isn't played twice.

T-10: First-Install (briS = 0)

  1. Factory reset (or manually set briS = 0 in config).
  2. Set turnOnAtBoot = true.
  3. Power cycle.
  4. Expected: LEDs turn on at brightness 128 (fallback).
  5. Check: Not dark; confirms bri = briS ? briS : 128 fallback works.

T-11: New Segment Within 5-Second Boot Window

  1. Power cycle, immediately (< 5 seconds) go to the segment editor and add a new segment.
  2. Expected: New segment starts black instead of orange.
  3. Check (UX regression): Does the user see unexpected black? Is this behavior acceptable? After 5 seconds, verify new segments correctly start in orange.

T-12: Multi-Segment Boot Preset

  1. Configure a preset that defines 3+ segments with different colors.
  2. Set bootPreset = N, turnOnAtBoot = true.
  3. Power cycle.
  4. Expected: All active segments fade from black to their respective preset colors. Inactive segments remain black/off.
  5. Check: colors[1] and colors[2] also transition correctly (not just colors[0]).

T-13: Non-Fade Transition Mode

  1. Set the transition mode to a non-fade type (e.g., Wipe), bootPreset = N, turnOnAtBoot = true.
  2. Power cycle.
  3. Expected: Per PR description, LEDs start at default brightness immediately without fading from black.
  4. Check: No black-to-color animation; LEDs snap to preset state.

T-14: WLED_BOOTUPDELAY Defined

  1. Compile with WLED_BOOTUPDELAY = 10000 (10s).
  2. Power cycle; wait 8 seconds, add a segment.
  3. Expected: Segment still starts black (within 15s window).
  4. Wait 16 seconds, add another segment.
  5. Expected: Segment starts in orange (outside window).

The most critical cases to verify first are EC-3 (transition not restored for boot preset path, affecting whether fade-in actually occurs), EC-4 (briLast not set, affecting power toggle), and EC-2 (whether bri stays 0 when turnOnAtBoot = false + bootPreset > 0 renders the preset invisible until handlePresets() in setup()).

@DedeHai

DedeHai commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator Author

I tested all the suggested cases and made some improvements. this is how it works now, copy from source code comment for reference:

  • if turnOnAtBoot is false, strip is set to black. It will fade in to startup brightness and orange when turned on
  • if a bootup preset is set, it will fade to that preset if it has on:true set (to default brightness) or to that preset's brightness if set
  • if turnOnAtBoot is true the LEDs will fade in to orange and default brightness
  • if a booup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
  • there is no way to have LEDs off at boot and upon turn-on have them immediatel jump to a target brightness but users can use a playlist to do that

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@wled00/wled.cpp`:
- Line 624: Fix the typo in the comment on line 624 where "booup" is misspelled.
Change "booup" to "bootup" in the comment that starts with "if a booup preset is
set" to correctly read "if a bootup preset is set".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ae61826-11cf-47e0-bd66-338208522b86

📥 Commits

Reviewing files that changed from the base of the PR and between 598e08c and 9b03b78.

📒 Files selected for processing (1)
  • wled00/wled.cpp

Comment thread wled00/wled.cpp
// if turnOnAtBoot is false, strip is set to black. It will fade in to startup brightness and orange when turned on
// if a bootup preset is set, it will fade to that preset if it has on:true set (to default brightness) or to that preset's brightness if set
// if turnOnAtBoot is true the LEDs will fade in to orange and default brightness
// if a booup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Typo: "booup" should be "bootup".

📝 Proposed fix
-  // if a booup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
+  // if a bootup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// if a booup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
// if a bootup preset is set, it will start at the default brightness except if "fade" transition is used, then it will still fade from black
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wled00/wled.cpp` at line 624, Fix the typo in the comment on line 624 where
"booup" is misspelled. Change "booup" to "bootup" in the comment that starts
with "if a booup preset is set" to correctly read "if a bootup preset is set".

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant