Skip to content
10 changes: 10 additions & 0 deletions wled00/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,16 @@ void handleIO()
{
handleButton();

// If in realtime mode and presets are explicitly allowed to override (e.g., via buttons),
// we process them here to avoid messing with the main loop.
if (realtimeMode && !realtimeOverride && !(realtimeMode && useMainSegmentOnly) && realtimeAllowPresets) {
handlePresets();
if (!presetNeedsSaving()) {
handlePlaylist();
}
handlePresets();
}
Comment on lines +368 to +376
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect main loop ordering/guards for handlePresets, handlePlaylist, presetNeedsSaving
rg -nP --type=cpp -C4 '\bhandlePresets\s*\(\)|\bhandlePlaylist\s*\(\)|\bpresetNeedsSaving\s*\(\)' wled00/wled.cpp

# Show handlePresets implementation to assess idempotency / queued-preset behavior
ast-grep --pattern 'void handlePresets() {
  $$$
}'

# Show handlePlaylist implementation (does it queue via applyPreset?)
ast-grep --pattern 'void handlePlaylist() {
  $$$
}'

Repository: wled/WLED

Length of output: 900


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Inspect the exact button.cpp block around the reported lines
echo "---- button.cpp context (lines ~340-410) ----"
nl -ba wled00/button.cpp | sed -n '340,410p'

# 2) Find definitions/signatures for handlePresets/handlePlaylist
echo "---- locate handlePresets definition ----"
rg -n --type=cpp '\bhandlePresets\s*\(' wled00 -g'*.cpp'

echo "---- locate handlePlaylist definition ----"
rg -n --type=cpp '\bhandlePlaylist\s*\(' wled00 -g'*.cpp'

# 3) Show main loop and bootPreset block rationale in wled.cpp
echo "---- wled.cpp context around first preset/playlist section ----"
nl -ba wled00/wled.cpp | sed -n '80,170p'

echo "---- wled.cpp context around presetNeedsSaving / handlePlaylist / handlePresets ----"
nl -ba wled00/wled.cpp | sed -n '360,440p'

echo "---- wled.cpp context around bootPreset > 0 block ----"
nl -ba wled00/wled.cpp | sed -n '470,530p'

# 4) Print handlePresets/handlePlaylist implementations once located
#    (Use the first definition found per function to keep output bounded.)
HP_LINE=$(rg -n --type=cpp -m1 '\bhandlePresets\s*\(' wled00 -g'*.cpp' | cut -d: -f1)
HP_FILE=$(rg -n --type=cpp -m1 '\bhandlePresets\s*\(' wled00 -g'*.cpp' | cut -d: -f1 --output-separator='' | true)
# Can't reliably extract file via cut above because ripgrep output includes "file:line:..."
# Re-run with stable parsing:
HP_MATCH=$(rg -n --type=cpp -m1 '\bhandlePresets\s*\(' wled00 -g'*.cpp')
HP_FILE=$(echo "$HP_MATCH" | cut -d: -f1)
HP_LINE=$(echo "$HP_MATCH" | cut -d: -f2)

HL_MATCH=$(rg -n --type=cpp -m1 '\bhandlePlaylist\s*\(' wled00 -g'*.cpp')
HL_FILE=$(echo "$HL_MATCH" | cut -d: -f1)
HL_LINE=$(echo "$HL_MATCH" | cut -d: -f2)

echo "---- handlePresets implementation snapshot: ${HP_FILE}:${HP_LINE} ----"
nl -ba "$HP_FILE" | sed -n "$((HP_LINE-20)),$((HP_LINE+60))p"

echo "---- handlePlaylist implementation snapshot: ${HL_FILE}:${HL_LINE} ----"
nl -ba "$HL_FILE" | sed -n "$((HL_LINE-20)),$((HL_LINE+60))p"

Repository: wled/WLED

Length of output: 160


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- button.cpp context (lines ~350-390) ----"
cat -n wled00/button.cpp | sed -n '350,390p'

echo "---- locate handlePresets definition ----"
rg -n --type=cpp '\bhandlePresets\s*\(' wled00 -g'*.cpp'

echo "---- locate handlePlaylist definition ----"
rg -n --type=cpp '\bhandlePlaylist\s*\(' wled00 -g'*.cpp'

echo "---- wled.cpp context around presetNeedsSaving / handlePlaylist / handlePresets ----"
cat -n wled00/wled.cpp | sed -n '80,160p'

echo "---- wled.cpp context around bootPreset > 0 block ----"
cat -n wled00/wled.cpp | sed -n '480,535p'

Repository: wled/WLED

Length of output: 8145


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- presets.cpp: handlePresets() implementation (around line ~145) ----"
cat -n wled00/presets.cpp | sed -n '110,240p'

echo "---- playlist.cpp: handlePlaylist() implementation (around line ~151) ----"
cat -n wled00/playlist.cpp | sed -n '120,240p'

