diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 2e2c1a6..7047a3e 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -155,6 +155,7 @@ set(headers displays/starfielddisplay.h displays/statusdisplay.h displays/updatedisplay.h + displays/menus/ledstripselectotamode.h icons/alert.h icons/battery.h icons/bluetooth.h @@ -336,6 +337,7 @@ set(sources displays/menus/timesettingsmenu.cpp displays/menus/wifiscanmenu.cpp displays/menus/wifisettingsmenu.cpp + displays/menus/ledstripselectotamode.cpp displays/metersdisplay.cpp displays/pingpongdisplay.cpp displays/poweroffdisplay.cpp diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 6ae137a..f1860dc 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -172,6 +172,7 @@ struct EnableLedstripStVOFrontlight : public RefAccessorSaveSettings { boo struct AnimationMultiplierAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.ledstrip.animationMultiplier; } }; struct LedstripBrightnessAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.ledstrip.brightness; } }; struct LedstripEnableBlinkAnimation : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.enableAnimBlink; } }; +struct LedstripOtaAnimationAccessor : public RefAccessorSaveSettings { OtaAnimationModes &getRef() const override { return settings.ledstrip.otaMode; } }; #endif // Battery diff --git a/main/displays/menus/ledstripmenu.cpp b/main/displays/menus/ledstripmenu.cpp index 271c308..5ea993b 100644 --- a/main/displays/menus/ledstripmenu.cpp +++ b/main/displays/menus/ledstripmenu.cpp @@ -17,6 +17,7 @@ #include "accessors/settingsaccessors.h" #ifdef FEATURE_LEDSTRIP #include "ledstrip.h" +#include "displays/menus/ledstripselectotamode.h" #endif #include "displays/ledstripcolorsdisplay.h" #include "displays/menus/mainmenu.h" @@ -125,6 +126,7 @@ LedstripMenu::LedstripMenu() if (!simplified) { constructMenuItem, SwitchScreenAction>>(); } constructMenuItem, SwitchScreenAction>>(); + if (!simplified) { constructMenuItem, SwitchScreenAction>>(); } constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); if (!simplified) { constructMenuItem, SwitchScreenAction>>(); } diff --git a/main/displays/menus/ledstripselectotamode.cpp b/main/displays/menus/ledstripselectotamode.cpp new file mode 100644 index 0000000..e69de29 diff --git a/main/displays/menus/ledstripselectotamode.h b/main/displays/menus/ledstripselectotamode.h new file mode 100644 index 0000000..ad40792 --- /dev/null +++ b/main/displays/menus/ledstripselectotamode.h @@ -0,0 +1,44 @@ +#pragma once + +// Local includes +#include "menudisplay.h" +#include "utils.h" +#include "menuitem.h" +#include "ledstrip.h" +#include "icons/back.h" +#include "texts.h" +#include "actions/switchscreenaction.h" +#include "accessors/settingsaccessors.h" +#include "ledstripmenu.h" + +#ifdef FEATURE_LEDSTRIP +using namespace espgui; + +template +class LedstripChangeOtaAnimModeAction : public virtual ActionInterface +{ +public: + void triggered() override + { + settings.ledstrip.otaMode = mode; + saveSettings(); + } +}; + +namespace { + class ledstripOtaAnimationChangeMenu : + public MenuDisplay, + public StaticText, + public BackActionInterface> + { + public: + ledstripOtaAnimationChangeMenu() + { + constructMenuItem, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); + } + }; +} // Namespace +#endif diff --git a/main/ledstrip.cpp b/main/ledstrip.cpp index c94bf3a..7a8d34f 100644 --- a/main/ledstrip.cpp +++ b/main/ledstrip.cpp @@ -8,6 +8,7 @@ #include "espchrono.h" #include "ledstripdefines.h" #include "utils.h" +#include "ota.h" using namespace std::chrono_literals; @@ -31,11 +32,11 @@ void updateLedStrip() { EVERY_N_MILLISECONDS( 20 ) { gHue++; } static bool have_disabled_beeper = false; + const bool enAnim = settings.ledstrip.enableAnimBlink; if (cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) { std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); - const bool enAnim = settings.ledstrip.enableAnimBlink; if (espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms || enAnim) { const auto anim_to_fill = time_to_percent(750ms, 500ms, 100ms, settings.ledstrip.enableFullBlink ? (leds.size() / 2) : settings.ledstrip.bigOffset - settings.ledstrip.smallOffset, settings.ledstrip.enableFullBlink); @@ -212,7 +213,7 @@ void updateLedStrip() void showAnimation() { - if (settings.ledstrip.enableLedAnimation && !simplified) + if (settings.ledstrip.enableLedAnimation && !simplified && (!asyncOtaTaskStarted || settings.ledstrip.otaMode != OtaAnimationModes::None)) { if (animation_type == LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW) showDefaultLedstrip(); else if (animation_type == LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW) showBetterRainbow(); @@ -220,12 +221,47 @@ void showAnimation() else if (animation_type == LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR) showCustomColor(); else showDefaultLedstrip(); } + else if (asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None) + { + // show ota animation + showOtaAnimation(); + } else { std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); } } +void showOtaAnimation() +{ + std::fill(std::begin(leds), std::end(leds), CRGB{0,0,0}); + const auto leds_count = leds.size(); + const int one_percent = leds_count / 100; + float percentage = 0; + + const auto progress = asyncOta->progress(); + if (const auto totalSize = asyncOta->totalSize(); totalSize && *totalSize > 0) + { + percentage = (float(progress) / *totalSize * 100); + if (settings.ledstrip.otaMode == OtaAnimationModes::GreenProgressBar) + { + int numLeds = one_percent * percentage; + if (numLeds >= leds_count) + { + numLeds = leds_count - 1; + } + std::fill(std::begin(leds), std::begin(leds) + numLeds, CRGB{0,255,0}); + } + else if (settings.ledstrip.otaMode == OtaAnimationModes::ColorChangeAll) + { + const uint8_t redChannel = 255 - (2.55 * percentage); + const uint8_t greenChannel = 2.55 * percentage; + + std::fill(std::begin(leds), std::end(leds), CRGB{redChannel, greenChannel, 0}); + } + } +} + void showBetterRainbow() { fill_rainbow(&*std::begin(leds), leds.size(), gHue); diff --git a/main/ledstrip.h b/main/ledstrip.h index ab7e6d5..925fcb7 100644 --- a/main/ledstrip.h +++ b/main/ledstrip.h @@ -20,6 +20,13 @@ enum Bobbycar_Side FRONT }; +enum OtaAnimationModes +{ + None, + GreenProgressBar, + ColorChangeAll +}; + extern std::vector leds; extern uint8_t gHue; @@ -31,6 +38,7 @@ void showAnimation(); void showBetterRainbow(); void showSpeedSyncAnimation(); void showCustomColor(); +void showOtaAnimation(); void initLedStrip(); void updateLedStrip(); diff --git a/main/presets.h b/main/presets.h index 98d766e..5644db6 100644 --- a/main/presets.h +++ b/main/presets.h @@ -13,6 +13,7 @@ #include "settings.h" #include "stringsettings.h" #include "ledstripdefines.h" +#include "ledstrip.h" using namespace std::chrono_literals; @@ -246,7 +247,8 @@ constexpr Settings::Ledstrip defaultLedstrip { .stvoFrontEnable = false, .animationMultiplier = 10, .brightness = 255, - .enableAnimBlink = false + .enableAnimBlink = false, + .otaMode = OtaAnimationModes::GreenProgressBar }; #endif diff --git a/main/settings.h b/main/settings.h index 483b787..7f3a714 100644 --- a/main/settings.h +++ b/main/settings.h @@ -21,6 +21,7 @@ #include "bluetoothmode.h" #endif #include "unifiedmodelmode.h" +#include "ledstrip.h" enum class LarsmModeMode : uint8_t { Mode1, Mode2, Mode3, Mode4 }; @@ -171,6 +172,7 @@ struct Settings int16_t animationMultiplier; uint8_t brightness; bool enableAnimBlink; + OtaAnimationModes otaMode; } ledstrip; #endif @@ -304,6 +306,7 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("ledAnimMul", ledstrip.animationMultiplier); callable("ledbrightness", ledstrip.brightness); callable("enAnimBlink", ledstrip.enableAnimBlink); + callable("ledOtaAnim", ledstrip.otaMode); #endif callable("batteryCS", battery.cellsSeries); diff --git a/main/settingspersister.cpp b/main/settingspersister.cpp index 605e7d5..5922637 100644 --- a/main/settingspersister.cpp +++ b/main/settingspersister.cpp @@ -189,6 +189,16 @@ template<> struct nvsGetterHelper { static esp_err_t nvs_get(n *out_value = UnifiedModelMode(tempValue); return err; }}; +#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA) +template<> struct nvsGetterHelper { static esp_err_t nvs_get(nvs_handle handle, const char* key, OtaAnimationModes* out_value) +{ + uint8_t tempValue; + esp_err_t err = nvs_get_u8(handle, key, &tempValue); + if (err == ESP_OK) + *out_value = OtaAnimationModes(tempValue); + return err; +}}; +#endif template<> struct nvsGetterHelper { static esp_err_t nvs_get(nvs_handle handle, const char* key, wifi_mode_t* out_value) { uint8_t tempValue; @@ -345,6 +355,12 @@ template<> struct nvsSetterHelper { static esp_err_t nvs_set(n { return nvs_set_u8(handle, key, uint8_t(value)); }}; +#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA) +template<> struct nvsSetterHelper { static esp_err_t nvs_set(nvs_handle handle, const char* key, OtaAnimationModes value) +{ + return nvs_set_u8(handle, key, uint8_t(value)); +}}; +#endif template<> struct nvsSetterHelper { static esp_err_t nvs_set(nvs_handle handle, const char* key, wifi_mode_t value) { return nvs_set_u8(handle, key, uint8_t(value)); diff --git a/main/texts.h b/main/texts.h index c939f79..7d3837f 100644 --- a/main/texts.h +++ b/main/texts.h @@ -294,6 +294,11 @@ constexpr char TEXT_ANIMATION_MULTIPLIER[] = "Animation Multiplier"; constexpr char TEXT_LEDSTRIP_BRIGHTNESS[] = "Ledstrip Brightness"; constexpr char TEXT_LEDSTRIP_ALLCUSTOMOFF[] = "All custom off"; constexpr char TEXT_LEDSTRIP_EN_BLINK_ANIM[] = "Animated Blink"; +constexpr char TEXT_LEDSTRIP_CHANGE_OTA_ANIM[] = "Change Ota animation"; + +constexpr char TEXT_OTAANIM_NONE[] = "None"; +constexpr char TEXT_OTAANIM_PROGRESS[] = "Progress Bar"; +constexpr char TEXT_OTAANIM_COLOR[] = "Color change"; //constexpr char TEXT_BACK[] = "Back"; //LedstripSelectAnimationMenu diff --git a/main/webserver_dumpnvs.h b/main/webserver_dumpnvs.h index 56ac87c..7607665 100644 --- a/main/webserver_dumpnvs.h +++ b/main/webserver_dumpnvs.h @@ -39,7 +39,8 @@ typename std::enable_if< !std::is_same::value && !std::is_same::value && !std::is_same::value && - !std::is_same::value + !std::is_same::value && + !std::is_same::value , bool>::type showInputForSetting(std::string_view key, T value, JsonObject &body) { @@ -119,6 +120,15 @@ showInputForSetting(std::string_view key, T value, JsonObject &body) return true; } +template +typename std::enable_if< + std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, JsonObject &body) +{ + body[key] = int(value); + return true; +} esp_err_t webserver_dump_nvs_handler(httpd_req_t *req) {