diff --git a/platformio.ini b/platformio.ini index 158661f84..121d75270 100644 --- a/platformio.ini +++ b/platformio.ini @@ -61,7 +61,7 @@ arduino_core_develop = https://github.com/platformio/platform-espressif8266#deve arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage # Platform to use for ESP8266 -platform_wled_default = ${common.arduino_core_3_0_2} +platform_wled_default = ${common.arduino_core_2_7_4} # We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7 platformio/toolchain-xtensa @ ~2.40802.200502 diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp b/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp index 9724a1b7b..36d322fa0 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp +++ b/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp @@ -100,9 +100,9 @@ void userLoop() { needRedraw = true; } else if (knownBrightness != bri) { needRedraw = true; - } else if (knownMode != strip.getMode()) { + } else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { + } else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -126,8 +126,8 @@ void userLoop() { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; u8x8.clear(); u8x8.setFont(u8x8_font_chroma48medium8_r); diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/usermod_bme280.cpp b/usermods/Enclosure_with_OLED_temp_ESP07/usermod_bme280.cpp index c39c74d2c..587312832 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/usermod_bme280.cpp +++ b/usermods/Enclosure_with_OLED_temp_ESP07/usermod_bme280.cpp @@ -143,9 +143,9 @@ void userLoop() { needRedraw = true; } else if (knownBrightness != bri) { needRedraw = true; - } else if (knownMode != strip.getMode()) { + } else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { + } else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -169,8 +169,8 @@ void userLoop() { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; u8x8.clear(); u8x8.setFont(u8x8_font_chroma48medium8_r); diff --git a/usermods/PIR_sensor_switch/PIR_Highlight_Standby b/usermods/PIR_sensor_switch/PIR_Highlight_Standby index 4cca1874d..152388e8b 100644 --- a/usermods/PIR_sensor_switch/PIR_Highlight_Standby +++ b/usermods/PIR_sensor_switch/PIR_Highlight_Standby @@ -61,7 +61,7 @@ class PIRsensorSwitch : public Usermod { private: // PIR sensor pin const uint8_t PIRsensorPin = 13; // D7 on D1 mini - // notification mode for colorUpdated() + // notification mode for stateUpdated() const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // CALL_MODE_DIRECT_CHANGE // 1 min delay before switch off after the sensor state goes LOW uint32_t m_switchOffDelay = 60000; @@ -127,7 +127,7 @@ class PIRsensorSwitch : public Usermod { if (bri != briHighlight) { bri = briHighlight; // set current highlight brightness to last set highlight brightness } - colorUpdated(NotifyUpdateMode); + stateUpdated(NotifyUpdateMode); highlightActive = true; // flag highlight is on } else { // **pir timer has elapsed** @@ -157,7 +157,7 @@ class PIRsensorSwitch : public Usermod { } applyMacro(macroLongPress); // apply standby lighting without brightness } - colorUpdated(NotifyUpdateMode); + stateUpdated(NotifyUpdateMode); highlightActive = false; // flag highlight is off } } diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 8e683a497..8085d79a9 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -61,7 +61,7 @@ private: bool savedState = false; uint32_t offTimerStart = 0; // off timer start time - byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for colorUpdated(): CALL_MODE_NO_NOTIFY or CALL_MODE_DIRECT_CHANGE + byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for stateUpdated(): CALL_MODE_NO_NOTIFY or CALL_MODE_DIRECT_CHANGE byte sensorPinState = LOW; // current PIR sensor pin state bool initDone = false; // status of initialization bool PIRtriggered = false; @@ -136,7 +136,7 @@ private: // preset not assigned if (bri == 0) { bri = briLast; - colorUpdated(NotifyUpdateMode); + stateUpdated(NotifyUpdateMode); } } else { if (m_offPreset) { @@ -159,7 +159,7 @@ private: if (bri != 0) { briLast = bri; bri = 0; - colorUpdated(NotifyUpdateMode); + stateUpdated(NotifyUpdateMode); } } } diff --git a/usermods/ST7789_display/ST7789_display.h b/usermods/ST7789_display/ST7789_display.h index bd501d08f..19ad5790a 100644 --- a/usermods/ST7789_display/ST7789_display.h +++ b/usermods/ST7789_display/ST7789_display.h @@ -118,11 +118,11 @@ class St7789DisplayUsermod : public Usermod { { needRedraw = true; } - else if (knownMode != strip.getMode()) + else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; } - else if (knownPalette != strip.getSegment(0).palette) + else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -148,8 +148,8 @@ class St7789DisplayUsermod : public Usermod { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; tft.fillScreen(TFT_BLACK); tft.setTextSize(2); diff --git a/usermods/TTGO-T-Display/usermod.cpp b/usermods/TTGO-T-Display/usermod.cpp index 75e90b1eb..9e08a001a 100644 --- a/usermods/TTGO-T-Display/usermod.cpp +++ b/usermods/TTGO-T-Display/usermod.cpp @@ -110,9 +110,9 @@ void userLoop() { needRedraw = true; } else if (knownBrightness != bri) { needRedraw = true; - } else if (knownMode != strip.getMode()) { + } else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { + } else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -136,8 +136,8 @@ void userLoop() { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; tft.fillScreen(TFT_BLACK); tft.setTextSize(2); diff --git a/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h index 9597992fd..210ec3f58 100644 --- a/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h +++ b/usermods/VL53L0X_gestures/usermod_vl53l0x_gestures.h @@ -106,7 +106,7 @@ class UsermodVL53L0XGestures : public Usermod { // set brightness according to range bri = (VL53L0X_MAX_RANGE_MM - max(range, VL53L0X_MIN_RANGE_OFFSET)) * 255 / (VL53L0X_MAX_RANGE_MM - VL53L0X_MIN_RANGE_OFFSET); DEBUG_PRINTF(F("new brightness: %d"), bri); - colorUpdated(1); + stateUpdated(1); } } else if (wasMotionBefore) { //released long dur = millis() - motionStartTime; diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp index a93b20c99..79241b5e2 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp @@ -137,9 +137,9 @@ void userLoop() { needRedraw = true; } else if (knownBrightness != bri) { needRedraw = true; - } else if (knownMode != strip.getMode()) { + } else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { + } else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -163,8 +163,8 @@ void userLoop() { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; u8x8.clear(); u8x8.setFont(u8x8_font_chroma48medium8_r); diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod_bme280.cpp b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod_bme280.cpp index 15ec58add..fe53a4628 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod_bme280.cpp +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod_bme280.cpp @@ -143,9 +143,9 @@ void userLoop() { needRedraw = true; } else if (knownBrightness != bri) { needRedraw = true; - } else if (knownMode != strip.getMode()) { + } else if (knownMode != strip.getMainSegment().mode) { needRedraw = true; - } else if (knownPalette != strip.getSegment(0).palette) { + } else if (knownPalette != strip.getMainSegment().palette) { needRedraw = true; } @@ -169,8 +169,8 @@ void userLoop() { #endif knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; u8x8.clear(); u8x8.setFont(u8x8_font_chroma48medium8_r); diff --git a/usermods/battery_keypad_controller/wled06_usermod.ino b/usermods/battery_keypad_controller/wled06_usermod.ino index acc1bd8c4..b70682b43 100644 --- a/usermods/battery_keypad_controller/wled06_usermod.ino +++ b/usermods/battery_keypad_controller/wled06_usermod.ino @@ -54,35 +54,27 @@ void userLoop() switch (myKey) { case '1': applyPreset(1); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '2': applyPreset(2); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '3': applyPreset(3); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '4': applyPreset(4); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '5': applyPreset(5); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '6': applyPreset(6); - colorUpdated(CALL_MODE_FX_CHANGED); break; case 'A': applyPreset(7); - colorUpdated(CALL_MODE_FX_CHANGED); break; case 'B': applyPreset(8); - colorUpdated(CALL_MODE_FX_CHANGED); break; case '7': diff --git a/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h b/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h index 2deb6338a..6274abcee 100644 --- a/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h +++ b/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h @@ -391,7 +391,7 @@ public: uint16_t brightness = map(lux, 0, 1000, umSSDRBrightnessMin, umSSDRBrightnessMax); if (bri != brightness) { bri = brightness; - colorUpdated(1); + stateUpdated(1); } } umSSDRLastRefresh = millis(); diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index 67c78feed..08d551be0 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -111,7 +111,7 @@ class StairwayWipeUsermod : public Usermod { transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(CALL_MODE_NOTIFICATION); + stateUpdated(CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index a0dcc3bb2..eeece4438 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -104,7 +104,7 @@ void turnOff() transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(CALL_MODE_NOTIFICATION); + stateUpdated(CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h index f2864362c..0c0614c47 100644 --- a/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h +++ b/usermods/usermod_v2_auto_save/usermod_v2_auto_save.h @@ -91,8 +91,8 @@ class AutoSaveUsermod : public Usermod { knownBrightness = bri; knownEffectSpeed = effectSpeed; knownEffectIntensity = effectIntensity; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; } // gets called every time WiFi is (re-)connected. Initialize own network @@ -106,8 +106,8 @@ class AutoSaveUsermod : public Usermod { if (!autoSaveAfterSec || !enabled || strip.isUpdating() || currentPreset>0) return; // setting 0 as autosave seconds disables autosave unsigned long now = millis(); - uint8_t currentMode = strip.getMode(); - uint8_t currentPalette = strip.getSegment(0).palette; + uint8_t currentMode = strip.getMainSegment().mode; + uint8_t currentPalette = strip.getMainSegment().palette; unsigned long wouldAutoSaveAfter = now + autoSaveAfterSec*1000; if (knownBrightness != bri) { diff --git a/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h b/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h index c5251cba6..a49961dd5 100644 --- a/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h +++ b/usermods/usermod_v2_four_line_display/usermod_v2_four_line_display.h @@ -349,8 +349,8 @@ class FourLineDisplayUsermod : public Usermod { (knownBrightness != bri) || (knownEffectSpeed != effectSpeed) || (knownEffectIntensity != effectIntensity) || - (knownMode != strip.getMode()) || - (knownPalette != strip.getSegment(0).palette)) { + (knownMode != strip.getMainSegment().mode) || + (knownPalette != strip.getMainSegment().palette)) { knownHour = 99; // force time update lastRedraw = now; // update lastRedraw marker } else if (sleepMode && !displayTurnedOff && ((now - lastRedraw)/1000)%5 == 0) { @@ -398,8 +398,8 @@ class FourLineDisplayUsermod : public Usermod { knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID(); knownIp = apActive ? IPAddress(4, 3, 2, 1) : Network.localIP(); knownBrightness = bri; - knownMode = strip.getMode(); - knownPalette = strip.getSegment(0).palette; + knownMode = strip.getMainSegment().mode; + knownPalette = strip.getMainSegment().palette; knownEffectSpeed = effectSpeed; knownEffectIntensity = effectIntensity; diff --git a/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h b/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h index bf909bdca..0ea77e844 100644 --- a/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h +++ b/usermods/usermod_v2_rotary_encoder_ui/usermod_v2_rotary_encoder_ui.h @@ -290,12 +290,8 @@ public: } void lampUdated() { - bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette); - - //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) - // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - colorUpdated(CALL_MODE_DIRECT_CHANGE); - updateInterfaces(CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } void changeBrightness(bool increase) { diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index 98d84016a..b6e5ee70d 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -466,12 +466,11 @@ public: } void lampUdated() { - //bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette); //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - setValuesFromMainSeg(); //to make transition work on main segment - colorUpdated(CALL_MODE_DIRECT_CHANGE); - updateInterfaces(CALL_MODE_DIRECT_CHANGE); + //setValuesFromMainSeg(); //to make transition work on main segment (should no longer be required) + stateUpdated(CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } void changeBrightness(bool increase) { diff --git a/wled00/FX.h b/wled00/FX.h index 30cd5a48e..657d79eea 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -347,7 +347,8 @@ class WS2812FX { if (intensity != b.intensity) d |= SEG_DIFFERS_FX; if (palette != b.palette) d |= SEG_DIFFERS_FX; - if ((options & 0b00101111) != (b.options & 0b00101111)) d |= SEG_DIFFERS_OPT; + if ((options & 0b00101110) != (b.options & 0b00101110)) d |= SEG_DIFFERS_OPT; + if ((options & 0x01) != (b.options & 0x01)) d |= SEG_DIFFERS_SEL; for (uint8_t i = 0; i < NUM_COLORS; i++) { if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; @@ -649,6 +650,7 @@ class WS2812FX { calcGammaTable(float), trigger(void), setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0, uint16_t offset = UINT16_MAX), + setMainSegmentId(uint8_t n), restartRuntime(), resetSegments(), makeAutoSegments(), @@ -662,27 +664,21 @@ class WS2812FX { bool gammaCorrectBri = false, gammaCorrectCol = true, - applyToAllSelected = true, - setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p), checkSegmentAlignment(void), hasCCTBus(void), // return true if the strip is being sent pixel updates isUpdating(void); uint8_t - mainSegment = 0, paletteFade = 0, paletteBlend = 0, milliampsPerLed = 55, cctBlending = 0, getBrightness(void), - getMode(void), - getSpeed(void), getModeCount(void), getPaletteCount(void), getMaxSegments(void), getActiveSegmentsNum(void), - //getFirstSelectedSegment(void), getMainSegmentId(void), getTargetFps(void), setPixelSegment(uint8_t n), @@ -714,11 +710,9 @@ class WS2812FX { getPixelColor(uint16_t), getColor(void); - WS2812FX::Segment& - getSegment(uint8_t n); - - WS2812FX::Segment_runtime - getSegmentRuntime(void); + WS2812FX::Segment + &getSegment(uint8_t n), + &getMainSegment(void); WS2812FX::Segment* getSegments(void); @@ -912,6 +906,8 @@ class WS2812FX { uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; + uint8_t _mainSegment; + segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element // start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[] {0, 7, 0, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 302464b63..a59da9ad6 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -393,63 +393,20 @@ uint8_t WS2812FX::getPaletteCount() return 13 + GRADIENT_PALETTE_COUNT; } -//TODO effect transitions - - -bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) { - Segment& seg = _segments[getMainSegmentId()]; - uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette; - - bool applied = false; - - if (applyToAllSelected) { - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) - { - if (_segments[i].isSelected()) - { - _segments[i].speed = s; - _segments[i].intensity = in; - _segments[i].palette = p; - setMode(i, m); - applied = true; - } - } - } - - if (!applyToAllSelected || !applied) { - seg.speed = s; - seg.intensity = in; - seg.palette = p; - setMode(mainSegment, m); - } - - if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true; - return false; -} - void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { setColor(slot, RGBW32(r, g, b, w)); } +//applies to all active and selected segments void WS2812FX::setColor(uint8_t slot, uint32_t c) { if (slot >= NUM_COLORS) return; - bool applied = false; - - if (applyToAllSelected) { - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) - { - if (_segments[i].isSelected()) { - _segments[i].setColor(slot, c, i); - applied = true; - } + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) + { + if (_segments[i].isActive() && _segments[i].isSelected()) { + _segments[i].setColor(slot, c, i); } } - - if (!applyToAllSelected || !applied) { - uint8_t mainseg = getMainSegmentId(); - _segments[mainseg].setColor(slot, c, mainseg); - } } void WS2812FX::setBrightness(uint8_t b) { @@ -466,14 +423,6 @@ void WS2812FX::setBrightness(uint8_t b) { if (_segment_runtimes[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) show(); //apply brightness change immediately if no refresh soon } -uint8_t WS2812FX::getMode(void) { - return _segments[getMainSegmentId()].mode; -} - -uint8_t WS2812FX::getSpeed(void) { - return _segments[getMainSegmentId()].speed; -} - uint8_t WS2812FX::getBrightness(void) { return _brightness; } @@ -482,27 +431,33 @@ uint8_t WS2812FX::getMaxSegments(void) { return MAX_NUM_SEGMENTS; } -/*uint8_t WS2812FX::getFirstSelectedSegment(void) -{ +void WS2812FX::setMainSegmentId(uint8_t n) { + if (n >= MAX_NUM_SEGMENTS) return; + if (_segments[n].isActive() && _segments[n].isSelected()) { + _mainSegment = n; return; + } for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - if (_segments[i].isActive() && _segments[i].isSelected()) return i; + if (_segments[i].isActive() && _segments[i].isSelected()) { + _mainSegment = i; return; + } } - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active + //if none selected, use supplied n if active, or first active + if (_segments[n].isActive()) { + _mainSegment = n; return; + } + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - if (_segments[i].isActive()) return i; + if (_segments[i].isActive()) { + _mainSegment = i; return; + } } - return 0; -}*/ + _mainSegment = 0; + return; +} uint8_t WS2812FX::getMainSegmentId(void) { - if (mainSegment >= MAX_NUM_SEGMENTS) return 0; - if (_segments[mainSegment].isActive()) return mainSegment; - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //get first active - { - if (_segments[i].isActive()) return i; - } - return 0; + return _mainSegment; } uint8_t WS2812FX::getActiveSegmentsNum(void) { @@ -539,8 +494,8 @@ WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { return _segments[id]; } -WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) { - return SEGENV; +WS2812FX::Segment& WS2812FX::getMainSegment(void) { + return _segments[getMainSegmentId()]; } WS2812FX::Segment* WS2812FX::getSegments(void) { @@ -596,17 +551,8 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, delete[] seg.name; seg.name = nullptr; } - if (n == mainSegment) //if main segment is deleted, set first active as main segment - { - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) - { - if (_segments[i].isActive()) { - mainSegment = i; - return; - } - } - mainSegment = 0; //should not happen (always at least one active segment) - } + //if main segment is deleted, set first selected/active as main segment + if (n == _mainSegment) setMainSegmentId(0); return; } if (i1 < _length) seg.start = i1; @@ -628,7 +574,7 @@ void WS2812FX::restartRuntime() { void WS2812FX::resetSegments() { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) if (_segments[i].name) delete[] _segments[i].name; - mainSegment = 0; + _mainSegment = 0; memset(_segments, 0, sizeof(_segments)); //memset(_segment_runtimes, 0, sizeof(_segment_runtimes)); _segment_index = 0; diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index 1f85f7ab1..8f04f0161 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -44,7 +44,7 @@ void onAlexaChange(EspalexaDevice* dev) if (bri == 0) { bri = briLast; - colorUpdated(CALL_MODE_ALEXA); + stateUpdated(CALL_MODE_ALEXA); } } else { applyPreset(macroAlexaOn, CALL_MODE_ALEXA); @@ -58,7 +58,7 @@ void onAlexaChange(EspalexaDevice* dev) { briLast = bri; bri = 0; - colorUpdated(CALL_MODE_ALEXA); + stateUpdated(CALL_MODE_ALEXA); } } else { applyPreset(macroAlexaOff, CALL_MODE_ALEXA); @@ -67,7 +67,7 @@ void onAlexaChange(EspalexaDevice* dev) } else if (m == EspalexaDeviceProperty::bri) { bri = espalexaDevice->getValue(); - colorUpdated(CALL_MODE_ALEXA); + stateUpdated(CALL_MODE_ALEXA); } else //color { if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white @@ -79,9 +79,7 @@ void onAlexaChange(EspalexaDevice* dev) if (strip.hasCCTBus()) { uint8_t segid = strip.getMainSegmentId(); WS2812FX::Segment& seg = strip.getSegment(segid); - uint8_t cctPrev = seg.cct; seg.setCCT(k, segid); - if (seg.cct != cctPrev) effectChanged = true; //send UDP col[0]= 0; col[1]= 0; col[2]= 0; col[3]= 255; } else if (strip.hasWhiteChannel()) { switch (ct) { //these values empirically look good on RGBW diff --git a/wled00/blynk.cpp b/wled00/blynk.cpp index ce3904487..b1619d816 100644 --- a/wled00/blynk.cpp +++ b/wled00/blynk.cpp @@ -44,27 +44,27 @@ void updateBlynk() BLYNK_WRITE(V0) { bri = param.asInt();//bri - colorUpdated(CALL_MODE_BLYNK); + stateUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V1) { blHue = param.asInt();//hue - colorHStoRGB(blHue*10,blSat,(false)? colSec:col); + colorHStoRGB(blHue*10,blSat,col); colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V2) { blSat = param.asInt();//sat - colorHStoRGB(blHue*10,blSat,(false)? colSec:col); + colorHStoRGB(blHue*10,blSat,col); colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V3) { bool on = (param.asInt()>0); - if (!on != !bri) {toggleOnOff(); colorUpdated(CALL_MODE_BLYNK);} + if (!on != !bri) {toggleOnOff(); stateUpdated(CALL_MODE_BLYNK);} } BLYNK_WRITE(V4) diff --git a/wled00/button.cpp b/wled00/button.cpp index 8472d392c..03a90aaae 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -16,8 +16,8 @@ void shortPressAction(uint8_t b) { if (!macroButton[b]) { switch (b) { - case 0: toggleOnOff(); colorUpdated(CALL_MODE_BUTTON); break; - case 1: ++effectCurrent %= strip.getModeCount(); effectChanged = true; colorUpdated(CALL_MODE_BUTTON); break; + case 0: toggleOnOff(); stateUpdated(CALL_MODE_BUTTON); break; + case 1: ++effectCurrent %= strip.getModeCount(); colorUpdated(CALL_MODE_BUTTON); break; } } else { applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET); @@ -35,8 +35,8 @@ void longPressAction(uint8_t b) { if (!macroLongPress[b]) { switch (b) { - case 0: _setRandomColor(false,true); break; - case 1: bri += 8; colorUpdated(CALL_MODE_BUTTON); buttonPressedTime[b] = millis(); break; // repeatable action + case 0: setRandomColor(col); colorUpdated(CALL_MODE_BUTTON); break; + case 1: bri += 8; stateUpdated(CALL_MODE_BUTTON); buttonPressedTime[b] = millis(); break; // repeatable action } } else { applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET); @@ -55,7 +55,7 @@ void doublePressAction(uint8_t b) if (!macroDoublePress[b]) { switch (b) { //case 0: toggleOnOff(); colorUpdated(CALL_MODE_BUTTON); break; //instant short press on button 0 if no macro set - case 1: ++effectPalette %= strip.getPaletteCount(); effectChanged = true; colorUpdated(CALL_MODE_BUTTON); break; + case 1: ++effectPalette %= strip.getPaletteCount(); colorUpdated(CALL_MODE_BUTTON); break; } } else { applyPreset(macroDoublePress[b], CALL_MODE_BUTTON_PRESET); @@ -109,12 +109,12 @@ void handleSwitch(uint8_t b) if (!buttonPressedBefore[b]) { // on -> off if (macroButton[b]) applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET); else { //turn on - if (!bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} + if (!bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);} } } else { // off -> on if (macroLongPress[b]) applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET); else { //turn off - if (bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} + if (bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);} } } @@ -161,36 +161,17 @@ void handleAnalog(uint8_t b) } else if (macroDoublePress[b] == 249) { // effect speed effectSpeed = aRead; - effectChanged = true; - for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); - if (!seg.isSelected()) continue; - seg.speed = effectSpeed; - } } else if (macroDoublePress[b] == 248) { // effect intensity effectIntensity = aRead; - effectChanged = true; - for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); - if (!seg.isSelected()) continue; - seg.intensity = effectIntensity; - } } else if (macroDoublePress[b] == 247) { // selected palette effectPalette = map(aRead, 0, 252, 0, strip.getPaletteCount()-1); - effectChanged = true; - for (uint8_t i = 0; i < strip.getMaxSegments(); i++) { - WS2812FX::Segment& seg = strip.getSegment(i); - if (!seg.isSelected()) continue; - seg.palette = effectPalette; - } } else if (macroDoublePress[b] == 200) { // primary color, hue, full saturation colorHStoRGB(aRead*256,255,col); } else { // otherwise use "double press" for segment selection - //uint8_t mainSeg = strip.getMainSegmentId(); WS2812FX::Segment& seg = strip.getSegment(macroDoublePress[b]); if (aRead == 0) { seg.setOption(SEG_OPTION_ON, 0); // off @@ -258,7 +239,7 @@ void handleButton() if (b == 0 && dur > WLED_LONG_AP) { //long press on button 0 (when released) WLED::instance().initAP(true); } else if (!buttonLongPressed[b]) { //short press - if (b == 0 && !macroDoublePress[b]) { //don't wait for double press on button 0 if no double press macro set + if (b != 1 && !macroDoublePress[b]) { //don't wait for double press on buttons without a default action if no double press macro set shortPressAction(b); } else { //double press if less than 350 ms between current press and previous short press release (buttonWaitTime!=0) if (doublePress) { diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 7c7fbc4d1..4bd251e33 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -261,6 +261,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(receiveNotificationEffects, if_sync_recv["fx"]); CJSON(receiveGroups, if_sync_recv["grp"]); CJSON(receiveSegmentOptions, if_sync_recv["seg"]); + CJSON(receiveSegmentBounds, if_sync_recv["sb"]); //! following line might be a problem if called after boot receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions); @@ -673,9 +674,10 @@ void serializeConfig() { JsonObject if_sync_recv = if_sync.createNestedObject("recv"); if_sync_recv["bri"] = receiveNotificationBrightness; if_sync_recv["col"] = receiveNotificationColor; - if_sync_recv["fx"] = receiveNotificationEffects; + if_sync_recv["fx"] = receiveNotificationEffects; if_sync_recv["grp"] = receiveGroups; if_sync_recv["seg"] = receiveSegmentOptions; + if_sync_recv["sb"] = receiveSegmentBounds; JsonObject if_sync_send = if_sync.createNestedObject("send"); if_sync_send[F("dir")] = notifyDirect; diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 0655060e6..01dbdcb42 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -4,6 +4,12 @@ * Color conversion methods */ +void setRandomColor(byte* rgb) +{ + lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); + colorHStoRGB(lastRandomIndex*256,255,rgb); +} + void colorFromUint32(uint32_t in, bool secondary) { byte *_col = secondary ? colSec : col; diff --git a/wled00/const.h b/wled00/const.h index aaeb7fc5e..6e411abd5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -226,6 +226,7 @@ #define SEG_DIFFERS_FX 0x08 #define SEG_DIFFERS_BOUNDS 0x10 #define SEG_DIFFERS_GSO 0x20 +#define SEG_DIFFERS_SEL 0x80 //Playlist option byte #define PL_OPTION_SHUFFLE 0x01 @@ -344,4 +345,6 @@ #define DEFAULT_LED_COUNT 30 #endif +#define INTERFACE_UPDATE_COOLDOWN 2000 //time in ms to wait between websockets, alexa, and MQTT updates + #endif diff --git a/wled00/data/index.js b/wled00/data/index.js index 65d8ad68e..aa110e1e7 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -215,7 +215,7 @@ function onLoad() { //TODO: do some parsing first }) .catch(function (error) { - console.log("holidays.json does not contain array of holidays. Defaults loaded."); + console.log("No array of holidays in holidays.json. Defaults loaded."); }) .finally(function(){ loadBg(cfg.theme.bg.url); @@ -280,6 +280,8 @@ function showToast(text, error = false) { } function showErrorToast() { + // if we received a timeout force WS reconnect + reconnectWS(); showToast('Connection to light failed!', true); } function clearErrorToast() { @@ -953,10 +955,17 @@ function cmpP(a, b) { return a[1].n.localeCompare(b[1].n,undefined, {numeric: true}); } +//forces a WebSockets reconnect if timeout (error toast), or successful HTTP response to JSON request +function reconnectWS() { + if (ws) ws.close(); + ws = null; + if (lastinfo && lastinfo.ws > -1) setTimeout(makeWS,500); +} + function makeWS() { if (ws) return; ws = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws'); - ws.binaryType = "arraybuffer"; + ws.binaryType = "arraybuffer"; ws.onmessage = function(event) { if (event.data instanceof ArrayBuffer) return; //liveview packet var json = JSON.parse(event.data); @@ -974,9 +983,16 @@ function makeWS() { displayRover(info, s); readState(json.state); }; - ws.onclose = function(event) { - d.getElementById('connind').style.backgroundColor = "#831"; - } + ws.onclose = (e)=>{ + //if there is already a new web socket open, do not null ws + if (ws && ws.readyState === WebSocket.OPEN) return; + + d.getElementById('connind').style.backgroundColor = "#831"; + ws = null; + } + ws.onopen = (e)=>{ + reqsLegal = true; + } } function readState(s,command=false) { @@ -1128,6 +1144,7 @@ function requestJson(command, rinfo = true) { return; } var s = json; + if (reqsLegal && !ws) reconnectWS(); if (!command || rinfo) { //we have info object if (!rinfo) { //entire JSON (on load) @@ -1143,7 +1160,7 @@ function requestJson(command, rinfo = true) { }); },25); - reqsLegal = true; + reqsLegal = true; } var info = json.info; @@ -1176,7 +1193,7 @@ function requestJson(command, rinfo = true) { displayRover(info, s); } - readState(s,command); + readState(s,command); }) .catch(function (error) { showToast(error, true); @@ -1452,8 +1469,8 @@ function makePlEntry(p,i) { } function makePlUtil() { - if (pNum < 2) { - showToast("You need at least 2 presets to make a playlist!"); return; + if (pNum < 1) { + showToast("Please make a preset first!"); return; } if (plJson[0].transition[0] < 0) plJson[0].transition[0] = tr; d.getElementById('putil').innerHTML = `