From 77dee439e6cfe70c3e65598788e04e37ae2838aa Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Wed, 24 Feb 2021 20:23:32 +0100 Subject: [PATCH] 1st attempt at 'blazoncek' 0.12 --- wled00/FX.cpp | 92 +- wled00/FX.h | 23 +- wled00/FX_fcn.cpp | 82 +- wled00/NodeStruct.cpp | 16 + wled00/NodeStruct.h | 33 + wled00/bus_manager.h | 49 +- wled00/bus_wrapper.h | 60 +- wled00/button.cpp | 3 +- wled00/cfg.cpp | 45 +- wled00/const.h | 2 +- wled00/data/index.css | 176 +- wled00/data/index.htm | 103 +- wled00/data/index.js | 711 ++++-- wled00/data/settings_leds.htm | 709 +++--- wled00/data/style.css | 110 +- wled00/fcn_declare.h | 4 + wled00/html_settings.h | 33 +- wled00/html_ui.h | 4201 +++++++++++++++++---------------- wled00/json.cpp | 201 +- wled00/led.cpp | 1 + wled00/playlist.cpp | 118 +- wled00/set.cpp | 47 +- wled00/udp.cpp | 122 +- wled00/wled.cpp | 38 +- wled00/wled.h | 17 +- wled00/wled_eeprom.cpp | 2 +- wled00/xml.cpp | 50 +- 27 files changed, 4102 insertions(+), 2946 deletions(-) create mode 100644 wled00/NodeStruct.cpp create mode 100644 wled00/NodeStruct.h diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 3fdfcff1..62476c3a 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -395,41 +395,12 @@ uint16_t WS2812FX::mode_rainbow_cycle(void) { } -/* - * theater chase function - */ -uint16_t WS2812FX::theater_chase(uint32_t color1, uint32_t color2, bool do_palette) { - byte gap = 2 + ((255 - SEGMENT.intensity) >> 5); - uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*2; - uint32_t it = now / cycleTime; - if (it != SEGENV.step) //new color - { - SEGENV.aux0 = (SEGENV.aux0 +1) % gap; - SEGENV.step = it; - } - - for(uint16_t i = 0; i < SEGLEN; i++) { - if((i % gap) == SEGENV.aux0) { - if (do_palette) - { - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - } else { - setPixelColor(i, color1); - } - } else { - setPixelColor(i, color2); - } - } - return FRAMETIME; -} - - /* * Theatre-style crawling lights. * Inspired by the Adafruit examples. */ uint16_t WS2812FX::mode_theater_chase(void) { - return theater_chase(SEGCOLOR(0), SEGCOLOR(1), true); + return running(SEGCOLOR(0), SEGCOLOR(1), true); } @@ -438,7 +409,7 @@ uint16_t WS2812FX::mode_theater_chase(void) { * Inspired by the Adafruit examples. */ uint16_t WS2812FX::mode_theater_chase_rainbow(void) { - return theater_chase(color_wheel(SEGENV.step), SEGCOLOR(1), false); + return running(color_wheel(SEGENV.step), SEGCOLOR(1), true); } @@ -966,29 +937,27 @@ uint16_t WS2812FX::mode_chase_flash_random(void) { /* * Alternating pixels running function. */ -uint16_t WS2812FX::running(uint32_t color1, uint32_t color2) { - uint8_t pxw = 1 + (SEGMENT.intensity >> 5); - uint32_t cycleTime = 35 + (255 - SEGMENT.speed); +uint16_t WS2812FX::running(uint32_t color1, uint32_t color2, bool theatre) { + uint8_t width = (theatre ? 3 : 1) + (SEGMENT.intensity >> 4); // window + uint32_t cycleTime = 50 + (255 - SEGMENT.speed); uint32_t it = now / cycleTime; - if (SEGMENT.speed == 0) it = 0; - + bool usePalette = color1 == SEGCOLOR(0); + for(uint16_t i = 0; i < SEGLEN; i++) { - if((i + SEGENV.aux0) % (pxw*2) < pxw) { - if (color1 == SEGCOLOR(0)) - { - setPixelColor(SEGLEN -i -1, color_from_palette(SEGLEN -i -1, true, PALETTE_SOLID_WRAP, 0)); - } else - { - setPixelColor(SEGLEN -i -1, color1); - } + uint32_t col = color2; + if (usePalette) color1 = color_from_palette(i, true, PALETTE_SOLID_WRAP, 0); + if (theatre) { + if ((i % width) == SEGENV.aux0) col = color1; } else { - setPixelColor(SEGLEN -i -1, color2); + int8_t pos = (i % (width<<1)); + if ((pos < SEGENV.aux0-width) || ((pos >= SEGENV.aux0) && (pos < SEGENV.aux0+width))) col = color1; } + setPixelColor(i,col); } if (it != SEGENV.step ) { - SEGENV.aux0 = (SEGENV.aux0 +1) % (pxw*2); + SEGENV.aux0 = (SEGENV.aux0 +1) % (theatre ? width : (width<<1)); SEGENV.step = it; } return FRAMETIME; @@ -1778,7 +1747,7 @@ uint16_t WS2812FX::mode_fire_2012() // Step 1. Cool down every cell a little for (uint16_t i = 0; i < SEGLEN; i++) { uint8_t temp = qsub8(heat[i], random8(0, (((20 + SEGMENT.speed /3) * 10) / SEGLEN) + 2)); - heat[i] = (temp==0 && i> 3; uint8_t bitNum = i & 0x07; @@ -2650,7 +2616,7 @@ uint16_t WS2812FX::mode_sinelon_dual(void) { } uint16_t WS2812FX::mode_sinelon_rainbow(void) { - return sinelon_base(true, true); + return sinelon_base(false, true); } @@ -2955,7 +2921,7 @@ uint16_t WS2812FX::mode_starburst(void) { uint16_t WS2812FX::mode_exploding_fireworks(void) { //allocate segment data - uint16_t numSparks = 2 + (SEGLEN >> 1); + uint16_t numSparks = 2 + (SEGLEN >> 2); if (numSparks > 80) numSparks = 80; uint16_t dataSize = sizeof(spark) * numSparks; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -3051,7 +3017,7 @@ uint16_t WS2812FX::mode_exploding_fireworks(void) SEGENV.aux0--; if (SEGENV.aux0 < 4) { SEGENV.aux0 = 0; //back to flare - SEGENV.step = (SEGMENT.intensity > random8()); //decide firing side + SEGENV.step = actuallyReverse ^ (SEGMENT.intensity > random8()); //decide firing side } } @@ -3162,7 +3128,7 @@ uint16_t WS2812FX::mode_tetrix(void) { if (SEGENV.step == 0) { //init drop->speed = 0.0238 * (SEGMENT.speed ? (SEGMENT.speed>>3)+1 : random8(6,40)); // set speed - drop->pos = SEGLEN-1; // start at end of segment + drop->pos = SEGLEN; // start at end of segment (no need to subtract 1) drop->col = color_from_palette(random8(0,15)<<4,false,false,0); // limit color choices so there is enough HUE gap SEGENV.step = 1; // drop state (0 init, 1 forming, 2 falling) SEGENV.aux0 = (SEGMENT.intensity ? (SEGMENT.intensity>>5)+1 : random8(1,5)) * (1+(SEGLEN>>6)); // size of brick @@ -3194,8 +3160,8 @@ uint16_t WS2812FX::mode_tetrix(void) { / adapted from https://github.com/atuline/FastLED-Demos/blob/master/plasma/plasma.ino */ uint16_t WS2812FX::mode_plasma(void) { - uint8_t thisPhase = beatsin8(6,-64,64); // Setting phase change for a couple of waves. - uint8_t thatPhase = beatsin8(7,-64,64); + uint8_t thisPhase = beatsin8(6+_segment_index%3,-64,64); // Setting phase change for a couple of waves. + uint8_t thatPhase = beatsin8(7+_segment_index%3,-64,64); for (int i = 0; i < SEGLEN; i++) { // For each of the LED's in the strand, set color & brightness based on a wave as follows: uint8_t colorIndex = cubicwave8((i*(1+ 3*(SEGMENT.speed >> 5)))+(thisPhase) & 0xFF)/2 // factor=23 // Create a wave and add a phase change and add another wave with its own phase change. @@ -3634,7 +3600,7 @@ uint16_t WS2812FX::mode_chunchun(void) for (uint16_t i = 0; i < numBirds; i++) { counter -= span/numBirds; - int megumin = sin16(counter) + 0x8000; + uint16_t megumin = sin16(counter) + 0x8000; uint32_t bird = (megumin * SEGLEN) >> 16; uint32_t c = color_from_palette((i * 255)/ numBirds, false, true, 0); setPixelColor(bird, c); diff --git a/wled00/FX.h b/wled00/FX.h index b681a079..d38c0718 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -24,8 +24,6 @@ Modified for WLED */ -#include "wled.h" - #ifndef WS2812FX_h #define WS2812FX_h @@ -58,11 +56,11 @@ /* each segment uses 52 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ #ifdef ESP8266 - #define MAX_NUM_SEGMENTS 12 + #define MAX_NUM_SEGMENTS 13 /* How many color transitions can run at once */ #define MAX_NUM_TRANSITIONS 8 /* How much data bytes all segments combined may allocate */ - #define MAX_SEGMENT_DATA 2048 + #define MAX_SEGMENT_DATA 2560 #else #define MAX_NUM_SEGMENTS 16 #define MAX_NUM_TRANSITIONS 16 @@ -584,7 +582,7 @@ class WS2812FX { } void - finalizeInit(bool supportWhite, uint16_t countPixels, bool skipFirst), + finalizeInit(void), service(void), blur(uint8_t), fill(uint32_t), @@ -609,7 +607,6 @@ class WS2812FX { setPixelSegment(uint8_t n); bool - reverseMode = false, //is the entire LED strip reversed? gammaCorrectBri = false, gammaCorrectCol = true, applyToAllSelected = true, @@ -624,8 +621,6 @@ class WS2812FX { paletteFade = 0, paletteBlend = 0, milliampsPerLed = 55, -// getStripType(uint8_t strip=0), -// setStripType(uint8_t type, uint8_t strip=0), getBrightness(void), getMode(void), getSpeed(void), @@ -640,17 +635,11 @@ class WS2812FX { get_random_wheel_index(uint8_t); int8_t -// setStripPin(uint8_t strip, int8_t pin), -// getStripPin(uint8_t strip=0), -// setStripPinClk(uint8_t strip, int8_t pin), -// getStripPinClk(uint8_t strip=0), tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec); uint16_t ablMilliampsMax, currentMilliamps, -// setStripLen(uint8_t strip, uint16_t len), -// getStripLen(uint8_t strip=0), triwave16(uint16_t), getFps(); @@ -803,7 +792,7 @@ class WS2812FX { CRGBPalette16 currentPalette; CRGBPalette16 targetPalette; - uint16_t _length, _lengthRaw, _virtualSegmentLength; + uint16_t _length, _virtualSegmentLength; uint16_t _rand16seed; uint8_t _brightness; uint16_t _usedSegmentData = 0; @@ -816,7 +805,6 @@ class WS2812FX { bool _useRgbw = false, - _skipFirstMode, _triggered; mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element @@ -830,7 +818,6 @@ class WS2812FX { color_wipe(bool, bool), dynamic(bool), scan(bool), - theater_chase(uint32_t, uint32_t, bool), running_base(bool), larson_scanner(bool), sinelon_base(bool,bool), @@ -839,7 +826,7 @@ class WS2812FX { gradient_base(bool), ripple_base(bool), police_base(uint32_t, uint32_t, bool), - running(uint32_t, uint32_t), + running(uint32_t, uint32_t, bool theatre=false), tricolor_chase(uint32_t, uint32_t), twinklefox_base(bool), spots_base(uint16_t), diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index aa1f88a6..e1d6ff1b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -23,7 +23,7 @@ Modified heavily for WLED */ - +#include "wled.h" #include "FX.h" #include "palettes.h" @@ -44,34 +44,41 @@ another example. Switches direction every 5 LEDs. {"map":[ 0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, - 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25] + 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25]} */ //do not call this method from system context (network callback) -void WS2812FX::finalizeInit(bool supportWhite, uint16_t countPixels, bool skipFirst) +void WS2812FX::finalizeInit(void) { - if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return; RESET_RUNTIME; - _useRgbw = supportWhite; - _length = countPixels; - _skipFirstMode = skipFirst; - - _lengthRaw = _length; - if (_skipFirstMode) { - _lengthRaw += LED_SKIP_AMOUNT; - } + _useRgbw = false; //if busses failed to load, add default (FS issue...) if (busses.getNumBusses() == 0) { uint8_t defPin[] = {LEDPIN}; - BusConfig defCfg = BusConfig(TYPE_WS2812_RGB, defPin, 0, _lengthRaw, COL_ORDER_GRB); + BusConfig defCfg = BusConfig(TYPE_WS2812_RGB, defPin, 0, 30, COL_ORDER_GRB, false, false); busses.add(defCfg); } deserializeMap(); - _segments[0].start = 0; - _segments[0].stop = _length; + _length = 0; + for (uint8_t i=0; iisRgbw(); + _segments[i].start = bus->getStart(); + _length += bus->getLength(); + _segments[i].stop = _segments[i].start + bus->getLength(); + _segments[i].mode = DEFAULT_MODE; + _segments[i].colors[0] = DEFAULT_COLOR; + _segments[i].speed = DEFAULT_SPEED; + _segments[i].intensity = DEFAULT_INTENSITY; + _segments[i].grouping = 1; + _segments[i].setOption(SEG_OPTION_SELECTED, 1); + _segments[i].setOption(SEG_OPTION_ON, 1); + _segments[i].opacity = 255; + } setBrightness(_brightness); @@ -154,16 +161,13 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) { int16_t realIndex = iGroup; if (IS_REVERSE) { if (IS_MIRROR) { - realIndex = (SEGMENT.length() -1) / 2 - iGroup; //only need to index half the pixels + realIndex = (SEGMENT.length() - 1) / 2 - iGroup; //only need to index half the pixels } else { - realIndex = SEGMENT.length() - iGroup - 1; + realIndex = (SEGMENT.length() - 1) - iGroup; } } realIndex += SEGMENT.start; - /* Reverse the whole string */ - if (reverseMode) realIndex = REV(realIndex); - return realIndex; } @@ -183,9 +187,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } } - uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; if (SEGLEN) {//from segment - //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) if (_bri_t < 255) { r = scale8(r, _bri_t); @@ -195,37 +197,25 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); - /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ - bool reversed = reverseMode ^ IS_REVERSE; + /* Set all the pixels in the group */ uint16_t realIndex = realPixelIndex(i); for (uint16_t j = 0; j < SEGMENT.grouping; j++) { - int16_t indexSet = realIndex + (reversed ? -j : j); - int16_t indexSetRev = indexSet; - if (reverseMode) indexSetRev = REV(indexSet); - if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; - if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) { - busses.setPixelColor(indexSet + skip, col); + int16_t indexSet = realIndex + (IS_REVERSE ? -j : j); + if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) { // watch for group out of bounds condition if (IS_MIRROR) { //set the corresponding mirrored pixel - if (reverseMode) { - busses.setPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); - } else { - busses.setPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); - } + int16_t indexSetRev = SEGMENT.stop + SEGMENT.start - indexSet - 1; + if (indexSetRev < customMappingSize) indexSetRev = customMappingTable[indexSetRev]; + busses.setPixelColor(indexSetRev, col); } + if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; + busses.setPixelColor(indexSet, col); } } } else { //live data, etc. - if (reverseMode) i = REV(i); if (i < customMappingSize) i = customMappingTable[i]; - uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); - busses.setPixelColor(i + skip, col); - } - if (skip && i == 0) { - for (uint16_t j = 0; j < skip; j++) { - busses.setPixelColor(j, BLACK); - } + busses.setPixelColor(i, col); } } @@ -498,11 +488,9 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) i = realPixelIndex(i); if (i < customMappingSize) i = customMappingTable[i]; - - if (_skipFirstMode) i += LED_SKIP_AMOUNT; - - if (i >= _lengthRaw) return 0; + if (i >= _length) return 0; + // TODO: may need to add IS_REVERSE and IS_MIRROR logic return busses.getPixelColor(i); } diff --git a/wled00/NodeStruct.cpp b/wled00/NodeStruct.cpp new file mode 100644 index 00000000..7f9cf92c --- /dev/null +++ b/wled00/NodeStruct.cpp @@ -0,0 +1,16 @@ +#include "NodeStruct.h" + +String getNodeTypeDisplayString(uint8_t nodeType) { + switch (nodeType) + { + case NODE_TYPE_ID_ESP8266: return F("ESP8266"); + case NODE_TYPE_ID_ESP32: return F("ESP32"); + } + return "Undefined"; +} + +NodeStruct::NodeStruct() : + age(0), nodeType(0) +{ + for (uint8_t i = 0; i < 4; ++i) { ip[i] = 0; } +} diff --git a/wled00/NodeStruct.h b/wled00/NodeStruct.h new file mode 100644 index 00000000..5098924a --- /dev/null +++ b/wled00/NodeStruct.h @@ -0,0 +1,33 @@ +#ifndef DATASTRUCTS_NODESTRUCT_H +#define DATASTRUCTS_NODESTRUCT_H + +/*********************************************************************************************\ +* NodeStruct from the ESP Easy project (https://github.com/letscontrolit/ESPEasy) +\*********************************************************************************************/ + +#include +#include + + +#define NODE_TYPE_ID_UNDEFINED 0 +#define NODE_TYPE_ID_ESP8266 1 +#define NODE_TYPE_ID_ESP32 2 + +String getNodeTypeDisplayString(uint8_t nodeType); + +/*********************************************************************************************\ +* NodeStruct +\*********************************************************************************************/ +struct NodeStruct +{ + NodeStruct(); + + String nodeName; + IPAddress ip; + uint8_t unit; + uint8_t age; + uint8_t nodeType; +}; +typedef std::map NodesMap; + +#endif // DATASTRUCTS_NODESTRUCT_H diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 8ed68020..610a56bf 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -17,12 +17,14 @@ struct BusConfig { uint16_t start = 0; uint8_t colorOrder = COL_ORDER_GRB; bool reversed = false; + bool skipFirst = false; uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255}; - BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false) { - type = busType; count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; + BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, bool skip = false) { + type = busType; count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipFirst = skip; uint8_t nPins = 1; - if (type > 47) nPins = 2; - else if (type > 41 && type < 46) nPins = NUM_PWM_PINS(type); + // bit 7 is hacked to include RGBW info (1=RGBW, 0=RGB) + if ((type&0x7F) > 47) nPins = 2; + else if ((type&0x7F) > 41 && (type&0x7F) < 46) nPins = NUM_PWM_PINS((type&0x7F)); for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i]; } }; @@ -61,7 +63,7 @@ class Bus { } virtual uint16_t getLength() { - return 1; + return 1; // is this ok? shouldn't it be 0 in virtual function? } virtual void setColorOrder() {} @@ -70,6 +72,10 @@ class Bus { return COL_ORDER_RGB; } + virtual bool isRgbw() { + return false; + } + uint8_t getType() { return _type; } @@ -90,19 +96,22 @@ class Bus { class BusDigital : public Bus { public: - BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) { - if (!IS_DIGITAL(bc.type) || !bc.count) return; + BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type&0x7F, bc.start) { + uint8_t type = bc.type & 0x7F; // bit 7 is hacked to include RGBW info + if (!IS_DIGITAL(type) || !bc.count) return; _pins[0] = bc.pins[0]; if (!pinManager.allocatePin(_pins[0])) return; - if (IS_2PIN(bc.type)) { + if (IS_2PIN(type)) { _pins[1] = bc.pins[1]; if (!pinManager.allocatePin(_pins[1])) { cleanup(); return; } } - _len = bc.count; + _skip = bc.skipFirst ? LED_SKIP_AMOUNT : 0; //sacrificial pixels + _len = bc.count + _skip; reversed = bc.reversed; - _iType = PolyBus::getI(bc.type, _pins, nr); + _rgbw = (bool)((bc.type>>7) & 0x01); // RGBW override in bit 7 + _iType = PolyBus::getI(type, _pins, nr, _rgbw); if (_iType == I_NONE) return; _busPtr = PolyBus::create(_iType, _pins, _len); _valid = (_busPtr != nullptr); @@ -131,11 +140,13 @@ class BusDigital : public Bus { void setPixelColor(uint16_t pix, uint32_t c) { if (reversed) pix = _len - pix -1; + pix += _skip; PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder); } uint32_t getPixelColor(uint16_t pix) { if (reversed) pix = _len - pix -1; + pix += _skip; return PolyBus::getPixelColor(_busPtr, _iType, pix, _colorOrder); } @@ -144,7 +155,7 @@ class BusDigital : public Bus { } uint16_t getLength() { - return _len; + return _len - _skip; } uint8_t getPins(uint8_t* pinArray) { @@ -158,6 +169,10 @@ class BusDigital : public Bus { _colorOrder = colorOrder; } + bool isRgbw() { + return _rgbw; + } + void reinit() { PolyBus::begin(_busPtr, _iType, _pins); } @@ -181,6 +196,8 @@ class BusDigital : public Bus { uint8_t _pins[2] = {255, 255}; uint8_t _iType = I_NONE; uint16_t _len = 0; + uint8_t _skip = 0; + bool _rgbw = false; void * _busPtr = nullptr; }; @@ -264,6 +281,10 @@ class BusPwm : public Bus { return numPins; } + bool isRgbw() { + return (_type > TYPE_ONOFF && _type <= TYPE_ANALOG_5CH && _type != TYPE_ANALOG_3CH); + } + void cleanup() { deallocatePins(); } @@ -305,8 +326,9 @@ class BusManager { } else { busses[numBusses] = new BusPwm(bc); } - numBusses++; - return numBusses -1; +// numBusses++; +// return numBusses -1; + return numBusses++; } //do not call this method from system context (network callback) @@ -331,6 +353,7 @@ class BusManager { uint16_t bstart = b->getStart(); if (pix < bstart || pix >= bstart + b->getLength()) continue; busses[i]->setPixelColor(pix - bstart, c); + break; } } diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index da3f96e3..d588586f 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -79,23 +79,25 @@ #define I_32_R7_TM1_4 54 #define I_32_I0_TM1_4 55 #define I_32_I1_TM1_4 56 -//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S) +//Bit Bang theoretically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S) //APA102 #define I_HS_DOT_3 57 //hardware SPI #define I_SS_DOT_3 58 //soft SPI +#define I_HS_DOT_4 59 //hardware SPI, RGBW? +#define I_SS_DOT_4 60 //soft SPI, RGBW? //LPD8806 -#define I_HS_LPD_3 59 -#define I_SS_LPD_3 60 +#define I_HS_LPD_3 61 +#define I_SS_LPD_3 62 //WS2801 -#define I_HS_WS1_3 61 -#define I_SS_WS1_3 62 +#define I_HS_WS1_3 63 +#define I_SS_WS1_3 64 //P9813 -#define I_HS_P98_3 63 -#define I_SS_P98_3 64 +#define I_HS_P98_3 65 +#define I_SS_P98_3 66 /*** ESP8266 Neopixel methods ***/ @@ -173,8 +175,10 @@ #endif //APA102 -#define B_HS_DOT_3 NeoPixelBrightnessBus //hardware SPI -#define B_SS_DOT_3 NeoPixelBrightnessBus //soft SPI +#define B_HS_DOT_3 NeoPixelBrightnessBus // hardware SPI +#define B_SS_DOT_3 NeoPixelBrightnessBus // soft SPI +#define B_HS_DOT_4 NeoPixelBrightnessBus // HW SPI, RGBW mode? +#define B_SS_DOT_4 NeoPixelBrightnessBus // soft SPI, RGBW mode? //LPD8806 #define B_HS_LPD_3 NeoPixelBrightnessBus @@ -212,6 +216,7 @@ class PolyBus { case I_8266_DM_TM1_4: (static_cast(busPtr))->Begin(); break; case I_8266_BB_TM1_4: (static_cast(busPtr))->Begin(); break; case I_HS_DOT_3: (static_cast(busPtr))->Begin(); break; + case I_HS_DOT_4: (static_cast(busPtr))->Begin(); break; case I_HS_LPD_3: (static_cast(busPtr))->Begin(); break; case I_HS_WS1_3: (static_cast(busPtr))->Begin(); break; case I_HS_P98_3: (static_cast(busPtr))->Begin(); break; @@ -259,11 +264,13 @@ class PolyBus { case I_32_I1_TM1_4: (static_cast(busPtr))->Begin(); break; // ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin() case I_HS_DOT_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break; + case I_HS_DOT_4: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break; case I_HS_LPD_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break; case I_HS_WS1_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break; case I_HS_P98_3: (static_cast(busPtr))->Begin(pins[1], -1, pins[0], -1); break; #endif case I_SS_DOT_3: (static_cast(busPtr))->Begin(); break; + case I_SS_DOT_4: (static_cast(busPtr))->Begin(); break; case I_SS_LPD_3: (static_cast(busPtr))->Begin(); break; case I_SS_WS1_3: (static_cast(busPtr))->Begin(); break; case I_SS_P98_3: (static_cast(busPtr))->Begin(); break; @@ -336,6 +343,8 @@ class PolyBus { // for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat) case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[1], pins[0]); break; case I_SS_DOT_3: busPtr = new B_SS_DOT_3(len, pins[1], pins[0]); break; + case I_HS_DOT_4: busPtr = new B_HS_DOT_4(len, pins[1], pins[0]); break; + case I_SS_DOT_4: busPtr = new B_SS_DOT_4(len, pins[1], pins[0]); break; case I_HS_LPD_3: busPtr = new B_HS_LPD_3(len, pins[1], pins[0]); break; case I_SS_LPD_3: busPtr = new B_SS_LPD_3(len, pins[1], pins[0]); break; case I_HS_WS1_3: busPtr = new B_HS_WS1_3(len, pins[1], pins[0]); break; @@ -411,6 +420,8 @@ class PolyBus { #endif case I_HS_DOT_3: (static_cast(busPtr))->Show(); break; case I_SS_DOT_3: (static_cast(busPtr))->Show(); break; + case I_HS_DOT_4: (static_cast(busPtr))->Show(); break; + case I_SS_DOT_4: (static_cast(busPtr))->Show(); break; case I_HS_LPD_3: (static_cast(busPtr))->Show(); break; case I_SS_LPD_3: (static_cast(busPtr))->Show(); break; case I_HS_WS1_3: (static_cast(busPtr))->Show(); break; @@ -484,6 +495,8 @@ class PolyBus { #endif case I_HS_DOT_3: return (static_cast(busPtr))->CanShow(); break; case I_SS_DOT_3: return (static_cast(busPtr))->CanShow(); break; + case I_HS_DOT_4: return (static_cast(busPtr))->CanShow(); break; + case I_SS_DOT_4: return (static_cast(busPtr))->CanShow(); break; case I_HS_LPD_3: return (static_cast(busPtr))->CanShow(); break; case I_SS_LPD_3: return (static_cast(busPtr))->CanShow(); break; case I_HS_WS1_3: return (static_cast(busPtr))->CanShow(); break; @@ -500,11 +513,6 @@ class PolyBus { uint8_t w = c >> 24; RgbwColor col; - //TODO make color order override possible on a per-strip basis - #ifdef COLOR_ORDER_OVERRIDE - if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; - #endif - //reorder channels to selected order switch (co) { @@ -581,6 +589,8 @@ class PolyBus { #endif case I_HS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; case I_SS_DOT_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_HS_DOT_4: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; + case I_SS_DOT_4: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; case I_HS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; case I_SS_LPD_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; case I_HS_WS1_3: (static_cast(busPtr))->SetPixelColor(pix, RgbColor(col.R,col.G,col.B)); break; @@ -654,6 +664,8 @@ class PolyBus { #endif case I_HS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break; case I_SS_DOT_3: (static_cast(busPtr))->SetBrightness(b); break; + case I_HS_DOT_4: (static_cast(busPtr))->SetBrightness(b); break; + case I_SS_DOT_4: (static_cast(busPtr))->SetBrightness(b); break; case I_HS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break; case I_SS_LPD_3: (static_cast(busPtr))->SetBrightness(b); break; case I_HS_WS1_3: (static_cast(busPtr))->SetBrightness(b); break; @@ -728,6 +740,8 @@ class PolyBus { #endif case I_HS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_SS_DOT_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_HS_DOT_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; + case I_SS_DOT_4: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_HS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_SS_LPD_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; case I_HS_WS1_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; @@ -736,10 +750,6 @@ class PolyBus { case I_SS_P98_3: col = (static_cast(busPtr))->GetPixelColor(pix); break; } - #ifdef COLOR_ORDER_OVERRIDE - if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; - #endif - switch (co) { // W G R B @@ -819,6 +829,8 @@ class PolyBus { #endif case I_HS_DOT_3: delete (static_cast(busPtr)); break; case I_SS_DOT_3: delete (static_cast(busPtr)); break; + case I_HS_DOT_4: delete (static_cast(busPtr)); break; + case I_SS_DOT_4: delete (static_cast(busPtr)); break; case I_HS_LPD_3: delete (static_cast(busPtr)); break; case I_SS_LPD_3: delete (static_cast(busPtr)); break; case I_HS_WS1_3: delete (static_cast(busPtr)); break; @@ -829,7 +841,7 @@ class PolyBus { } //gives back the internal type index (I_XX_XXX_X above) for the input - static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0) { + static uint8_t getI(uint8_t busType, uint8_t* pins, uint8_t num = 0, bool rgbwOverride = false) { if (!IS_DIGITAL(busType)) return I_NONE; if (IS_2PIN(busType)) { //SPI LED chips bool isHSPI = false; @@ -840,7 +852,7 @@ class PolyBus { #endif uint8_t t = I_NONE; switch (busType) { - case TYPE_APA102: t = I_SS_DOT_3; break; + case TYPE_APA102: t = rgbwOverride ? I_SS_DOT_4 : I_SS_DOT_3; break; case TYPE_LPD8806: t = I_SS_LPD_3; break; case TYPE_WS2801: t = I_SS_WS1_3; break; case TYPE_P9813: t = I_SS_P98_3; break; @@ -855,9 +867,9 @@ class PolyBus { switch (busType) { case TYPE_WS2812_RGB: case TYPE_WS2812_WWA: - return I_8266_U0_NEO_3 + offset; +// return I_8266_U0_NEO_3 + offset; case TYPE_SK6812_RGBW: - return I_8266_U0_NEO_4 + offset; + return (rgbwOverride ? I_8266_U0_NEO_4 : I_8266_U0_NEO_3) + offset; case TYPE_WS2811_400KHZ: return I_8266_U0_400_3 + offset; } @@ -867,9 +879,9 @@ class PolyBus { switch (busType) { case TYPE_WS2812_RGB: case TYPE_WS2812_WWA: - return I_32_R0_NEO_3 + offset; +// return I_32_R0_NEO_3 + offset; case TYPE_SK6812_RGBW: - return I_32_R0_NEO_4 + offset; + return (rgbwOverride ? I_32_R0_NEO_4 : I_32_R0_NEO_3) + offset; case TYPE_WS2811_400KHZ: return I_32_R0_400_3 + offset; } diff --git a/wled00/button.cpp b/wled00/button.cpp index 458ff22a..0e354142 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -94,7 +94,8 @@ void handleIO() { if (!offMode) { #ifdef ESP8266 - //turn off built-in LED if strip is turned off + // turn off built-in LED if strip is turned off + // this will break digital bus so will need to be reinitialised on On pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); #endif diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 2175c97b..514c3fba 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -90,16 +90,18 @@ void deserializeConfig() { // initialize LED pins and lengths prior to other HW JsonObject hw_led = hw[F("led")]; - CJSON(ledCount, hw_led[F("total")]); - if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; +// CJSON(ledCount, hw_led[F("total")]); +// if (ledCount > MAX_LEDS) ledCount = MAX_LEDS; + ledCount = 0; CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]); CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); - CJSON(strip.reverseMode, hw_led[F("rev")]); + //CJSON(strip.reverseMode, hw_led[F("rev")]); CJSON(strip.rgbwMode, hw_led[F("rgbwm")]); JsonArray ins = hw_led["ins"]; uint8_t s = 0; + bool skipFirst = skipFirstLed = false; useRGBW = false; busses.removeAll(); for (JsonObject elm : ins) { @@ -107,32 +109,36 @@ void deserializeConfig() { uint8_t pins[5] = {255, 255, 255, 255, 255}; JsonArray pinArr = elm[F("pin")]; if (pinArr.size() == 0) continue; - pins[0] = pinArr[0]; +// pins[0] = pinArr[0]; uint8_t i = 0; for (int p : pinArr) { - pins[i] = p; - i++; + pins[i++] = p; +// i++; if (i>4) break; } uint16_t length = elm[F("len")]; - if (length==0) continue; - uint8_t colorOrder = (int)elm[F("order")]; - //only use skip from the first strip (this shouldn't have been in ins obj. but remains here for compatibility) - if (s==0) skipFirstLed = elm[F("skip")]; + if (length==0 || length+ledCount > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop + // maybe we should have + // start = ledCount; // length of previous strips uint16_t start = elm[F("start")] | 0; - if (start >= ledCount) continue; + if (start >= ledCount+length) continue; // something is very wrong :) //limit length of strip if it would exceed total configured LEDs - if (start + length > ledCount) length = ledCount - start; + //if (start + length > ledCount) length = ledCount - start; + uint8_t colorOrder = (int)elm[F("order")]; + //(this shouldn't have been in ins obj. but remains here for compatibility) + skipFirstLed |= skipFirst = (bool) elm[F("skip")]; uint8_t ledType = elm[F("type")] | TYPE_WS2812_RGB; bool reversed = elm[F("rev")]; //RGBW mode is enabled if at least one of the strips is RGBW - useRGBW = (useRGBW || BusManager::isRgbw(ledType)); + if ((bool)elm[F("rgbw")]) SET_BIT(ledType,7); else UNSET_BIT(ledType,7); // hack bit 7 to indicate RGBW (as an override if necessary) + useRGBW |= (bool)elm[F("rgbw")]; s++; - BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed); + ledCount += length; + BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst); busses.add(bc); } - strip.finalizeInit(useRGBW, ledCount, skipFirstLed); + strip.finalizeInit(); JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0]; CJSON(buttonEnabled, hw_btn_ins_0[F("type")]); @@ -441,7 +447,7 @@ void serializeConfig() { hw_led[F("total")] = ledCount; hw_led[F("maxpwr")] = strip.ablMilliampsMax; hw_led[F("ledma")] = strip.milliampsPerLed; - hw_led[F("rev")] = strip.reverseMode; + hw_led[F("rev")] = false; //strip.reverseMode; // not used anymore, reversing per-strip hw_led[F("rgbwm")] = strip.rgbwMode; JsonArray hw_led_ins = hw_led.createNestedArray("ins"); @@ -452,16 +458,17 @@ void serializeConfig() { if (!bus || bus->getLength()==0) break; JsonObject ins = hw_led_ins.createNestedObject(); ins[F("en")] = true; - ins[F("start")] = bus->getStart(); + ins[F("start")] = bus->getStart(); // really needed? ins[F("len")] = bus->getLength(); JsonArray ins_pin = ins.createNestedArray("pin"); uint8_t pins[5]; uint8_t nPins = bus->getPins(pins); for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]); ins[F("order")] = bus->getColorOrder(); - ins[F("rev")] = bus->reversed; - ins[F("skip")] = (skipFirstLed && s == 0) ? 1 : 0; + ins[F("rev")] = bus->reversed; + ins[F("skip")] = skipFirstLed ? 1 : 0; ins[F("type")] = bus->getType(); + ins[F("rgbw")] = bus->isRgbw(); } JsonObject hw_btn = hw.createNestedObject("btn"); diff --git a/wled00/const.h b/wled00/const.h index 2a355d62..0a916329 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -207,7 +207,7 @@ // Size of buffer for API JSON object (increase for more segments) #ifdef ESP8266 - #define JSON_BUFFER_SIZE 9216 + #define JSON_BUFFER_SIZE 10240 #else #define JSON_BUFFER_SIZE 16384 #endif diff --git a/wled00/data/index.css b/wled00/data/index.css index 606d6970..69c4d19b 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -214,7 +214,7 @@ button { .top button { padding: var(--tbp); -} +} .bot button { padding: var(--bbp); @@ -251,7 +251,6 @@ button { position: relative; width: 100%; width: calc(100%/var(--n)); - padding: 11px 0; box-sizing: border-box; border: 0px; overflow: auto; @@ -260,10 +259,7 @@ button { } #Effects { - padding-top: 0; - margin-top: 11px; - height: calc(100% - 11px); - -webkit-overflow-scrolling: touch; + -webkit-overflow-scrolling: touch; } .smooth { transition: transform calc(var(--f, 1)*.5s) ease-out } @@ -297,10 +293,7 @@ button { background: var(--c-1); top: -1px; z-index: 1; - margin-top: 1px; - width: 274px; - margin: auto; - border-radius: 25px; + margin: 1px auto auto; } #staytop1 { @@ -432,16 +425,23 @@ img { } .sliderbubble { - width: 36px; - line-height: 24px; - background: var(--c-3); - position: absolute; - transform: translateX(-50%); - border-radius: 12px; - margin-left: 12px; - margin-top: 3px; - padding: 0px; - display: inline; + width: 24px; + position: relative; + display: inline-block; + border-radius: 5px; + background: var(--c-3); + color: white; + padding: 2px 5px; + font-size: 14px; + right: 5px; + transition: visibility 0.25s ease, opacity 0.25s ease; + opacity: 0; + visibility: hidden; +} + +output.sliderbubbleshow { + visibility: visible; + opacity: 1; } .hidden { @@ -487,11 +487,6 @@ input[type=range]::-moz-range-thumb { background: var(--c-f); transform: translateY(7px); } -input[type=range]:active + .sliderbubble { - display: inline; - transform: translateX(-50%); -} - #wwrap { display: none; } @@ -633,7 +628,7 @@ textarea { } ::selection { - background: var(--c-b); + background: var(--c-b); } input[type=text] { @@ -655,8 +650,8 @@ input[type=number]:focus, input[type=text]:focus { background: var(--c-6); } -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; } @@ -683,13 +678,13 @@ input[type=number]::-webkit-outer-spin-button { } .pid { - position: absolute; - top: 0px; - left: 0px; - padding: 11px 0px 0px 11px; - font-size: 16px; - width: 20px; - text-align: center; + position: absolute; + top: 0px; + left: 0px; + padding: 11px 0px 0px 11px; + font-size: 16px; + width: 20px; + text-align: center; color: var(--c-b); } @@ -729,7 +724,7 @@ input[type=number]::-webkit-outer-spin-button { } .pwr { - color: var(--c-6); + color: var(--c-6); transform: translate(2px, 3px); cursor: pointer; } @@ -761,7 +756,7 @@ input[type=number]::-webkit-outer-spin-button { } .schkl { - padding: 2px 22px 0px 35px; + padding: 2px 5px 0px 35px; margin: 0 0 0 2px; } @@ -860,7 +855,101 @@ input[type=number]::-webkit-outer-spin-button { border-radius: 20px; text-align: left; transition: background-color 0.5s; - filter: brightness(1); + filter: brightness(1); +} + +.list { + position: relative; + width: 260px; + border-radius: 20px; + background-color: var(--c-2); + transition: background-color 0.5s; + overflow: hidden; + margin: auto auto 20px; + padding-bottom: 5px; +} +.lstI { + position: relative; + border-bottom: 1px solid var(--c-3); + display: flex; + align-items: center; + padding: 8px 10px; + cursor: pointer; +} + +.lstI:hover { + background: var(--c-4); +} + +.lstI:last-child { + border: none; +} + +.lstI.selected { + background: var(--c-5); +} + +.lstIcontent { + width: 100%; + vertical-align: middle; + padding: 0 20px 0 5px; + text-align: left; +} + +.lstIname { + margin: 3px 0; + white-space: nowrap; + cursor: pointer; +} + +.lstIprev { + border: 1px solid var(--c-4); + border-radius: 4px; + width: 100%; + height: 8px; + margin: auto; +} + +.fndIcn { /* needed for magnifier SVG, can be removed when magnifier is in Wicons font */ + width: 24px; + height: 24px; + stroke: var(--c-e); + stroke-width: 3px; + fill-opacity: 0; +} + +div.fnd div { + position: absolute; + top: 10px; + left: 13px; +} + +div.fnd span { + position: absolute; + display: none; + top: 10px; + right: 13px; + cursor: pointer; +} + +input[type="text"].fnd { + display: block; + width: 260px; + box-sizing: border-box; + padding: 8px 48px 8px 60px; + margin: 0 auto 10px; + text-align: left; + border-radius: 0; + background: var(--c-1); + border-bottom: 1px solid var(--c-3); +} + +input[type="text"].fnd:focus { + background-color: var(--c-5); +} + +input[type="text"].fnd:not(:placeholder-shown) { + background-color: var(--c-4); } .pres { @@ -893,7 +982,7 @@ input[type=number]::-webkit-outer-spin-button { width: 6px; } ::-webkit-scrollbar-track { - background: transparent; + background: transparent; } ::-webkit-scrollbar-thumb { background: var(--c-sb); @@ -904,6 +993,13 @@ input[type=number]::-webkit-outer-spin-button { background: var(--c-sbh); } +@media not all and (hover: none) { + .sliderwrap:hover + output.sliderbubble { + visibility: visible; + opacity: 1; + } +} + @media all and (max-width: 335px) { .sliderbubble { display: none; @@ -934,4 +1030,4 @@ input[type=number]::-webkit-outer-spin-button { #buttonPcm { display: none; } -} \ No newline at end of file +} diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 9bdaae86..209b4a36 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -35,6 +35,7 @@
+ @@ -45,17 +46,26 @@
-
- -
+
+
+ +
+
+

-
- -
+
+
+ +
+
+

-
- -
+
+
+ +
+
+

@@ -63,6 +73,7 @@
+
@@ -87,51 +98,77 @@
-

Color palette

+

Color palette

- +
+ + +
+
+
+
+ +
+ + Default + +
+
+
+
+ + Loading + +
+
+ +

Effect speed

-
+
-
+

Effect intensity

-
+
-

Effect mode

-
- +
+
+ + +
+
+

Effect mode

+
+ Loading... +
-
- Loading... -
-
- +
+
+ +
Loading... -
-
-
@@ -139,8 +176,8 @@
-
- +
+
@@ -148,7 +185,7 @@
Loading...

-
@@ -196,4 +233,4 @@ - \ No newline at end of file + diff --git a/wled00/data/index.js b/wled00/data/index.js index 563e6fb0..3b39df11 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1,13 +1,16 @@ //page js +const lsPalKey = "wledPalx"; var loc = false, locip; var noNewSegs = false; var isOn = false, nlA = false, isLv = false, isInfo = false, syncSend = false, syncTglRecv = true, isRgbw = false; var whites = [0,0,0]; +var selColors; var expanded = [false]; var powered = [true]; var nlDur = 60, nlTar = 0; var nlFade = false; var selectedFx = 0; +var selectedPal = 0; var csel = 0; var currentPreset = -1; var lastUpdate = 0; @@ -15,7 +18,8 @@ var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0; var pcMode = false, pcModeA = false, lastw = 0; var d = document; const ranges = RangeTouch.setup('input[type="range"]', {}); -var pJson = {}; +var palettesData; +var pJson = {}, eJson = {}, lJson = {}; var pN = "", pI = 0; var pmt = 1, pmtLS = 0, pmtLast = 0; var lastinfo = {}; @@ -29,17 +33,17 @@ var cpick = new iro.ColorPicker("#picker", { wheelLightness: false, wheelAngle: 90, layout: [ - { + { component: iro.ui.Wheel, options: {} }, - { + { component: iro.ui.Slider, options: { sliderType: 'value' } }, - { + { component: iro.ui.Slider, options: { sliderType: 'kelvin', @@ -157,7 +161,6 @@ function loadBg(iUrl) { } img.addEventListener('load', (event) => { var a = parseFloat(cfg.theme.alpha.bg); - d.getElementById('staytop2').style.background = "transparent"; if (isNaN(a)) a = 0.6; bg.style.opacity = a; bg.style.backgroundImage = `url(${img.src})`; @@ -167,22 +170,22 @@ function loadBg(iUrl) { function onLoad() { if (window.location.protocol == "file:") { - loc = true; - locip = localStorage.getItem('locIp'); - if (!locip) - { - locip = prompt("File Mode. Please enter WLED IP!"); - localStorage.setItem('locIp', locip); - } + loc = true; + locip = localStorage.getItem('locIp'); + if (!locip) + { + locip = prompt("File Mode. Please enter WLED IP!"); + localStorage.setItem('locIp', locip); + } } var sett = localStorage.getItem('wledUiCfg'); if (sett) cfg = mergeDeep(cfg, JSON.parse(sett)); - + resetPUtil(); - + applyCfg(); loadBg(cfg.theme.bg.url); - + var cd = d.getElementById('csl').children; for (var i = 0; i < cd.length; i++) { cd[i].style.backgroundColor = "rgb(0, 0, 0)"; @@ -194,14 +197,26 @@ function onLoad() { setColor(1); }); pmtLS = localStorage.getItem('wledPmt'); - setTimeout(function(){requestJson(null, false);}, 25); + + // Load initial data + getPalettesDataCached(); + loadPalettes(function() { + loadFX(function() { + loadPresets(function() { + requestJson(null, false, true, function() { + loadPalettesData(); + }); + }); + }); + }); + d.addEventListener("visibilitychange", handleVisibilityChange, false); size(); d.getElementById("cv").style.opacity=0; if (localStorage.getItem('pcm') == "true") togglePcMode(true); var sls = d.querySelectorAll('input[type="range"]'); for (var sl of sls) { - sl.addEventListener('input', updateBubble, true); + //sl.addEventListener('input', updateBubble, true); sl.addEventListener('touchstart', toggleBubble); sl.addEventListener('touchend', toggleBubble); } @@ -233,7 +248,7 @@ function showToast(text, error = false) { x.className = error ? "error":"show"; clearTimeout(timeout); x.style.animation = 'none'; - x.style.animation = null; + x.style.animation = null; timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); } @@ -255,23 +270,21 @@ function getRuntimeStr(rt) if (!days && hrs) str += ", "; if (t > 59 && !days) str += mins + " min"; if (t < 3600 && t > 59) str += ", "; - if (t < 3600) str += (t - mins*60) + " sec"; + if (t < 3600) str += (t - mins*60) + " sec"; return str; } -function inforow(key, val, unit = "") -{ +function inforow(key, val, unit = "") { return `${key}${val}${unit}`; } -function getLowestUnusedP() -{ +function getLowestUnusedP() { var l = 1; for (var key in pJson) { if (key == l) l++; - } - if (l > 250) l = 250; + } + if (l > 250) l = 250; return l; } @@ -285,13 +298,14 @@ function checkUsed(i) { } function pName(i) { + if (!pJson || !pJson[i]) return ""; var n = "Preset " + i; if (pJson[i].n) n = pJson[i].n; return n; } function papiVal(i) { - if (!pJson[i]) return ""; + if (!pJson || !pJson[i]) return ""; var o = Object.assign({},pJson[i]); if (o.win) return o.win; delete o.n; delete o.p; delete o.ql; @@ -299,9 +313,8 @@ function papiVal(i) { } function qlName(i) { - if (!pJson[i]) return ""; - if (!pJson[i].ql) return ""; - return pJson[i].ql; + if (!pJson || !pJson[i] || !pJson[i].ql) return ""; + return pJson[i].ql; } function cpBck() { @@ -311,7 +324,7 @@ function cpBck() { copyText.setSelectionRange(0, 999999); document.execCommand("copy"); - + showToast("Copied to clipboard!"); } @@ -322,12 +335,12 @@ function presetError(empty) bckstr = localStorage.getItem("wledP"); if (bckstr.length > 10) hasBackup = true; } catch (e) { - + } var cn = `
`; - if (empty) + if (empty) cn += `You have no presets yet!`; - else + else cn += `Sorry, there was an issue loading your presets!`; if (hasBackup) { @@ -345,13 +358,13 @@ function presetError(empty) if (hasBackup) d.getElementById('bck').value = bckstr; } -function loadPresets() +function loadPresets(callback = null) { var url = '/presets.json'; if (loc) { url = `http://${locip}/presets.json`; } - + fetch (url, { method: 'get' @@ -365,11 +378,87 @@ function loadPresets() .then(json => { pJson = json; populatePresets(); + if (callback) { + callback(); + } }) .catch(function (error) { showToast(error, true); console.log(error); presetError(false); + if (callback) { + callback(); + } + }); +} + +function loadPalettes(callback = null) +{ + var url = '/json/palettes'; + if (loc) { + url = `http://${locip}/json/palettes`; + } + + fetch + (url, { + method: 'get' + }) + .then(res => { + if (!res.ok) { + showErrorToast(); + } + return res.json(); + }) + .then(json => { + lJson = Object.entries(json); + populatePalettes(); + updateUI(); + if (callback) { + callback(); + } + }) + .catch(function (error) { + showToast(error, true); + console.log(error); + presetError(false); + if (callback) { + callback(); + } + }); +} + +function loadFX(callback = null) +{ + var url = '/json/effects'; + if (loc) { + url = `http://${locip}/json/effects`; + } + + fetch + (url, { + method: 'get' + }) + .then(res => { + if (!res.ok) { + showErrorToast(); + } + return res.json(); + }) + .then(json => { + eJson = Object.entries(json); + populateEffects(); + updateUI(); + if (callback) { + callback(); + } + }) + .catch(function (error) { + showToast(error, true); + console.log(error); + presetError(false); + if (callback) { + callback(); + } }); } @@ -380,7 +469,7 @@ function populateQL() var cn = ""; if (pQL.length > 0) { cn += `

Quick load

`; - + var it = 0; for (var key of (pQL||[])) { @@ -392,7 +481,7 @@ function populateQL() } } if (it != 0) cn+= '
'; - + cn += `

All presets

`; } d.getElementById('pql').innerHTML = cn; @@ -401,13 +490,14 @@ function populateQL() function populatePresets(fromls) { if (fromls) pJson = JSON.parse(localStorage.getItem("wledP")); + if (!pJson) {pJson={};return}; delete pJson["0"]; var cn = ""; var arr = Object.entries(pJson); arr.sort(cmpP); var added = false; - pQL = []; - var is = []; + pQL = []; + var is = []; for (var key of (arr||[])) { @@ -416,7 +506,7 @@ function populatePresets(fromls) var qll = key[1].ql; if (qll) pQL.push([i, qll]); is.push(i); - + cn += `
`; if (cfg.comp.pid) cn += `
${i}
`; cn += `
${pName(i)}
@@ -452,29 +542,39 @@ function populateInfo(i) var pwru = "Not calculated"; if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";} else if (pwr > 0) {pwr = 50 * Math.round(pwr/50); pwru = pwr + " mA";} - var urows=""; - if (i.u) { - for (const [k, val] of Object.entries(i.u)) - { - if (val[1]) { - urows += inforow(k,val[0],val[1]); - } else { - urows += inforow(k,val); - } - } - } + var urows=""; + if (i.nodes) { + i.nodes.sort((a,b) => (a.name).localeCompare(b.name)); + for (var x=0;x${o.name}`; + urows += inforow(url,o.type); + } + } + } + if (i.u) { + for (const [k, val] of Object.entries(i.u)) + { + if (val[1]) { + urows += inforow(k,val[0],val[1]); + } else { + urows += inforow(k,val); + } + } + } var vcn = "Kuuhaku"; - if (i.ver.startsWith("0.12.")) vcn = "Hikari"; + if (i.ver.startsWith("0.11.")) vcn = "Mirai"; if (i.cn) vcn = i.cn; - + cn += `v${i.ver} "${vcn}"

${urows} ${inforow("Build",i.vid)} ${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")} ${inforow("Uptime",getRuntimeStr(i.uptime))} ${inforow("Free heap",heap," kB")} - ${inforow("Estimated current",pwru)} - ${inforow("Frames / second",i.leds.fps)} + ${inforow("Estimated current",pwru)} ${inforow("MAC address",i.mac)} ${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")} ${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} @@ -486,17 +586,17 @@ function populateSegments(s) { var cn = ""; segCount = 0; lowestUnused = 0; lSeg = 0; - + for (var y = 0; y < (s.seg||[]).length; y++) { segCount++; - + var inst=s.seg[y]; let i = parseInt(inst.id); powered[i] = inst.on; if (i == lowestUnused) lowestUnused = i+1; if (i > lSeg) lSeg = i; - + cn += `