From ca337ce99e98083d17337e630eec32569bd9cc6e Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 10 Aug 2021 15:51:20 +0200 Subject: [PATCH] OTA implemented --- icons/update.png | Bin 0 -> 10686 bytes main/CMakeLists.txt | 1 + main/displays/menus/mainmenu.h | 3 ++ main/displays/updatedisplay.h | 76 +++++++++++++++++++-------------- main/icons/update.h | 46 ++++++++++++++++++++ main/ota.h | 65 ++++++++++++++-------------- main/presets.h | 3 ++ main/stringsettings.h | 8 ++++ main/texts.h | 1 + 9 files changed, 141 insertions(+), 62 deletions(-) create mode 100644 icons/update.png create mode 100644 main/icons/update.h diff --git a/icons/update.png b/icons/update.png new file mode 100644 index 0000000000000000000000000000000000000000..9ea00f4d4cad08c4b6a7891302a0afa677a6ca7f GIT binary patch literal 10686 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, SwitchScreenAction>>(); #endif constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::demos>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::update>>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::poweroff>>>(); constructMenuItem, RebootAction, StaticMenuItemIcon<&icons::reboot>>>(); constructMenuItem, SwitchScreenAction>>(); diff --git a/main/displays/updatedisplay.h b/main/displays/updatedisplay.h index 36e1811..4367e25 100644 --- a/main/displays/updatedisplay.h +++ b/main/displays/updatedisplay.h @@ -4,6 +4,9 @@ #include #include +// esp-idf includes +#include + // 3rdparty lib includes #ifdef FEATURE_OTA #include @@ -17,51 +20,32 @@ #include "texts.h" #include "widgets/label.h" #include "widgets/progressbar.h" -#include "modes/ignoreinputmode.h" +#include "ota.h" namespace { -class StatusDisplay; +class MainMenu; } namespace { #ifdef FEATURE_OTA -class UpdateDisplay : public Display, public DummyBack +class UpdateDisplay : public Display, public BackActionInterface> { public: - UpdateDisplay(const std::string &title); - UpdateDisplay(std::string &&title); - void start() override; void initScreen() override; void redraw() override; void confirm() override; -public: - bool m_finished; - unsigned int m_progress; - unsigned int m_total; - private: - const std::string m_title; - - Label m_progressLabel{20, 150}; + Label m_statusLabel{120, 75}; + Label m_progressLabel{120, 100}; + Label m_totalLabel{120, 125}; ProgressBar m_progressBar{20, 200, 200, 10, 0, 100}; }; -UpdateDisplay::UpdateDisplay(const std::string &title) : - m_title{title} -{} - -UpdateDisplay::UpdateDisplay(std::string &&title) : - m_title{std::move(title)} -{} - void UpdateDisplay::start() { - m_finished = false; - m_progress = 0; - m_total = 1; } void UpdateDisplay::initScreen() @@ -70,29 +54,59 @@ void UpdateDisplay::initScreen() tft.setTextFont(4); tft.setTextColor(TFT_YELLOW); - tft.drawString(m_title.c_str(), 5, 5, 4); + tft.drawString(TEXT_UPDATE, 5, 5, 4); tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE); tft.setTextColor(TFT_WHITE, TFT_BLACK); - tft.drawString("Progress:", 20, 125); + tft.drawString("Status:", 20, m_statusLabel.y()); + m_statusLabel.start(); + + tft.drawString("Progress:", 20, m_progressLabel.y()); m_progressLabel.start(); + tft.drawString("Total:", 20, m_totalLabel.y()); + m_totalLabel.start(); + m_progressBar.start(); } void UpdateDisplay::redraw() { - m_progressLabel.redraw(fmt::format("{}/{}", m_progress, m_total)); + if (asyncOta) + { + m_statusLabel.redraw(toString(asyncOta->status())); + const auto progress = asyncOta->progress(); + m_progressLabel.redraw(std::to_string(progress)); + if (const auto totalSize = asyncOta->totalSize()) + { + m_totalLabel.redraw(std::to_string(*totalSize)); + m_progressBar.redraw(float(progress) / *totalSize * 100); + } + else + { + m_totalLabel.clear(); + m_progressBar.redraw(0); + } + } + else + { + m_statusLabel.clear(); + m_progressLabel.clear(); + m_totalLabel.clear(); - m_progressBar.redraw(float(m_progress) / m_total * 100.f); + m_progressBar.redraw(0); + } } void UpdateDisplay::confirm() { - if (m_finished) - switchScreen(); + //if (m_finished) + // switchScreen(); + + if (const auto result = triggerOta(stringSettings.otaUrl); !result) + ESP_LOGE("BOBBY", "triggerOta() failed with %.*s", result.error().size(), result.error().data()); } #endif } diff --git a/main/icons/update.h b/main/icons/update.h new file mode 100644 index 0000000..06214aa --- /dev/null +++ b/main/icons/update.h @@ -0,0 +1,46 @@ +#pragma once + +#include "icon.h" + +namespace { +namespace icons { +const Icon<24, 24> update{{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0010 (16) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0020 (32) pixels + 0x0000, 0x1CC1, 0x1620, 0x0E00, 0x0DA0, 0x0D40, 0x2581, 0x1CE1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0030 (48) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1500, 0x0E60, 0x0E20, 0x0DA0, 0x0D40, 0x2581, 0x1C41, // 0x0040 (64) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0050 (80) pixels + 0x0C60, 0x1540, 0x0E60, 0x0E00, 0x0D80, 0x0D40, 0x25A1, 0x1C81, 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0060 (96) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C60, 0x1D61, 0x2681, 0x0E00, 0x0D80, 0x0D40, 0x2DA1, 0x1C21, // 0x0070 (112) pixels + 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0080 (128) pixels + 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D60, 0x0D20, 0x2DA2, 0x1C21, 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0090 (144) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D60, 0x0D20, 0x2DA2, 0x1BE1, // 0x00A0 (160) pixels + 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00B0 (176) pixels + 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D40, 0x0D20, 0x2DA2, 0x1BE1, 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00C0 (192) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D40, 0x0D20, 0x2DA2, 0x1BE1, // 0x00D0 (208) pixels + 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00E0 (224) pixels + 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D40, 0x0D20, 0x2DA2, 0x1BE1, 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00F0 (240) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C80, 0x25A1, 0x2EA1, 0x0E00, 0x0D20, 0x0D20, 0x2DA2, 0x1BE1, // 0x0100 (256) pixels + 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0110 (272) pixels + 0x0C60, 0x25A0, 0x2EA1, 0x0E00, 0x0D20, 0x0D20, 0x2DA2, 0x1BE1, 0x0DA0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0120 (288) pixels + 0x0000, 0x0000, 0x0000, 0x2403, 0x03E0, 0x0420, 0x0440, 0x0460, 0x2463, 0x25A1, 0x26A1, 0x0E00, 0x0D20, 0x0D20, 0x2DC2, 0x1461, // 0x0130 (304) pixels + 0x14A0, 0x1460, 0x1480, 0x1480, 0x0D41, 0x0E80, 0x0000, 0x0000, 0x0000, 0x0000, 0x1381, 0x34C4, 0x3662, 0x3682, 0x36A2, 0x36A1, // 0x0140 (320) pixels + 0x3E44, 0x3682, 0x26A1, 0x0E00, 0x0D20, 0x0D20, 0x1D81, 0x0D61, 0x14E0, 0x1500, 0x1540, 0x1560, 0x15C2, 0x1582, 0x16C0, 0x0000, // 0x0150 (336) pixels + 0x0000, 0x0000, 0x0000, 0x2C83, 0x46C3, 0x37E1, 0x2FE0, 0x2FE0, 0x2780, 0x1F00, 0x1680, 0x0E00, 0x0D20, 0x0D20, 0x0D60, 0x0D80, // 0x0160 (352) pixels + 0x0DC0, 0x0E00, 0x0E40, 0x1660, 0x1CE1, 0x1DA1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1C41, 0x4723, 0x2FE1, 0x1FE0, // 0x0170 (368) pixels + 0x1F60, 0x1700, 0x0E80, 0x0E00, 0x0D20, 0x0D20, 0x0D60, 0x0D80, 0x0DC0, 0x0E00, 0x1620, 0x1520, 0x1540, 0x0E40, 0x0000, 0x0000, // 0x0180 (384) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1C61, 0x3EE3, 0x37E1, 0x1F60, 0x1700, 0x0E80, 0x0E00, 0x0D20, 0x0D20, 0x0D60, 0x0D80, // 0x0190 (400) pixels + 0x0DC0, 0x1600, 0x14E1, 0x14A1, 0x0E40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x24C1, 0x3EC3, // 0x01A0 (416) pixels + 0x2781, 0x1700, 0x0E80, 0x0E00, 0x0D20, 0x0D20, 0x0D60, 0x0D80, 0x15E0, 0x1481, 0x14E1, 0x0E20, 0x0000, 0x0000, 0x0000, 0x0000, // 0x01B0 (432) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1C81, 0x3EE3, 0x2701, 0x0E80, 0x0E00, 0x0D20, 0x0D20, 0x0D60, 0x15A0, // 0x01C0 (448) pixels + 0x14C1, 0x14C1, 0x0DC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x01D0 (464) pixels + 0x1481, 0x3643, 0x26A1, 0x0E00, 0x0D40, 0x0D20, 0x1580, 0x1481, 0x1441, 0x0DC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x01E0 (480) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1CC1, 0x3602, 0x1E20, 0x0D40, 0x0D20, 0x1421, 0x1481, // 0x01F0 (496) pixels + 0x0D80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0200 (512) pixels + 0x0000, 0x0000, 0x14A0, 0x35E3, 0x1D61, 0x1441, 0x1461, 0x0D20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0210 (528) pixels + 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 +}}; +} +} diff --git a/main/ota.h b/main/ota.h index 0eb9c8c..233fca5 100644 --- a/main/ota.h +++ b/main/ota.h @@ -1,49 +1,52 @@ #pragma once +// 3rdparty lib includes #ifdef FEATURE_OTA #include #endif +#include -#include "screens.h" -#include "globals.h" -#include "displays/updatedisplay.h" +// local includes namespace { #ifdef FEATURE_OTA +cpputils::DelayedConstruction asyncOta; +bool asyncOtaTaskStarted{}; + void initOta() { -// ArduinoOTA -// .onStart([]() { -// std::string type; -// switch (ArduinoOTA.getCommand()) -// { -// case U_FLASH: type = "sketch"; break; -// case U_SPIFFS: type = "filesystem"; break; -// default: type = "unknown"; -// } -// switchScreenImpl("Updating " + type); -// }) -// .onEnd([]() { -// ((UpdateDisplay*)currentDisplay.get())->m_finished = true; -// ((UpdateDisplay*)currentDisplay.get())->redraw(); -// }) -// .onProgress([](unsigned int progress, unsigned int total) { -// ((UpdateDisplay*)currentDisplay.get())->m_progress = progress; -// ((UpdateDisplay*)currentDisplay.get())->m_total = total; -// ((UpdateDisplay*)currentDisplay.get())->redraw(); -// }) -// .onError([](ota_error_t error) { -// ((UpdateDisplay*)currentDisplay.get())->m_error = error; -// ((UpdateDisplay*)currentDisplay.get())->m_errorValid = true; -// ((UpdateDisplay*)currentDisplay.get())->redraw(); -// }); - -// ArduinoOTA.begin(); } void handleOta() { -// ArduinoOTA.handle(); + if (asyncOta) + asyncOta->update(); +} + +tl::expected triggerOta(std::string_view url) +{ + ESP_LOGI(TAG, "%.*s", url.size(), url.data()); + + if (!asyncOta) + asyncOta.construct(); + + if (!asyncOtaTaskStarted) + { + if (const auto result = asyncOta->startTask(); !result) + { + ESP_LOGE(TAG, "starting OTA task failed: %.*s", result.error().size(), result.error().data()); + return tl::make_unexpected(fmt::format("starting OTA task failed: {}", result.error())); + } + + asyncOtaTaskStarted = true; + } + + if (const auto result = asyncOta->trigger(url, {}, {}, {}); !result) + return tl::make_unexpected(std::move(result).error()); + + wifi_stack::delete_scan_result(); + + return {}; } #endif } diff --git a/main/presets.h b/main/presets.h index edbf354..0b43f7d 100644 --- a/main/presets.h +++ b/main/presets.h @@ -231,6 +231,9 @@ StringSettings makeDefaultStringSettings() }, #ifdef FEATURE_CLOUD .cloudUrl = {}, +#endif +#ifdef FEATURE_OTA + .otaUrl = {}, #endif }; } diff --git a/main/stringsettings.h b/main/stringsettings.h index f8241e8..53c8cdf 100644 --- a/main/stringsettings.h +++ b/main/stringsettings.h @@ -18,6 +18,10 @@ struct StringSettings std::string cloudUrl; #endif +#ifdef FEATURE_OTA + std::string otaUrl; +#endif + template void executeForEveryCommonSetting(T &&callable); @@ -53,6 +57,10 @@ void StringSettings::executeForEveryCommonSetting(T &&callable) #ifdef FEATURE_CLOUD callable("cloudUrl", cloudUrl); #endif + +#ifdef FEATURE_OTA + callable("otaUrl", otaUrl); +#endif } template diff --git a/main/texts.h b/main/texts.h index 9f7a410..9868126 100644 --- a/main/texts.h +++ b/main/texts.h @@ -79,6 +79,7 @@ constexpr char TEXT_SETTINGS[] = "Settings"; constexpr char TEXT_LOCKVEHICLE[] = "Lock vehicle"; constexpr char TEXT_MOSFETS[] = "Mosfets"; constexpr char TEXT_DEMOS[] = "Demos"; +constexpr char TEXT_UPDATE[] = "Update"; constexpr char TEXT_POWEROFF[] = "Poweroff"; constexpr char TEXT_REBOOT[] = "Reboot"; constexpr char TEXT_DEBUG[] = "Debug";