Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThe PR refines preset initialization logic by exempting ChangesPreset Initialization and Boot Handling
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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/presets.cpp`:
- Around line 197-200: The guard currently lets any fdo["ps"] value through for
CALL_MODE_INIT (so string cycling specs like "1~5~" reach deserializeState);
restrict the CALL_MODE_INIT exception to numeric preset values by adding a type
check (e.g. fdo["ps"].is<int>() or appropriate numeric type) to the existing
condition (mirror the pattern used for CALL_MODE_BUTTON_PRESET which checks
fdo["ps"].is<const char *>()), so only numeric "ps" values are preserved for
deserializeState() and non-numeric strings are removed with fdo.remove("ps") to
avoid unintended playlist/cycling behavior.
🪄 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: 8125ad27-4651-45d0-adf2-70d57c1158bb
📒 Files selected for processing (2)
wled00/presets.cppwled00/wled.cpp
|
would a playlist not be able to do the same? |
Thanks for the feedback! Hence why I’m still in draft mode - I’m not ready to say this is review or merge ready just yet.
|
TODO: set up logic handling inside handlePresets() and anywhere else required to implement behavior that is described in comments here.
Add TODO comments for handling boot presets and playlists.
willmmiles
left a comment
There was a problem hiding this comment.
Re performance changes: I do expect that the latency of how long it takes the main loop to get around to applying the boot preset will be highly dependent on environment and wifi setup. In fact, one down side of the proposed new approach is that it may lead to more devices showing visible stutters and hiccups during the connection sequence, as the light "starts up" earlier. There's undoubtedly room for improvement there -- I suspect some of the execution order details in the current code are workarounds for issues with older platforms that may not still apply. I don't think we should spend too much time worrying about this (either way) at the moment.
Re ps vs playlists: there's a very real sense in which the functionality of "ps" and "playlist" overlap: "ps" could (almost) be implemented as a single-entry "playlist" with 0 delay. In this context, both approaches require extra work at setup() time -- but realistically we probably should handle both, if only so that we don't have to document a bunch of special cases.
In practice I think this works out to something like:
if (bootPreset > 0) {
handlePreset(); // execute boot preset
handlePlaylist(); // if boot preset set a playlist, process it
handlePreset(); // if either of the above set a preset for deferred execution, execute it now
}| if (needsCfgSave) serializeConfigToFS(); // usermods required new parameters; need to wait for strip to be initialised #4752 | ||
|
|
||
| if (bootPreset > 0) { | ||
| if (!presetNeedsSaving()) { |
There was a problem hiding this comment.
How could this be true during setup()?
| if (bootPreset > 0) { | ||
| if (!presetNeedsSaving()) { | ||
| handlePlaylist(); // handle boot playlist at setup | ||
| yield(); |
There was a problem hiding this comment.
Why do we need to yield() from setup()? That seems quite strange to me -- we haven't even turned the network on yet at this point.
|
|
||
| if (bootPreset > 0) { | ||
| if (!presetNeedsSaving()) { | ||
| handlePlaylist(); // handle boot playlist at setup |
There was a problem hiding this comment.
This will never execute because the boot preset hasn't been parsed yet, and thus no playlist can be in flight.
TODO:
The primary goal for this PR is to improve reliability of boot preset handling when realtime input (DDP/E1.31/etc.) becomes active very early during startup (see discussion from #5569).
Problem
Previously, boot preset application depended on the normal loop path.
handlePresets()in the main loop is gated behind realtime mode checks:if (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly))If realtime mode became active before the first normal preset processing pass, the boot preset could be skipped or only partially applied. This was especially problematic for boot presets intended to set
LiveDataOverride(lor).Solution
This PR adds an additional
handlePresets()call duringsetup(). The new startup-time call is intentionally placed:UsermodManager::setup()serializeConfigToFS())This placement avoids calling usermod JSON handlers before setup while ensuring the boot preset is processed deterministically during startup.
Additional Improvements
- the boot preset is allowed a single chained
"ps"preset load duringCALL_MODE_INIT.Normally
"ps"is stripped from preset JSON to prevent recursive preset execution. This PR preserves that protection for all normal runtime preset loads. During boot initialization only, one"ps"handoff is allowed. The chained preset executes underCALL_MODE_NO_NOTIFY, so further chaining remains blocked by the existing recursion protection.Example:
{ "lor": 2, "ps": 250 }One practical use case is the
autosaveusermod:lorlor:2at boot before restoring the autosaved stateOther usermods may benefit from similar boot-time state injection before loading a normal runtime preset.
- Measurably faster light activation after power on.
As a side effect of the improved boot preset behavior, for boot presets that set
"on": true, there is a measurably faster light activation after power-on. This is especially useful for users who power their controllers from a physical wall switch and expect lights to turn on immediately when power is restored.In local testing: