diff --git a/CHANGELOG.md b/CHANGELOG.md index 403c4b81d..ee2740839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ### Builds after release 0.12.0 +#### Build 2107091 + +- Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type) +- Increased hue buffer +- Renamed `NOTIFIER_CALL_MODE_` to `CALL_MODE_` + +#### Build 2107090 + +- Busses extend total configured LEDs if required +- Fixed extra button pins defaulting to 0 on first boot + #### Build 2107080 - Made Peek use the main websocket connection instead of opening a second one diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index e5a116ca8..88aa77933 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -123,7 +123,7 @@ class Animated_Staircase : public Usermod { // Always mark segments as "transitional", we are animating the staircase segments->setOption(SEG_OPTION_TRANSITIONAL, 1, 1); } - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } /* @@ -298,7 +298,7 @@ class Animated_Staircase : public Usermod { } segments->setOption(SEG_OPTION_ON, 1, 1); } - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); DEBUG_PRINTLN(F("Animated Staircase disabled.")); } enabled = enable; diff --git a/usermods/PIR_sensor_switch/PIR_Highlight_Standby b/usermods/PIR_sensor_switch/PIR_Highlight_Standby index ddbbddeae..4cca1874d 100644 --- a/usermods/PIR_sensor_switch/PIR_Highlight_Standby +++ b/usermods/PIR_sensor_switch/PIR_Highlight_Standby @@ -62,7 +62,7 @@ class PIRsensorSwitch : public Usermod { // PIR sensor pin const uint8_t PIRsensorPin = 13; // D7 on D1 mini // notification mode for colorUpdated() - const byte NotifyUpdateMode = NOTIFIER_CALL_MODE_NO_NOTIFY; // NOTIFIER_CALL_MODE_DIRECT_CHANGE + 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; // off timer start time diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index ae63ed474..d875a42da 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -58,7 +58,7 @@ private: // PIR sensor pin int8_t PIRsensorPin = PIR_SENSOR_PIN; // notification mode for colorUpdated() - const byte NotifyUpdateMode = NOTIFIER_CALL_MODE_NO_NOTIFY; // NOTIFIER_CALL_MODE_DIRECT_CHANGE + const byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // CALL_MODE_DIRECT_CHANGE // delay before switch off after the sensor state goes LOW uint32_t m_switchOffDelay = 600000; // 10min // off timer start time diff --git a/usermods/battery_keypad_controller/wled06_usermod.ino b/usermods/battery_keypad_controller/wled06_usermod.ino index 877713b61..acc1bd8c4 100644 --- a/usermods/battery_keypad_controller/wled06_usermod.ino +++ b/usermods/battery_keypad_controller/wled06_usermod.ino @@ -54,46 +54,46 @@ void userLoop() switch (myKey) { case '1': applyPreset(1); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '2': applyPreset(2); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '3': applyPreset(3); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '4': applyPreset(4); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '5': applyPreset(5); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '6': applyPreset(6); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'A': applyPreset(7); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'B': applyPreset(8); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '7': effectCurrent += 1; if (effectCurrent >= MODE_COUNT) effectCurrent = 0; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '*': effectCurrent -= 1; if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '8': @@ -102,7 +102,7 @@ void userLoop() } else if (effectSpeed < 255) { effectSpeed += 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '0': if (effectSpeed > 15) { @@ -110,7 +110,7 @@ void userLoop() } else if (effectSpeed > 0) { effectSpeed -= 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '9': @@ -119,7 +119,7 @@ void userLoop() } else if (effectIntensity < 255) { effectIntensity += 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case '#': if (effectIntensity > 15) { @@ -127,18 +127,18 @@ void userLoop() } else if (effectIntensity > 0) { effectIntensity -= 1; } - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'C': effectPalette += 1; if (effectPalette >= 50) effectPalette = 0; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; case 'D': effectPalette -= 1; if (effectPalette <= 0) effectPalette = 50; - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); break; } diff --git a/usermods/rgb-rotary-encoder/readme.md b/usermods/rgb-rotary-encoder/readme.md new file mode 100644 index 000000000..2bf0ecb72 --- /dev/null +++ b/usermods/rgb-rotary-encoder/readme.md @@ -0,0 +1,86 @@ +# RGB Encoder Board + +This usermod-v2 adds support for the awesome RGB Rotary Encoder Board by Adam Zeloof / "Isotope Engineering" to control the overall brightness of your WLED instance: https://github.com/isotope-engineering/RGB-Encoder-Board. A great DIY rotary encoder with 20 tiny SK6805 / "NeoPixel Nano" LEDs. + +https://user-images.githubusercontent.com/3090131/124680599-0180ab80-dec7-11eb-9065-a6d08ebe0287.mp4 + +## Credits +The actual / original code that does the different LED modes is from Adam Zeloof. So I don't take credit for these. But I ported it to WLED, which involved replacing the LED library he used (because, guess what, WLED already has one; so no need to add another one, but use whatever WLED uses), plus the rotary encoder library, because that one was not compatible with ESP, only Arduino. +So it was quite more work than I hoped, but I got there eventually :) + +## Requirements +* "ESP Rotary" by Lennart Hennigs, v1.5.0 or higher: https://github.com/LennartHennigs/ESPRotary + +## Usermod installation +Simply copy the below block (build task) to your `platformio_override.ini` and compile WLED using this new build task. Or use an existing one and add the buildflag `-D RGB_ROTARY_ENCODER`. + +ESP32: +``` +[env:custom_esp32dev_usermod_rgb_encoder_board] +extends = env:esp32dev +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 -D RGB_ROTARY_ENCODER +lib_deps = ${esp32.lib_deps} + lennarthennigs/ESP Rotary@^1.5.0 +``` + +ESP8266 / D1 Mini: +``` +[env:custom_d1_mini_usermod_rgb_encoder_board] +extends = env:d1_mini +build_flags = ${common.build_flags_esp8266} -D RGB_ROTARY_ENCODER +lib_deps = ${esp8266.lib_deps} + lennarthennigs/ESP Rotary@^1.5.0 +``` + +## How to connect the board to your ESP +We gonna need (minimum) three or (maximum) four GPIOs for the board: +* "ea": Basically tells if the encoder goes into one or the other direction +* "eb": Same thing, but the other direction +* "di": LED data in. To actually control the LEDs +* *(optional)* "sw": The integrated switch in the rotary encoder. Can be omitted for the bare functionality of just controlling the brightness + +We also gonna need some power, so: + +* "vdd": Needs to be connected to **+5V**. +* "gnd": Well, it's GND. + +You can freely pick the GPIOs, it doesn't matter. Those will be configured in the "Usermods" section in the WLED web panel: + +## Configuration +Navigate to the "Config" and then to the "Usermods" section. If you compiled WLED with `-D RGB_ROTARY_ENCODER`, you will see the config for it there. The settings there are the GPIOs we mentioned before (*Note: The switch pin is not there, as this can just be configured the "normal" button on the "LED Preferences" page*), plus a few more: +* LED pin: + * Possible values: Any valid and available GPIO + * Default: 3 + * What it does: Pin to control the LED ring +* ea pin: + * Possible values: Any valid and available GPIO + * Default: 15 + * What it does: First of the two rotary encoder pins +* eb pin: + * Possible values: Any valid and available GPIO + * Default: 32 + * What it does: Second of the two rotary encoder pins +* LED Mode: + * Possible values: 1-3 + * Default: 3 + * What it does: The usermod provides three different modes of how the LEDs can look like. Here's an example: https://github.com/isotope-engineering/RGB-Encoder-Board/blob/master/images/rgb-encoder-animations.gif + * Up left is "1" + * Up right is not supported / doesn't make sense for brightness control + * Bottom left is "2" + * Bottom right is "3" +* LED Brightness: + * Possible values: 1-255 + * Default: 64 + * What it does: Brightness of the LED ring +* Steps per click: + * Possible values: Any positive number + * Default: 4 + * What it does: With each "click", a rotary encoder actually increments it's "steps". Most rotary encoder do four "steps" per "click". I know this sounds super weird, so just leave this the default value, unless your rotary encoder behaves weirdly, like with one click, it makes two LEDs light up, or you sometimes need two click for one LED. Then you should play around with this value or write a small sketch using the same "ESP Rotary" library and read out the steps it does. +* Increment per click: + * Possible values: Any positive number + * Default: 5 + * What it does: Most rotary encoder have 20 "clicks", so basically 20 positions. This value should be set to 100 / `number of clicks` + +## Change log +2021-07 +* First implementation. diff --git a/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h new file mode 100644 index 000000000..ab680a8f3 --- /dev/null +++ b/usermods/rgb-rotary-encoder/rgb-rotary-encoder.h @@ -0,0 +1,344 @@ +#pragma once + +#include "ESPRotary.h" +#include +#include "wled.h" + +class RgbRotaryEncoderUsermod : public Usermod +{ + private: + bool enabled = false; + bool initDone = false; + bool isDirty = false; + BusDigital *ledBus; + /* + * Green - eb - Q4 - 32 + * Red - ea - Q1 - 15 + * Black - sw - Q2 - 12 + */ + ESPRotary *rotaryEncoder; + int8_t ledIo = 3; // GPIO to control the LEDs + int8_t eaIo = 15; // "ea" from RGB Encoder Board + int8_t ebIo = 32; // "eb" from RGB Encoder Board + byte stepsPerClick = 4; // How many "steps" your rotary encoder does per click. This varies per rotary encoder + /* This could vary per rotary encoder: Usually rotary encoders have 20 "clicks". + If yours has less/more, adjust this to: 100% = 20 LEDs * incrementPerClick */ + byte incrementPerClick = 5; + byte ledMode = 3; + byte ledBrightness = 64; + + // This is all needed to calculate the brightness, rotary position, etc. + const byte minPos = 5; // minPos is not zero, because if we want to turn the LEDs off, we use the built-in button ;) + const byte maxPos = 100; // maxPos=100, like 100% + const byte numLeds = 20; + byte lastKnownPos = 0; + + byte currentColors[3]; + byte lastKnownBri = 0; + + + void initRotaryEncoder() + { + if (!pinManager.allocatePin(eaIo, false)) { + eaIo = -1; + } + if (!pinManager.allocatePin(ebIo, false)) { + ebIo = -1; + } + if (eaIo == -1 || ebIo == -1) { + cleanup(); + return; + } + + // I don't know why, but setting the upper bound here does not work. It results into 1717922932 O_o + rotaryEncoder = new ESPRotary(eaIo, ebIo, stepsPerClick, incrementPerClick, maxPos, currentPos, incrementPerClick); + rotaryEncoder->setUpperBound(maxPos); // I have to again set it here and then it works / is actually 100... + + rotaryEncoder->setChangedHandler(RgbRotaryEncoderUsermod::cbRotate); + } + + void initLedBus() + { + byte _pins[5] = {(byte)ledIo, 255, 255, 255, 255}; + BusConfig busCfg = BusConfig(TYPE_WS2812_RGB, _pins, 0, numLeds, COL_ORDER_GRB, false, 0); + + ledBus = new BusDigital(busCfg, WLED_MAX_BUSSES - 1); + if (!ledBus->isOk()) { + cleanup(); + return; + } + + ledBus->setBrightness(ledBrightness); + } + + void updateLeds() + { + switch (ledMode) { + case 2: + { + currentColors[0] = 255; currentColors[1] = 0; currentColors[2] = 0; + for (int i = 0; i < currentPos / incrementPerClick - 1; i++) { + ledBus->setPixelColor(i, 0); + } + ledBus->setPixelColor(currentPos / incrementPerClick - 1, colorFromRgbw(currentColors)); + for (int i = currentPos / incrementPerClick; i < numLeds; i++) { + ledBus->setPixelColor(i, 0); + } + } + break; + + default: + case 1: + case 3: + // WLED orange (of course), which we will use in mode 1 + currentColors[0] = 255; currentColors[1] = 160; currentColors[2] = 0; + for (int i = 0; i < currentPos / incrementPerClick; i++) { + if (ledMode == 3) { + hsv2rgb((i) / float(numLeds), 1, .25); + } + ledBus->setPixelColor(i, colorFromRgbw(currentColors)); + } + for (int i = currentPos / incrementPerClick; i < numLeds; i++) { + ledBus->setPixelColor(i, 0); + } + break; + } + + isDirty = true; + } + + void cleanup() + { + // Only deallocate pins if we allocated them ;) + if (eaIo != -1) { + pinManager.deallocatePin(eaIo); + } + if (ebIo != -1) { + pinManager.deallocatePin(ebIo); + } + + delete rotaryEncoder; + delete ledBus; + + enabled = false; + } + + int getPositionForBrightness() + { + return int(((float)bri / (float)255) * 100); + } + + float fract(float x) { return x - int(x); } + + float mix(float a, float b, float t) { return a + (b - a) * t; } + + void hsv2rgb(float h, float s, float v) { + currentColors[0] = int((v * mix(1.0, constrain(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + currentColors[1] = int((v * mix(1.0, constrain(abs(fract(h + 0.6666666) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + currentColors[2] = int((v * mix(1.0, constrain(abs(fract(h + 0.3333333) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s)) * 255); + } + + public: + static byte currentPos; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _ledIo[]; + static const char _eaIo[]; + static const char _ebIo[]; + static const char _ledMode[]; + static const char _ledBrightness[]; + static const char _stepsPerClick[]; + static const char _incrementPerClick[]; + + + static void cbRotate(ESPRotary& r) { + currentPos = r.getPosition(); + } + + /** + * Enable/Disable the usermod + */ + // inline void enable(bool enable) { enabled = enable; } + /** + * Get usermod enabled/disabled state + */ + // inline bool isEnabled() { return enabled; } + + /* + * setup() is called once at boot. WiFi is not yet connected at this point. + * You can use it to initialize variables, sensors or similar. + */ + void setup() + { + if (enabled) { + currentPos = getPositionForBrightness(); + lastKnownBri = bri; + + initRotaryEncoder(); + initLedBus(); + + // No updating of LEDs here, as that's sometimes not working; loop() will take care of that + + initDone = true; + } + } + + /* + * loop() is called continuously. Here you can check for events, read sensors, etc. + * + * Tips: + * 1. You can use "if (WLED_CONNECTED)" to check for a successful network connection. + * Additionally, "if (WLED_MQTT_CONNECTED)" is available to check for a connection to an MQTT broker. + * + * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds. + * Instead, use a timer check as shown here. + */ + void loop() + { + if (!enabled || strip.isUpdating()) return; + + rotaryEncoder->loop(); + + // If the rotary was changed + if(lastKnownPos != currentPos) { + lastKnownPos = currentPos; + + bri = min(int(round((2.55 * currentPos))), 255); + lastKnownBri = bri; + + updateLeds(); + colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + } + + // If the brightness is changed not with the rotary, update the rotary + if (bri != lastKnownBri) { + currentPos = lastKnownPos = getPositionForBrightness(); + lastKnownBri = bri; + rotaryEncoder->resetPosition(currentPos); + updateLeds(); + } + + // Update LEDs here in loop to also validate that we can update/show + if (isDirty && ledBus->canShow()) { + isDirty = false; + ledBus->show(); + } + } + + void addToConfig(JsonObject &root) + { + JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname + + top[FPSTR(_enabled)] = enabled; + top[FPSTR(_ledIo)] = ledIo; + top[FPSTR(_eaIo)] = eaIo; + top[FPSTR(_ebIo)] = ebIo; + top[FPSTR(_ledMode)] = ledMode; + top[FPSTR(_ledBrightness)] = ledBrightness; + top[FPSTR(_stepsPerClick)] = stepsPerClick; + top[FPSTR(_incrementPerClick)] = incrementPerClick; + } + + /** + * readFromConfig() is called before setup() to populate properties from values stored in cfg.json + * + * The function should return true if configuration was successfully loaded or false if there was no configuration. + */ + bool readFromConfig(JsonObject &root) + { + JsonObject top = root[FPSTR(_name)]; + if (top.isNull()) { + DEBUG_PRINTF("[%s] No config found. (Using defaults.)\n", _name); + return false; + } + + bool oldEnabled = enabled; + int8_t oldLedIo = ledIo; + int8_t oldEaIo = eaIo; + int8_t oldEbIo = ebIo; + byte oldLedMode = ledMode; + byte oldStepsPerClick = stepsPerClick; + byte oldIncrementPerClick = incrementPerClick; + byte oldLedBrightness = ledBrightness; + + getJsonValue(top[FPSTR(_enabled)], enabled); + getJsonValue(top[FPSTR(_ledIo)], ledIo); + getJsonValue(top[FPSTR(_eaIo)], eaIo); + getJsonValue(top[FPSTR(_ebIo)], ebIo); + getJsonValue(top[FPSTR(_stepsPerClick)], stepsPerClick); + getJsonValue(top[FPSTR(_incrementPerClick)], incrementPerClick); + ledMode = top[FPSTR(_ledMode)] > 0 && top[FPSTR(_ledMode)] < 4 ? top[FPSTR(_ledMode)] : ledMode; + ledBrightness = top[FPSTR(_ledBrightness)] > 0 && top[FPSTR(_ledBrightness)] <= 255 ? top[FPSTR(_ledBrightness)] : ledBrightness; + + if (!initDone) { + // First run: reading from cfg.json + // Nothing to do here, will be all done in setup() + } + // Mod was disabled, so run setup() + else if (enabled && enabled != oldEnabled) { + DEBUG_PRINTF("[%s] Usermod has been re-enabled\n", _name); + setup(); + } + // Config has been changed, so adopt to changes + else { + if (!enabled) { + DEBUG_PRINTF("[%s] Usermod has been disabled\n", _name); + cleanup(); + } + else { + DEBUG_PRINTF("[%s] Usermod is enabled\n", _name); + if (ledIo != oldLedIo) { + delete ledBus; + initLedBus(); + } + + if (ledBrightness != oldLedBrightness) { + ledBus->setBrightness(ledBrightness); + isDirty = true; + } + + if (ledMode != oldLedMode) { + updateLeds(); + } + + if (eaIo != oldEaIo || ebIo != oldEbIo || stepsPerClick != oldStepsPerClick || incrementPerClick != oldIncrementPerClick) { + pinManager.deallocatePin(oldEaIo); + pinManager.deallocatePin(oldEbIo); + + delete rotaryEncoder; + initRotaryEncoder(); + } + } + + DEBUG_PRINTF("[%s] Config (re)loaded\n", _name); + } + + return true; + } + + /* + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() + { + return 0x4711; + } + + //More methods can be added in the future, this example will then be extended. + //Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class! +}; + +byte RgbRotaryEncoderUsermod::currentPos = 5; +// strings to reduce flash memory usage (used more than twice) +const char RgbRotaryEncoderUsermod::_name[] PROGMEM = "RGB-Rotary-Encoder"; +const char RgbRotaryEncoderUsermod::_enabled[] PROGMEM = "Enabled"; +const char RgbRotaryEncoderUsermod::_ledIo[] PROGMEM = "LED-pin"; +const char RgbRotaryEncoderUsermod::_eaIo[] PROGMEM = "ea-pin"; +const char RgbRotaryEncoderUsermod::_ebIo[] PROGMEM = "eb-pin"; +const char RgbRotaryEncoderUsermod::_ledMode[] PROGMEM = "LED-Mode"; +const char RgbRotaryEncoderUsermod::_ledBrightness[] PROGMEM = "LED-Brightness"; +const char RgbRotaryEncoderUsermod::_stepsPerClick[] PROGMEM = "Steps-per-Click"; +const char RgbRotaryEncoderUsermod::_incrementPerClick[] PROGMEM = "Increment-per-Click"; \ No newline at end of file diff --git a/usermods/rotary_encoder_change_effect/wled06_usermod.ino b/usermods/rotary_encoder_change_effect/wled06_usermod.ino index f004ba2f4..5444ab9fb 100644 --- a/usermods/rotary_encoder_change_effect/wled06_usermod.ino +++ b/usermods/rotary_encoder_change_effect/wled06_usermod.ino @@ -39,7 +39,7 @@ void userLoop() { //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(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); lastTime = millis(); } } diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index 816b6e8d9..67c78feed 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -42,7 +42,7 @@ class StairwayWipeUsermod : public Usermod { if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete effectCurrent = FX_MODE_STATIC; timeStaticStart = millis(); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 2; } } else if (wipeState == 2) { //static @@ -54,7 +54,7 @@ class StairwayWipeUsermod : public Usermod { #ifdef STAIRCASE_WIPE_OFF effectCurrent = FX_MODE_COLOR_WIPE; strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 4; #else turnOff(); @@ -100,7 +100,7 @@ class StairwayWipeUsermod : public Usermod { bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); } void turnOff() @@ -111,7 +111,7 @@ class StairwayWipeUsermod : public Usermod { transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(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 0cc85df74..a0dcc3bb2 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -47,7 +47,7 @@ void userLoop() if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete effectCurrent = FX_MODE_STATIC; timeStaticStart = millis(); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 2; } } else if (wipeState == 2) { //static @@ -59,7 +59,7 @@ void userLoop() #ifdef STAIRCASE_WIPE_OFF effectCurrent = FX_MODE_COLOR_WIPE; strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 4; #else turnOff(); @@ -93,7 +93,7 @@ void startWipe() bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); } void turnOff() @@ -104,7 +104,7 @@ void turnOff() transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h index 24f1e7ae4..61b76ba19 100644 --- a/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h +++ b/usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h @@ -138,8 +138,8 @@ public: } //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(NOTIFIER_CALL_MODE_BUTTON); - updateInterfaces(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } Enc_A_prev = Enc_A; // Store value of A for next time loopTime = currentTime; // Updates loopTime 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 5ff1090d2..424bb67ac 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 @@ -267,8 +267,8 @@ public: //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(NOTIFIER_CALL_MODE_DIRECT_CHANGE); - updateInterfaces(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); + updateInterfaces(CALL_MODE_DIRECT_CHANGE); } void changeBrightness(bool increase) { diff --git a/usermods/word-clock-matrix/word-clock-matrix.cpp b/usermods/word-clock-matrix/word-clock-matrix.cpp index aadfb8b18..5c8985f17 100644 --- a/usermods/word-clock-matrix/word-clock-matrix.cpp +++ b/usermods/word-clock-matrix/word-clock-matrix.cpp @@ -64,13 +64,13 @@ void hourChime() { //strip.resetSegments(); selectWordSegments(true); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); savePreset(13, false); selectWordSegments(false); //strip.getSegment(0).setOption(0, true); strip.getSegment(0).setOption(2, true); applyPreset(12); - colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + colorUpdated(CALL_MODE_FX_CHANGED); } void displayTime(byte hour, byte minute) diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index 83e7c25f1..2e5b9b17b 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -44,10 +44,10 @@ void onAlexaChange(EspalexaDevice* dev) if (bri == 0) { bri = briLast; - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOn); + applyPreset(macroAlexaOn, CALL_MODE_ALEXA); if (bri == 0) espalexaDevice->setValue(briLast); //stop Alexa from complaining if macroAlexaOn does not actually turn on } } else if (m == EspalexaDeviceProperty::off) @@ -58,16 +58,16 @@ void onAlexaChange(EspalexaDevice* dev) { briLast = bri; bri = 0; - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } else { - applyPreset(macroAlexaOff); + applyPreset(macroAlexaOff, CALL_MODE_ALEXA); if (bri != 0) espalexaDevice->setValue(0); //stop Alexa from complaining if macroAlexaOff does not actually turn off } } else if (m == EspalexaDeviceProperty::bri) { bri = espalexaDevice->getValue(); - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } else //color { if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white @@ -93,7 +93,7 @@ void onAlexaChange(EspalexaDevice* dev) col[2] = ( color & 0xFF); col[3] = 0; } - colorUpdated(NOTIFIER_CALL_MODE_ALEXA); + colorUpdated(CALL_MODE_ALEXA); } } diff --git a/wled00/blynk.cpp b/wled00/blynk.cpp index f74b5012d..929c3d438 100644 --- a/wled00/blynk.cpp +++ b/wled00/blynk.cpp @@ -46,45 +46,45 @@ void updateBlynk() BLYNK_WRITE(V0) { bri = param.asInt();//bri - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V1) { blHue = param.asInt();//hue colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V2) { blSat = param.asInt();//sat colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V3) { bool on = (param.asInt()>0); - if (!on != !bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BLYNK);} + if (!on != !bri) {toggleOnOff(); colorUpdated(CALL_MODE_BLYNK);} } BLYNK_WRITE(V4) { effectCurrent = param.asInt()-1;//fx - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V5) { effectSpeed = param.asInt();//sx - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V6) { effectIntensity = param.asInt();//ix - colorUpdated(NOTIFIER_CALL_MODE_BLYNK); + colorUpdated(CALL_MODE_BLYNK); } BLYNK_WRITE(V7) diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index f9e2487b9..2172f667d 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -33,6 +33,18 @@ struct BusConfig { else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type); for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i]; } + + //validates start and length and extends total if needed + bool adjustBounds(uint16_t& total) { + if (!count) count = 1; + if (count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS; + if (start >= MAX_LEDS) return false; + //limit length of strip if it would exceed total permissible LEDs + if (start + count > MAX_LEDS) count = MAX_LEDS - start; + //extend total count accordingly + if (start + count > total) total = start + count; + return true; + } }; //parent class of BusDigital and BusPwm @@ -112,11 +124,10 @@ class Bus { class BusDigital : public Bus { public: BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) { - uint8_t type = bc.type; - if (!IS_DIGITAL(type) || !bc.count) return; + if (!IS_DIGITAL(bc.type) || !bc.count) return; if (!pinManager.allocatePin(bc.pins[0])) return; _pins[0] = bc.pins[0]; - if (IS_2PIN(type)) { + if (IS_2PIN(bc.type)) { if (!pinManager.allocatePin(bc.pins[1])) { cleanup(); return; } @@ -125,8 +136,8 @@ class BusDigital : public Bus { reversed = bc.reversed; _skip = bc.skipAmount; //sacrificial pixels _len = bc.count + _skip; - _rgbw = bc.rgbwOverride || Bus::isRgbw(type); // RGBW override in bit 7 - _iType = PolyBus::getI(type, _pins, nr, _rgbw); + _rgbw = bc.rgbwOverride || Bus::isRgbw(bc.type); // RGBW override in bit 7 + _iType = PolyBus::getI(bc.type, _pins, nr, _rgbw); if (_iType == I_NONE) return; _busPtr = PolyBus::create(_iType, _pins, _len, nr); _valid = (_busPtr != nullptr); @@ -237,11 +248,11 @@ class BusPwm : public Bus { #endif for (uint8_t i = 0; i < numPins; i++) { - if (!pinManager.allocatePin(bc.pins[i])) { - deallocatePins(); - return; + uint8_t currentPin = bc.pins[i]; + if (!pinManager.allocatePin(currentPin)) { + deallocatePins(); return; } - _pins[i] = bc.pins[i]; + _pins[i] = currentPin; // store only after allocatePin() succeeds #ifdef ESP8266 pinMode(_pins[i], OUTPUT); #else diff --git a/wled00/button.cpp b/wled00/button.cpp index ff0f4ee64..ba6a0c973 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -13,9 +13,9 @@ void shortPressAction(uint8_t b) if (!macroButton[b]) { toggleOnOff(); - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } else { - applyPreset(macroButton[b]); + applyPreset(macroButton[b], CALL_MODE_BUTTON); } // publish MQTT message @@ -62,14 +62,14 @@ void handleSwitch(uint8_t b) if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce) if (!buttonPressedBefore[b]) { // on -> off - if (macroButton[b]) applyPreset(macroButton[b]); + if (macroButton[b]) applyPreset(macroButton[b], CALL_MODE_BUTTON); else { //turn on - if (!bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} + if (!bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} } } else { // off -> on - if (macroLongPress[b]) applyPreset(macroLongPress[b]); + if (macroLongPress[b]) applyPreset(macroLongPress[b], CALL_MODE_BUTTON); else { //turn off - if (bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON);} + if (bri) {toggleOnOff(); colorUpdated(CALL_MODE_BUTTON);} } } @@ -154,14 +154,14 @@ void handleAnalog(uint8_t b) seg.setOption(SEG_OPTION_ON, 1); } // this will notify clients of update (websockets,mqtt,etc) - updateInterfaces(NOTIFIER_CALL_MODE_BUTTON); + updateInterfaces(CALL_MODE_BUTTON); } } else { //TODO: // we can either trigger a preset depending on the level (between short and long entries) // or use it for RGBW direct control } - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } void handleButton() @@ -195,7 +195,7 @@ void handleButton() { if (!buttonLongPressed[b]) { - if (macroLongPress[b]) {applyPreset(macroLongPress[b]);} + if (macroLongPress[b]) {applyPreset(macroLongPress[b], CALL_MODE_BUTTON);} else _setRandomColor(false,true); // publish MQTT message @@ -224,7 +224,7 @@ void handleButton() if (macroDoublePress[b]) { if (doublePress) { - applyPreset(macroDoublePress[b]); + applyPreset(macroDoublePress[b], CALL_MODE_BUTTON); // publish MQTT message if (buttonPublishMqtt && WLED_MQTT_CONNECTED) { diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 4d6c2329f..09392bf77 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -120,12 +120,12 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (i>4) break; } - uint16_t length = elm[F("len")]; + uint16_t length = elm[F("len")] | 1; if (length==0 || length+lC > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop + uint8_t colorOrder = (int)elm[F("order")]; + uint8_t skipFirst = elm[F("skip")]; uint16_t start = elm[F("start")] | 0; if (start > lC+length) continue; // something is very wrong :) - uint8_t colorOrder = elm[F("order")]; - uint8_t skipFirst = elm[F("skip")]; uint8_t ledType = elm["type"] | TYPE_WS2812_RGB; bool reversed = elm["rev"]; //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) @@ -134,6 +134,18 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst); mem += BusManager::memUsage(bc); if (mem <= MAX_LED_MEMORY && busses.getNumBusses() <= WLED_MAX_BUSSES) busses.add(bc); // finalization will be done in WLED::beginStrip() +/* + BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst); + if (bc.adjustBounds(ledCount)) { + //RGBW mode is enabled if at least one of the strips is RGBW + strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(ledType)); + //refresh is required to remain off if at least one of the strips requires the refresh. + strip.isOffRefreshRequred |= BusManager::isOffRefreshRequred(ledType); + s++; + mem += busses.memUsage(bc); + if (mem <= MAX_LED_MEMORY) busses.add(bc); + } +*/ } // finalization done in beginStrip() } @@ -170,8 +182,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } else { // new install/missing configuration (button 0 has defaults) if (fromFS) { + // relies upon only being called once with fromFS == true, which is currently true. uint8_t s=0; - if (pinManager.allocatePin(btnPin[0])) s++; // do not clear button 0 if pin successfully allocated + if (pinManager.allocatePin(btnPin[0],false)) s++; // do not clear button 0 if pin successfully allocated for (; s root; + StaticJsonDocument<1024> root; if (str[0] == '[') //is JSON array { auto error = deserializeJson(root, str); diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 2997f8ff3..568976dfc 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -69,9 +69,9 @@ void decBrightness() } // apply preset or fallback to a effect and palette if it doesn't exist -void presetFallback(int8_t presetID, int8_t effectID, int8_t paletteID) +void presetFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) { - if (!applyPreset(presetID)) { + if (!applyPreset(presetID, CALL_MODE_BUTTON)) { effectCurrent = effectID; effectPalette = paletteID; } @@ -88,11 +88,11 @@ bool decodeIRCustom(uint32_t code) { //just examples, feel free to modify or remove case IRCUSTOM_ONOFF : toggleOnOff(); break; - case IRCUSTOM_MACRO1 : applyPreset(1); break; + case IRCUSTOM_MACRO1 : applyPreset(1, CALL_MODE_BUTTON); break; default: return false; } - if (code != IRCUSTOM_MACRO1) colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it + if (code != IRCUSTOM_MACRO1) colorUpdated(CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it return true; } */ @@ -187,51 +187,51 @@ void decodeIR(uint32_t code) } if (nightlightActive && bri == 0) nightlightActive = false; - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input + colorUpdated(CALL_MODE_BUTTON); //for notifier, IR is considered a button input } void applyRepeatActions(){ if (lastRepeatableAction == ACTION_BRIGHT_UP) { - incBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + incBrightness(); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_BRIGHT_DOWN ) { - decBrightness(); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + decBrightness(); colorUpdated(CALL_MODE_BUTTON); } if (lastRepeatableAction == ACTION_SPEED_UP) { - changeEffectSpeed(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectSpeed(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_SPEED_DOWN ) { - changeEffectSpeed(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectSpeed(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } if (lastRepeatableAction == ACTION_INTENSITY_UP) { - changeEffectIntensity(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectIntensity(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } else if (lastRepeatableAction == ACTION_INTENSITY_DOWN ) { - changeEffectIntensity(lastRepeatableValue); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + changeEffectIntensity(lastRepeatableValue); colorUpdated(CALL_MODE_BUTTON); } if (lastValidCode == IR40_WPLUS) { - relativeChangeWhite(10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + relativeChangeWhite(10); colorUpdated(CALL_MODE_BUTTON); } else if (lastValidCode == IR40_WMINUS) { - relativeChangeWhite(-10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + relativeChangeWhite(-10, 5); colorUpdated(CALL_MODE_BUTTON); } else if ((lastValidCode == IR24_ON || lastValidCode == IR40_ON) && irTimesRepeated > 7 ) { nightlightActive = true; nightlightStartTime = millis(); - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); + colorUpdated(CALL_MODE_BUTTON); } else if (irEnabled == 8) { @@ -261,11 +261,11 @@ void decodeIR24(uint32_t code) case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break; case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; case IR24_PINK : colorFromUint32(COLOR_PINK); break; - case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; - case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; - case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; - case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; + case IR24_FLASH : presetFallback(1, FX_MODE_COLORTWINKLE, effectPalette); break; + case IR24_STROBE : presetFallback(2, FX_MODE_RAINBOW_CYCLE, effectPalette); break; + case IR24_FADE : presetFallback(3, FX_MODE_BREATH, effectPalette); break; + case IR24_SMOOTH : presetFallback(4, FX_MODE_RAINBOW, effectPalette); break; default: return; } lastValidCode = code; @@ -293,11 +293,11 @@ void decodeIR24OLD(uint32_t code) case IR24_OLD_PURPLE : colorFromUint32(COLOR_PURPLE); break; case IR24_OLD_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; case IR24_OLD_PINK : colorFromUint32(COLOR_PINK); break; - case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR24_OLD_FLASH : if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break; - case IR24_OLD_STROBE : if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break; - case IR24_OLD_FADE : if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR24_OLD_SMOOTH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; + case IR24_OLD_FLASH : presetFallback(1, FX_MODE_COLORTWINKLE, 0); break; + case IR24_OLD_STROBE : presetFallback(2, FX_MODE_RAINBOW_CYCLE, 0); break; + case IR24_OLD_FADE : presetFallback(3, FX_MODE_BREATH, 0); break; + case IR24_OLD_SMOOTH : presetFallback(4, FX_MODE_RAINBOW, 0); break; default: return; } lastValidCode = code; @@ -386,10 +386,10 @@ void decodeIR40(uint32_t code) case IR40_SLOW : changeEffectSpeed(-16); break; case IR40_JUMP7 : changeEffectIntensity( 16); break; case IR40_AUTO : changeEffectIntensity(-16); break; - case IR40_JUMP3 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; - case IR40_FADE3 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR40_FADE7 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; - case IR40_FLASH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR40_JUMP3 : presetFallback(1, FX_MODE_STATIC, 0); break; + case IR40_FADE3 : presetFallback(2, FX_MODE_BREATH, 0); break; + case IR40_FADE7 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break; + case IR40_FLASH : presetFallback(4, FX_MODE_RAINBOW, 0); break; } lastValidCode = code; } @@ -441,12 +441,12 @@ void decodeIR44(uint32_t code) case IR44_BLUEMINUS : changeEffectIntensity(-16); break; case IR44_QUICK : changeEffectSpeed( 16); break; case IR44_SLOW : changeEffectSpeed(-16); break; - case IR44_DIY1 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; - case IR44_DIY2 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR44_DIY3 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; - case IR44_DIY4 : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; - case IR44_DIY5 : if (!applyPreset(5)) { effectCurrent = FX_MODE_METEOR_SMOOTH; effectPalette = 0; } break; - case IR44_DIY6 : if (!applyPreset(6)) { effectCurrent = FX_MODE_RAIN; effectPalette = 0; } break; + case IR44_DIY1 : presetFallback(1, FX_MODE_STATIC, 0); break; + case IR44_DIY2 : presetFallback(2, FX_MODE_BREATH, 0); break; + case IR44_DIY3 : presetFallback(3, FX_MODE_FIRE_FLICKER, 0); break; + case IR44_DIY4 : presetFallback(4, FX_MODE_RAINBOW, 0); break; + case IR44_DIY5 : presetFallback(5, FX_MODE_METEOR_SMOOTH, 0); break; + case IR44_DIY6 : presetFallback(6, FX_MODE_RAIN, 0); break; case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break; case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break; case IR44_JUMP3 : bri = 63; break; @@ -477,10 +477,10 @@ void decodeIR21(uint32_t code) case IR21_PURPLE: colorFromUint32(COLOR_PURPLE); break; case IR21_PINK: colorFromUint32(COLOR_PINK); break; case IR21_WHITE: colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR21_FLASH: if (!applyPreset(1)) { effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; } break; - case IR21_STROBE: if (!applyPreset(2)) { effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; } break; - case IR21_FADE: if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; - case IR21_SMOOTH: if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; + case IR21_FLASH: presetFallback(1, FX_MODE_COLORTWINKLE, 0); break; + case IR21_STROBE: presetFallback(2, FX_MODE_RAINBOW_CYCLE, 0); break; + case IR21_FADE: presetFallback(3, FX_MODE_BREATH, 0); break; + case IR21_SMOOTH: presetFallback(4, FX_MODE_RAINBOW, 0); break; default: return; } lastValidCode = code; @@ -522,9 +522,9 @@ void decodeIR9(uint32_t code) { switch (code) { case IR9_POWER : toggleOnOff(); break; - case IR9_A : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; - case IR9_B : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; - case IR9_C : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; + case IR9_A : presetFallback(1, FX_MODE_COLORTWINKLE, effectPalette); break; + case IR9_B : presetFallback(2, FX_MODE_RAINBOW_CYCLE, effectPalette); break; + case IR9_C : presetFallback(3, FX_MODE_BREATH, effectPalette); break; case IR9_UP : incBrightness(); break; case IR9_DOWN : decBrightness(); break; //case IR9_UP : changeEffectIntensity(16); break; @@ -616,7 +616,7 @@ void decodeIRJson(uint32_t code) // command is JSON object //allow applyPreset() to reuse JSON buffer, or it would alloc. a second buffer and run out of mem. fileDoc = &irDoc; - deserializeState(jsonCmdObj); + deserializeState(jsonCmdObj, CALL_MODE_BUTTON); fileDoc = nullptr; } } diff --git a/wled00/json.cpp b/wled00/json.cpp index a98824466..1ac825263 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -207,7 +207,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId) return; // seg.hasChanged(prev); } -bool deserializeState(JsonObject root, byte presetId) +bool deserializeState(JsonObject root, byte callMode, byte presetId) { DEBUG_PRINTLN(F("Deserializing state")); @@ -337,7 +337,7 @@ bool deserializeState(JsonObject root, byte presetId) if (ps >= 0) { DEBUG_PRINTLN(F("Applying preset")); if (!presetId) unloadPlaylist(); //stop playlist if preset changed manually - applyPreset(ps); + applyPreset(ps, callMode); return stateResponse; } @@ -355,10 +355,10 @@ bool deserializeState(JsonObject root, byte presetId) loadPlaylist(playlist, presetId); noNotification = true; //do not notify both for this request and the first playlist entry } else { - interfaceUpdateCallMode = NOTIFIER_CALL_MODE_WS_SEND; + interfaceUpdateCallMode = CALL_MODE_WS_SEND; } - colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(noNotification ? CALL_MODE_NO_NOTIFY : callMode); return stateResponse; } diff --git a/wled00/led.cpp b/wled00/led.cpp index 5873dc0f9..ce2b6fdc9 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -88,13 +88,13 @@ void colorUpdated(int callMode) { //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 - if (callMode != NOTIFIER_CALL_MODE_INIT && - callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments + if (callMode != CALL_MODE_INIT && + callMode != CALL_MODE_DIRECT_CHANGE && + callMode != CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments bool someSel = false; - if (callMode == NOTIFIER_CALL_MODE_NOTIFICATION) { + if (callMode == CALL_MODE_NOTIFICATION) { someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); } @@ -119,17 +119,17 @@ void colorUpdated(int callMode) interfaceUpdateCallMode = callMode; } else { if (nightlightActive && !nightlightActiveOld && - callMode != NOTIFIER_CALL_MODE_NOTIFICATION && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) + callMode != CALL_MODE_NOTIFICATION && + callMode != CALL_MODE_NO_NOTIFY) { - notify(NOTIFIER_CALL_MODE_NIGHTLIGHT); - interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT; + notify(CALL_MODE_NIGHTLIGHT); + interfaceUpdateCallMode = CALL_MODE_NIGHTLIGHT; } } if (!colChanged) return; //following code is for e.g. initiating transitions - if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) + if (callMode != CALL_MODE_NO_NOTIFY && nightlightActive && (nightlightMode == NL_MODE_FADE || nightlightMode == NL_MODE_COLORFADE)) { briNlT = bri; nightlightDelayMs -= (millis() - nightlightStartTime); @@ -143,19 +143,19 @@ void colorUpdated(int callMode) if (briT == 0) { //setLedsStandard(true); //do not color transition if starting from off! - if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning + if (callMode != CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning } briIT = bri; if (bri > 0) briLast = bri; //deactivate nightlight if target brightness is reached - if (bri == nightlightTargetBri && callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false; + if (bri == nightlightTargetBri && callMode != CALL_MODE_NO_NOTIFY && nightlightMode != NL_MODE_SUN) nightlightActive = false; if (fadeTransition) { //set correct delay if not using notification delay - if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; + if (callMode != CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; jsonTransitionOnce = false; strip.setTransition(transitionDelayTemp); if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;} @@ -180,20 +180,20 @@ void colorUpdated(int callMode) void updateInterfaces(uint8_t callMode) { sendDataWs(); - if (callMode == NOTIFIER_CALL_MODE_WS_SEND) { + if (callMode == CALL_MODE_WS_SEND) { lastInterfaceUpdate = millis(); return; } #ifndef WLED_DISABLE_ALEXA - if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) { + if (espalexaDevice != nullptr && callMode != CALL_MODE_ALEXA) { espalexaDevice->setValue(bri); espalexaDevice->setColor(col[0], col[1], col[2]); } #endif #ifndef WLED_DISABLE_BLYNK - if (callMode != NOTIFIER_CALL_MODE_BLYNK && - callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk(); + if (callMode != CALL_MODE_BLYNK && + callMode != CALL_MODE_NO_NOTIFY) updateBlynk(); #endif doPublishMqtt = true; lastInterfaceUpdate = millis(); @@ -256,7 +256,7 @@ void handleNightlight() if (bri) effectSpeed += 60; //sunset if currently on briNlT = !bri; //true == sunrise, false == sunset if (!bri) bri = briLast; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); @@ -267,7 +267,7 @@ void handleNightlight() { for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color } - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } if (nper >= 1) //nightlight duration over { @@ -275,7 +275,7 @@ void handleNightlight() if (nightlightMode == NL_MODE_SET) { bri = nightlightTargetBri; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } if (bri == 0) briLast = briNlT; if (nightlightMode == NL_MODE_SUN) @@ -301,7 +301,7 @@ void handleNightlight() effectCurrent = colNlT[0]; effectSpeed = colNlT[1]; effectPalette = colNlT[2]; - colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); + colorUpdated(CALL_MODE_NO_NOTIFY); } nightlightActiveOld = false; } diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index ce06242d1..b1fbf44c4 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -15,7 +15,7 @@ void parseMQTTBriPayload(char* payload) uint8_t in = strtoul(payload, NULL, 10); if (in == 0 && bri > 0) briLast = bri; bri = in; - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } } @@ -88,12 +88,14 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties if (strcmp_P(topic, PSTR("/col")) == 0) { colorFromDecOrHexString(col, (char*)payloadStr); - colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated(CALL_MODE_DIRECT_CHANGE); } else if (strcmp_P(topic, PSTR("/api")) == 0) { if (payload[0] == '{') { //JSON API DynamicJsonDocument doc(JSON_BUFFER_SIZE); deserializeJson(doc, payloadStr); + fileDoc = &doc; deserializeState(doc.as()); + fileDoc = nullptr; } else { //HTTP API String apireq = "win&"; apireq += (char*)payloadStr; diff --git a/wled00/presets.cpp b/wled00/presets.cpp index cdbd82a37..8ffc96b10 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -4,7 +4,7 @@ * Methods to handle saving and loading presets to/from the filesystem */ -bool applyPreset(byte index) +bool applyPreset(byte index, byte callMode) { if (index == 0) return false; if (fileDoc) { @@ -14,7 +14,7 @@ bool applyPreset(byte index) #ifdef WLED_DEBUG_FS serializeJson(*fileDoc, Serial); #endif - deserializeState(fdo, index); + deserializeState(fdo, callMode, index); } else { DEBUGFS_PRINTLN(F("Make read buf")); DynamicJsonDocument fDoc(JSON_BUFFER_SIZE); @@ -24,7 +24,7 @@ bool applyPreset(byte index) #ifdef WLED_DEBUG_FS serializeJson(fDoc, Serial); #endif - deserializeState(fdo, index); + deserializeState(fdo, callMode, index); } if (!errorFlag) { diff --git a/wled00/set.cpp b/wled00/set.cpp index 386d3ccfe..606fca03a 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -918,7 +918,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) strip.applyToAllSelected = false; pos = req.indexOf(F("&NN")); //do not send UDP notifications this time - colorUpdated((pos > 0) ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); + colorUpdated((pos > 0) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE); return true; } diff --git a/wled00/udp.cpp b/wled00/udp.cpp index 03d689762..e1dea0a1b 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -13,14 +13,14 @@ void notify(byte callMode, bool followUp) if (!udpConnected) return; switch (callMode) { - case NOTIFIER_CALL_MODE_INIT: return; - case NOTIFIER_CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_BUTTON: if (!notifyButton) return; break; - case NOTIFIER_CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_HUE: if (!notifyHue) return; break; - case NOTIFIER_CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_BLYNK: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_ALEXA: if (!notifyAlexa) return; break; + case CALL_MODE_INIT: return; + case CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; + case CALL_MODE_BUTTON: if (!notifyButton) return; break; + case CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; + case CALL_MODE_HUE: if (!notifyHue) return; break; + case CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; + case CALL_MODE_BLYNK: if (!notifyDirect) return; break; + case CALL_MODE_ALEXA: if (!notifyAlexa) return; break; default: return; } byte udpOut[WLEDPACKETSIZE]; @@ -300,7 +300,7 @@ void handleNotifications() if (nightlightActive) nightlightDelayMins = udpIn[7]; if (receiveNotificationBrightness || !someSel) bri = udpIn[2]; - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); + colorUpdated(CALL_MODE_NOTIFICATION); return; } diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 5669f2f30..fb68d62e9 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -78,6 +78,10 @@ #include "../usermods/usermod_rotary_brightness_color/usermod_rotary_brightness_color.h" #endif +#ifdef RGB_ROTARY_ENCODER +#include "../usermods/rgb-rotary-encoder/rgb-rotary-encoder.h" +#endif + void registerUsermods() { /* @@ -151,4 +155,8 @@ void registerUsermods() #ifdef USERMOD_ROTARY_ENCODER_BRIGHTNESS_COLOR usermods.add(new RotaryEncoderBrightnessColor()); #endif + + #ifdef RGB_ROTARY_ENCODER + usermods.add(new RgbRotaryEncoderUsermod()); + #endif } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 37ad2683c..38e1371b6 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -270,6 +270,18 @@ void WLED::loop() if (busConfigs[i] == nullptr) break; mem += BusManager::memUsage(*busConfigs[i]); if (mem <= MAX_LED_MEMORY) busses.add(*busConfigs[i]); +/* + if (busConfigs[i]->adjustBounds(ledCount)) { + mem += busses.memUsage(*busConfigs[i]); + if (mem <= MAX_LED_MEMORY) { + busses.add(*busConfigs[i]); + //RGBW mode is enabled if at least one of the strips is RGBW + strip.isRgbw = (strip.isRgbw || BusManager::isRgbw(busConfigs[i]->type)); + //refresh is required to remain off if at least one of the strips requires the refresh. + strip.isOffRefreshRequred |= BusManager::isOffRefreshRequred(busConfigs[i]->type); + } + } +*/ delete busConfigs[i]; busConfigs[i] = nullptr; } strip.finalizeInit(); @@ -354,6 +366,8 @@ void WLED::setup() pinManager.allocatePin(2); #endif + for (uint8_t i=1; i 0) { - applyPreset(bootPreset); + applyPreset(bootPreset, CALL_MODE_INIT); } - colorUpdated(NOTIFIER_CALL_MODE_INIT); + colorUpdated(CALL_MODE_INIT); // init relay pin if (rlyPin>=0) @@ -504,14 +518,60 @@ void WLED::initConnection() // Only initialize ethernet board if not NONE if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) { ethernet_settings es = ethernetBoards[ethernetType]; - ETH.begin( - (uint8_t) es.eth_address, - (int) es.eth_power, - (int) es.eth_mdc, - (int) es.eth_mdio, - (eth_phy_type_t) es.eth_type, - (eth_clock_mode_t) es.eth_clk_mode - ); + // Use PinManager to ensure pins are available for + // ethernet AND to prevent other uses of these pins. + bool s = true; + byte pinsAllocated[4] { 255, 255, 255, 255 }; + + if (s && (s = pinManager.allocatePin((byte)es.eth_power))) { + pinsAllocated[0] = (byte)es.eth_power; + } + if (s && (s = pinManager.allocatePin((byte)es.eth_mdc))) { + pinsAllocated[1] = (byte)es.eth_mdc; + } + if (s && (s = pinManager.allocatePin((byte)es.eth_mdio))) { + pinsAllocated[2] = (byte)es.eth_mdio; + } + switch(es.eth_clk_mode) { + case ETH_CLOCK_GPIO0_IN: + s = pinManager.allocatePin(0, false); + pinsAllocated[3] = 0; + break; + case ETH_CLOCK_GPIO0_OUT: + s = pinManager.allocatePin(0); + pinsAllocated[3] = 0; + break; + case ETH_CLOCK_GPIO16_OUT: + s = pinManager.allocatePin(16); + pinsAllocated[3] = 16; + break; + case ETH_CLOCK_GPIO17_OUT: + s = pinManager.allocatePin(17); + pinsAllocated[3] = 17; + break; + default: + s = false; + break; + } + + if (s) { + s = ETH.begin( + (uint8_t) es.eth_address, + (int) es.eth_power, + (int) es.eth_mdc, + (int) es.eth_mdio, + (eth_phy_type_t) es.eth_type, + (eth_clock_mode_t) es.eth_clk_mode + ); + } + + if (!s) { + DEBUG_PRINTLN(F("Ethernet init failed")); + // de-allocate only those pins allocated before the failure + for (byte p : pinsAllocated) { + pinManager.deallocatePin(p); + } + } } #endif diff --git a/wled00/wled.h b/wled00/wled.h index b5e503f70..dcccfd095 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2107080 +#define VERSION 2107101 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -449,7 +449,7 @@ WLED_GLOBAL byte touchThreshold _INIT(TOUCH_THRESH WLED_GLOBAL bool notifyDirectDefault _INIT(notifyDirect); WLED_GLOBAL bool receiveNotifications _INIT(true); WLED_GLOBAL unsigned long notificationSentTime _INIT(0); -WLED_GLOBAL byte notificationSentCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL byte notificationSentCallMode _INIT(CALL_MODE_INIT); WLED_GLOBAL bool notificationTwoRequired _INIT(false); // effects @@ -515,7 +515,7 @@ WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0); // mqtt WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0); WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0); -WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT); WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers // alexa udp