Merge pull request #117 from bobbycar-graz/cloud

Please merge Commanders Changes
This commit is contained in:
2021-11-01 19:12:19 +01:00
committed by GitHub
33 changed files with 1972 additions and 44 deletions

BIN
icons/bobbycar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -77,7 +77,6 @@ set(headers
actions/multiaction.h
actions/rebootaction.h
actions/savesettingsaction.h
actions/selectbuildserveraction.h
actions/switchprofileaction.h
actions/tempomatmodeapplycurrentpeedaction.h
actions/updateswapfrontbackaction.h
@@ -117,6 +116,7 @@ set(headers
displays/menus/invertmenu.h
displays/menus/larsmmodesettingsmenu.h
displays/menus/ledstripmenu.h
displays/menus/ledstripcolorsmenu.h
displays/menus/ledstripselectanimationmenu.h
displays/menus/ledstripselectblinkmenu.h
displays/menus/limitssettingsmenu.h
@@ -126,6 +126,8 @@ set(headers
displays/menus/mosfetsmenu.h
displays/menus/motorfeedbackdebugmenu.h
displays/menus/motorstatedebugmenu.h
displays/menus/otamenu.h
displays/menus/selectotabuildmenu.h
displays/menus/presetsmenu.h
displays/menus/profilesmenu.h
displays/menus/selectbatterytypemenu.h
@@ -151,6 +153,7 @@ set(headers
icons/battery.h
icons/bluetooth.h
icons/bms.h
icons/bobbycar.h
icons/buzzer.h
icons/close.h
icons/demos.h
@@ -328,6 +331,7 @@ set(sources
icons/battery.cpp
icons/bluetooth.cpp
icons/bms.cpp
icons/bobbycar.cpp
icons/buzzer.cpp
icons/close.cpp
icons/demos.cpp

View File

@@ -126,6 +126,7 @@ struct CloudSendRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t
#endif
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } };
struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } };
struct DefaultModeSquareBremsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareBrems; } };
@@ -144,6 +145,10 @@ struct DefaultModeGas2WertAccessor : public RefAccessorSaveSettings<int16_t> { i
struct DefaultModeBrems1WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.brems1_wert; } };
struct DefaultModeBrems2WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.brems2_wert; } };
struct DefaultModeEnableHybridAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.hybrid.enable; } };
struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.activationLimit; } };
struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } };
struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } };
struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } };

View File

@@ -1,4 +0,0 @@
#pragma once
#include "actioninterface.h"
#include "globals.h"

View File

@@ -249,12 +249,15 @@ void RemoteControlCallbacks::onWrite(NimBLECharacteristic* pCharacteristic)
if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation;
#endif
modes::remoteControlMode.setCommand(RemoteCommand{
.frontLeft = doc["fl"].as<int16_t>(),
.frontRight = doc["fr"].as<int16_t>(),
.backLeft = doc["bl"].as<int16_t>(),
.backRight = doc["br"].as<int16_t>()
});
if (!simplified)
{
modes::remoteControlMode.setCommand(RemoteCommand{
.frontLeft = doc["fl"].as<int16_t>(),
.frontRight = doc["fr"].as<int16_t>(),
.backLeft = doc["bl"].as<int16_t>(),
.backRight = doc["br"].as<int16_t>()
});
}
}
#ifdef FEATURE_WIRELESS_CONFIG

View File

