OTA implemented
This commit is contained in:
BIN
icons/update.png
Normal file
BIN
icons/update.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -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
|
||||
|
@ -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>>>();
|
||||
|
@ -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
46
main/icons/update.h
Normal 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
|
||||
}};
|
||||
}
|
||||
}
|
65
main/ota.h
65
main/ota.h
@ -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
|
||||
}
|
||||
|
@ -231,6 +231,9 @@ StringSettings makeDefaultStringSettings()
|
||||
},
|
||||
#ifdef FEATURE_CLOUD
|
||||
.cloudUrl = {},
|
||||
#endif
|
||||
#ifdef FEATURE_OTA
|
||||
.otaUrl = {},
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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";
|
||||
|
Reference in New Issue
Block a user