diff --git a/wled00/FX.h b/wled00/FX.h
index 1becbf40..01453265 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -367,7 +367,7 @@ class WS2812FX {
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
uint8_t
- returnedSegment = 0,
+ mainSegment = 0,
paletteFade = 0,
paletteBlend = 0,
colorOrder = 0,
@@ -380,7 +380,7 @@ class WS2812FX {
getPaletteCount(void),
getMaxSegments(void),
getFirstSelectedSegment(void),
- getReturnedSegmentId(void),
+ getMainSegmentId(void),
gamma8(uint8_t),
get_random_wheel_index(uint8_t);
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 797c3de1..d4018a5d 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -331,7 +331,7 @@ void WS2812FX::setPalette(uint8_t p) {
}
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
- uint8_t retSeg = getReturnedSegmentId();
+ uint8_t retSeg = getMainSegmentId();
Segment& seg = _segments[retSeg];
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
@@ -370,11 +370,11 @@ void WS2812FX::setBrightness(uint8_t b) {
}
uint8_t WS2812FX::getMode(void) {
- return _segments[getReturnedSegmentId()].mode;
+ return _segments[getMainSegmentId()].mode;
}
uint8_t WS2812FX::getSpeed(void) {
- return _segments[getReturnedSegmentId()].speed;
+ return _segments[getMainSegmentId()].speed;
}
uint8_t WS2812FX::getBrightness(void) {
@@ -398,20 +398,21 @@ uint8_t WS2812FX::getFirstSelectedSegment(void)
return 0;
}
-uint8_t WS2812FX::getReturnedSegmentId(void) {
- if (returnedSegment >= MAX_NUM_SEGMENTS || !_segments[returnedSegment].isActive())
+uint8_t WS2812FX::getMainSegmentId(void) {
+ if (mainSegment >= MAX_NUM_SEGMENTS || !_segments[mainSegment].isActive())
{
return getFirstSelectedSegment();
}
- return returnedSegment;
+ return mainSegment;
}
uint32_t WS2812FX::getColor(void) {
- return _segments[getReturnedSegmentId()].colors[0];
+ return _segments[getMainSegmentId()].colors[0];
}
uint32_t WS2812FX::getPixelColor(uint16_t i)
{
+ i = i * (_disableNLeds+1);
if (reverseMode) i = _length- 1 -i;
if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
@@ -434,6 +435,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
default: return 0;
}
}
+ if (i >= _lengthRaw) return 0;
RgbwColor lColor = bus->GetPixelColorRgbw(i);
byte r = lColor.R, g = lColor.G, b = lColor.B;
switch (colorOrder)
diff --git a/wled00/data/liveview.htm b/wled00/data/liveview.htm
new file mode 100644
index 00000000..3cd457ed
--- /dev/null
+++ b/wled00/data/liveview.htm
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+ WLED Live Preview
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wled00/html_other.h b/wled00/html_other.h
index 5de0598f..915fc21a 100644
--- a/wled00/html_other.h
+++ b/wled00/html_other.h
@@ -33,6 +33,24 @@ const char PAGE_welcome[] PROGMEM = "";
#endif
+//liveview
+const char PAGE_liveview[] PROGMEM = R"=====(
+
+
+
+
+WLED Live Preview
+
+
+
+
+)=====";
+
+
/*
* favicon
*/
diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino
index b87b04e1..aca68696 100644
--- a/wled00/wled18_server.ino
+++ b/wled00/wled18_server.ino
@@ -36,6 +36,10 @@ void initServer()
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "*");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
+
+ server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
+ request->send_P(200, "text/html", PAGE_liveview);
+ });
//settings page
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino
index a9cb18ea..d5c8cd7c 100644
--- a/wled00/wled19_json.ino
+++ b/wled00/wled19_json.ino
@@ -2,6 +2,64 @@
* JSON API (De)serialization
*/
+void deserializeSegment(JsonObject elem, byte it)
+{
+ byte id = elem["id"] | it;
+ if (id < strip.getMaxSegments())
+ {
+ WS2812FX::Segment& seg = strip.getSegment(id);
+ uint16_t start = elem["start"] | seg.start;
+ int stop = elem["stop"] | -1;
+
+ if (stop < 0) {
+ uint16_t len = elem["len"];
+ stop = (len > 0) ? start + len : seg.stop;
+ }
+ strip.setSegment(id, start, stop);
+
+ JsonArray colarr = elem["col"];
+ if (!colarr.isNull())
+ {
+ for (uint8_t i = 0; i < 3; i++)
+ {
+ JsonArray colX = colarr[i];
+ if (colX.isNull()) break;
+ byte sz = colX.size();
+ if (sz > 0 && sz < 5)
+ {
+ int rgbw[] = {0,0,0,0};
+ byte cp = copyArray(colX, rgbw);
+ seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
+ if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
+ if (id == 0) //temporary
+ {
+ if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
+ if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
+ }
+ }
+ }
+ }
+
+ //if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
+ seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected
+ seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse
+ //int cln = seg_0["cln"];
+ //temporary, strip object gets updated via colorUpdated()
+ if (id == 0) {
+ effectCurrent = elem["fx"] | effectCurrent;
+ effectSpeed = elem["sx"] | effectSpeed;
+ effectIntensity = elem["ix"] | effectIntensity ;
+ effectPalette = elem["pal"] | effectPalette;
+ } else { //permanent
+ byte fx = elem["fx"] | seg.mode;
+ if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
+ seg.speed = elem["sx"] | seg.speed;
+ seg.intensity = elem["ix"] | seg.intensity;
+ seg.palette = elem["pal"] | seg.palette;
+ }
+ }
+}
+
bool deserializeState(JsonObject root)
{
bool stateResponse = root["v"] | false;
@@ -10,15 +68,18 @@ bool deserializeState(JsonObject root)
bool on = root["on"] | (bri > 0);
if (!on != !bri) toggleOnOff();
-
- if (root.containsKey("transition"))
+
+ int tr = root["transition"] | -1;
+ if (tr >= 0)
{
- transitionDelay = root["transition"];
+ transitionDelay = tr;
transitionDelay *= 100;
}
- if (root.containsKey("tt"))
+
+ tr = root["tt"] | -1;
+ if (tr >= 0)
{
- transitionDelayTemp = root["tt"];
+ transitionDelayTemp = tr;
transitionDelayTemp *= 100;
jsonTransitionOnce = true;
}
@@ -44,65 +105,31 @@ bool deserializeState(JsonObject root)
if (timein != -1) setTime(timein);
int it = 0;
- JsonArray segs = root["seg"];
- for (JsonObject elem : segs)
+ JsonVariant segVar = root["seg"];
+ if (segVar.is())
{
- byte id = elem["id"] | it;
- if (id < strip.getMaxSegments())
- {
- WS2812FX::Segment& seg = strip.getSegment(id);
- uint16_t start = elem["start"] | seg.start;
- int stop = elem["stop"] | -1;
-
- if (stop < 0) {
- uint16_t len = elem["len"];
- stop = (len > 0) ? start + len : seg.stop;
- }
- strip.setSegment(id, start, stop);
-
- JsonArray colarr = elem["col"];
- if (!colarr.isNull())
+ int id = segVar["id"] | -1;
+ if (id < 0) { //set all selected segments
+ for (byte s = 0; s < strip.getMaxSegments(); s++)
{
- for (uint8_t i = 0; i < 3; i++)
+ WS2812FX::Segment sg = strip.getSegment(s);
+ if (sg.isActive() && sg.isSelected())
{
- JsonArray colX = colarr[i];
- if (colX.isNull()) break;
- byte sz = colX.size();
- if (sz > 0 && sz < 5)
- {
- int rgbw[] = {0,0,0,0};
- byte cp = copyArray(colX, rgbw);
- seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
- if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
- if (id == 0) //temporary
- {
- if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
- if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
- }
- }
+ deserializeSegment(segVar, s);
}
}
-
- //if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
- seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected
- seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse
- //int cln = seg_0["cln"];
- //temporary, strip object gets updated via colorUpdated()
- if (id == 0) {
- effectCurrent = elem["fx"] | effectCurrent;
- effectSpeed = elem["sx"] | effectSpeed;
- effectIntensity = elem["ix"] | effectIntensity ;
- effectPalette = elem["pal"] | effectPalette;
- } else { //permanent
- byte fx = elem["fx"] | seg.mode;
- if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
- seg.speed = elem["sx"] | seg.speed;
- seg.intensity = elem["ix"] | seg.intensity;
- seg.palette = elem["pal"] | seg.palette;
- }
+ } else { //set only the segment with the specified ID
+ deserializeSegment(segVar, it);
+ }
+ } else {
+ JsonArray segs = segVar.as();
+ for (JsonObject elem : segs)
+ {
+ deserializeSegment(elem, it);
+ it++;
}
- it++;
}
+
colorUpdated(noNotification ? 5:1);
ps = root["psave"] | -1;