@@ -0,0 +1,193 @@
#pragma once
#include <ArduinoJson.h>
#include <cpputils.h>
#include <cleanuphelper.h>
// 3rdparty lib includes
#include <asynchttprequest.h>
#include <delayedconstruction.h>
// local includes
#include "globals.h"
#include "esp_log.h"
#include "fmt/core.h"
// esp-idf
#include "esp_http_client.h"
namespace {
void buildMenuFromJson(std::string json);
void buildMenuRequestError(std::string error);
static std::string url_for_hashes = "";
static std::string url_for_latest = "";
static std::array<std::string, 10> availableVersions = {};
bool request_running = false;
uint16_t request_failed = false;
bool parsing_finished = false;
static bool redownload = true;
cpputils::DelayedConstruction<AsyncHttpRequest> request;
std::string get_ota_url_from_index(uint16_t index)
{
if (index < stringSettings.otaServers.size())
{
auto otaServer = stringSettings.otaServers[index];
if (!otaServer.url.empty())
{
return otaServer.url;
}
else
{
ESP_LOGE("BOBBY", "Cannot get OTA url: otaServer.url is empty");
return "";
}
}
else
{
ESP_LOGE("BOBBY", "Cannot get OTA url: Invalid Index");
return "";
}
}
uint16_t count_available_buildserver()
{
uint16_t count = 0;
for (const auto &otaServer : stringSettings.otaServers) {
if (!otaServer.url.empty()) count++;
}
return count;
}
std::string get_hash_url(std::string hash)
{
return fmt::format(url_for_hashes, hash);
}
std::string get_latest_url()
{
return url_for_latest;
}
std::string fix_url(std::string url)
{
std::string fixed_url = url;
if (fixed_url.find("http") == std::string::npos)
{
fixed_url = fmt::format("http://{}", fixed_url);
}
return fixed_url;
}
std::string get_descriptor_url(std::string base_url)
{
std::string url = fix_url(base_url);
return fmt::format("{}/otaDescriptor?username={}", url, OTA_USERNAME);
}
void parse_response_into_variables(std::string response)
{
StaticJsonDocument<512> doc;
if (const auto error = deserializeJson(doc, response))
{
ESP_LOGE("BOBBY", "Error parsing server-response => %s", response.c_str());
return;
}
JsonObject availableVersionsObject = doc["availableVersions"];
static auto index = 0;
for (JsonPair kv : availableVersionsObject)
{
auto hash = kv.key().c_str();
if (index > availableVersions.size())
{
break;
}
availableVersions.at(index) = hash;
index++;
}
index = 0;
url_for_latest = fix_url(fmt::format("{}{}", stringSettings.otaServerUrl, doc["latest"].as<std::string>()));
url_for_hashes = fix_url(fmt::format("{}{}", stringSettings.otaServerUrl, doc["url"].as<std::string>()));
parsing_finished = true;
redownload = false;
}
void setup_request()
{
if (!request.constructed())
request.construct("ota-descriptor-request", espcpputils::CoreAffinity::Core0);
}
void start_descriptor_request(std::string server_base_url)
{
if (!redownload)
{
parsing_finished = true;
return;
}
if (!request.constructed())
{
ESP_LOGW("BOBBY", "request is im oarsch");
return;
}
const auto url = get_descriptor_url(server_base_url);
ESP_LOGD("BOBBY", "requesting data...");
if (const auto result = request->start(url); !result)
{
ESP_LOGW("BOBBY", "request start failed");
return;
}
request_running = true;
request_failed = false;
url_for_latest.clear();
url_for_hashes.clear();
availableVersions = {};
parsing_finished = false;
}
void check_descriptor_request()
{
if (!request.constructed())
{
ESP_LOGW("BOBBY", "request is im oarsch");
request_running = false;
request_failed = true;
return;
}
if (!request->finished())
{
// ESP_LOGW("BOBBY", "Request has not finished yet.");
return;
}
const auto helper = cpputils::makeCleanupHelper([](){ request->clearFinished(); });
const std::string content = std::move(request->takeBuffer());
if (const auto result = request->result(); !result)
{
ESP_LOGW("BOBBY", "request failed: %.*s", result.error().size(), result.error().data());
std::string failed_str = result.error().data();
auto statuscode = failed_str.substr(failed_str.length() - 3);
request_running = false;
request_failed = std::stoi(statuscode);
return;
}
const auto result = request->result();
ESP_LOGW("BOBBY", "Request finished: %s", content.c_str());
parse_response_into_variables(content);
request_running = false;
request_failed = false;
}
bool get_request_running()
{
return request_running;
}
}

View File

