Merge branch 'master' into merge-master
This commit is contained in:
commit
8af445e72b
@ -2,6 +2,11 @@
|
||||
|
||||
### Builds after release 0.12.0
|
||||
|
||||
#### Build 2202210
|
||||
|
||||
- Fixed HTTP API commands not applying to all selected segments if called from JSON
|
||||
- Improved Stream effects, no longer rely on LED state and won't fade out at low brightness
|
||||
|
||||
#### Build 2202200
|
||||
|
||||
- Added `info.leds.seglc` per-segment light capability info (PR #2552)
|
||||
|
27
readme.md
27
readme.md
@ -53,39 +53,18 @@ See the [documentation on our official site](https://kno.wled.ge)!
|
||||
|
||||
[On this page](https://kno.wled.ge/basics/tutorials/) you can find excellent tutorials made by the community and helpful tools to help you get your new lamp up and running!
|
||||
|
||||
## 🖼️ Images
|
||||
## 🖼️ User interface
|
||||
<img src="/images/macbook-pro-space-gray-on-the-wooden-table.jpg" width="50%"><img src="/images/walking-with-iphone-x.jpg" width="50%">
|
||||
|
||||
## 💾 Compatible LED Strips
|
||||
Type | Voltage | Comments
|
||||
|---|---|---|
|
||||
WS2812B | 5v |
|
||||
WS2813 | 5v |
|
||||
SK6812 | 5v | RGBW
|
||||
APA102 | 5v | C/D
|
||||
WS2801 | 5v | C/D
|
||||
LPD8806 | 5v | C/D
|
||||
TM1814 | 12v | RGBW
|
||||
WS2811 | 12v | 3-LED segments
|
||||
WS2815 | 12v |
|
||||
GS8208 | 12v |
|
||||
Analog/non-addressable | any | Requires additional circuitry
|
||||
|
||||
## 🧊 Compatible PC RGB Fans and ARGB accessories
|
||||
Brand | Model | Comments
|
||||
|---|---|---|
|
||||
Corsair | HD120 Fan | Uses WS2812B, data-in only
|
||||
PCCOOLER | Moonlight 5-pack Fans | Uses WS2812B, includes Data-out connector to keep each fan uniquely addressable if wired in series like traditional LED strips
|
||||
Any | 5v 3-pin ARGB for PC | Any PC RGB device that supports the 5v 3-pin ARGB motherboard header should work fine with WLED. All the major motherboard vendors support the Corsair HD120 and PCCOOLER fans listed, so we can safely assume any device that supports motherboard ARGB 5V 3-Pin standard will work with WLED.
|
||||
## 💾 Compatible hardware
|
||||
|
||||
See [here](https://kno.wled.ge/basics/compatible-hardware)!
|
||||
|
||||
## ✌️ Other
|
||||
|
||||
Licensed under the MIT license
|
||||
Credits [here](https://kno.wled.ge/about/contributors/)!
|
||||
|
||||
Uses Linearicons by Perxis!
|
||||
|
||||
Join the Discord server to discuss everything about WLED!
|
||||
|
||||
<a href="https://discord.gg/KuqP7NE"><img src="https://discordapp.com/api/guilds/473448917040758787/widget.png?style=banner2" width="25%"></a>
|
||||
|
@ -494,7 +494,7 @@ public:
|
||||
#endif
|
||||
effectCurrentIndex = max(min((increase ? effectCurrentIndex+1 : effectCurrentIndex-1), strip.getModeCount()-1), 0);
|
||||
effectCurrent = modes_alpha_indexes[effectCurrentIndex];
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
@ -522,7 +522,7 @@ public:
|
||||
display->updateRedrawTime();
|
||||
#endif
|
||||
effectSpeed = max(min((increase ? effectSpeed+fadeAmount : effectSpeed-fadeAmount), 255), 0);
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
@ -550,7 +550,7 @@ public:
|
||||
display->updateRedrawTime();
|
||||
#endif
|
||||
effectIntensity = max(min((increase ? effectIntensity+fadeAmount : effectIntensity-fadeAmount), 255), 0);
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
@ -579,7 +579,7 @@ public:
|
||||
#endif
|
||||
effectPaletteIndex = max(min((increase ? effectPaletteIndex+1 : effectPaletteIndex-1), strip.getPaletteCount()-1), 0);
|
||||
effectPalette = palettes_alpha_indexes[effectPaletteIndex];
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
@ -608,7 +608,7 @@ public:
|
||||
#endif
|
||||
currentHue1 = max(min((increase ? currentHue1+fadeAmount : currentHue1-fadeAmount), 255), 0);
|
||||
colorHStoRGB(currentHue1*256, currentSat1, col);
|
||||
colorChanged = true;
|
||||
stateChanged = true;
|
||||
if (applyToAll) {
|
||||
for (byte i=0; i<strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
|
@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "FX.h"
|
||||
#include "wled.h"
|
||||
|
||||
#define IBN 5100
|
||||
#define PALETTE_SOLID_WRAP (paletteBlend == 1 || paletteBlend == 3)
|
||||
@ -936,7 +937,7 @@ uint16_t WS2812FX::mode_chase_flash_random(void) {
|
||||
} else {
|
||||
SEGENV.step = (SEGENV.step + 1) % SEGLEN;
|
||||
|
||||
if(SEGENV.step == 0) {
|
||||
if (SEGENV.step == 0) {
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0);
|
||||
}
|
||||
}
|
||||
@ -965,8 +966,7 @@ uint16_t WS2812FX::running(uint32_t color1, uint32_t color2, bool theatre) {
|
||||
setPixelColor(i,col);
|
||||
}
|
||||
|
||||
if (it != SEGENV.step )
|
||||
{
|
||||
if (it != SEGENV.step) {
|
||||
SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1));
|
||||
SEGENV.step = it;
|
||||
}
|
||||
@ -996,26 +996,34 @@ uint16_t WS2812FX::mode_halloween(void) {
|
||||
|
||||
|
||||
/*
|
||||
* Random colored pixels running.
|
||||
* Random colored pixels running. ("Stream")
|
||||
*/
|
||||
uint16_t WS2812FX::mode_running_random(void) {
|
||||
uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed));
|
||||
uint32_t it = now / cycleTime;
|
||||
if (SEGENV.aux1 == it) return FRAMETIME;
|
||||
if (SEGENV.call == 0) SEGENV.aux0 = random16(); // random seed for PRNG on start
|
||||
|
||||
for(uint16_t i=SEGLEN-1; i > 0; i--) {
|
||||
setPixelColor( i, getPixelColor( i - 1));
|
||||
uint8_t zoneSize = ((255-SEGMENT.intensity) >> 4) +1;
|
||||
uint16_t PRNG16 = SEGENV.aux0;
|
||||
|
||||
uint8_t z = it % zoneSize;
|
||||
bool nzone = (!z && it != SEGENV.aux1);
|
||||
for (uint16_t i=SEGLEN-1; i > 0; i--) {
|
||||
if (nzone || z >= zoneSize) {
|
||||
uint8_t lastrand = PRNG16 >> 8;
|
||||
int16_t diff = 0;
|
||||
while (abs(diff) < 42) { // make sure the difference between adjacent colors is big enough
|
||||
PRNG16 = (uint16_t)(PRNG16 * 2053) + 13849; // next zone, next 'random' number
|
||||
diff = (PRNG16 >> 8) - lastrand;
|
||||
}
|
||||
|
||||
if(SEGENV.step == 0) {
|
||||
SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0);
|
||||
setPixelColor(0, color_wheel(SEGENV.aux0));
|
||||
if (nzone) {
|
||||
SEGENV.aux0 = PRNG16; // save next starting seed
|
||||
nzone = false;
|
||||
}
|
||||
|
||||
SEGENV.step++;
|
||||
if (SEGENV.step > (uint8_t)((255-SEGMENT.intensity) >> 4))
|
||||
{
|
||||
SEGENV.step = 0;
|
||||
z = 0;
|
||||
}
|
||||
setPixelColor(i, color_wheel(PRNG16 >> 8));
|
||||
z++;
|
||||
}
|
||||
|
||||
SEGENV.aux1 = it;
|
||||
@ -1589,26 +1597,36 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){
|
||||
|
||||
|
||||
/*
|
||||
* Running random pixels
|
||||
* Running random pixels ("Stream 2")
|
||||
* Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/RandomChase.h
|
||||
*/
|
||||
uint16_t WS2812FX::mode_random_chase(void)
|
||||
{
|
||||
if (SEGENV.call == 0) {
|
||||
SEGENV.step = RGBW32(random8(), random8(), random8(), 0);
|
||||
SEGENV.aux0 = random16();
|
||||
}
|
||||
uint16_t prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function
|
||||
uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed));
|
||||
uint32_t it = now / cycleTime;
|
||||
if (SEGENV.step == it) return FRAMETIME;
|
||||
uint32_t color = SEGENV.step;
|
||||
random16_set_seed(SEGENV.aux0);
|
||||
|
||||
for(uint16_t i = SEGLEN -1; i > 0; i--) {
|
||||
setPixelColor(i, getPixelColor(i-1));
|
||||
}
|
||||
uint32_t color = getPixelColor(0);
|
||||
if (SEGLEN > 1) color = getPixelColor( 1);
|
||||
uint8_t r = random8(6) != 0 ? (color >> 16 & 0xFF) : random8();
|
||||
uint8_t g = random8(6) != 0 ? (color >> 8 & 0xFF) : random8();
|
||||
uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8();
|
||||
setPixelColor(0, r, g, b);
|
||||
color = RGBW32(r, g, b, 0);
|
||||
setPixelColor(i, r, g, b);
|
||||
if (i == SEGLEN -1 && SEGENV.aux1 != (it & 0xFFFF)) { //new first color in next frame
|
||||
SEGENV.step = color;
|
||||
SEGENV.aux0 = random16_get_seed();
|
||||
}
|
||||
}
|
||||
|
||||
SEGENV.step = it;
|
||||
SEGENV.aux1 = it & 0xFFFF;
|
||||
|
||||
random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ void shortPressAction(uint8_t b)
|
||||
if (!macroButton[b]) {
|
||||
switch (b) {
|
||||
case 0: toggleOnOff(); stateUpdated(CALL_MODE_BUTTON); break;
|
||||
case 1: ++effectCurrent %= strip.getModeCount(); effectChanged = true; colorUpdated(CALL_MODE_BUTTON); break;
|
||||
case 1: ++effectCurrent %= strip.getModeCount(); stateChanged = true; colorUpdated(CALL_MODE_BUTTON); break;
|
||||
}
|
||||
} else {
|
||||
applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET);
|
||||
|
@ -17,7 +17,7 @@ void relativeChangeWhite(int8_t amount, byte lowerBoundary)
|
||||
if (new_val > 0xFF) new_val = 0xFF;
|
||||
else if (new_val < lowerBoundary) new_val = lowerBoundary;
|
||||
col[3] = new_val;
|
||||
colorChanged = true;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
||||
|
@ -157,7 +157,7 @@
|
||||
</div>
|
||||
<p class="labels h" id="cslLabel"></p>
|
||||
<div id="hexw">
|
||||
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter(this)" autocomplete="off" maxlength="8" />
|
||||
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter()" autocomplete="off" maxlength="8" />
|
||||
<button id="hexcnf" class="btn btn-xs" onclick="fromHex();"><i class="icons btn-icon"></i></button>
|
||||
</div>
|
||||
<div id="palw" class="il">
|
||||
|
@ -665,8 +665,8 @@ function populateSegments(s)
|
||||
<td>Offset</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${ledCount-1}" value="${inst.start}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${ledCount-(cfg.comp.seglen?inst.start:0)}" value="${inst.stop-(cfg.comp.seglen?inst.start:0)}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${ledCount-1}" value="${inst.start}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${ledCount-(cfg.comp.seglen?inst.start:0)}" value="${inst.stop-(cfg.comp.seglen?inst.start:0)}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}of" type="number" value="${inst.of}" oninput="updateLen(${i})"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -675,8 +675,8 @@ function populateSegments(s)
|
||||
<td>Apply</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><button class="btn btn-xs" onclick="setSeg(${i})"><i class="icons btn-icon" id="segc${i}"></i></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1481,8 +1481,8 @@ function makeSeg()
|
||||
<td width="38%">${cfg.comp.seglen?"LED count":"Stop LED"}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${lu}s" type="number" min="0" max="${ledCount-1}" value="${ns}" oninput="updateLen(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}e" type="number" min="0" max="${ct}" value="${ct}" oninput="updateLen(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}s" type="number" min="0" max="${ledCount-1}" value="${ns}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}e" type="number" min="0" max="${ct}" value="${ct}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><button class="btn btn-xs" onclick="setSeg(${lu});resetUtil();"><i class="icons bth-icon" id="segc${lu}"></i></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -2047,6 +2047,10 @@ function hexEnter()
|
||||
if(event.keyCode == 13) fromHex();
|
||||
}
|
||||
|
||||
function segEnter(s) {
|
||||
if(event.keyCode == 13) setSeg(s);
|
||||
}
|
||||
|
||||
function fromHex()
|
||||
{
|
||||
var str = gId('hexc').value;
|
||||
|
3250
wled00/html_ui.h
3250
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -98,7 +98,7 @@ void changeEffect(uint8_t fx)
|
||||
strip.setMode(strip.getMainSegmentId(), fx);
|
||||
}
|
||||
effectCurrent = fx;
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
void changePalette(uint8_t pal)
|
||||
@ -113,7 +113,7 @@ void changePalette(uint8_t pal)
|
||||
strip.getSegment(strip.getMainSegmentId()).palette = pal;
|
||||
}
|
||||
effectPalette = pal;
|
||||
effectChanged = true;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
void changeEffectSpeed(int8_t amount)
|
||||
@ -130,7 +130,6 @@ void changeEffectSpeed(int8_t amount)
|
||||
} else {
|
||||
strip.getSegment(strip.getMainSegmentId()).speed = effectSpeed;
|
||||
}
|
||||
effectChanged = true;
|
||||
} else { // if Effect == "solid Color", change the hue of the primary color
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = col[0];
|
||||
@ -154,8 +153,8 @@ void changeEffectSpeed(int8_t amount)
|
||||
} else {
|
||||
strip.getSegment(strip.getMainSegmentId()).colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
}
|
||||
colorChanged = true;
|
||||
}
|
||||
stateChanged = true;
|
||||
|
||||
if(amount > 0) lastRepeatableAction = ACTION_SPEED_UP;
|
||||
if(amount < 0) lastRepeatableAction = ACTION_SPEED_DOWN;
|
||||
@ -176,7 +175,6 @@ void changeEffectIntensity(int8_t amount)
|
||||
} else {
|
||||
strip.getSegment(strip.getMainSegmentId()).speed = effectIntensity;
|
||||
}
|
||||
effectChanged = true;
|
||||
} else { // if Effect == "solid Color", change the saturation of the primary color
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = col[0];
|
||||
@ -198,8 +196,8 @@ void changeEffectIntensity(int8_t amount)
|
||||
} else {
|
||||
strip.getSegment(strip.getMainSegmentId()).colors[0] = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
}
|
||||
colorChanged = true;
|
||||
}
|
||||
stateChanged = true;
|
||||
|
||||
if(amount > 0) lastRepeatableAction = ACTION_INTENSITY_UP;
|
||||
if(amount < 0) lastRepeatableAction = ACTION_INTENSITY_DOWN;
|
||||
@ -241,7 +239,7 @@ void changeColor(uint32_t c, int16_t cct=-1)
|
||||
if (isCCT && cct >= 0) seg.setCCT(cct, i);
|
||||
}
|
||||
setValuesFromMainSeg(); //make transitions graceful
|
||||
colorChanged = true;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
void decodeIR(uint32_t code)
|
||||
@ -257,7 +255,7 @@ void decodeIR(uint32_t code)
|
||||
lastRepeatableAction = ACTION_NONE;
|
||||
if (irEnabled == 8) { // any remote configurable with ir.json file
|
||||
decodeIRJson(code);
|
||||
colorUpdated(CALL_MODE_BUTTON);
|
||||
stateUpdated(CALL_MODE_BUTTON);
|
||||
return;
|
||||
}
|
||||
if (code > 0xFFFFFF) return; //invalid code
|
||||
@ -666,7 +664,7 @@ void decodeIRJson(uint32_t code)
|
||||
cmdStr += tmp;
|
||||
}
|
||||
fdo.clear(); // clear JSON buffer (it is no longer needed)
|
||||
handleSet(nullptr, cmdStr, false); // no colorUpdated() call here
|
||||
handleSet(nullptr, cmdStr, false); // no stateUpdated() call here
|
||||
}
|
||||
} else {
|
||||
// command is JSON object (TODO: currently will not handle irApplyToAllSelected correctly)
|
||||
|
@ -121,16 +121,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (sz == 0) continue; //do nothing on empty array
|
||||
|
||||
byte cp = copyArray(colX, rgbw, 4);
|
||||
if (cp == 1 && rgbw[0] == 0)
|
||||
seg.setColor(i, 0, id);
|
||||
colValid = true;
|
||||
}
|
||||
|
||||
if (!colValid) continue;
|
||||
|
||||
uint32_t color = RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]);
|
||||
colorChanged |= (seg.colors[i] != color);
|
||||
seg.setColor(i, color, id);
|
||||
seg.setColor(i, RGBW32(rgbw[0],rgbw[1],rgbw[2],rgbw[3]), id);
|
||||
if (seg.mode == FX_MODE_STATIC) strip.trigger(); //instant refresh
|
||||
}
|
||||
}
|
||||
@ -216,7 +212,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
seg.setOption(SEG_OPTION_FREEZE, false);
|
||||
}
|
||||
//send UDP if not in preset and something changed that is not just selection
|
||||
if (!presetId && (seg.differs(prev) & 0x7F)) effectChanged = true;
|
||||
if (!presetId && (seg.differs(prev) & 0x7F)) stateChanged = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -30,20 +30,14 @@ void applyValuesToSelectedSegs()
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
if (i != strip.getMainSegmentId() && (!seg.isActive() || !seg.isSelected())) continue;
|
||||
|
||||
if (effectSpeed != mainsegPrev.speed) {
|
||||
seg.speed = effectSpeed; effectChanged = true;}
|
||||
if (effectIntensity != mainsegPrev.intensity) {
|
||||
seg.intensity = effectIntensity; effectChanged = true;}
|
||||
if (effectPalette != mainsegPrev.palette) {
|
||||
seg.palette = effectPalette; effectChanged = true;}
|
||||
if (effectCurrent != mainsegPrev.mode) {
|
||||
strip.setMode(i, effectCurrent); effectChanged = true;}
|
||||
uint32_t col0 = RGBW32(col[0], col[1], col[2], col[3]);
|
||||
if (effectSpeed != mainsegPrev.speed) {seg.speed = effectSpeed; stateChanged = true;}
|
||||
if (effectIntensity != mainsegPrev.intensity) {seg.intensity = effectIntensity; stateChanged = true;}
|
||||
if (effectPalette != mainsegPrev.palette) {seg.palette = effectPalette; stateChanged = true;}
|
||||
if (effectCurrent != mainsegPrev.mode) {strip.setMode(i, effectCurrent); stateChanged = true;}
|
||||
uint32_t col0 = RGBW32( col[0], col[1], col[2], col[3]);
|
||||
uint32_t col1 = RGBW32(colSec[0], colSec[1], colSec[2], colSec[3]);
|
||||
if (col0 != mainsegPrev.colors[0]) {
|
||||
seg.setColor(0, col0, i); colorChanged = true;}
|
||||
if (col1 != mainsegPrev.colors[1]) {
|
||||
seg.setColor(1, col1, i); colorChanged = true;}
|
||||
if (col0 != mainsegPrev.colors[0]) {seg.setColor(0, col0, i); stateChanged = true;}
|
||||
if (col1 != mainsegPrev.colors[1]) {seg.setColor(1, col1, i); stateChanged = true;}
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,16 +94,15 @@ void stateUpdated(byte callMode) {
|
||||
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa 11: ws send only 12: button preset
|
||||
setValuesFromMainSeg();
|
||||
|
||||
if (bri != briOld || effectChanged || colorChanged) {
|
||||
if (bri != briOld || stateChanged) {
|
||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||
if (effectChanged) currentPreset = 0; //something changed, so we are no longer in the preset
|
||||
if (stateChanged) currentPreset = 0; //something changed, so we are no longer in the preset
|
||||
|
||||
if (callMode != CALL_MODE_NOTIFICATION && callMode != CALL_MODE_NO_NOTIFY) notify(callMode);
|
||||
|
||||
//set flag to update blynk, ws and mqtt
|
||||
interfaceUpdateCallMode = callMode;
|
||||
effectChanged = false;
|
||||
colorChanged = false;
|
||||
stateChanged = false;
|
||||
} else {
|
||||
if (nightlightActive && !nightlightActiveOld && callMode != CALL_MODE_NOTIFICATION && callMode != CALL_MODE_NO_NOTIFY) {
|
||||
notify(CALL_MODE_NIGHTLIGHT);
|
||||
|
128
wled00/set.cpp
128
wled00/set.cpp
@ -550,14 +550,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
byte selectedSeg = strip.getMainSegmentId();
|
||||
if (selectedSeg != prevMain) setValuesFromMainSeg();
|
||||
|
||||
//temporary values, do not write direcly to global values if only setting a single segment
|
||||
byte colIn[4] = {col[0], col[1], col[2], col[3]};
|
||||
byte colInSec[4] = {colSec[0], colSec[1], colSec[2], colSec[3]};
|
||||
byte effectIn = effectCurrent;
|
||||
byte speedIn = effectSpeed;
|
||||
byte intensityIn = effectIntensity;
|
||||
byte paletteIn = effectPalette;
|
||||
|
||||
bool singleSegment = false;
|
||||
|
||||
pos = req.indexOf(F("SS="));
|
||||
@ -577,6 +569,16 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
selseg.setOption(SEG_OPTION_SELECTED, t);
|
||||
}
|
||||
|
||||
// temporary values, write directly to segments, globals are updated by setValuesFromMainSeg()
|
||||
uint32_t col0 = selseg.colors[0];
|
||||
uint32_t col1 = selseg.colors[1];
|
||||
byte colIn[4] = {R(col0), G(col0), B(col0), W(col0)};
|
||||
byte colInSec[4] = {R(col1), G(col1), B(col1), W(col1)};
|
||||
byte effectIn = selseg.mode;
|
||||
byte speedIn = selseg.speed;
|
||||
byte intensityIn = selseg.intensity;
|
||||
byte paletteIn = selseg.palette;
|
||||
|
||||
uint16_t startI = selseg.start;
|
||||
uint16_t stopI = selseg.stop;
|
||||
uint8_t grpI = selseg.grouping;
|
||||
@ -642,20 +644,17 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
//set brightness
|
||||
updateVal(&req, "&A=", &bri);
|
||||
|
||||
bool col0Changed = false, col1Changed = false, col2Changed = false;
|
||||
bool col0Changed = false, col1Changed = false;
|
||||
//set colors
|
||||
updateVal(&req, "&R=", &colIn[0]);
|
||||
updateVal(&req, "&G=", &colIn[1]);
|
||||
updateVal(&req, "&B=", &colIn[2]);
|
||||
updateVal(&req, "&W=", &colIn[3]);
|
||||
for (byte i=0; i<4; i++) if (colIn[i]!=col[i]) col0Changed = colorChanged = true;
|
||||
if (col0Changed) selseg.setColor(0, RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]), selectedSeg); // use transitions
|
||||
updateVal(&req, "R2=", &colInSec[0]);
|
||||
updateVal(&req, "G2=", &colInSec[1]);
|
||||
updateVal(&req, "B2=", &colInSec[2]);
|
||||
updateVal(&req, "W2=", &colInSec[3]);
|
||||
for (byte i=0; i<4; i++) if (colInSec[i]!=colSec[i]) col1Changed = colorChanged = true;
|
||||
if (col1Changed) selseg.setColor(1, RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]), selectedSeg); // use transitions
|
||||
col0Changed |= updateVal(&req, "&R=", &colIn[0]);
|
||||
col0Changed |= updateVal(&req, "&G=", &colIn[1]);
|
||||
col0Changed |= updateVal(&req, "&B=", &colIn[2]);
|
||||
col0Changed |= updateVal(&req, "&W=", &colIn[3]);
|
||||
|
||||
col1Changed |= updateVal(&req, "R2=", &colInSec[0]);
|
||||
col1Changed |= updateVal(&req, "G2=", &colInSec[1]);
|
||||
col1Changed |= updateVal(&req, "B2=", &colInSec[2]);
|
||||
col1Changed |= updateVal(&req, "W2=", &colInSec[3]);
|
||||
|
||||
#ifdef WLED_ENABLE_LOXONE
|
||||
//lox parser
|
||||
@ -665,6 +664,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (parseLx(lxValue, colIn)) {
|
||||
bri = 255;
|
||||
nightlightActive = false; //always disable nightlight when toggling
|
||||
col0Changed = true;
|
||||
}
|
||||
}
|
||||
pos = req.indexOf(F("LY=")); // Lox secondary color
|
||||
@ -673,6 +673,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if(parseLx(lxValue, colInSec)) {
|
||||
bri = 255;
|
||||
nightlightActive = false; //always disable nightlight when toggling
|
||||
col1Changed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -688,9 +689,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
}
|
||||
byte sec = req.indexOf(F("H2"));
|
||||
colorHStoRGB(temphue, tempsat, (sec>0) ? colInSec : colIn);
|
||||
if (sec>0) col1Changed = true;
|
||||
else col0Changed = true;
|
||||
colorChanged = true;
|
||||
col0Changed |= (!sec); col1Changed |= sec;
|
||||
}
|
||||
|
||||
//set white spectrum (kelvin)
|
||||
@ -698,9 +697,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (pos > 0) {
|
||||
byte sec = req.indexOf(F("K2"));
|
||||
colorKtoRGB(getNumVal(&req, pos), (sec>0) ? colInSec : colIn);
|
||||
if (sec>0) col1Changed = true;
|
||||
else col0Changed = true;
|
||||
colorChanged = true;
|
||||
col0Changed |= (!sec); col1Changed |= sec;
|
||||
}
|
||||
|
||||
//set color from HEX or 32bit DEC
|
||||
@ -708,20 +705,20 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
pos = req.indexOf(F("CL="));
|
||||
if (pos > 0) {
|
||||
colorFromDecOrHexString(colIn, (char*)req.substring(pos + 3).c_str());
|
||||
selseg.setColor(0, RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]), selectedSeg); // defined above (SS= or main)
|
||||
col0Changed = colorChanged = true;
|
||||
col0Changed = true;
|
||||
}
|
||||
pos = req.indexOf(F("C2="));
|
||||
if (pos > 0) {
|
||||
colorFromDecOrHexString(colInSec, (char*)req.substring(pos + 3).c_str());
|
||||
selseg.setColor(1, RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]), selectedSeg); // defined above (SS= or main)
|
||||
col1Changed = colorChanged = true;
|
||||
col1Changed = true;
|
||||
}
|
||||
pos = req.indexOf(F("C3="));
|
||||
if (pos > 0) {
|
||||
colorFromDecOrHexString(tmpCol, (char*)req.substring(pos + 3).c_str());
|
||||
selseg.setColor(2, RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]), selectedSeg); // defined above (SS= or main)
|
||||
col2Changed = colorChanged = true;
|
||||
uint32_t col2 = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
|
||||
selseg.setColor(2, col2, selectedSeg); // defined above (SS= or main)
|
||||
stateChanged = true;
|
||||
if (!singleSegment) strip.setColor(2, col2); // will set color to all active & selected segments
|
||||
}
|
||||
|
||||
//set to random hue SR=0->1st SR=1->2nd
|
||||
@ -729,9 +726,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (pos > 0) {
|
||||
byte sec = getNumVal(&req, pos);
|
||||
setRandomColor(sec? colInSec : colIn);
|
||||
if (sec>0) col1Changed = true;
|
||||
else col0Changed = true;
|
||||
colorChanged = true;
|
||||
col0Changed |= (!sec); col1Changed |= sec;
|
||||
}
|
||||
|
||||
//swap 2nd & 1st
|
||||
@ -743,33 +738,44 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
colIn[i] = colInSec[i];
|
||||
colInSec[i] = temp;
|
||||
}
|
||||
col0Changed = col1Changed = colorChanged = true;
|
||||
col0Changed = col1Changed = true;
|
||||
}
|
||||
|
||||
//set effect parameters
|
||||
if (updateVal(&req, "FX=", &effectIn, 0, strip.getModeCount()-1) && request != nullptr) unloadPlaylist(); //unload playlist if changing FX using web request
|
||||
updateVal(&req, "SX=", &speedIn);
|
||||
updateVal(&req, "IX=", &intensityIn);
|
||||
updateVal(&req, "FP=", &paletteIn, 0, strip.getPaletteCount()-1);
|
||||
strip.setMode(selectedSeg, effectIn);
|
||||
selseg.speed = speedIn;
|
||||
selseg.intensity = intensityIn;
|
||||
selseg.palette = paletteIn;
|
||||
if (effectIn != effectCurrent || speedIn != effectSpeed || intensityIn != effectIntensity || paletteIn != effectPalette) effectChanged = true;
|
||||
// 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, selectedSeg);
|
||||
if (!singleSegment) strip.setColor(0, colIn0); // will set color to all active & selected segments
|
||||
}
|
||||
|
||||
//apply to all selected manually to prevent #1618.
|
||||
if (!singleSegment) {
|
||||
if (col1Changed) {
|
||||
stateChanged = true;
|
||||
uint32_t colIn1 = RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]);
|
||||
selseg.setColor(1, colIn1, selectedSeg);
|
||||
if (!singleSegment) strip.setColor(1, colIn1); // will set color to all active & selected segments
|
||||
}
|
||||
|
||||
bool fxModeChanged = false, speedChanged = false, intensityChanged = false, paletteChanged = false;
|
||||
// set effect parameters
|
||||
if (updateVal(&req, "FX=", &effectIn, 0, strip.getModeCount()-1)) {
|
||||
if (request != nullptr) unloadPlaylist(); // unload playlist if changing FX using web request
|
||||
fxModeChanged = true;
|
||||
}
|
||||
speedChanged = updateVal(&req, "SX=", &speedIn);
|
||||
intensityChanged = updateVal(&req, "IX=", &intensityIn);
|
||||
paletteChanged = updateVal(&req, "FP=", &paletteIn, 0, strip.getPaletteCount()-1);
|
||||
|
||||
stateChanged |= (fxModeChanged || speedChanged || intensityChanged || paletteChanged);
|
||||
|
||||
//apply to main and all selected segments to prevent #1618.
|
||||
for (uint8_t i = 0; i < strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isActive() || !seg.isSelected() || i == selectedSeg) continue;
|
||||
if (effectCurrent != effectIn) strip.setMode(i, effectIn);
|
||||
if (effectSpeed != speedIn) seg.speed = speedIn;
|
||||
if (effectIntensity != intensityIn) seg.intensity = intensityIn;
|
||||
if (effectPalette != paletteIn) seg.palette = paletteIn;
|
||||
if (col0Changed) seg.setColor(0, RGBW32(colIn[0], colIn[1], colIn[2], colIn[3]), i); // use transitions
|
||||
if (col1Changed) seg.setColor(1, RGBW32(colInSec[0], colInSec[1], colInSec[2], colInSec[3]), i); // use transitions
|
||||
if (col2Changed) seg.colors[2] = RGBW32(tmpCol[0], tmpCol[1], tmpCol[2], tmpCol[3]);
|
||||
}
|
||||
if (i != selectedSeg && (singleSegment || !seg.isActive() || !seg.isSelected())) continue; // skip non main segments if not applying to all
|
||||
if (fxModeChanged) strip.setMode(i, effectIn);
|
||||
if (speedChanged) seg.speed = speedIn;
|
||||
if (intensityChanged) seg.intensity = intensityIn;
|
||||
if (paletteChanged) seg.palette = paletteIn;
|
||||
}
|
||||
setValuesFromMainSeg(); // will fill col[] and cloSec[] as well as effectCurrent, ...
|
||||
|
||||
@ -899,16 +905,16 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
if (pos > 0) {
|
||||
userVar1 = getNumVal(&req, pos);
|
||||
}
|
||||
//you can add more if you need
|
||||
// you can add more if you need
|
||||
|
||||
if (!apply) return true; //when called by JSON API, do not call colorUpdated() here
|
||||
if (!apply) return true; // when called by JSON API, do not call stateUpdated() here
|
||||
|
||||
//internal call, does not send XML response
|
||||
pos = req.indexOf(F("IN"));
|
||||
if (pos < 1) XML_response(request);
|
||||
|
||||
pos = req.indexOf(F("&NN")); //do not send UDP notifications this time
|
||||
colorUpdated((pos > 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE);
|
||||
stateUpdated((pos > 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -359,8 +359,7 @@ void handleNotifications()
|
||||
strip.setSegment(id, selseg.start, selseg.stop, udpIn[5+ofs], udpIn[6+ofs], selseg.offset);
|
||||
}
|
||||
}
|
||||
effectChanged = true;
|
||||
colorChanged = true;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
if (applyEffects && (version < 11 || !receiveSegmentOptions)) { //simple effect sync, applies to all selected
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2202201
|
||||
#define VERSION 2202211
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -488,8 +488,7 @@ WLED_GLOBAL byte effectCurrent _INIT(0);
|
||||
WLED_GLOBAL byte effectSpeed _INIT(128);
|
||||
WLED_GLOBAL byte effectIntensity _INIT(128);
|
||||
WLED_GLOBAL byte effectPalette _INIT(0);
|
||||
WLED_GLOBAL bool effectChanged _INIT(false);
|
||||
WLED_GLOBAL bool colorChanged _INIT(false);
|
||||
WLED_GLOBAL bool stateChanged _INIT(false);
|
||||
|
||||
// network
|
||||
WLED_GLOBAL bool udpConnected _INIT(false), udp2Connected _INIT(false), udpRgbConnected _INIT(false);
|
||||
|
@ -240,7 +240,7 @@ void initServer()
|
||||
{
|
||||
serveMessage(request, 500, F("Failed updating firmware!"), F("Please check your file and retry!"), 254); return;
|
||||
}
|
||||
serveMessage(request, 200, F("Successfully updated firmware!"), F("Please wait while the module reboots..."), 131);
|
||||
serveMessage(request, 200, F("Successfully updated firmware!"), F("Rebooting..."), 131);
|
||||
doReboot = true;
|
||||
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||
if(!index){
|
||||
|
Loading…
Reference in New Issue
Block a user