Aircoookie / WLED

Control WS2812B and many more types of digital RGB LEDs with an ESP8266 or ESP32 over WiFi!
https://kno.wled.ge
MIT License
14.2k stars 3.03k forks source link

savePreset saves the wrong parameters if color, mode etc are changed directly after it #4009

Closed KrX3D closed 4 weeks ago

KrX3D commented 1 month ago

What happened?

in version 0.13.X when i used savePreset and changed color, mode etc after it the preset was saved correctly. now from version 0.14 the saved preset is wrong, it saves the changed mode and color which was applied after the savePreset

To Reproduce Bug

working code in 0.13.3:

uint8_t autoSavePreset = 200;

savePreset(autoSavePreset, "Test");
strip.setColor(0, 0,255,0);
strip.setColor(1, 0,0,0);
strip.setColor(2, 0,0,0);

for (uint8_t i = 0; i < strip.getMaxSegments(); i++)
{
WS2812FX::Segment& seg = strip.getSegment(i);
if ((!seg.isActive() || !seg.isSelected())) continue;

strip.getSegment(i).speed = 128;
strip.getSegment(i).intensity = 128;
strip.getSegment(i).palette = 0;
strip.getSegment(i).mode = 1;
}

Not working 0.14.4:

uint8_t autoSavePreset = 200;

savePreset(autoSavePreset, "Test");

strip.setColor(0, 0,255,0);
strip.setColor(1, 0,0,0);
strip.setColor(2, 0,0,0);

for (uint8_t i = 0; i < strip.getMaxSegments(); i++)
{
Segment& seg = strip.getSegment(i);
if ((!seg.isActive() || !seg.isSelected())) continue;

seg.mode = 1; //Blinking
seg.speed = 128;
seg.intensity = 128;
seg.palette = 0;
}

Expected Behavior

save the current vales like in version 0.13.X

Install Method

Self-Compiled

What version of WLED?

WLED 0.14.4

Which microcontroller/board are you seeing the problem on?

ESP8266, ESP32, ESP32-S3, ESP32-S2, ESP32-C3

Relevant log/trace output

No response

Anything else?

No response

Code of Conduct

blazoncek commented 1 month ago

Unfortunately, saving presets is no longer happening synchronously by default. If you want to save preset immediately you need to include "o":true in your JSON.

KrX3D commented 1 month ago

hi, thanks for the info.

which json do you mean? i used usermod_v2_example.h to create the usermod

blazoncek commented 1 month ago

JSON that is used for saving preset. If you are saving current state you will need to wait until at least one loop cycle. Unfortunately, there is no API to know when actual saving is done.

If you need to save temporary state, use saveTemporaryPreset().

KrX3D commented 1 month ago

hmm i tried it out and i also changed

inline void saveTemporaryPreset() {savePreset(210);};

so that the preset will be shown but it also saves the wrong values.

blazoncek commented 1 month ago

I cannot help you with your modifications. Sorry.

What I am trying to convey is the fact that presets are no longer saved synchronously (i.e. when savePreset() is called). This is due to preset corruption that sometimes happened while LEDs were updating and flash was being written to.

When (and if) this changes (i.e. is fixed in ESP/Arduino core) savePreset() will be updated to save state synchronously again. But that is not 100% certain.

KrX3D commented 1 month ago

hmm ok.

maybe i could try a different way.

  1. do you know if there is a way to detect a changed state? so if color, fx , on/off is changed, so i could react to that and savePreset
  2. if not, how could i save all current state to one or more variables to apply tham later again?
blazoncek commented 1 month ago

Try stateChanged, but that does not mean that savePreset() was already applied. There is no way AFAIK to know when current state has been saved. You can try and develop API for that, post a PR when done.

KrX3D commented 4 weeks ago

since i could get it to work i just ported the savePreset function from preset.ccp from 13.3 to 14.4 and now it works again.

softhack007 commented 4 weeks ago

since i could get it to work i just ported the savePreset function from preset.ccp from 13.3 to 14.4 and now it works again.

@KrX3D if that works for you, it works for you.

Just a word of caution

That said, I think you could call 'handlePresets()' after you did 'savePreset()', at least if you are in the usermod loop() or setup() function.
handlePresets() is the "worker function" that's also called later in the main loop() when a preset is scheduled for reading or writing.

softhack007 commented 4 weeks ago

Closing, as the behaviour is as designed. savePreset() schedules the async creation of a preset. The "real writing" to presets.json happens a bit later, controlled by the main WLED loop.