@@ -8,6 +8,11 @@
#include "icons/back.h"
#include "esptexthelpers.h"
#include "texts.h"
#ifdef FEATURE_OTA
#include <espasyncota.h>
#include <esp_ota_ops.h>
#include "fmt/core.h"
#endif
// forward declares
namespace {
@@ -17,6 +22,18 @@ class SettingsMenu;
using namespace espgui;
namespace {
class currentVersionText : public virtual TextInterface { public: std::string text() const override {
#ifdef FEATURE_OTA
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
{
return fmt::format("Version: {}", app_desc->version);
}
#endif
return "Version: 1.0";
};
};
constexpr char TEXT_VERSION[] = "Version: 1.0";
class AboutMenu :
@@ -27,7 +44,7 @@ class AboutMenu :
public:
AboutMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VERSION>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, currentVersionText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapTotal8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();

View File

@@ -1,5 +1,7 @@
#pragma once
#include <TFT_eSPI.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
@@ -8,6 +10,7 @@
#include "menuitem.h"
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "actions/dummyaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "texts.h"
@@ -29,6 +32,13 @@ using DefaultModeModelModeChangeDisplay = makeComponent<
BackActionInterface<SwitchScreenAction<DefaultModeSettingsMenu>>,
SwitchScreenAction<DefaultModeSettingsMenu>
>;
using DefaultModeHybridModelModeChangeDisplay = makeComponent<
ChangeValueDisplay<UnifiedModelMode>,
StaticText<TEXT_HYBRIDMODE>,
DefaultModeHybridModelModeAccessor,
BackActionInterface<SwitchScreenAction<DefaultModeSettingsMenu>>,
SwitchScreenAction<DefaultModeSettingsMenu>
>;
using DefaultModeSmoothingChangeDisplay = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SMOOTHINGVAL>,
@@ -92,6 +102,20 @@ using DefaultModeBrems2WertChangeDisplay = makeComponent<
BackActionInterface<SwitchScreenAction<DefaultModeSettingsMenu>>,
SwitchScreenAction<DefaultModeSettingsMenu>
>;
using DefaultModeHybridActivationLimitChangeDisplay = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_HYBRIDACTIVATIONLIMIT>,
DefaultModeHybridActivationLimitAccessor,
BackActionInterface<SwitchScreenAction<DefaultModeSettingsMenu>>,
SwitchScreenAction<DefaultModeSettingsMenu>
>;
using DefaultModeHybridDeactivationLimitChangeDisplay = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_HYBRIDDEACTIVATIONLIMIT>,
DefaultModeHybridDeactivationLimitAccessor,
BackActionInterface<SwitchScreenAction<DefaultModeSettingsMenu>>,
SwitchScreenAction<DefaultModeSettingsMenu>
>;
class DefaultModeSettingsMenu :
public MenuDisplay,
@@ -101,13 +125,17 @@ class DefaultModeSettingsMenu :
public:
DefaultModeSettingsMenu()
{
auto diff = std::abs(settings.hybrid.activationLimit - settings.hybrid.deactivationLimit);
if (diff < 20) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITS_TO_NEAR>, StaticFont<2>, StaticColor<TFT_RED>, DummyAction>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODELMODE>, SwitchScreenAction<DefaultModeModelModeChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_HYBRIDMODE>, SwitchScreenAction<DefaultModeHybridModelModeChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SQUAREGAS>, ToggleBoolAction, CheckboxIcon, DefaultModeSquareGasAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SQUAREBREMS>, ToggleBoolAction, CheckboxIcon, DefaultModeSquareBremsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLESMOOTHINGUP>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableSmoothingUpAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLESMOOTHINGDOWN>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableSmoothingDownAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLEFWSMOOTHINGUP>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableFieldWeakSmoothingUpAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLEFWSMOOTHINGDOWN>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableFieldWeakSmoothingDownAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_HYBRIDENABLE>, ToggleBoolAction, CheckboxIcon, DefaultModeEnableHybridAccessor>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_FWSMOOTHING_LIMIT, DefaultModeEnableFieldWeakSmoothingLowerLimitAccessor>, SwitchScreenAction<DefaultModeFwSmoothingLowerLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SMOOTHINGVAL, DefaultModeSmoothingAccessor>, SwitchScreenAction<DefaultModeSmoothingChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_FRONTPERCENTAGE, DefaultModeFrontPercentageAccessor>, SwitchScreenAction<DefaultModeFrontPercentageChangeDisplay>>>();
@@ -117,6 +145,8 @@ public:
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SUBBRAKEVAL, DefaultModeBrems2WertAccessor>, SwitchScreenAction<DefaultModeBrems2WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ADDGASVAL, DefaultModeGas1WertAccessor>, SwitchScreenAction<DefaultModeGas1WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ADDBRAKEVAL, DefaultModeBrems1WertAccessor>, SwitchScreenAction<DefaultModeBrems1WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_HYBRIDACTIVATIONLIMIT, DefaultModeHybridActivationLimitAccessor>, SwitchScreenAction<DefaultModeHybridActivationLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_HYBRIDDEACTIVATIONLIMIT, DefaultModeHybridDeactivationLimitAccessor>, SwitchScreenAction<DefaultModeHybridDeactivationLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<ModesSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};

View File

@@ -0,0 +1,259 @@
#pragma once
#include <TFT_eSPI.h>
#include <FastLED.h>
#include <cpputils.h>
// Local includes
#include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "ledstrip.h"
#include "icons/back.h"
#include "icons/bobbycar.h"
#include "texts.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actioninterface.h"
#include "globals.h"
#include "esp_log.h"
using namespace espgui;
namespace {
class LedstripMenu;
}
namespace {
static int8_t selected_side = 7;
static int8_t selected_color;
bool state_select_color{false};
bool last_state = {false};
const std::array<CRGB, 8> Colors = {
CRGB{0,0,0},
CRGB{255,255,255},
CRGB{255,0,0},
CRGB{255,255,0},
CRGB{0,255,0},
CRGB{0,255,255},
CRGB{0,0,255},
CRGB{255,0,255}
};
const std::array<uint16_t, 8> tft_colors = {
TFT_BLACK,
TFT_WHITE,
TFT_RED,
TFT_YELLOW,
TFT_GREEN,
TFT_CYAN,
TFT_BLUE,
TFT_MAGENTA
};
class LedstripColorsMenuBackAction : ActionInterface
{
public:
void triggered() {
if(!state_select_color)
{
switchScreen<LedstripMenu>();
}
else
{
state_select_color = false;
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
}
}
};
class LedstripColorsMenu :
public MenuDisplay,
public StaticText<TEXT_LEDSTRIPCOLORMENU>,
public BackActionInterface<LedstripColorsMenuBackAction>
{
using Base = MenuDisplay;
public:
void redraw() override;
void rotate(int offset) override;
void confirm() override;
void drawColors();
void drawSide(Bobbycar_Side side, unsigned int color);
void clearSides();
LedstripColorsMenu() {}
private:
bool already_drew_circle{false};
};
void LedstripColorsMenu::redraw()
{
Base::redraw();
tft.setSwapBytes(true);
tft.pushImage(70, 60, bobbyicons::bobbycar.WIDTH, bobbyicons::bobbycar.HEIGHT, bobbyicons::bobbycar.buffer);
tft.setSwapBytes(false);
auto y_pos = ((tft.width() - 40) / 8 + 4) + 240;
if (last_state != state_select_color)
{
tft.fillRect(0,y_pos - 1, tft.width(), 20, TFT_BLACK);
last_state = state_select_color;
}
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
if(state_select_color)
{
tft.drawString("Please select a color!", 50, y_pos);
}
else
{
tft.drawString("Please select a side!", 50, y_pos);
}
if(!already_drew_circle)
{
this->drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
already_drew_circle = true;
}
}
void LedstripColorsMenu::rotate(int offset)
{
if (offset < 0)
{
if (state_select_color)
{
selected_color++;
if (selected_color > 7)
{
selected_color = 0;
}
}
else
{
selected_side++;
if (selected_side > 7)
{
selected_side = 0;
}
}
}
else if (offset > 0)
{
if (state_select_color)
{
selected_color--;
if (selected_color < 0)
{
selected_color = 7;
}
}
else
{
selected_side--;
if (selected_side < 0)
{
selected_side = 7;
}
}
}
if (state_select_color)
{
this->drawColors();
}
else
{
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
this->clearSides();
this->drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
}
}
void LedstripColorsMenu::confirm()
{
if(!state_select_color)
{
state_select_color = true;
this->drawColors();
}
else
{
ledstrip_custom_colors[selected_side] = Colors[selected_color];
// Uncomment to close select color menu on color select
/*
state_select_color = false;
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
*/
}
}
void LedstripColorsMenu::drawColors()
{
uint16_t width = (tft.width() - 40);
auto cube_width = width / 8;
tft.fillRect(0, 228, tft.width(), cube_width + 4, TFT_BLACK);
tft.fillRect(21, 231, width - 1, cube_width - 1, TFT_WHITE);
tft.fillRect(20 + (selected_color * cube_width - 1), 228, cube_width + 4, cube_width + 4, TFT_YELLOW);
for (int index = 0; index < 8; index++)
{
auto offset = index * (cube_width);
tft.fillRect(22 + offset, 232, cube_width - 4, cube_width - 4, tft_colors[index]);
}
}
void LedstripColorsMenu::clearSides()
{
for(int index = 0; index < 8; index++)
{
this->drawSide(static_cast<Bobbycar_Side>(index), TFT_BLACK);
}
}
void LedstripColorsMenu::drawSide(Bobbycar_Side side, unsigned int color)
{
const auto middle = tft.width() / 2;
const auto width = bobbyicons::bobbycar.WIDTH;
const auto height = bobbyicons::bobbycar.HEIGHT;
const auto left = middle - (width / 2);
const auto right = middle + (width / 2);
const auto above = 50;
const auto bellow = above + 10 + bobbyicons::bobbycar.HEIGHT;
switch (side) {
case Bobbycar_Side::FRONT:
tft.fillRect(left, above, width, 5, color);
break;
case Bobbycar_Side::FRONT_LEFT:
tft.fillRect(left - 10, above + 10, 5, height / 2, color);
tft.fillRect(left, above, width / 2, 5, color);
break;
case Bobbycar_Side::LEFT:
tft.fillRect(left - 10, above + 10, 5, height, color);
break;
case Bobbycar_Side::BACK_LEFT:
tft.fillRect(left - 10, above + 10 + (height / 2), 5, height / 2, color);
tft.fillRect(left, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::BACK:
tft.fillRect(left, bellow + 5, width, 5, color);
break;
case Bobbycar_Side::BACK_RIGHT:
tft.fillRect(right + 5, above + 10 + (height / 2), 5, height / 2, color);
tft.fillRect(middle, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::RIGHT:
tft.fillRect(right + 5, above + 10, 5, height, color);
break;
case Bobbycar_Side::FRONT_RIGHT:
tft.fillRect(right + 5, above + 10, 5, height / 2, color);
tft.fillRect(middle, above, width / 2, 5, color);
break;
}
// tft.fillCircle(tft.width() / 2, 140, 100, TFT_BLACK);
}
} // Namespace

View File

@@ -1,4 +1,7 @@
#pragma once
#include <FastLED.h>
// local includes
#include "menudisplay.h"
#include "menuitem.h"
@@ -15,10 +18,12 @@
#include "ledstrip.h"
#endif
#include "changevaluedisplay.h"
#include "actioninterface.h"
// forward declares
namespace {
class MainWindow;
class LedstripColorsMenu;
} // namespace
using namespace espgui;
@@ -100,6 +105,17 @@ using ledstripBrightnessChangeScreen = makeComponent<
SwitchScreenAction<LedstripMenu>
>;
class AllCustomLedsOffAction : public virtual ActionInterface
{
public:
void triggered() {
for(int index = 0; index < 8; index++)
{
ledstrip_custom_colors[index] = CRGB{0,0,0};
}
}
};
class LedstripMenu :
public MenuDisplay,
public StaticText<TEXT_LEDSTRIP>,
@@ -108,6 +124,7 @@ class LedstripMenu :
public:
LedstripMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIPCOLORMENU>, SwitchScreenAction<LedstripColorsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDANIMATION>, ToggleBoolAction, CheckboxIcon, EnableLedAnimationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BRAKELIGHTS>, ToggleBoolAction, CheckboxIcon, EnableBrakeLightsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKBEEP>, ToggleBoolAction, CheckboxIcon, EnableBeepWhenBlinkAccessor>>();
@@ -115,6 +132,7 @@ public:
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_STVO>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOAccessor>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STVO_ENABLEFRONTLIGHT>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOFrontlight>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_ALLCUSTOMOFF>, AllCustomLedsOffAction>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTOFFSET, LedsStVOFrontOffsetAccessor>, SwitchScreenAction<StVOOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTLENGTH, LedsStVOFrontLengthAccessor>, SwitchScreenAction<StVOLengthChangeScreen>>>(); }

View File

@@ -22,6 +22,8 @@ class currentSelectedAnimationText : public virtual TextInterface { public: std:
return TEXT_ANIMATION_BETTERRAINBOW;
case LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION:
return TEXT_ANIMATION_SPEEDSYNCANIMATION;
case LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR:
return TEXT_ANIMATION_CUSTOMCOLOR;
default:
return "Animation Unkown";
}
@@ -48,6 +50,7 @@ namespace {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_DEFAULTRAINBOW>, LedStripSetAnimationAction<LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BETTERRAINBOW>, LedStripSetAnimationAction<LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_SPEEDSYNCANIMATION>, LedStripSetAnimationAction<LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_CUSTOMCOLOR>, LedStripSetAnimationAction<LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};

View File

@@ -46,7 +46,7 @@ class Lockscreen;
class MosfetsMenu;
class DemosMenu;
class GarageDisplay;
class UpdateDisplay;
class OtaMenu;
class PoweroffDisplay;
class DebugMenu;
class BatteryMenu;
@@ -97,7 +97,7 @@ public:
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }
#endif
#ifdef FEATURE_OTA
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATE>, SwitchScreenAction<UpdateDisplay>, StaticMenuItemIcon<&bobbyicons::update>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATE>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&bobbyicons::update>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&bobbyicons::poweroff>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();

View File

@@ -0,0 +1,49 @@
#pragma once
// local includes
#include "menudisplay.h"
#include "actioninterface.h"
#include "utils.h"
#include "actions/dummyaction.h"
#include "icons/back.h"
#include "icons/update.h"
#include "icons/presets.h"
#include "texts.h"
#include "buildserver.h"
// forward declares
namespace {
class MainMenu;
class UpdateDisplay;
class SelectBuildMenu;
class SelectBuildServerMenu;
} // namespace
using namespace espgui;
namespace {
class RedownloadJsonAction : public virtual ActionInterface {
public:
void triggered() override {
redownload = true;
}
};
class OtaMenu :
public MenuDisplay,
public StaticText<TEXT_UPDATE>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
{
public:
OtaMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILD>, SwitchScreenAction<SelectBuildMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATENOW>, SwitchScreenAction<UpdateDisplay>, StaticMenuItemIcon<&bobbyicons::update>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REDOWNLOAD>, RedownloadJsonAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // namespace

View File

@@ -1,13 +1,20 @@
#pragma once
// 3rdparty lib includes
#include <TFT_eSPI.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "actions/dummyaction.h"
#include "actions/selectbuildserveraction.h"
#include "icons/back.h"
#include "texts.h"
#include "globals.h"
#include "buildserver.h"
// Debugging
#include "esp_log.h"
#include "fmt/core.h"
// forward declares
@@ -19,6 +26,36 @@ using namespace espgui;
namespace {
class BuildserverMenuItem : public MenuItem
{
public:
std::string text() const override { return m_buildserver_name; }
void setBuildserverName(std::string &&buildserver_name) { m_buildserver_name = std::move(buildserver_name); }
void setBuildserverName(const std::string &buildserver_name) { m_buildserver_name = buildserver_name; }
void setBuildserverUrl(std::string &&buildserver_url) { m_buildserver_url = std::move(buildserver_url); }
void setBuildserverUrl(const std::string &buildserver_url) { m_buildserver_url = buildserver_url; }
void triggered() override
{
stringSettings.otaServerUrl = m_buildserver_url;
if (m_buildserver_url.substr(m_buildserver_url.length() - 4) == ".bin")
{
stringSettings.otaUrl = m_buildserver_url;
}
saveSettings();
redownload = true;
url_for_latest.clear();
url_for_hashes.clear();
availableVersions = {};
}
private:
std::string m_buildserver_url;
std::string m_buildserver_name;
};
class SelectBuildServerMenu :
public MenuDisplay,
public StaticText<TEXT_SELECTBUILDSERVERMENU>,
@@ -27,24 +64,21 @@ class SelectBuildServerMenu :
public:
SelectBuildServerMenu() {
auto numDisplayedServers = 0;
for (auto index = 0; index < stringSettings.otaServers.size(); index++)
for (const auto &otaServer : stringSettings.otaServers)
{
auto otaServer = stringSettings.otaServers[index];
std::string url = otaServer.url;
std::string name = (otaServer.name.empty()) ? url : otaServer.name;
if (!name.empty()) {
auto menuitem = constructMenuItem<makeComponent<MenuItem, ChangeableText, DummyAction>>();
menuitem.setTitle(name);
numDisplayedServers++;
auto &menuitem = constructMenuItem<BuildserverMenuItem>();
menuitem.setBuildserverName(name);
menuitem.setBuildserverUrl(url);
}
}
if (!numDisplayedServers)
if (menuItemCount() < 1)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();

View File

@@ -0,0 +1,154 @@
#pragma once
#include <espwifistack.h>
#include <TFT_eSPI.h>
#include "esp_log.h"
#include "fmt/core.h"
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "actions/dummyaction.h"
#include "icons/back.h"
#include "icons/update.h"
#include "texts.h"
#include "buildserver.h"
#include "globals.h"
#define MESSAGE(text) constructMenuItem<makeComponent<MenuItem, StaticText<text>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>()
// forward declares
namespace {
class OtaMenu;
} // namespace
using namespace espgui;
namespace {
// ToDo: if (request_failed) => MESSAGE("An error occurred")
template<int item_color>
class VersionMenuItem : public MenuItem
{
public:
std::string text() const override { return m_hash; }
void setHash(std::string &&hash) { m_hash = std::move(hash); }
void setHash(const std::string &hash) { m_hash = hash; }
void setUrl(std::string &&url) { m_url = std::move(url); }
void setUrl(const std::string &url) { m_url = url; }
void triggered() override
{
stringSettings.otaUrl = m_url;
saveSettings();
}
int color() const override
{
return item_color;
}
private:
std::string m_url;
std::string m_hash;
};
class SelectBuildMenu :
public MenuDisplay,
public StaticText<TEXT_SELECTBUILD>,
public BackActionInterface<SwitchScreenAction<OtaMenu>>
{
using Base = MenuDisplay;
public:
void update() override;
void buildMenuFromJson();
void buildMenuRequestError(std::string error);
SelectBuildMenu()
{
if (count_available_buildserver() < 1)
{
MESSAGE(TEXT_OTA_NOBUILDSERVERAVAILABLE);
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
else if (stringSettings.otaServerUrl.empty())
{
MESSAGE(TEXT_OTA_NOBUILDSERVERSELECTED);
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
else
{
const auto staStatus = wifi_stack::get_sta_status();
if (staStatus != wifi_stack::WiFiStaStatus::CONNECTED)
{
MESSAGE(TEXT_OTA_NOCONNECTION);
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
else
{
std::string serverUrl = stringSettings.otaServerUrl;
if (serverUrl.substr(serverUrl.length() - 4) == ".bin")
{
auto &menuitem = constructMenuItem<VersionMenuItem<TFT_WHITE>>();
std::size_t last_slash_index = serverUrl.find_last_of("/");
auto filename = serverUrl.substr(last_slash_index+1);
auto hash = filename.substr(0, filename.length() - 4);
menuitem.setHash(hash);
menuitem.setUrl(fix_url(serverUrl));
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
else
{
setup_request();
start_descriptor_request(serverUrl);
}
}
}
}
};
void SelectBuildMenu::update()
{
if(get_request_running())
{
check_descriptor_request();
if (request_failed)
{
this->buildMenuRequestError(fmt::format("Error: {}", request_failed));
request_failed = false;
}
}
if (parsing_finished)
{
parsing_finished = false;
if (!availableVersions.empty())
{
this->buildMenuFromJson();
}
}
Base::update();
}
void SelectBuildMenu::buildMenuFromJson()
{
auto &latest = constructMenuItem<VersionMenuItem<TFT_GREEN>>();
latest.setHash("latest");
latest.setUrl(url_for_latest);
for (const std::string &hash : availableVersions)
{
auto &menuitem = constructMenuItem<VersionMenuItem<TFT_WHITE>>();
menuitem.setHash(hash);
menuitem.setUrl(fmt::format(url_for_hashes, hash));
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void SelectBuildMenu::buildMenuRequestError(std::string error)
{
auto &item = constructMenuItem<makeComponent<MenuItem, ChangeableText, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
item.setTitle(error);
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
} // namespace

View File

@@ -23,12 +23,12 @@
#include "ota.h"
namespace {
class MainMenu;
class OtaMenu;
}
namespace {
#ifdef FEATURE_OTA
class UpdateDisplay : public Display, public BackActionInterface<SwitchScreenAction<MainMenu>>
class UpdateDisplay : public Display, public BackActionInterface<SwitchScreenAction<OtaMenu>>
{
public:
void start() override;

View File

@@ -55,6 +55,8 @@ Settings settings;
StringSettings stringSettings;
SettingsPersister settingsPersister;
std::array<CRGB, 8> ledstrip_custom_colors = {};
class Controllers : public std::array<Controller, 2>
{
public:

1006
main/icons/bobbycar.cpp Normal file

File diff suppressed because it is too large Load Diff

7
main/icons/bobbycar.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include "icon.h"
namespace bobbyicons {
extern const espgui::Icon<100, 160> bobbycar;
} // namespace bobbyicons

View File

@@ -10,6 +10,18 @@
#include "ledstripdefines.h"
namespace {
enum Bobbycar_Side {
FRONT_RIGHT,
RIGHT,
BACK_RIGHT,
BACK,
BACK_LEFT,
LEFT,
FRONT_LEFT,
FRONT
};
std::vector<CRGB> leds;
uint8_t gHue = 0;
@@ -20,6 +32,7 @@ void showDefaultLedstrip();
void showAnimation();
void showBetterRainbow();
void showSpeedSyncAnimation();
void showCustomColor();
void initLedStrip()
{
@@ -154,6 +167,7 @@ void showAnimation() {
if (animation_type == LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW) showDefaultLedstrip();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW) showBetterRainbow();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION) showSpeedSyncAnimation();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR) showCustomColor();
else showDefaultLedstrip();
}
else
@@ -221,5 +235,39 @@ void showDefaultLedstrip()
dothue += 32;
}
}
void showCustomColor()
{
const auto eighth_length = leds.size() / 8;
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
std::fill(std::begin(leds), std::end(leds), ledstrip_custom_colors[int(Bobbycar_Side::FRONT)]); // Front
std::fill(center - (eighth_length / 2), center + (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK)]); // Back
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
#else
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
#else
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
#else
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
#endif
}
} // namespace
#endif

View File

@@ -17,3 +17,4 @@
#define LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW 0
#define LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW 1
#define LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION 2
#define LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR 3

View File

@@ -61,6 +61,9 @@ using namespace std::chrono_literals;
#include "displays/menus/mainmenu.h"
#include "displays/menus/tempomatmodesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h"
#ifdef FEATURE_LEDSTRIP
#include "displays/menus/ledstripcolorsmenu.h"
#endif
#ifdef FEATURE_MOSFETS
#include "displays/menus/mosfetsmenu.h"
#endif
@@ -106,6 +109,8 @@ using namespace std::chrono_literals;
#include "displays/statusdisplay.h"
#ifdef FEATURE_OTA
#include "displays/updatedisplay.h"
#include "displays/menus/otamenu.h"
#include "displays/menus/selectotabuildmenu.h"
#endif
#include "screens.h"
#include "dpad.h"

View File

@@ -23,6 +23,7 @@ public:
bool waitForGasLoslass{false};
bool waitForBremsLoslass{false};
bool hybridModeActivated{false};
private:
espchrono::millis_clock::time_point lastTime{espchrono::millis_clock::now()};
@@ -128,7 +129,36 @@ void DefaultMode::update()
lastPwm = pwm;
lastTime = now;
const auto pair = split(settings.defaultMode.modelMode);
auto pair = split(settings.defaultMode.modelMode);
if (settings.hybrid.enable)
{
auto activationLimit = settings.hybrid.activationLimit;
auto deactivationLimit = settings.hybrid.deactivationLimit;
auto diff = std::abs(activationLimit - deactivationLimit);
if (diff < 20)
{
int half = (diff / 2) + 0.5;
deactivationLimit -= half;
activationLimit += half;
}
if (!hybridModeActivated && (pwm > activationLimit))
{
hybridModeActivated = true;
}
else if (hybridModeActivated && (pwm < deactivationLimit))
{
hybridModeActivated = false;
}
if (hybridModeActivated)
{
pair = split(settings.hybrid.hybridMode);
}
}
for (bobbycar::protocol::serial::MotorState &motor : motorsInController(controllers.front))
{
motor.ctrlTyp = pair.first;

View File

@@ -265,6 +265,13 @@ constexpr Settings::Battery defaultBattery {
.applyCalibration = true
};
constexpr Settings::Hybrid defaultHybrid {
.hybridMode = UnifiedModelMode::FocTorque,
.enable = false,
.activationLimit = 1000,
.deactivationLimit = 950,
};
constexpr Settings defaultSettings {
#ifdef FEATURE_BMS
.autoConnectBms = false,
@@ -291,6 +298,7 @@ constexpr Settings defaultSettings {
.ledstrip = defaultLedstrip,
#endif
.battery = defaultBattery,
.hybrid = defaultHybrid,
.lockscreen = defaultLockscreen
};
@@ -327,18 +335,19 @@ StringSettings makeDefaultStringSettings()
.timeServer = "europe.pool.ntp.org",
#endif
#ifdef FEATURE_OTA
.otaServers = std::array<ConfiguredOtaServer, 2> {
.otaServers = std::array<ConfiguredOtaServer, 5> {
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },/*
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },
ConfiguredOtaServer { .name = {}, .url = {} },*/
},
.otaServerUrl = {},
#endif
};
}

View File

@@ -89,6 +89,26 @@ void handleSerial()
InputDispatcher::backButton(true);
InputDispatcher::backButton(false);
break;
case 'z':
case 'Z':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#else
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#endif
break;
case 'u':
case 'U':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#else
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#endif
break;
}
}
}

View File

@@ -3,6 +3,7 @@
// system includes
#include <cstdint>
#include <array>
#include <FastLED.h>
// esp-idf includes
#include <esp_wifi_types.h>
@@ -184,6 +185,13 @@ struct Settings
bool applyCalibration;
} battery;
struct Hybrid {
UnifiedModelMode hybridMode;
bool enable;
int16_t activationLimit;
int16_t deactivationLimit;
} hybrid;
struct LockscreenSettings {
bool allowPresetSwitch;
std::array<int8_t, 4> pin;
@@ -301,6 +309,11 @@ void Settings::executeForEveryCommonSetting(T &&callable)
callable("batB50VCal", battery.back50VoltCalibration);
callable("applyBatCal", battery.applyCalibration);
callable("hybridMode", hybrid.hybridMode);
callable("hybridEn", hybrid.enable);
callable("hybridAcL", hybrid.activationLimit);
callable("hybridDeacL", hybrid.deactivationLimit);
callable("lockAlwPresetSw", lockscreen.allowPresetSwitch);
callable("lockscreenPin", lockscreen.pin);
}

View File

@@ -43,7 +43,8 @@ struct StringSettings
std::string url;
};
std::array<ConfiguredOtaServer, 2> otaServers;
std::array<ConfiguredOtaServer, 5> otaServers;
std::string otaServerUrl;
#endif
};
@@ -89,13 +90,13 @@ void StringSettings::executeForEveryCommonSetting(T &&callable)
callable("otaName0", otaServers[0].name);
callable("otaUrl0", otaServers[0].url);
callable("otaName1", otaServers[1].name);
callable("otaUrl1", otaServers[1].url);/*
callable("otaUrl1", otaServers[1].url);
callable("otaName2", otaServers[2].name);
callable("otaUrl2", otaServers[2].url);
callable("otaName3", otaServers[3].name);
callable("otaUrl3", otaServers[3].url);
callable("otaName4", otaServers[4].name);
callable("otaUrl4", otaServers[4].url);
callable("otaUrl4", otaServers[4].url);/*
callable("otaName5", otaServers[5].name);
callable("otaUrl5", otaServers[5].url);
callable("otaName6", otaServers[6].name);
@@ -106,6 +107,8 @@ void StringSettings::executeForEveryCommonSetting(T &&callable)
callable("otaUrl8", otaServers[8].url);
callable("otaName9", otaServers[9].name);
callable("otaUrl9", otaServers[9].url);*/
callable("otaserver", otaServerUrl);
#endif
}

View File

@@ -195,6 +195,7 @@ constexpr char TEXT_DYNAMICMENU[] = "Dynamic menu";
//DefaultModeSettingsMenu
//constexpr char TEXT_DEFAULTMODESETTINGS[] = "Default mode settings";
constexpr char TEXT_MODELMODE[] = "Model mode";
constexpr char TEXT_HYBRIDMODE[] = "Hybrid mode";
constexpr char TEXT_SQUAREGAS[] = "Square gas";
constexpr char TEXT_SQUAREBREMS[] = "Square brems";
constexpr char TEXT_ENABLESMOOTHINGUP[] = "Enable up smoothing";
@@ -210,6 +211,10 @@ constexpr char TEXT_SUBGASVAL[] = "Add Gas";
constexpr char TEXT_SUBBRAKEVAL[] = "Add Brake";
constexpr char TEXT_ADDGASVAL[] = "Sub Gas";
constexpr char TEXT_ADDBRAKEVAL[] = "Sub Brake";
constexpr char TEXT_HYBRIDENABLE[] = "Enable Hybrid mode";
constexpr char TEXT_HYBRIDACTIVATIONLIMIT[] = "Hybrid activation-limit";
constexpr char TEXT_HYBRIDDEACTIVATIONLIMIT[] = "Hybrid deactivation-limit";
constexpr char TEXT_LIMITS_TO_NEAR[] = "Hybrid limits too near (>20)";
//constexpr char TEXT_BACK[] = "Back";
//DynamicDebugMenu
@@ -284,6 +289,7 @@ constexpr char TEXT_STVO_FRONTLENGTH[] = "StVO Front Length";
constexpr char TEXT_STVO_ENABLEFRONTLIGHT[] = "StVO Front Enable";
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_BACK[] = "Back";
//LedstripSelectAnimationMenu
@@ -291,6 +297,7 @@ constexpr char TEXT_SELECTANIMATION[] = "Select Animation";
constexpr char TEXT_ANIMATION_DEFAULTRAINBOW[] = "Default Rainbow";
constexpr char TEXT_ANIMATION_BETTERRAINBOW[] = "Better Rainbow";
constexpr char TEXT_ANIMATION_SPEEDSYNCANIMATION[] = "Speed Sync";
constexpr char TEXT_ANIMATION_CUSTOMCOLOR[] = "Custom Color";
//LedstripSelectBlinkMenu
constexpr char TEXT_ANIMATION_BLINKNONE[] = "Blink Off";
@@ -475,6 +482,18 @@ constexpr char TEXT_CRASH_DIVZERO[] = "42 / 0";
constexpr char TEXT_SELECTBUILDSERVERMENU[] = "Select Buildserver";
constexpr char TEXT_NOBUILDSERVERCONFIGURED[] = "Not configured";
//Otamenu
constexpr char TEXT_UPDATENOW[] = "Update now";
constexpr char TEXT_SELECTBUILD[] = "Select build";
constexpr char TEXT_OTA_NOBUILDSERVERAVAILABLE[] = "E:No server saved.";
constexpr char TEXT_OTA_NOBUILDSERVERSELECTED[] = "E:No server selected.";
constexpr char TEXT_OTA_NOCONNECTION[] = "E:No internet.";
constexpr char TEXT_OTA_WAITFORRESPONSE[] = "Wait for response...";
constexpr char TEXT_REDOWNLOAD[] = "Reload list";
//LedstripColorMenu
constexpr char TEXT_LEDSTRIPCOLORMENU[] = "Customize Ledstrip";
#ifdef FEATURE_CAN
constexpr char TEXT_POWERSUPPLY[] = "Powersupply";
#endif

View File

@@ -522,7 +522,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120
CONFIG_ESP_MAIN_TASK_CORE_AFFINITY=1
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
@@ -1424,7 +1424,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=5120
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set

View File

@@ -522,7 +522,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120
CONFIG_ESP_MAIN_TASK_CORE_AFFINITY=1
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
@@ -1419,7 +1419,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=5120
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set

View File

@@ -522,7 +522,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120
CONFIG_ESP_MAIN_TASK_CORE_AFFINITY=1
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
@@ -1417,7 +1417,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=5120
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set

View File

@@ -522,7 +522,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120
CONFIG_ESP_MAIN_TASK_CORE_AFFINITY=1
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
@@ -1417,7 +1417,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=5120
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set

View File

@@ -522,7 +522,7 @@ CONFIG_ADC_CAL_LUT_ENABLE=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120
CONFIG_ESP_MAIN_TASK_CORE_AFFINITY=1
CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y
@@ -1424,7 +1424,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_MAIN_TASK_STACK_SIZE=5120
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set