Merge branch 'better-website'
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
|
||||
| Service | Status |
|
||||
| :--- | ---: |
|
||||
| Actions (master) |  |
|
||||
| Actions |  |
|
||||
|
||||
## How to clone ? (READ THIS OR YOU WILL FAIL)
|
||||
|
||||
|
@ -86,6 +86,7 @@ set(BOBBYCAR_BUILDFLAGS
|
||||
# -DFEATURE_NTP
|
||||
-DFEATURE_WIRELESS_CONFIG
|
||||
-DFEATURE_LEDSTRIP
|
||||
-DLEDSTRIP_LENGTH=288
|
||||
-DPINS_LEDSTRIP=33
|
||||
# -DLEDSTRIP_WRONG_DIRECTION
|
||||
-DLEDSTRIP_ANIMATION_DEFAULT=0
|
||||
|
@ -179,8 +179,10 @@ struct EnableLedstripStVOFrontlight : public RefAccessorSaveSettings<bool> { boo
|
||||
struct AnimationMultiplierAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.animationMultiplier; } };
|
||||
struct LedstripBrightnessAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.ledstrip.brightness; } };
|
||||
struct LedstripEnableBlinkAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableAnimBlink; } };
|
||||
#ifdef FEATURE_OTA
|
||||
struct LedstripOtaAnimationAccessor : public RefAccessorSaveSettings<OtaAnimationModes> { OtaAnimationModes &getRef() const override { return settings.ledstrip.otaMode; } };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Battery
|
||||
struct BatterySeriesCellsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.battery.cellsSeries; } };
|
||||
|
@ -127,7 +127,9 @@ LedstripMenu::LedstripMenu()
|
||||
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTANIMATION>, SwitchScreenAction<LedstripSelectAnimationMenu>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKANIMATION>, SwitchScreenAction<LedstripSelectBlinkMenu>>>();
|
||||
#ifdef FEATURE_OTA
|
||||
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_CHANGE_OTA_ANIM>, SwitchScreenAction<ledstripOtaAnimationChangeMenu>>>(); }
|
||||
#endif
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_MULTIPLIER>, SwitchScreenAction<animationMultiplierChangeScreen>>>();
|
||||
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_LEDSCOUNT, LedsCountAccessor>, SwitchScreenAction<LedsCountChangeScreen>>>(); }
|
||||
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CENTEROFFSET, CenterOffsetAccessor>, SwitchScreenAction<CenterOffsetChangeScreen>>>(); }
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "accessors/settingsaccessors.h"
|
||||
#include "ledstripmenu.h"
|
||||
|
||||
#ifdef FEATURE_LEDSTRIP
|
||||
#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA)
|
||||
using namespace espgui;
|
||||
|
||||
template <OtaAnimationModes mode>
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> battery{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "battery"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -39,6 +39,6 @@ const espgui::Icon<24, 24> bluetooth{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x19ED, 0x4353, 0x53F5, 0x5C37, 0x5C57, 0x5C57, 0x5C37, 0x53F5, 0x4332, // 0x0220 (544) pixels
|
||||
0x19ED, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x00A6, 0x21EC, 0x2A6F, 0x32B1, 0x32B1, 0x2A6F, 0x19EC, 0x00A6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "bluetooth"};
|
||||
#endif
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> buzzer{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5AEB, 0x52CA, 0x1884, 0x39C6, 0x39E7, 0x3A07, 0x52EA, 0x52AA, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x52AA, 0x52CA, 0x5AEB, 0x5ACB, 0x5ACA, 0x4A4A, 0x52AA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "buzzer"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -34,5 +34,5 @@ const espgui::Icon<32, 32> close{{
|
||||
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5800,0xA800,0xB0A2,0xA8E3,0xA0A2,0xA041,0x9800,0x9800,0xA041,0xA0A2,0xA8E3,0xB0A2,0xA800,0x5800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 29, 960 pixels
|
||||
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x6000,0x8800,0xA000,0xA800,0xA800,0xA000,0x8800,0x6000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 30, 992 pixels
|
||||
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // row 31, 1024 pixels
|
||||
}};
|
||||
}, "close"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> demos{{
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x9CF3, 0xB5B6, 0xC638, 0xC638, 0xB596, 0xA514, 0x9CD3, 0x94B2, 0x9CD3, 0xA514, 0xAD75, 0xC618, // 0x0220 (544) pixels
|
||||
0xC638, 0xBDD7, 0xA514, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xCE79, // 0x0230 (560) pixels
|
||||
0xD6DA, 0xDEFB, 0xE71C, 0xE73C, 0xE71C, 0xE71C, 0xDEDB, 0xD69A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "demos"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> graph{{
|
||||
0x0000, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, // 0x0220 (544) pixels
|
||||
0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x0000, 0x0000, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x738E, 0x7BCF, 0x7BCF, // 0x0230 (560) pixels
|
||||
0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x738E, 0x7BCF, 0x7BCF, 0x7BCF, 0x7BCF, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "graph"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> info{{
|
||||
0x0000, 0x0000, 0x0000, 0x014C, 0x016D, 0x0335, 0x014C, 0x01AE, 0x0210, 0x0272, 0x02B4, 0x02B4, 0x02D4, 0x02B4, 0x0272, 0x0210, // 0x0220 (544) pixels
|
||||
0x01AE, 0x014B, 0x0315, 0x016D, 0x014C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00C6, 0x014C, 0x01EE, 0x016C, // 0x0230 (560) pixels
|
||||
0x01AD, 0x01CE, 0x01EE, 0x01CE, 0x01CE, 0x01EE, 0x01CE, 0x01AD, 0x016C, 0x01EE, 0x016C, 0x00A5, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "info"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> lock{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0xC569, 0xE648, 0xE5E2, 0xD540, 0xC4E0, 0xBC60, 0xB420, 0xB420, 0xB440, 0xBC60, 0xC480, 0xCD00, // 0x0220 (544) pixels
|
||||
0xDDA0, 0xE687, 0xDE8F, 0xACEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "lock"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> modes{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0x0000, 0x0002, 0x0849, 0x2190, 0x3270, 0x3B30, 0x3B90, 0x3B90, 0x2B0F, 0x224F, 0x114C, // 0x0220 (544) pixels
|
||||
0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0004, 0x0006, 0x0007, 0x0007, 0x0006, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "modes"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> neopixel{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "neopixel"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> poweroff{{
|
||||
0xA8C3, 0xA1A5, 0x9984, 0x9102, 0x9122, 0x9942, 0x9942, 0x9962, 0x9962, 0x9982, 0x9982, 0x9982, 0x9982, 0x9982, 0x9982, 0x9962, // 0x0220 (544) pixels
|
||||
0x9962, 0x9142, 0x9142, 0x9122, 0x9122, 0x9143, 0x8903, 0x9820, 0xB000, 0xA061, 0x9061, 0x9020, 0x9020, 0x9020, 0x9020, 0x9020, // 0x0230 (560) pixels
|
||||
0x9020, 0x9020, 0x9020, 0x8820, 0x8820, 0x8820, 0x8820, 0x8820, 0x8820, 0x8820, 0x8820, 0x8820, 0x9040, 0x9040, 0x9820, 0xB800, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "poweroff"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> presets{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x1120, 0x2A41, 0x3B02, 0x4B83, 0x4BA4, 0x4B83, 0x4343, 0x32A2, 0x21A1, // 0x0220 (544) pixels
|
||||
0x0880, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0880, 0x08E0, 0x08C0, 0x0040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "presets"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> reboot{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "reboot"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> scan{{
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20E4, 0x20C4, 0x0000, 0x0000, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x1082, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x10A2, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "scan"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> settings{{
|
||||
0x122E, 0x122E, 0x1969, 0x0000, 0x0000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0820, 0x0820, 0x0840, 0x0061, 0x0061, 0x0041, 0x0041, // 0x0220 (544) pixels
|
||||
0x0041, 0x0042, 0x0000, 0x0000, 0x0000, 0x5841, 0x5841, 0x5841, 0x122E, 0x122E, 0x1969, 0x0000, 0x0000, 0x0800, 0x0800, 0x0800, // 0x0230 (560) pixels
|
||||
0x0800, 0x0820, 0x0820, 0x0840, 0x0061, 0x0061, 0x0041, 0x0041, 0x0041, 0x0042, 0x0800, 0x0800, 0x0000, 0x5841, 0x5841, 0x5841, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "settings"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -39,6 +39,6 @@ const espgui::Icon<24, 24> statistics{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xA3E1, 0xFE21, 0xE5A1, 0xB461, 0x3960, 0x5200, 0x8320, 0xA3C0, 0xE581, 0xFE21, // 0x0220 (544) pixels
|
||||
0xFE21, 0xE581, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0020, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3960, 0xC4C1, 0xF601, 0x8340, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}
|
||||
}, "statistics"
|
||||
};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> time{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18A3, 0x41C9, 0x4A2B, 0x524C, 0x524C, 0x4A2B, 0x39A9, 0x10A3, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "time"};
|
||||
} // namespace
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> update{{
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1480, 0x2CE3, 0x0BE0, 0x0D20, 0x0000, // 0x0220 (544) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0B40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "update"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -38,5 +38,5 @@ const espgui::Icon<24, 24> wifi{{
|
||||
0x0000, 0x0000, 0x8C50, 0x8C50, 0x6B6D, 0x7BEF, 0xC637, 0x2124, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0220 (544) pixels
|
||||
0x634C, 0x9D13, 0x7BEF, 0x738D, 0x8C50, 0x8C50, 0x0000, 0x0000, 0x0000, 0x0000, 0x8C50, 0x8C50, 0x8430, 0x8430, 0x0000, 0x0000, // 0x0230 (560) pixels
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8430, 0x8430, 0x8C50, 0x8C50, 0x0000, 0x0000, // 0x0240 (576) pixels
|
||||
}};
|
||||
}, "wifi"};
|
||||
} // namespace bobbyicons
|
||||
|
@ -213,7 +213,12 @@ void updateLedStrip()
|
||||
|
||||
void showAnimation()
|
||||
{
|
||||
if (settings.ledstrip.enableLedAnimation && !simplified && !(asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None))
|
||||
if (settings.ledstrip.enableLedAnimation
|
||||
&& !simplified
|
||||
#ifdef FEATURE_OTA
|
||||
&& !(asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (animation_type == LedstripAnimation::DefaultRainbow) showDefaultLedstrip();
|
||||
else if (animation_type == LedstripAnimation::BetterRainbow) showBetterRainbow();
|
||||
@ -221,17 +226,20 @@ void showAnimation()
|
||||
else if (animation_type == LedstripAnimation::CustomColor) showCustomColor();
|
||||
else showDefaultLedstrip();
|
||||
}
|
||||
#ifdef FEATURE_OTA
|
||||
else if (asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None)
|
||||
{
|
||||
// show ota animation
|
||||
showOtaAnimation();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEATURE_OTA
|
||||
void showOtaAnimation()
|
||||
{
|
||||
std::fill(std::begin(leds), std::end(leds), CRGB{0,0,0});
|
||||
@ -260,6 +268,7 @@ void showOtaAnimation()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void showBetterRainbow()
|
||||
{
|
||||
|
@ -19,12 +19,14 @@ enum Bobbycar_Side
|
||||
FRONT
|
||||
};
|
||||
|
||||
#ifdef FEATURE_OTA
|
||||
enum OtaAnimationModes
|
||||
{
|
||||
None,
|
||||
GreenProgressBar,
|
||||
ColorChangeAll
|
||||
};
|
||||
#endif
|
||||
|
||||
extern std::vector<CRGB> leds;
|
||||
extern uint8_t gHue;
|
||||
@ -37,7 +39,9 @@ void showAnimation();
|
||||
void showBetterRainbow();
|
||||
void showSpeedSyncAnimation();
|
||||
void showCustomColor();
|
||||
#ifdef FEATURE_OTA
|
||||
void showOtaAnimation();
|
||||
#endif
|
||||
|
||||
void initLedStrip();
|
||||
void updateLedStrip();
|
||||
|
@ -1,5 +1,9 @@
|
||||
constexpr const char * const TAG = "BOBBY";
|
||||
|
||||
#ifndef OTA_USERNAME
|
||||
#error No OTA username!
|
||||
#endif
|
||||
|
||||
// system includes
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -50,8 +50,15 @@ StringSettings makeDefaultStringSettings()
|
||||
},
|
||||
.otaServerUrl = {},
|
||||
#endif
|
||||
#ifdef AP_PASSWORD
|
||||
.ap_password = STRING(AP_PASSWORD),
|
||||
.otaServerBranch = {}
|
||||
#else
|
||||
.ap_password = "Bobbycar_123",
|
||||
#endif
|
||||
#ifdef FEATURE_OTA
|
||||
.otaServerBranch = {},
|
||||
#endif
|
||||
.webserver_password = {},
|
||||
};
|
||||
}
|
||||
} // namespace presets
|
||||
|
@ -266,7 +266,9 @@ constexpr Settings::Ledstrip defaultLedstrip {
|
||||
.animationMultiplier = 10,
|
||||
.brightness = 255,
|
||||
.enableAnimBlink = false,
|
||||
#ifdef FEATURE_OTA
|
||||
.otaMode = OtaAnimationModes::GreenProgressBar
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -183,7 +183,9 @@ struct Settings
|
||||
int16_t animationMultiplier;
|
||||
uint8_t brightness;
|
||||
bool enableAnimBlink;
|
||||
#ifdef FEATURE_OTA
|
||||
OtaAnimationModes otaMode;
|
||||
#endif
|
||||
} ledstrip;
|
||||
#endif
|
||||
|
||||
@ -330,7 +332,9 @@ void Settings::executeForEveryCommonSetting(T &&callable)
|
||||
callable("ledAnimMul", ledstrip.animationMultiplier);
|
||||
callable("ledbrightness", ledstrip.brightness);
|
||||
callable("enAnimBlink", ledstrip.enableAnimBlink);
|
||||
#ifdef FEATURE_OTA
|
||||
callable("ledOtaAnim", ledstrip.otaMode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
callable("batteryCS", battery.cellsSeries);
|
||||
|
@ -49,7 +49,10 @@ struct StringSettings
|
||||
std::string dns_key;
|
||||
#endif
|
||||
std::string ap_password;
|
||||
#ifdef FEATURE_OTA
|
||||
std::string otaServerBranch;
|
||||
#endif
|
||||
std::string webserver_password;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -114,12 +117,13 @@ void StringSettings::executeForEveryCommonSetting(T &&callable)
|
||||
// callable("otaUrl9", otaServers[9].url);
|
||||
|
||||
callable("otaserver", otaServerUrl);
|
||||
callable("otaBranch", otaServerBranch);
|
||||
#endif
|
||||
#ifdef FEATURE_DNS_NS
|
||||
callable("dnskey", dns_key);
|
||||
#endif
|
||||
callable("ap_pw", ap_password);
|
||||
callable("otaBranch", otaServerBranch);
|
||||
callable("webpw", webserver_password);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -4,11 +4,9 @@ constexpr const char * const TAG = "bobbycloud";
|
||||
// 3rd party includes
|
||||
#include <ArduinoJson.h>
|
||||
#include <FastLED.h>
|
||||
#ifdef FEATURE_OTA
|
||||
#include <espcppmacros.h>
|
||||
#include <espstrutils.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#endif
|
||||
|
||||
// local includes
|
||||
#include "udpcloud.h"
|
||||
|
@ -33,6 +33,7 @@ void initWebserver()
|
||||
httpd_uri_t { .uri = "/reboot", .method = HTTP_GET, .handler = webserver_reboot_handler, .user_ctx = NULL },
|
||||
#ifdef FEATURE_OTA
|
||||
httpd_uri_t { .uri = "/ota", .method = HTTP_GET, .handler = webserver_ota_handler, .user_ctx = NULL },
|
||||
httpd_uri_t { .uri = "/otaPercent", .method = HTTP_GET, .handler = webserver_ota_percentage_handler, .user_ctx = NULL },
|
||||
httpd_uri_t { .uri = "/triggerOta", .method = HTTP_GET, .handler = webserver_trigger_ota_handler, .user_ctx = NULL },
|
||||
#endif
|
||||
httpd_uri_t { .uri = "/settings", .method = HTTP_GET, .handler = webserver_settings_handler, .user_ctx = NULL },
|
||||
@ -42,6 +43,7 @@ void initWebserver()
|
||||
#ifdef OLD_NVS
|
||||
httpd_uri_t { .uri = "/dumpnvs", .method = HTTP_GET, .handler = webserver_dump_nvs_handler, .user_ctx = NULL },
|
||||
#endif
|
||||
httpd_uri_t { .uri = "/check", .method = HTTP_GET, .handler = webserver_status_handler, .user_ctx = NULL },
|
||||
})
|
||||
{
|
||||
const auto result = httpd_register_uri_handler(httpdHandle, &uri);
|
||||
@ -66,4 +68,36 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req)
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "REBOOT called...")
|
||||
}
|
||||
|
||||
esp_err_t webserver_status_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
|
||||
if (!helper.locked())
|
||||
{
|
||||
constexpr const std::string_view msg = "could not lock webserver_lock";
|
||||
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
|
||||
}
|
||||
|
||||
std::string wants_json_query;
|
||||
if (auto result = esphttpdutils::webserver_get_query(req))
|
||||
wants_json_query = *result;
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "%.*s", result.error().size(), result.error().data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", result.error());
|
||||
}
|
||||
|
||||
char tmpBuf[256];
|
||||
const auto key_result = httpd_query_key_value(wants_json_query.data(), "json", tmpBuf, 256);
|
||||
if (key_result == ESP_OK && (tmpBuf == stringSettings.webserver_password || stringSettings.webserver_password.empty()))
|
||||
{
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "Ok.");
|
||||
}
|
||||
else
|
||||
{
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Unauthorized, "text/plain", "");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,4 +32,5 @@ extern httpd_handle_t httpdHandle;
|
||||
void initWebserver();
|
||||
void handleWebserver();
|
||||
esp_err_t webserver_reboot_handler(httpd_req_t *req);
|
||||
esp_err_t webserver_status_handler(httpd_req_t *req);
|
||||
#endif
|
||||
|
@ -19,6 +19,113 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
|
||||
|
||||
std::string body;
|
||||
|
||||
std::string wants_json_query;
|
||||
if (auto result = esphttpdutils::webserver_get_query(req))
|
||||
wants_json_query = *result;
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "%.*s", result.error().size(), result.error().data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", result.error());
|
||||
}
|
||||
|
||||
char tmpBuf[256];
|
||||
const auto key_result = httpd_query_key_value(wants_json_query.data(), "json", tmpBuf, 256);
|
||||
if (key_result == ESP_OK && (tmpBuf == stringSettings.webserver_password || stringSettings.webserver_password.empty()))
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
body += "{";
|
||||
if (auto currentDisplay = static_cast<const espgui::Display *>(espgui::currentDisplay.get()))
|
||||
{
|
||||
body.reserve(4096);
|
||||
if (const auto *textInterface = currentDisplay->asTextInterface())
|
||||
{
|
||||
body += fmt::format("\"name\":\"{}\",", textInterface->text());
|
||||
}
|
||||
|
||||
if (const auto *menuDisplay = currentDisplay->asMenuDisplay())
|
||||
{
|
||||
body += fmt::format("\"index\":{},\"items\":[", menuDisplay->selectedIndex());
|
||||
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const espgui::MenuItem &menuItem){
|
||||
body += "{";
|
||||
const auto itemName = menuItem.text();
|
||||
std::string color{};
|
||||
std::string font{};
|
||||
switch (menuItem.color()) {
|
||||
case TFT_RED:
|
||||
color = "&1";
|
||||
break;
|
||||
case TFT_GREEN:
|
||||
color = "&2";
|
||||
break;
|
||||
case TFT_BLUE:
|
||||
color = "&3";
|
||||
break;
|
||||
case TFT_YELLOW:
|
||||
color = "&4";
|
||||
break;
|
||||
case TFT_BLACK:
|
||||
color = "&5";
|
||||
break;
|
||||
case TFT_WHITE:
|
||||
color = "&6";
|
||||
break;
|
||||
case TFT_GREY:
|
||||
case TFT_DARKGREY:
|
||||
color = "&7";
|
||||
break;
|
||||
default:
|
||||
color = "";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (menuItem.font())
|
||||
{
|
||||
case 2:
|
||||
font = "&s";
|
||||
break;
|
||||
case 4:
|
||||
font = "&m";
|
||||
break;
|
||||
default:
|
||||
font = "";
|
||||
break;
|
||||
}
|
||||
|
||||
std::string menuItemName = font + color + itemName;
|
||||
body += fmt::format("\"name\":\"{}\",\"icon\":\"{}\",\"index\":{}", menuItemName, (menuItem.icon()) ? menuItem.icon()->name : "", selectedIndex);
|
||||
body += "},";
|
||||
});
|
||||
body += "],";
|
||||
}
|
||||
else if (const auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface())
|
||||
{
|
||||
body += fmt::format("\"value\":\"{}\",", changeValueDisplay->shownValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"err\":\"Screen not implemented yet.\",";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"err\":\"Currently no screen instantiated.\",";
|
||||
}
|
||||
body += "}";
|
||||
|
||||
size_t lastGesch = body.rfind("},");
|
||||
if (std::string::npos != lastGesch)
|
||||
body = body.erase(lastGesch+1, 1);
|
||||
|
||||
size_t lastEckig = body.rfind("],");
|
||||
if (std::string::npos != lastEckig)
|
||||
body = body.erase(lastEckig+1, 1);
|
||||
}
|
||||
else if (key_result != ESP_ERR_NOT_FOUND && tmpBuf != stringSettings.webserver_password)
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Unauthorized, "text/plain", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
HtmlTag htmlTag{"html", body};
|
||||
|
||||
@ -105,7 +212,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/html", body)
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, (key_result == ESP_OK) ? "application/json":"text/html", body)
|
||||
}
|
||||
|
||||
esp_err_t webserver_triggerButton_handler(httpd_req_t *req)
|
||||
|
@ -113,6 +113,7 @@ showInputForSetting(std::string_view key, T value, JsonObject &body)
|
||||
|
||||
esp_err_t webserver_dump_nvs_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
|
||||
if (!helper.locked())
|
||||
{
|
||||
|
@ -11,6 +11,63 @@ namespace {
|
||||
constexpr const char * const TAG = "BOBBYWEB";
|
||||
} // namespace
|
||||
|
||||
esp_err_t webserver_ota_percentage_handler(httpd_req_t *req)
|
||||
{
|
||||
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
|
||||
if (!helper.locked())
|
||||
{
|
||||
constexpr const std::string_view msg = "could not lock webserver_lock";
|
||||
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
|
||||
}
|
||||
|
||||
std::string body;
|
||||
|
||||
std::string wants_json_query;
|
||||
if (auto result = esphttpdutils::webserver_get_query(req))
|
||||
wants_json_query = *result;
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "%.*s", result.error().size(), result.error().data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", result.error());
|
||||
}
|
||||
|
||||
char tmpBuf[256];
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
const auto key_result = httpd_query_key_value(wants_json_query.data(), "json", tmpBuf, 256);
|
||||
if (key_result == ESP_OK && (tmpBuf == stringSettings.webserver_password || stringSettings.webserver_password.empty()))
|
||||
{
|
||||
body += "{";
|
||||
if (asyncOta)
|
||||
{
|
||||
const auto progress = asyncOta->progress();
|
||||
const auto totalSize = asyncOta->totalSize();
|
||||
|
||||
body += fmt::format("\"cur_ota_percent\":\"{}\",", (totalSize && *totalSize > 0) ? fmt::format("{:.02f}", float(progress) / *totalSize * 100) : "?");
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"info\":\"Updater is not constructed.\"";
|
||||
}
|
||||
|
||||
body += "}";
|
||||
}
|
||||
else if (key_result != ESP_ERR_NOT_FOUND && tmpBuf != stringSettings.webserver_password)
|
||||
{
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Unauthorized, "text/plain", "");
|
||||
}
|
||||
|
||||
size_t lastGesch = body.rfind("},");
|
||||
if (std::string::npos != lastGesch)
|
||||
body = body.erase(lastGesch+1, 1);
|
||||
|
||||
size_t lastEckig = body.rfind("],");
|
||||
if (std::string::npos != lastEckig)
|
||||
body = body.erase(lastEckig+1, 1);
|
||||
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, (key_result == ESP_OK) ? "application/json" : "text/html", body)
|
||||
}
|
||||
|
||||
esp_err_t webserver_ota_handler(httpd_req_t *req)
|
||||
{
|
||||
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
|
||||
@ -23,6 +80,83 @@ esp_err_t webserver_ota_handler(httpd_req_t *req)
|
||||
|
||||
std::string body;
|
||||
|
||||
std::string wants_json_query;
|
||||
if (auto result = esphttpdutils::webserver_get_query(req))
|
||||
wants_json_query = *result;
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "%.*s", result.error().size(), result.error().data());
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", result.error());
|
||||
}
|
||||
|
||||
char tmpBuf[256];
|
||||
const auto key_result = httpd_query_key_value(wants_json_query.data(), "json", tmpBuf, 256);
|
||||
if (key_result == ESP_OK && (tmpBuf == stringSettings.webserver_password || stringSettings.webserver_password.empty()))
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
body += "{";
|
||||
|
||||
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
|
||||
{
|
||||
body += fmt::format("\"cur_name\":\"{}\",", app_desc->project_name);
|
||||
body += fmt::format("\"cur_ver\":\"{}\",", app_desc->version);
|
||||
body += fmt::format("\"cur_secver\":\"{}\",", app_desc->secure_version);
|
||||
body += fmt::format("\"cur_ts\":\"{}\",", app_desc->time);
|
||||
body += fmt::format("\"cur_idf\":\"{}\",", app_desc->idf_ver);
|
||||
body += fmt::format("\"cur_sha\":\"{}\",", espcpputils::toHexString({app_desc->app_elf_sha256, 8}));
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"err\":\"Could not access esp_ota_get_app_description()\",";
|
||||
}
|
||||
|
||||
body += "\"updater\":{";
|
||||
|
||||
if (asyncOta)
|
||||
{
|
||||
body += fmt::format("\"status\":\"{}\"", toString(asyncOta->status()));
|
||||
|
||||
if (const auto &appDesc = asyncOta->appDesc())
|
||||
{
|
||||
const auto progress = asyncOta->progress();
|
||||
const auto totalSize = asyncOta->totalSize();
|
||||
|
||||
body += fmt::format("\"cur_ota_percent\":\"{}\",", (totalSize && *totalSize > 0) ? fmt::format("{:.02f}", float(progress) / *totalSize * 100) : "?");
|
||||
body += fmt::format("\"cur_ota_progress\":\"{}\",", progress);
|
||||
body += fmt::format("\"cur_ota_total\":\"{}\",", totalSize ? std::to_string(*totalSize) : "?");
|
||||
body += fmt::format("\"new_name\":\"{}\",", appDesc->project_name);
|
||||
body += fmt::format("\"new_ver\":\"{}\",", appDesc->version);
|
||||
body += fmt::format("\"new_secver\":\"{}\",", appDesc->secure_version);
|
||||
body += fmt::format("\"new_ts\":\"{}\",", appDesc->time);
|
||||
body += fmt::format("\"new_idf\":\"{}\",", appDesc->idf_ver);
|
||||
body += fmt::format("\"new_sha\":\"{}\",", espcpputils::toHexString({appDesc->app_elf_sha256, 8}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"err\":\"Could not access asyncOta->appDesc()\",";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
body += "\"info\":\"Updater is not constructed.\"";
|
||||
}
|
||||
|
||||
body += "}}";
|
||||
size_t lastGesch = body.rfind("},");
|
||||
if (std::string::npos != lastGesch)
|
||||
body = body.erase(lastGesch+1, 1);
|
||||
|
||||
size_t lastEckig = body.rfind("],");
|
||||
if (std::string::npos != lastEckig)
|
||||
body = body.erase(lastEckig+1, 1);
|
||||
}
|
||||
else if (tmpBuf != stringSettings.webserver_password)
|
||||
{
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Unauthorized, "text/plain", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
HtmlTag htmlTag{"html", body};
|
||||
|
||||
@ -197,7 +331,7 @@ esp_err_t webserver_ota_handler(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/html", body)
|
||||
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, (key_result == ESP_OK) ? "application/json" : "text/html", body)
|
||||
}
|
||||
|
||||
esp_err_t webserver_trigger_ota_handler(httpd_req_t *req)
|
||||
|
@ -24,5 +24,6 @@
|
||||
|
||||
#if defined(FEATURE_WEBSERVER) && defined(FEATURE_OTA)
|
||||
esp_err_t webserver_ota_handler(httpd_req_t *req);
|
||||
esp_err_t webserver_ota_percentage_handler(httpd_req_t *req);
|
||||
esp_err_t webserver_trigger_ota_handler(httpd_req_t *req);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user