From 0e8806eb2b71aabb3fbb82ccd57309a9e1243179 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 30 Nov 2019 19:17:25 +0100 Subject: [PATCH] Integrated liveview --- wled00/FX.h | 4 +- wled00/FX_fcn.cpp | 16 +++-- wled00/data/liveview.htm | 59 ++++++++++++++++ wled00/html_other.h | 18 +++++ wled00/wled18_server.ino | 4 ++ wled00/wled19_json.ino | 141 +++++++++++++++++++++++---------------- 6 files changed, 176 insertions(+), 66 deletions(-) create mode 100644 wled00/data/liveview.htm diff --git a/wled00/FX.h b/wled00/FX.h index 1becbf405..01453265e 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 797c3de1c..d4018a5d8 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 000000000..3cd457ed8 --- /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 5de0598f0..915fc21a7 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 b87b04e17..aca68696b 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 a9cb18ea0..d5c8cd7c8 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;