From b141ec7ea704516c0458670e9acd01b82e62cf36 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 13 Nov 2022 12:13:49 +0100 Subject: [PATCH] Fix for #2880 (stateChanged on segment on/off) Added comments. Added X1, X2, X3, M1, M2, M3 segment options to HTTP API. Added "on" handling with "ps". --- wled00/FX_fcn.cpp | 21 +++++++++++---------- wled00/colors.cpp | 3 +++ wled00/const.h | 14 +++++++------- wled00/json.cpp | 6 +++--- wled00/set.cpp | 39 +++++++++++++++++++++++++++------------ wled00/wled.h | 2 +- 6 files changed, 52 insertions(+), 33 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 218362528..908bf00b6 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -326,11 +326,7 @@ uint8_t Segment::currentBri(uint8_t briNew, bool useCct) { } uint8_t Segment::currentMode(uint8_t newMode) { - if (transitional && _t) { - return _t->_modeP; - } else { - return newMode; - } + return (progress()>32767U) ? newMode : _t->_modeP; // change effect in the middle of transition } uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) { @@ -369,6 +365,7 @@ bool Segment::setColor(uint8_t slot, uint32_t c) { //returns true if changed if (slot >= NUM_COLORS || c == colors[slot]) return false; if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change colors[slot] = c; + stateChanged = true; // send UDP/WS broadcast return true; } @@ -381,12 +378,14 @@ void Segment::setCCT(uint16_t k) { if (cct == k) return; if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change cct = k; + stateChanged = true; // send UDP/WS broadcast } void Segment::setOpacity(uint8_t o) { if (opacity == o) return; if (fadeTransition) startTransition(strip.getTransition()); // start transition prior to change opacity = o; + stateChanged = true; // send UDP/WS broadcast } void Segment::setOption(uint8_t n, bool val) { @@ -394,6 +393,7 @@ void Segment::setOption(uint8_t n, bool val) { if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change if (val) options |= 0x01 << n; else options &= ~(0x01 << n); + if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET || n == SEG_OPTION_TRANSITIONAL)) stateChanged = true; // send UDP/WS broadcast } void Segment::setMode(uint8_t fx, bool loadDefaults) { @@ -425,6 +425,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { } } } + stateChanged = true; // send UDP/WS broadcast } } } @@ -436,6 +437,7 @@ void Segment::setPalette(uint8_t pal) { palette = pal; } } + stateChanged = true; // send UDP/WS broadcast } // 2D matrix @@ -671,11 +673,10 @@ uint8_t Segment::differs(Segment& b) const { if (startY != b.startY) d |= SEG_DIFFERS_BOUNDS; if (stopY != b.stopY) d |= SEG_DIFFERS_BOUNDS; - //bit pattern: msb first: [transposed mirrorY reverseY] transitional (tbd) paused needspixelstate mirrored on reverse selected - if ((options & 0b1111111110011110) != (b.options & 0b1111111110011110)) d |= SEG_DIFFERS_OPT; - if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL; - - for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; + //bit pattern: (msb first) sound:3, mapping:3, transposed, mirrorY, reverseY, [transitional, reset,] paused, mirrored, on, reverse, [selected] + if ((options & 0b1111111110011110U) != (b.options & 0b1111111110011110U)) d |= SEG_DIFFERS_OPT; + if ((options & 0x0001U) != (b.options & 0x0001U)) d |= SEG_DIFFERS_SEL; + for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; return d; } diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 0b8c7811e..0387a925a 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -344,6 +344,7 @@ uint8_t gamma8_cal(uint8_t b, float gamma) return (int)(powf((float)b / 255.0f, gamma) * 255.0f + 0.5f); } +// re-calculates & fills gamma table void calcGammaTable(float gamma) { for (uint16_t i = 0; i < 256; i++) { @@ -351,11 +352,13 @@ void calcGammaTable(float gamma) } } +// used for individual channel or brightness gamma correction uint8_t gamma8(uint8_t b) { return gammaT[b]; } +// used for color gamma correction uint32_t gamma32(uint32_t color) { if (!gammaCorrectCol) return color; diff --git a/wled00/const.h b/wled00/const.h index 6ffa0d5fd..c62cd21b4 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -251,13 +251,13 @@ #define SEG_OPTION_TRANSPOSED 9 //Segment differs return byte -#define SEG_DIFFERS_BRI 0x01 -#define SEG_DIFFERS_OPT 0x02 -#define SEG_DIFFERS_COL 0x04 -#define SEG_DIFFERS_FX 0x08 -#define SEG_DIFFERS_BOUNDS 0x10 -#define SEG_DIFFERS_GSO 0x20 -#define SEG_DIFFERS_SEL 0x80 +#define SEG_DIFFERS_BRI 0x01 // opacity +#define SEG_DIFFERS_OPT 0x02 // all segment options except: selected, reset & transitional +#define SEG_DIFFERS_COL 0x04 // colors +#define SEG_DIFFERS_FX 0x08 // effect/mode parameters +#define SEG_DIFFERS_BOUNDS 0x10 // segment start/stop ounds +#define SEG_DIFFERS_GSO 0x20 // grouping, spacing & offset +#define SEG_DIFFERS_SEL 0x80 // selected //Playlist option byte #define PL_OPTION_SHUFFLE 0x01 diff --git a/wled00/json.cpp b/wled00/json.cpp index f36433ad8..f7b87b8a5 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -244,9 +244,8 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) } strip.trigger(); } - // send UDP if not in preset and something changed that is not just selection - // send UDP if something changed that is not just selection or segment power/opacity - if ((seg.differs(prev) & 0x7E) && seg.on == prev.on) stateChanged = true; + // send UDP/WS if segment options changed (except selection; will also deselect current preset) + if (seg.differs(prev) & 0x7F) stateChanged = true; } // deserializes WLED state (fileDoc points to doc object if called from web server) @@ -403,6 +402,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) root.remove("v"); // may be added in UI call root.remove("time"); // may be added in UI call root.remove("ps"); + root.remove("on"); // some exetrnal calls add "on" to "ps" call if (root.size() == 0) { unloadPlaylist(); // we need to unload playlist applyPreset(ps, callMode); // async load (only preset ID was specified) diff --git a/wled00/set.cpp b/wled00/set.cpp index 78c27cd95..8caad36ca 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -697,13 +697,18 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) byte speedIn = selseg.speed; byte intensityIn = selseg.intensity; byte paletteIn = selseg.palette; - - uint16_t startI = selseg.start; - uint16_t stopI = selseg.stop; - uint16_t startY = selseg.startY; - uint16_t stopY = selseg.stopY; - uint8_t grpI = selseg.grouping; - uint16_t spcI = selseg.spacing; + byte custom1In = selseg.custom1; + byte custom2In = selseg.custom2; + byte custom3In = selseg.custom3; + byte check1In = selseg.check1; + byte check2In = selseg.check2; + byte check3In = selseg.check3; + uint16_t startI = selseg.start; + uint16_t stopI = selseg.stop; + uint16_t startY = selseg.startY; + uint16_t stopY = selseg.stopY; + uint8_t grpI = selseg.grouping; + uint16_t spcI = selseg.spacing; pos = req.indexOf(F("&S=")); //segment start if (pos > 0) { startI = getNumVal(&req, pos); @@ -838,7 +843,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str()); uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]); selseg.setColor(2, col2); // defined above (SS= or main) - stateChanged = true; if (!singleSegment) strip.setColor(2, col2); // will set color to all active & selected segments } @@ -864,20 +868,19 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) // apply colors to selected segment, and all selected segments if applicable if (col0Changed) { - stateChanged = true; uint32_t colIn0 = RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]); selseg.setColor(0, colIn0); if (!singleSegment) strip.setColor(0, colIn0); // will set color to all active & selected segments } if (col1Changed) { - stateChanged = true; uint32_t colIn1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]); selseg.setColor(1, colIn1); if (!singleSegment) strip.setColor(1, colIn1); // will set color to all active & selected segments } bool fxModeChanged = false, speedChanged = false, intensityChanged = false, paletteChanged = false; + bool custom1Changed = false, custom2Changed = false, custom3Changed = false, check1Changed = false, check2Changed = false, check3Changed = false; // set effect parameters if (updateVal(req.c_str(), "FX=", &effectIn, 0, strip.getModeCount()-1)) { if (request != nullptr) unloadPlaylist(); // unload playlist if changing FX using web request @@ -886,8 +889,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) speedChanged = updateVal(req.c_str(), "SX=", &speedIn); intensityChanged = updateVal(req.c_str(), "IX=", &intensityIn); paletteChanged = updateVal(req.c_str(), "FP=", &paletteIn, 0, strip.getPaletteCount()-1); - - stateChanged |= (fxModeChanged || speedChanged || intensityChanged || paletteChanged); + custom1Changed = updateVal(req.c_str(), "X1=", &custom1In); + custom2Changed = updateVal(req.c_str(), "X2=", &custom2In); + custom3Changed = updateVal(req.c_str(), "X3=", &custom3In); + check1Changed = updateVal(req.c_str(), "M1=", &check1In); + check2Changed = updateVal(req.c_str(), "M2=", &check2In); + check3Changed = updateVal(req.c_str(), "M3=", &check3In); + + stateChanged |= (fxModeChanged || speedChanged || intensityChanged || paletteChanged || custom1Changed || custom2Changed || custom3Changed || check1Changed || check2Changed || check3Changed); // apply to main and all selected segments to prevent #1618. for (uint8_t i = 0; i < strip.getSegmentsNum(); i++) { @@ -897,6 +906,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) if (speedChanged) seg.speed = speedIn; if (intensityChanged) seg.intensity = intensityIn; if (paletteChanged) seg.setPalette(paletteIn); + if (custom1Changed) seg.custom1 = custom1In; + if (custom2Changed) seg.custom2 = custom2In; + if (custom3Changed) seg.custom3 = custom3In; + if (check1Changed) seg.check1 = (bool)check1In; + if (check2Changed) seg.check2 = (bool)check2In; + if (check3Changed) seg.check3 = (bool)check3In; } //set advanced overlay diff --git a/wled00/wled.h b/wled00/wled.h index ab7f51342..281b47aa2 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2211111 +#define VERSION 2211130 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG