OTA implemented

This commit is contained in:
2021-08-10 15:51:20 +02:00
parent b1f3a59828
commit ca337ce99e
9 changed files with 141 additions and 62 deletions

BIN
icons/update.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -119,6 +119,7 @@ set(headers
icons/scan.h
icons/settings.h
icons/unchecked.h
icons/update.h
icons/wifi.h
menudisplay.h
menuitem.h

View File

@ -15,6 +15,7 @@
#include "icons/settings.h"
#include "icons/lock.h"
#include "icons/demos.h"
#include "icons/update.h"
#include "icons/poweroff.h"
#include "icons/reboot.h"
@ -31,6 +32,7 @@ class SettingsMenu;
class Lockscreen;
class MosfetsMenu;
class DemosMenu;
class UpdateDisplay;
class PoweroffDisplay;
class DebugMenu;
} // namespace
@ -62,6 +64,7 @@ public:
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&icons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATE>, SwitchScreenAction<UpdateDisplay>, StaticMenuItemIcon<&icons::update>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&icons::poweroff>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&icons::reboot>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>();

View File

@ -4,6 +4,9 @@
#include <array>
#include <string>
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#ifdef FEATURE_OTA
#include <espasyncota.h>
@ -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<SwitchScreenAction<MainMenu>>
{
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<StatusDisplay>();
//if (m_finished)
// switchScreen<StatusDisplay>();
if (const auto result = triggerOta(stringSettings.otaUrl); !result)
ESP_LOGE("BOBBY", "triggerOta() failed with %.*s", result.error().size(), result.error().data());
}
#endif
}

46
main/icons/update.h Normal file
View File

@ -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
}};
}
}

View File

@ -1,49 +1,52 @@
#pragma once
// 3rdparty lib includes
#ifdef FEATURE_OTA
#include <espasyncota.h>
#endif
#include <delayedconstruction.h>
#include "screens.h"
#include "globals.h"
#include "displays/updatedisplay.h"
// local includes
namespace {
#ifdef FEATURE_OTA
cpputils::DelayedConstruction<EspAsyncOta> 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<UpdateDisplay>("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<void, std::string> 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
}

View File

@ -231,6 +231,9 @@ StringSettings makeDefaultStringSettings()
},
#ifdef FEATURE_CLOUD
.cloudUrl = {},
#endif
#ifdef FEATURE_OTA
.otaUrl = {},
#endif
};
}

View File

@ -18,6 +18,10 @@ struct StringSettings
std::string cloudUrl;
#endif
#ifdef FEATURE_OTA
std::string otaUrl;
#endif
template<typename T>
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<typename T>

View File

@ -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";