echo "---- locate presetNeedsSaving() definition ----"
rg -n --type=cpp '\bpresetNeedsSaving\s*\(' wled00/presets.cpp wled00/*.cpp

echo "---- print region around presetNeedsSaving() definition (if found) ----"
PRESET_NEEDS_LINE=$(rg -n --type=cpp 'presetNeedsSaving\s*\(' wled00/presets.cpp | head -n1 | cut -d: -f2 || true)
PRESET_NEEDS_FILE=$(rg -n --type=cpp 'presetNeedsSaving\s*\(' wled00/presets.cpp | head -n1 | cut -d: -f1 || true)
if [[ -n "${PRESET_NEEDS_LINE:-}" && -n "${PRESET_NEEDS_FILE:-}" ]]; then
  cat -n "$PRESET_NEEDS_FILE" | sed -n "$((PRESET_NEEDS_LINE-30)),$((PRESET_NEEDS_LINE+60))p"
else
  echo "presetNeedsSaving() definition not found in presets.cpp (showing call sites only)."
fi

Repository: wled/WLED

Length of output: 10629


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- presets.cpp: presetNeedsSaving() definition (top of file) ----"
cat -n wled00/presets.cpp | sed -n '1,120p'

echo "---- presets.cpp: call sites where presetNeedsSaving() gates behavior ----"
rg -n --type=cpp '\bpresetNeedsSaving\s*\(' wled00 -g'*.cpp' -g'*.h'

Repository: wled/WLED

Length of output: 4701


Clarify the intent of the double handlePresets() call in realtime button override

  • handlePlaylist() does not apply the next preset directly; it queues one by setting presetToApply via applyPresetFromPlaylist(...), so the second handlePresets() is required to actually apply that queued preset.
  • Update the comment in wled00/button.cpp (368-376) to describe the sequencing (“apply queued preset → optionally advance playlist/queue next preset → apply again”), matching the same handlePresets(); handlePlaylist(); handlePresets(); pattern used for bootPreset > 0 in wled00/wled.cpp.
  • Confirm this presets-first ordering in realtime mode is intentionally different from the normal main loop (handlePlaylist() then handlePresets()), so playlist advancement can’t override the button preset when realtime override is enabled.
🤖 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/button.cpp` around lines 368 - 376, The current comment near the
realtime button override branch is unclear about why handlePresets() is called
twice; update the comment to state that we first apply any queued preset
(handlePresets()), then advance/queue the next preset via handlePlaylist() which
sets presetToApply through applyPresetFromPlaylist(...), and finally call
handlePresets() again to actually apply that newly queued preset — mirroring the
handlePresets(); handlePlaylist(); handlePresets(); pattern used for bootPreset
in wled00/wled.cpp; also explicitly note that this presets-first ordering in
realtime mode (when realtimeMode && !realtimeOverride && !useMainSegmentOnly &&
realtimeAllowPresets) is intentional and differs from the main loop order so
playlist advancement cannot override a button-requested preset.


// if we want to control on-board LED (ESP8266) or relay we have to do it here as the final show() may not happen until
// next loop() cycle
handleOnOff();
Expand Down
2 changes: 2 additions & 0 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(receiveDirect, if_live["en"]); // UDP/Hyperion realtime
CJSON(useMainSegmentOnly, if_live[F("mso")]);
CJSON(realtimeRespectLedMaps, if_live[F("rlm")]);
CJSON(realtimeAllowPresets, if_live[F("rop")]);
CJSON(e131Port, if_live["port"]); // 5568
if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation
CJSON(e131Multicast, if_live[F("mc")]);
Expand Down Expand Up @@ -1126,6 +1127,7 @@ void serializeConfig(JsonObject root) {
if_live["en"] = receiveDirect; // UDP/Hyperion realtime
if_live[F("mso")] = useMainSegmentOnly;
if_live[F("rlm")] = realtimeRespectLedMaps;
if_live[F("rop")] = realtimeAllowPresets;
if_live["port"] = e131Port;
if_live[F("mc")] = e131Multicast;

Expand Down
3 changes: 2 additions & 1 deletion wled00/data/settings_sync.htm
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ <h3>Instance List</h3>
<h3>Realtime</h3>
Receive UDP realtime: <input type="checkbox" name="RD"><br>
Use main segment only: <input type="checkbox" name="MO"><br>
Respect LED Maps: <input type="checkbox" name="RLM"><br><br>
Respect LED Maps: <input type="checkbox" name="RLM"><br>
Immediately force presets switching during realtime mode: <input type="checkbox" name="ROP"><br><br>
<h4>Network DMX input</h4><br>
Type:
<select name=DI onchange="SP(); adj();">
Expand Down
1 change: 1 addition & 0 deletions wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
receiveDirect = request->hasArg(F("RD")); // UDP realtime
useMainSegmentOnly = request->hasArg(F("MO"));
realtimeRespectLedMaps = request->hasArg(F("RLM"));
realtimeAllowPresets = request->hasArg(F("ROP"));
e131SkipOutOfSequence = request->hasArg(F("ES"));
e131Multicast = request->hasArg(F("EM"));
t = request->arg(F("EP")).toInt();
Expand Down
1 change: 1 addition & 0 deletions wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ WLED_GLOBAL uint8_t tpmPacketCount _INIT(0);
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
WLED_GLOBAL bool useMainSegmentOnly _INIT(false);
WLED_GLOBAL bool realtimeRespectLedMaps _INIT(true); // Respect LED maps when receiving realtime data
WLED_GLOBAL bool realtimeAllowPresets _INIT(false); // Allow presets/buttons to override realtime mode

WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0);
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT);
Expand Down
1 change: 1 addition & 0 deletions wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ void getSettingsJS(byte subPage, Print& settingsScript)
printSetFormCheckbox(settingsScript,PSTR("RD"),receiveDirect);
printSetFormCheckbox(settingsScript,PSTR("MO"),useMainSegmentOnly);
printSetFormCheckbox(settingsScript,PSTR("RLM"),realtimeRespectLedMaps);
printSetFormCheckbox(settingsScript,PSTR("ROP"),realtimeAllowPresets);
printSetFormValue(settingsScript,PSTR("EP"),e131Port);
printSetFormCheckbox(settingsScript,PSTR("ES"),e131SkipOutOfSequence);
printSetFormCheckbox(settingsScript,PSTR("EM"),e131Multicast);
Expand Down