This commit is contained in:
2021-11-02 01:43:58 +01:00
parent 8c2ce911ba
commit 1de44c630b
57 changed files with 1789 additions and 1816 deletions

View File

@ -317,6 +317,7 @@ set(sources
displays/menus/presetsmenu.cpp displays/menus/presetsmenu.cpp
displays/menus/profilesmenu.cpp displays/menus/profilesmenu.cpp
displays/menus/selectbatterytypemenu.cpp displays/menus/selectbatterytypemenu.cpp
displays/menus/selectbuildservermenu.cpp
displays/menus/selectmodemenu.cpp displays/menus/selectmodemenu.cpp
displays/menus/settingsmenu.cpp displays/menus/settingsmenu.cpp
displays/menus/stationwifisettingsmenu.cpp displays/menus/stationwifisettingsmenu.cpp

View File

@ -0,0 +1,15 @@
#include "bluetoothbeginaction.h"
// local includes
#include "globals.h"
#ifdef FEATURE_BLUETOOTH
void BluetoothBeginAction::triggered()
{
if (!bluetoothSerial.begin(deviceName))
{
//Serial.println("Could not begin bluetooth");
// TODO: better error handling
}
}
#endif

View File

@ -1,23 +1,12 @@
#pragma once #pragma once
#include "actioninterface.h" // 3rdparty lib includes
#include "globals.h" #include <actioninterface.h>
using namespace espgui;
namespace {
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
class BluetoothBeginAction : public virtual ActionInterface class BluetoothBeginAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override void triggered() override;
{
if (!bluetoothSerial.begin(deviceName))
{
//Serial.println("Could not begin bluetooth");
// TODO: better error handling
}
}
}; };
#endif #endif
}

View File

@ -0,0 +1 @@
#include "battery.h"

View File

@ -3,10 +3,10 @@
// 3rdparty lib includes // 3rdparty lib includes
#include <fmt/core.h> #include <fmt/core.h>
#include <cpptypesafeenum.h> #include <cpptypesafeenum.h>
#include <cpputils.h>
// local includes // local includes
#include "globals.h" #include "globals.h"
#include "cpputils.h"
#define BatteryCellTypeValues(x) \ #define BatteryCellTypeValues(x) \
x(_22P) \ x(_22P) \
@ -16,91 +16,94 @@
DECLARE_TYPESAFE_ENUM(BatteryCellType, : uint8_t, BatteryCellTypeValues) DECLARE_TYPESAFE_ENUM(BatteryCellType, : uint8_t, BatteryCellTypeValues)
namespace { namespace {
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) { if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; return 100 * (expected_ah - cpputils::mapValue<float>(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
}
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) if(cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) return 100 * (expected_ah - mapFloat(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
float getBatteryPercentage(float batVoltage, BatteryCellType cellType) float getBatteryPercentage(float batVoltage, BatteryCellType cellType)
{ {
const float cellVoltage = batVoltage / settings.battery.cellsSeries; const float cellVoltage = batVoltage / settings.battery.cellsSeries;
switch (cellType) { switch (cellType)
case BatteryCellType::_22P: { {
const float expected_ah = 2.2; case BatteryCellType::_22P:
if(cellVoltage > 4.15){ {
return 100; const float expected_ah = 2.2;
} if (cellVoltage > 4.15)
CURVE(4.15, 4.04, 0, 0.25) return 100;
CURVE(4.04, 3.95, 0.25, 0.5)
CURVE(3.95, 3.86, 0.5, 0.75) CURVE(4.15, 4.04, 0, 0.25)
CURVE(3.86, 3.74, 0.75, 1.0) CURVE(4.04, 3.95, 0.25, 0.5)
CURVE(3.74, 3.64, 1.0, 1.25) CURVE(3.95, 3.86, 0.5, 0.75)
CURVE(3.64, 3.59, 1.25, 1.5) CURVE(3.86, 3.74, 0.75, 1.0)
CURVE(3.59, 3.54, 1.5, 1.75) CURVE(3.74, 3.64, 1.0, 1.25)
CURVE(3.54, 3.43, 1.75, 2.0) CURVE(3.64, 3.59, 1.25, 1.5)
CURVE(3.43, 3.35, 2.0, 2.1) CURVE(3.59, 3.54, 1.5, 1.75)
CURVE(3.35, 2.50, 2.1, 2.2) CURVE(3.54, 3.43, 1.75, 2.0)
break; CURVE(3.43, 3.35, 2.0, 2.1)
} CURVE(3.35, 2.50, 2.1, 2.2)
case BatteryCellType::MH1: { break;
const float expected_ah = 3.2; }
if(cellVoltage > 4.15){ case BatteryCellType::MH1:
return 100; {
} const float expected_ah = 3.2;
CURVE(4.15, 4.09, 0, 0.25) if (cellVoltage > 4.15)
CURVE(4.09, 4.04, 0.25, 0.5) return 100;
CURVE(4.04, 3.95, 0.5, 0.75)
CURVE(3.95, 3.88, 0.75, 1.0) CURVE(4.15, 4.09, 0, 0.25)
CURVE(3.88, 3.79, 1.0, 1.25) CURVE(4.09, 4.04, 0.25, 0.5)
CURVE(3.79, 3.70, 1.25, 1.5) CURVE(4.04, 3.95, 0.5, 0.75)
CURVE(3.70, 3.65, 1.5, 1.75) CURVE(3.95, 3.88, 0.75, 1.0)
CURVE(3.65, 3.60, 1.75, 2.0) CURVE(3.88, 3.79, 1.0, 1.25)
CURVE(3.60, 3.56, 2.0, 2.25) CURVE(3.79, 3.70, 1.25, 1.5)
CURVE(3.56, 3.50, 2.25, 2.5) CURVE(3.70, 3.65, 1.5, 1.75)
CURVE(3.50, 3.40, 2.5, 2.75) CURVE(3.65, 3.60, 1.75, 2.0)
CURVE(3.40, 3.30, 2.75, 3.0) CURVE(3.60, 3.56, 2.0, 2.25)
CURVE(3.30, 2.5, 3.0, 3.2) CURVE(3.56, 3.50, 2.25, 2.5)
break; CURVE(3.50, 3.40, 2.5, 2.75)
} CURVE(3.40, 3.30, 2.75, 3.0)
case BatteryCellType::HG2: { CURVE(3.30, 2.5, 3.0, 3.2)
const float expected_ah = 3.0; break;
if(cellVoltage > 4.15){ }
return 100; case BatteryCellType::HG2:
} {
CURVE(4.15, 4.08, 0, 0.25) const float expected_ah = 3.0;
CURVE(4.08, 4.01, 0.25, 0.5) if (cellVoltage > 4.15)
CURVE(4.01, 3.92, 0.5, 0.75) return 100;
CURVE(3.92, 3.84, 0.75, 1.0)
CURVE(3.84, 3.75, 1.0, 1.25) CURVE(4.15, 4.08, 0, 0.25)
CURVE(3.75, 3.67, 1.25, 1.5) CURVE(4.08, 4.01, 0.25, 0.5)
CURVE(3.67, 3.62, 1.5, 1.75) CURVE(4.01, 3.92, 0.5, 0.75)
CURVE(3.62, 3.55, 1.75, 2.0) CURVE(3.92, 3.84, 0.75, 1.0)
CURVE(3.55, 3.44, 2.0, 2.25) CURVE(3.84, 3.75, 1.0, 1.25)
CURVE(3.44, 3.30, 2.25, 2.5) CURVE(3.75, 3.67, 1.25, 1.5)
CURVE(3.30, 3.05, 2.5, 2.75) CURVE(3.67, 3.62, 1.5, 1.75)
CURVE(3.05, 2.50, 2.75, 3.0) CURVE(3.62, 3.55, 1.75, 2.0)
break; CURVE(3.55, 3.44, 2.0, 2.25)
} CURVE(3.44, 3.30, 2.25, 2.5)
case BatteryCellType::VTC5: { CURVE(3.30, 3.05, 2.5, 2.75)
const float expected_ah = 2.6; CURVE(3.05, 2.50, 2.75, 3.0)
if(cellVoltage > 4.15){ break;
return 100; }
} case BatteryCellType::VTC5:
CURVE(4.15, 4.08, 0, 0.25) {
CURVE(4.08, 3.98, 0.25, 0.5) const float expected_ah = 2.6;
CURVE(3.98, 3.89, 0.5, 0.75) if (cellVoltage > 4.15)
CURVE(3.89, 3.79, 0.75, 1.0) return 100;
CURVE(3.79, 3.71, 1.0, 1.25)
CURVE(3.71, 3.64, 1.25, 1.5) CURVE(4.15, 4.08, 0, 0.25)
CURVE(3.64, 3.53, 1.5, 1.75) CURVE(4.08, 3.98, 0.25, 0.5)
CURVE(3.53, 3.44, 1.75, 2.0) CURVE(3.98, 3.89, 0.5, 0.75)
CURVE(3.44, 3.20, 2.0, 2.25) CURVE(3.89, 3.79, 0.75, 1.0)
CURVE(3.20, 2.80, 2.25, 2.5) CURVE(3.79, 3.71, 1.0, 1.25)
CURVE(2.80, 2.50, 2.5, 2.60) CURVE(3.71, 3.64, 1.25, 1.5)
break; CURVE(3.64, 3.53, 1.5, 1.75)
} CURVE(3.53, 3.44, 1.75, 2.0)
CURVE(3.44, 3.20, 2.0, 2.25)
CURVE(3.20, 2.80, 2.25, 2.5)
CURVE(2.80, 2.50, 2.5, 2.60)
break;
}
} }
return 0.f; return 0.f;
} }
@ -116,7 +119,7 @@ float getRemainingWattHours()
float avgVoltage = 0; float avgVoltage = 0;
for (auto &controller : controllers) for (auto &controller : controllers)
{ {
avgVoltage += controller.getCalibratedVoltage(settings.battery.applyCalibration); avgVoltage += controller.getCalibratedVoltage();
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();
@ -128,7 +131,7 @@ std::string getBatteryPercentageString()
float avgVoltage = 0; float avgVoltage = 0;
for (auto &controller : controllers) for (auto &controller : controllers)
{ {
avgVoltage += controller.getCalibratedVoltage(settings.battery.applyCalibration); avgVoltage += controller.getCalibratedVoltage();
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();

View File

@ -81,11 +81,11 @@ void handleBle()
{ {
auto arr = doc.createNestedArray("v"); auto arr = doc.createNestedArray("v");
if (controllers.front.feedbackValid) if (controllers.front.feedbackValid)
arr.add(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration)); arr.add(controllers.front.getCalibratedVoltage());
else else
arr.add(nullptr); arr.add(nullptr);
if (controllers.back.feedbackValid) if (controllers.back.feedbackValid)
arr.add(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration)); arr.add(controllers.back.getCalibratedVoltage());
else else
arr.add(nullptr); arr.add(nullptr);
} }

View File

@ -110,7 +110,7 @@ void cloudCollect()
} }
cloudBuffer += fmt::format(",[{:.02f},{:.02f}", cloudBuffer += fmt::format(",[{:.02f},{:.02f}",
controller.getCalibratedVoltage(settings.battery.applyCalibration), controller.getCalibratedVoltage(),
fixBoardTemp(controller.feedback.boardTemp)); fixBoardTemp(controller.feedback.boardTemp));
constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command, constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command,

View File

@ -1,5 +1,8 @@
#include "controller.h" #include "controller.h"
// local includes
#include "globals.h"
Controller::Controller( Controller::Controller(
#ifdef FEATURE_SERIAL #ifdef FEATURE_SERIAL
HardwareSerial &serial, HardwareSerial &serial,
@ -15,10 +18,10 @@ Controller::Controller(
{ {
} }
float Controller::getCalibratedVoltage(bool applyCalibration) const float Controller::getCalibratedVoltage() const
{ {
float voltage = feedback.batVoltage; float voltage = feedback.batVoltage;
if (applyCalibration) if (settings.battery.applyCalibration)
{ {
voltage = ((voltage - float(voltageCalib30V)) * (20.f / (float(voltageCalib50V) - float(voltageCalib30V))) + 30.f); voltage = ((voltage - float(voltageCalib30V)) * (20.f / (float(voltageCalib50V) - float(voltageCalib30V))) + 30.f);
} }

View File

@ -53,5 +53,5 @@ struct Controller
FeedbackParser parser{serial, feedbackValid, feedback}; FeedbackParser parser{serial, feedbackValid, feedback};
#endif #endif
float getCalibratedVoltage(bool applyCalibration) const; float getCalibratedVoltage() const;
}; };

View File

@ -48,7 +48,7 @@ public:
using RightCommand = CommandTexts<LeftCommandGetter>; using RightCommand = CommandTexts<LeftCommandGetter>;
//struct BatVoltageText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.batVoltage); return line; } }; //struct BatVoltageText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.batVoltage); return line; } };
struct BatVoltageFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}V", controller::get().getCalibratedVoltage(settings.battery.applyCalibration)); return line; } }; struct BatVoltageFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}V", controller::get().getCalibratedVoltage()); return line; } };
//struct BoardTempText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.boardTemp); return line; } }; //struct BoardTempText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.boardTemp); return line; } };
struct BoardTempFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}C", fixBoardTemp(controller::get().feedback.boardTemp)); return line; } }; struct BoardTempFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}C", fixBoardTemp(controller::get().feedback.boardTemp)); return line; } };
struct TimeoutCntSerialText : public virtual TextInterface { public: std::string text() const override { std::string line{"timeoutCntSerial: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.timeoutCntSerial); return line; } }; struct TimeoutCntSerialText : public virtual TextInterface { public: std::string text() const override { std::string line{"timeoutCntSerial: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.timeoutCntSerial); return line; } };

View File

@ -11,11 +11,6 @@
#include "widgets/label.h" #include "widgets/label.h"
#include "screenmanager.h" #include "screenmanager.h"
namespace {
class MainMenu;
class MetersDisplay;
class StatusDisplay;
}
namespace { namespace {
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS) #if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
class BmsDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack class BmsDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack

View File

@ -0,0 +1,276 @@
#include "calibratedisplay.h"
// 3rdparty lib includes
#include <tftinstance.h>
#include <screenmanager.h>
// local includes
#include "displays/statusdisplay.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
CalibrateDisplay::CalibrateDisplay(bool bootup) :
m_bootup{bootup}
{
}
std::string CalibrateDisplay::text() const
{
return TEXT_CALIBRATE;
}
void CalibrateDisplay::start()
{
Base::start();
m_oldMode = currentMode;
currentMode = &m_mode;
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
m_gas = std::nullopt;
m_brems = std::nullopt;
}
void CalibrateDisplay::initScreen()
{
Base::initScreen();
espgui::tft.setTextFont(4);
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
espgui::tft.drawString("gas:", 25, 47);
espgui::tft.drawString("brems:", 25, 147);
for (auto &label : m_labels)
label.start();
for (auto &progressBar : m_progressBars)
progressBar.start();
m_renderedButton = -1;
}
void CalibrateDisplay::update()
{
Base::update();
if (raw_gas)
m_gas = cpputils::mapValueClamped<float>(*raw_gas, m_gasMin, m_gasMax, 0., 1000.);
else
m_gas = std::nullopt;
if (raw_brems)
m_brems = cpputils::mapValueClamped<float>(*raw_brems, m_bremsMin, m_bremsMax, 0., 1000.);
else
m_brems = std::nullopt;
}
void CalibrateDisplay::redraw()
{
Base::redraw();
m_labels[0].redraw(m_gas ? fmt::format("{:.02f}", *m_gas) : "?");
m_labels[1].redraw(raw_gas ? std::to_string(*raw_gas) : "?");
if (m_status == Status::GasMin)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[2].redraw(std::to_string(m_gasMin));
if (m_status == Status::GasMin)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::GasMax)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[3].redraw(std::to_string(m_gasMax));
if (m_status == Status::GasMax)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[0].redraw(m_gas ? *m_gas : 0);
m_labels[4].redraw(m_brems ? fmt::format("{:.02f}", *m_brems) : "?");
m_labels[5].redraw(raw_brems ? std::to_string(*raw_brems) : "?");
if (m_status == Status::BremsMin)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[6].redraw(std::to_string(m_bremsMin));
if (m_status == Status::BremsMin)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::BremsMax)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[7].redraw(std::to_string(m_bremsMax));
if (m_status == Status::BremsMax)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[1].redraw(m_brems ? *m_brems : 0);
m_labels[8].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Start calibrating?";
case Status::GasMin: return "Release gas";
case Status::GasMax: return "Press gas";
case Status::BremsMin: return "Release brems";
case Status::BremsMax: return "Press brems";
case Status::Confirm: return "Verify";
}
__builtin_unreachable();
}());
{
const auto failed = !m_gas || !m_brems || (m_status == Status::Confirm && (*m_gas > 100 || *m_brems > 100));
const auto color = failed ? TFT_DARKGREY : TFT_WHITE;
espgui::tft.setTextColor(color, TFT_BLACK);
m_labels[9].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Yes";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax: return "Next";
case Status::Confirm: return "Save";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 0 || m_renderedButton == 0))
espgui::tft.drawRect(3, 275, 100, 27, m_selectedButton == 0 ? color : TFT_BLACK);
}
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labels[10].redraw([&](){
switch (m_status)
{
case Status::Begin: return "No";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm: return "Abort";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 1 || m_renderedButton == 1))
espgui::tft.drawRect(123, 275, 100, 27, m_selectedButton == 1 ? TFT_WHITE : TFT_BLACK);
m_renderedButton = m_selectedButton;
}
void CalibrateDisplay::stop()
{
Base::stop();
if (currentMode == &m_mode)
{
// to avoid crash after deconstruction
m_mode.stop();
lastMode = nullptr;
currentMode = m_oldMode;
}
}
void CalibrateDisplay::rotate(int offset)
{
Base::rotate(offset);
m_selectedButton += offset;
if (m_selectedButton < 0)
m_selectedButton = 1;
if (m_selectedButton > 1)
m_selectedButton = 0;
}
void CalibrateDisplay::back()
{
Base::back();
switch (m_status)
{
case Status::Begin:
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
break;
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm:
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
}
}
void CalibrateDisplay::confirm()
{
Base::confirm();
switch (m_selectedButton)
{
case 0: // left button pressed
if (!raw_gas || !raw_brems || !m_gas || !m_brems)
return;
switch (m_status)
{
case Status::Begin:
m_status = Status::GasMin;
break;
case Status::GasMin:
m_gasMin = *raw_gas;
m_status = Status::GasMax;
break;
case Status::GasMax:
m_gasMax = *raw_gas;
m_status = Status::BremsMin;
{
const auto dead = (m_gasMax - m_gasMin)/20;
m_gasMin += dead;
m_gasMax -= dead;
}
break;
case Status::BremsMin:
m_bremsMin = *raw_brems;
m_status = Status::BremsMax;
break;
case Status::BremsMax:
m_bremsMax = *raw_brems;
m_status = Status::Confirm;
{
const auto dead = (m_bremsMax - m_bremsMin)/20;
m_bremsMin += dead;
m_bremsMax -= dead;
}
break;
case Status::Confirm:
if (*m_gas > 100 || *m_brems > 100)
return;
copyToSettings();
saveSettings();
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
}
break;
case 1: // right button pressed
back();
}
}
void CalibrateDisplay::copyFromSettings()
{
m_gasMin = settings.boardcomputerHardware.gasMin;
m_gasMax = settings.boardcomputerHardware.gasMax;
m_bremsMin = settings.boardcomputerHardware.bremsMin;
m_bremsMax = settings.boardcomputerHardware.bremsMax;
}
void CalibrateDisplay::copyToSettings()
{
settings.boardcomputerHardware.gasMin = m_gasMin;
settings.boardcomputerHardware.gasMax = m_gasMax;
settings.boardcomputerHardware.bremsMin = m_bremsMin;
settings.boardcomputerHardware.bremsMax = m_bremsMax;
}

View File

@ -7,29 +7,26 @@
// 3rdparty lib includes // 3rdparty lib includes
#include <fmt/core.h> #include <fmt/core.h>
#include <cpputils.h> #include <cpputils.h>
#include <displaywithtitle.h>
#include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/progressbar.h>
// local includes // local includes
#include "display.h"
#include "actions/switchscreenaction.h"
#include "globals.h" #include "globals.h"
#include "utils.h" #include "utils.h"
#include "texts.h" #include "texts.h"
#include "widgets/label.h"
#include "widgets/progressbar.h"
#include "modes/ignoreinputmode.h" #include "modes/ignoreinputmode.h"
namespace { class CalibrateDisplay : public espgui::DisplayWithTitle
class StatusDisplay;
class BoardcomputerHardwareSettingsMenu;
}
namespace {
class CalibrateDisplay : public Display
{ {
using Base = espgui::DisplayWithTitle;
public: public:
CalibrateDisplay() = default; CalibrateDisplay() = default;
CalibrateDisplay(bool bootup); CalibrateDisplay(bool bootup);
std::string text() const override;
void start() override; void start() override;
void initScreen() override; void initScreen() override;
void update() override; void update() override;
@ -50,26 +47,26 @@ private:
ModeInterface *m_oldMode; ModeInterface *m_oldMode;
IgnoreInputMode m_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque}; IgnoreInputMode m_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque};
std::array<Label, 11> m_labels {{ std::array<espgui::Label, 11> m_labels {{
Label{25, 72}, // 100, 23 espgui::Label{25, 72}, // 100, 23
Label{145, 72}, // 100, 23 espgui::Label{145, 72}, // 100, 23
Label{25, 97}, // 100, 23 espgui::Label{25, 97}, // 100, 23
Label{145, 97}, // 100, 23 espgui::Label{145, 97}, // 100, 23
Label{25, 172}, // 100, 23 espgui::Label{25, 172}, // 100, 23
Label{145, 172}, // 100, 23 espgui::Label{145, 172}, // 100, 23
Label{25, 197}, // 100, 23 espgui::Label{25, 197}, // 100, 23
Label{145, 197}, // 100, 23 espgui::Label{145, 197}, // 100, 23
Label{25, 247}, // 190, 23 espgui::Label{25, 247}, // 190, 23
Label{25, 277}, // 100, 23 espgui::Label{25, 277}, // 100, 23
Label{145, 277}, // 100, 23 espgui::Label{145, 277}, // 100, 23
}}; }};
std::array<ProgressBar, 2> m_progressBars {{ std::array<espgui::ProgressBar, 2> m_progressBars {{
ProgressBar{20, 129, 200, 10, 0, 1000}, espgui::ProgressBar{20, 129, 200, 10, 0, 1000},
ProgressBar{20, 229, 200, 10, 0, 1000} espgui::ProgressBar{20, 229, 200, 10, 0, 1000}
}}; }};
enum Status { enum Status {
@ -87,257 +84,3 @@ private:
int16_t m_gasMin, m_gasMax, m_bremsMin, m_bremsMax; int16_t m_gasMin, m_gasMax, m_bremsMin, m_bremsMax;
std::optional<float> m_gas, m_brems; std::optional<float> m_gas, m_brems;
}; };
CalibrateDisplay::CalibrateDisplay(bool bootup) :
m_bootup{bootup}
{
}
void CalibrateDisplay::start()
{
m_oldMode = currentMode;
currentMode = &m_mode;
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
m_gas = std::nullopt;
m_brems = std::nullopt;
}
void CalibrateDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextFont(4);
tft.setTextColor(TFT_YELLOW);
tft.drawString(TEXT_CALIBRATE, 5, 5, 4);
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString("gas:", 25, 47);
tft.drawString("brems:", 25, 147);
for (auto &label : m_labels)
label.start();
for (auto &progressBar : m_progressBars)
progressBar.start();
m_renderedButton = -1;
}
void CalibrateDisplay::update()
{
if (raw_gas)
m_gas = cpputils::mapValueClamped<float>(*raw_gas, m_gasMin, m_gasMax, 0., 1000.);
else
m_gas = std::nullopt;
if (raw_brems)
m_brems = cpputils::mapValueClamped<float>(*raw_brems, m_bremsMin, m_bremsMax, 0., 1000.);
else
m_brems = std::nullopt;
}
void CalibrateDisplay::redraw()
{
m_labels[0].redraw(m_gas ? fmt::format("{:.02f}", *m_gas) : "?");
m_labels[1].redraw(raw_gas ? std::to_string(*raw_gas) : "?");
if (m_status == Status::GasMin)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[2].redraw(std::to_string(m_gasMin));
if (m_status == Status::GasMin)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::GasMax)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[3].redraw(std::to_string(m_gasMax));
if (m_status == Status::GasMax)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[0].redraw(m_gas ? *m_gas : 0);
m_labels[4].redraw(m_brems ? fmt::format("{:.02f}", *m_brems) : "?");
m_labels[5].redraw(raw_brems ? std::to_string(*raw_brems) : "?");
if (m_status == Status::BremsMin)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[6].redraw(std::to_string(m_bremsMin));
if (m_status == Status::BremsMin)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::BremsMax)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[7].redraw(std::to_string(m_bremsMax));
if (m_status == Status::BremsMax)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[1].redraw(m_brems ? *m_brems : 0);
m_labels[8].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Start calibrating?";
case Status::GasMin: return "Release gas";
case Status::GasMax: return "Press gas";
case Status::BremsMin: return "Release brems";
case Status::BremsMax: return "Press brems";
case Status::Confirm: return "Verify";
}
__builtin_unreachable();
}());
{
const auto failed = !m_gas || !m_brems || (m_status == Status::Confirm && (*m_gas > 100 || *m_brems > 100));
const auto color = failed ? TFT_DARKGREY : TFT_WHITE;
tft.setTextColor(color, TFT_BLACK);
m_labels[9].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Yes";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax: return "Next";
case Status::Confirm: return "Save";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 0 || m_renderedButton == 0))
tft.drawRect(3, 275, 100, 27, m_selectedButton == 0 ? color : TFT_BLACK);
}
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labels[10].redraw([&](){
switch (m_status)
{
case Status::Begin: return "No";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm: return "Abort";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 1 || m_renderedButton == 1))
tft.drawRect(123, 275, 100, 27, m_selectedButton == 1 ? TFT_WHITE : TFT_BLACK);
m_renderedButton = m_selectedButton;
}
void CalibrateDisplay::stop()
{
if (currentMode == &m_mode)
{
// to avoid crash after deconstruction
m_mode.stop();
lastMode = nullptr;
currentMode = m_oldMode;
}
}
void CalibrateDisplay::rotate(int offset)
{
m_selectedButton += offset;
if (m_selectedButton < 0)
m_selectedButton = 1;
if (m_selectedButton > 1)
m_selectedButton = 0;
}
void CalibrateDisplay::back()
{
switch (m_status)
{
case Status::Begin:
if (m_bootup)
switchScreen<StatusDisplay>();
else
switchScreen<BoardcomputerHardwareSettingsMenu>();
break;
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm:
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
}
}
void CalibrateDisplay::confirm()
{
switch (m_selectedButton)
{
case 0: // left button pressed
if (!raw_gas || !raw_brems || !m_gas || !m_brems)
return;
switch (m_status)
{
case Status::Begin:
m_status = Status::GasMin;
break;
case Status::GasMin:
m_gasMin = *raw_gas;
m_status = Status::GasMax;
break;
case Status::GasMax:
m_gasMax = *raw_gas;
m_status = Status::BremsMin;
{
const auto dead = (m_gasMax - m_gasMin)/20;
m_gasMin += dead;
m_gasMax -= dead;
}
break;
case Status::BremsMin:
m_bremsMin = *raw_brems;
m_status = Status::BremsMax;
break;
case Status::BremsMax:
m_bremsMax = *raw_brems;
m_status = Status::Confirm;
{
const auto dead = (m_bremsMax - m_bremsMin)/20;
m_bremsMin += dead;
m_bremsMax -= dead;
}
break;
case Status::Confirm:
if (*m_gas > 100 || *m_brems > 100)
return;
copyToSettings();
saveSettings();
if (m_bootup)
switchScreen<StatusDisplay>();
else
switchScreen<BoardcomputerHardwareSettingsMenu>();
}
break;
case 1: // right button pressed
back();
}
}
void CalibrateDisplay::copyFromSettings()
{
m_gasMin = settings.boardcomputerHardware.gasMin;
m_gasMax = settings.boardcomputerHardware.gasMax;
m_bremsMin = settings.boardcomputerHardware.bremsMin;
m_bremsMax = settings.boardcomputerHardware.bremsMax;
}
void CalibrateDisplay::copyToSettings()
{
settings.boardcomputerHardware.gasMin = m_gasMin;
settings.boardcomputerHardware.gasMax = m_gasMax;
settings.boardcomputerHardware.bremsMin = m_bremsMin;
settings.boardcomputerHardware.bremsMax = m_bremsMax;
}
}

View File

@ -0,0 +1,82 @@
#include "calibratevoltagedisplay.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <actions/toggleboolaction.h>
#include <checkboxicon.h>
// local includes
#include "displays/menus/batterymenu.h"
#include "accessors/settingsaccessors.h"
namespace {
class Save30VCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class Save50VCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class ResetCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front30VoltCalibration = 3000;
settings.battery.back30VoltCalibration = 3000;
settings.battery.front50VoltCalibration = 5000;
settings.battery.back50VoltCalibration = 5000;
saveSettings();
}
};
float convertToFloat(int16_t value)
{
return value/100.;
}
class BatteryVoltageCalibrationFront30VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration)); } };
class BatteryVoltageCalibrationBack30VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration)); } };
class BatteryVoltageCalibrationFront50VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration)); } };
class BatteryVoltageCalibrationBack50VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration)); } };
class BatteryVoltageCalibratedText : public virtual espgui::TextInterface { public: std::string text() const override { if (settings.battery.applyCalibration) return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(), controllers.back.getCalibratedVoltage()); else return "Not activated"; } };
} // namespace
using namespace espgui;
CalibrateVoltageDisplay::CalibrateVoltageDisplay()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_30V>, Save30VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_50V>, Save50VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_APPLYCALIB>, ToggleBoolAction, CheckboxIcon, BatteryApplyCalibrationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibratedText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_RESET>, ResetCalibrationAction>>();
}
void CalibrateVoltageDisplay::back()
{
switchScreen<BatteryMenu>();
}

View File

@ -14,78 +14,12 @@
#include "widgets/label.h" #include "widgets/label.h"
#include "globals.h" #include "globals.h"
using namespace espgui; class CalibrateVoltageDisplay :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_BATTERY_CALIBRATE>
{
public:
CalibrateVoltageDisplay();
namespace { void back() override;
class CalibrateVoltageDisplay; };
class BatteryMenu;
class Save30VCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class Save50VCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class ResetCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front30VoltCalibration = 3000;
settings.battery.back30VoltCalibration = 3000;
settings.battery.front50VoltCalibration = 5000;
settings.battery.back50VoltCalibration = 5000;
saveSettings();
}
};
float convertToFloat(int16_t value)
{
return value/100.;
}
class BatteryVoltageCalibrationFront30VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration)); } };
class BatteryVoltageCalibrationBack30VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration)); } };
class BatteryVoltageCalibrationFront50VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration)); } };
class BatteryVoltageCalibrationBack50VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration)); } };
class BatteryVoltageCalibratedText : public virtual TextInterface { public: std::string text() const override { if (settings.battery.applyCalibration) return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(settings.battery.applyCalibration), controllers.back.getCalibratedVoltage(settings.battery.applyCalibration)); else return "Not activated"; } };
}
namespace {
class CalibrateVoltageDisplay :
public MenuDisplay,
public StaticText<TEXT_BATTERY_CALIBRATE>,
public BackActionInterface<SwitchScreenAction<BatteryMenu>>
{
public:
CalibrateVoltageDisplay()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_30V>, Save30VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_50V>, Save50VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_APPLYCALIB>, ToggleBoolAction, CheckboxIcon, BatteryApplyCalibrationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibratedText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_RESET>, ResetCalibrationAction>>();
}
};
} // Namespace

View File

@ -11,11 +11,6 @@
#include "widgets/progressbar.h" #include "widgets/progressbar.h"
#include "modes/ignoreinputmode.h" #include "modes/ignoreinputmode.h"
namespace {
class StatusDisplay;
class BoardcomputerHardwareSettingsMenu;
}
namespace { namespace {
#ifdef FEATURE_GAMETRAK #ifdef FEATURE_GAMETRAK
class GametrakCalibrateDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>, public BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>> class GametrakCalibrateDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>, public BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>

View File

@ -0,0 +1,46 @@
#include "aboutmenu.h"
// local includes
#include "utils.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "esptexthelpers.h"
#ifdef FEATURE_OTA
#include <espasyncota.h>
#include <esp_ota_ops.h>
#include "fmt/core.h"
#endif
AboutMenu::AboutMenu()
{
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>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, HeapTotal32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, EspChipRevisionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCpuFreqMHzText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCycleCountText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSdkVersionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSpeedText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipModeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchMd5Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFreeSketchSpaceText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void AboutMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -1,29 +1,15 @@
#pragma once #pragma once
// local includes // 3rdparty lib includes
#include "menudisplay.h" #include <menudisplay.h>
#include "utils.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#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 // local includes
namespace { #include "texts.h"
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {
class CurrentVersionText : public virtual TextInterface { public: std::string text() const override {
class currentVersionText : public virtual TextInterface { public: std::string text() const override {
#ifdef FEATURE_OTA #ifdef FEATURE_OTA
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description()) if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
{ {
@ -38,36 +24,11 @@ constexpr char TEXT_VERSION[] = "Version: 1.0";
class AboutMenu : class AboutMenu :
public MenuDisplay, public MenuDisplay,
public StaticText<TEXT_ABOUT>, public StaticText<TEXT_ABOUT>
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
{ {
public: public:
AboutMenu() AboutMenu();
{
constructMenuItem<makeComponent<MenuItem, currentVersionText, DummyAction>>(); void back() override;
constructMenuItem<makeComponent<MenuItem, HeapTotal8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, HeapTotal32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, EspChipRevisionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCpuFreqMHzText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCycleCountText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSdkVersionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSpeedText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipModeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchMd5Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFreeSketchSpaceText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
} // namespace } // namespace

View File

@ -0,0 +1,55 @@
#include "batterymenu.h"
// 3rdparty lib includes
#include <changevaluedisplay.h>
// local includes
#include "mainmenu.h"
#include "displays/calibratevoltagedisplay.h"
#include "accessors/settingsaccessors.h"
class CurrentBatteryStatusText : public virtual espgui::TextInterface { public: std::string text() const override { return getBatteryPercentageString(); } };
using BatteryCellSeriesChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_CELL_SERIES>,
BatterySeriesCellsAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using BatteryCellParallelChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_CELL_PARALLEL>,
BatteryParallelCellsAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using BatteryWHperKMChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint16_t>,
espgui::StaticText<TEXT_BATTERY_WHKM>,
BatteryWHperKMAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using namespace espgui;
BatteryMenu::BatteryMenu()
{
constructMenuItem<makeComponent<MenuItem, CurrentBatteryStatusText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_SERIES, BatterySeriesCellsAccessor>, SwitchScreenAction<BatteryCellSeriesChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_PARALLEL, BatteryParallelCellsAccessor>, SwitchScreenAction<BatteryCellParallelChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BATTERY_WHKM, BatteryWHperKMAccessor>, SwitchScreenAction<BatteryWHperKMChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_CELL_TYPE>, SwitchScreenAction<BatteryTypeMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_CALIBRATE>, SwitchScreenAction<CalibrateVoltageDisplay>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void BatteryMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,71 +1,25 @@
#pragma once #pragma once
// 3rdparty lib includes
#include <menudisplay.h>
#include <menuitem.h>
#include <icons/back.h>
#include <actions/dummyaction.h>
#include <actions/switchscreenaction.h>
// Local includes // Local includes
#include "menudisplay.h"
#include "utils.h" #include "utils.h"
#include "menuitem.h"
#include "icons/back.h"
#include "icons/settings.h" #include "icons/settings.h"
#include "texts.h" #include "texts.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "mainmenu.h"
#include "battery.h" #include "battery.h"
#include "selectbatterytypemenu.h" #include "selectbatterytypemenu.h"
#include "displays/calibratevoltagedisplay.h"
// Helper class BatteryMenu :
class currentBatteryStatus : public virtual TextInterface { public: std::string text() const override { return getBatteryPercentageString(); } }; public espgui::MenuDisplay,
public espgui::StaticText<TEXT_BATTERY>
{
public:
BatteryMenu();
using namespace espgui; void back() override;
};
namespace {
class BatteryMenu;
class CalibrateVoltageDisplay;
using BatteryCellSeriesChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_CELL_SERIES>,
BatterySeriesCellsAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
using BatteryCellParallelChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_CELL_PARALLEL>,
BatteryParallelCellsAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
using BatteryWHperKMChangeScreen = makeComponent<
ChangeValueDisplay<uint16_t>,
StaticText<TEXT_BATTERY_WHKM>,
BatteryWHperKMAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
}
namespace {
class BatteryMenu :
public MenuDisplay,
public StaticText<TEXT_BATTERY>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
{
public:
BatteryMenu()
{
constructMenuItem<makeComponent<MenuItem, currentBatteryStatus, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_SERIES, BatterySeriesCellsAccessor>, SwitchScreenAction<BatteryCellSeriesChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_PARALLEL, BatteryParallelCellsAccessor>, SwitchScreenAction<BatteryCellParallelChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BATTERY_WHKM, BatteryWHperKMAccessor>, SwitchScreenAction<BatteryWHperKMChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_CELL_TYPE>, SwitchScreenAction<BatteryTypeMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_CALIBRATE>, SwitchScreenAction<CalibrateVoltageDisplay>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace

View File

@ -11,11 +11,6 @@
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
// forward declares
namespace {
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -21,11 +21,6 @@
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
// forward declares
namespace {
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -0,0 +1,183 @@
#include "boardcomputerhardwaresettingsmenu.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <changevaluedisplay.h>
#include <actions/dummyaction.h>
#include <actions/switchscreenaction.h>
#include <actions/toggleboolaction.h>
#include <icons/back.h>
#include <checkboxicon.h>
// local includes
#include "utils.h"
#include "icons/lock.h"
#include "accessors/settingsaccessors.h"
#include "displays/menus/lockscreensettingsmenu.h"
#include "displays/calibratedisplay.h"
namespace {
struct GasText : public virtual espgui::TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"gas",
raw_gas ? std::to_string(*raw_gas) : "?",
gas ? fmt::format("{:.02f}", *gas) : "?");
}
};
struct BremsText : public virtual espgui::TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"brems",
raw_brems ? std::to_string(*raw_brems) : "?",
brems ? fmt::format("{:.02f}", *brems) : "?");
}
};
using SampleCountChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SAMPLECOUNT>,
SampleCountAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_GASMIN>,
GasMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_GASMAX>,
GasMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_BREMSMIN>,
BremsMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_BREMSMAX>,
BremsMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
using DPadDebounceChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_DPADDEBOUNCE>,
DPadDebounceAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
#ifdef FEATURE_GAMETRAK
struct GametrakXText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakX: {}: {:.02f}", raw_gametrakX, gametrakX); }
};
struct GametrakYText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakY: {}: {:.02f}", raw_gametrakY, gametrakY); }
};
struct GametrakDistText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakDist: {}: {:.02f}", raw_gametrakDist, gametrakDist); }
};
using GametrakXMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKXMIN>,
GametrakXMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakXMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKXMAX>,
GametrakXMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKYMIN>,
GametrakYMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKYMAX>,
GametrakYMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKDISTMIN>,
GametrakDistMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKDISTMAX>,
GametrakDistMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
} // namespace
using namespace espgui;
BoardcomputerHardwareSettingsMenu::BoardcomputerHardwareSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKSCREENSETTINGS>, SwitchScreenAction<LockscreenSettingsMenu>, StaticMenuItemIcon<&bobbyicons::lock>>>();
constructMenuItem<makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CALIBRATE>, SwitchScreenAction<CalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SAMPLECOUNT, SampleCountAccessor>, SwitchScreenAction<SampleCountChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMIN, GasMinAccessor>, SwitchScreenAction<GasMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMAX, GasMaxAccessor>, SwitchScreenAction<GasMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMIN, BremsMinAccessor>, SwitchScreenAction<BremsMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMAX, BremsMaxAccessor>, SwitchScreenAction<BremsMaxChangeScreen>>>();
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_DPADDEBOUNCE, DPadDebounceAccessor>, SwitchScreenAction<DPadDebounceChangeScreen>>>();
#endif
#ifdef FEATURE_GAMETRAK
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>,
constructMenuItem<makeComponent<MenuItem, GametrakXText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakYText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakDistText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GAMETRAKCALIBRATE>, SwitchScreenAction<GametrakCalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMIN>, SwitchScreenAction<GametrakXMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMAX>, SwitchScreenAction<GametrakXMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMIN>, SwitchScreenAction<GametrakYMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMAX>, SwitchScreenAction<GametrakYMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMIN>, SwitchScreenAction<GametrakDistMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMAX>, SwitchScreenAction<GametrakDistMaxChangeScreen>>>();
#endif
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIMERS>, SwitchScreenAction<TimersMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>>();
}
void BoardcomputerHardwareSettingsMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -1,195 +1,15 @@
#pragma once #pragma once
// 3rdparty lib includes
#include <fmt/core.h>
// local includes // local includes
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h"
#include "changevaluedisplay.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "icons/lock.h"
#include "icons/back.h"
#include "checkboxicon.h"
#include "texts.h" #include "texts.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
class LockscreenSettingsMenu;
class CalibrateDisplay;
class GametrakCalibrateDisplay;
class TimersMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {
struct GasText : public virtual TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"gas",
raw_gas ? std::to_string(*raw_gas) : "?",
gas ? fmt::format("{:.02f}", *gas) : "?");
}
};
struct BremsText : public virtual TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"brems",
raw_brems ? std::to_string(*raw_brems) : "?",
brems ? fmt::format("{:.02f}", *brems) : "?");
}
};
using SampleCountChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SAMPLECOUNT>,
SampleCountAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_GASMIN>,
GasMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_GASMAX>,
GasMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BREMSMIN>,
BremsMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BREMSMAX>,
BremsMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
using DPadDebounceChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_DPADDEBOUNCE>,
DPadDebounceAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
#ifdef FEATURE_GAMETRAK
struct GametrakXText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakX: {}: {:.02f}", raw_gametrakX, gametrakX); }
};
struct GametrakYText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakY: {}: {:.02f}", raw_gametrakY, gametrakY); }
};
struct GametrakDistText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakDist: {}: {:.02f}", raw_gametrakDist, gametrakDist); }
};
using GametrakXMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKXMIN>,
GametrakXMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakXMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKXMAX>,
GametrakXMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKYMIN>,
GametrakYMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKYMAX>,
GametrakYMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKDISTMIN>,
GametrakDistMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKDISTMAX>,
GametrakDistMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
class BoardcomputerHardwareSettingsMenu : class BoardcomputerHardwareSettingsMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, public espgui::StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
{ {
public: public:
BoardcomputerHardwareSettingsMenu() BoardcomputerHardwareSettingsMenu();
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKSCREENSETTINGS>, SwitchScreenAction<LockscreenSettingsMenu>, StaticMenuItemIcon<&bobbyicons::lock>>>(); void back() override;
constructMenuItem<makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CALIBRATE>, SwitchScreenAction<CalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SAMPLECOUNT, SampleCountAccessor>, SwitchScreenAction<SampleCountChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMIN, GasMinAccessor>, SwitchScreenAction<GasMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMAX, GasMaxAccessor>, SwitchScreenAction<GasMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMIN, BremsMinAccessor>, SwitchScreenAction<BremsMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMAX, BremsMaxAccessor>, SwitchScreenAction<BremsMaxChangeScreen>>>();
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_DPADDEBOUNCE, DPadDebounceAccessor>, SwitchScreenAction<DPadDebounceChangeScreen>>>();
#endif
#ifdef FEATURE_GAMETRAK
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>,
constructMenuItem<makeComponent<MenuItem, GametrakXText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakYText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakDistText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GAMETRAKCALIBRATE>, SwitchScreenAction<GametrakCalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMIN>, SwitchScreenAction<GametrakXMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMAX>, SwitchScreenAction<GametrakXMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMIN>, SwitchScreenAction<GametrakYMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMAX>, SwitchScreenAction<GametrakYMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMIN>, SwitchScreenAction<GametrakDistMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMAX>, SwitchScreenAction<GametrakDistMaxChangeScreen>>>();
#endif
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIMERS>, SwitchScreenAction<TimersMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
} // namespace

View File

@ -13,12 +13,6 @@
#include "globals.h" #include "globals.h"
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BuzzerMenu;
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -17,12 +17,6 @@
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
#include "cloud.h" #include "cloud.h"
// forward declares
namespace {
class CloudSettingsMenu;
class SettingsMenu;
} // namespace
namespace { namespace {
using CloudTransmitTimeoutChangeScreen = makeComponent< using CloudTransmitTimeoutChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>, ChangeValueDisplay<int16_t>,

View File

@ -14,15 +14,6 @@
#include "globals.h" #include "globals.h"
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
// forward declares
namespace {
class ControllerHardwareSettingsMenu;
class BoardcomputerHardwareSettingsMenu;
class EnableMenu;
class InvertMenu;
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -9,11 +9,6 @@
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
// forward declares
namespace {
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -10,12 +10,6 @@
#include "texts.h" #include "texts.h"
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
// forward declares
namespace {
class LimitsSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -12,12 +12,6 @@
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
#include "changevaluedisplay.h" #include "changevaluedisplay.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
class LockscreenSettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -0,0 +1,90 @@
#include "mainmenu.h"
// 3rdparty lib includes
#include "actions/switchscreenaction.h"
#include "icons/back.h"
// local includes
#include "displays/statusdisplay.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/ledstripmenu.h"
#include "actions/modesettingsaction.h"
#include "displays/menus/presetsmenu.h"
#include "displays/menus/profilesmenu.h"
#include "displays/menus/graphsmenu.h"
#include "displays/menus/batterymenu.h"
#include "displays/powersupplydisplay.h"
#include "displays/menus/bmsmenu.h"
#include "displays/menus/settingsmenu.h"
#include "displays/menus/mosfetsmenu.h"
#include "displays/menus/demosmenu.h"
#include "displays/lockscreen.h"
#include "displays/garagedisplay.h"
#include "displays/menus/otamenu.h"
#include "displays/poweroffdisplay.h"
#include "actions/rebootaction.h"
#include "displays/menus/debugmenu.h"
#include "icons/battery.h"
#include "icons/modes.h"
#include "icons/presets.h"
#include "icons/graph.h"
#ifdef FEATURE_BMS
#include "icons/bms.h"
#endif
#include "icons/settings.h"
#include "icons/lock.h"
#include "icons/demos.h"
#ifdef FEATURE_OTA
#include "icons/update.h"
#endif
#ifdef FEATURE_LEDSTRIP
#include "icons/neopixel.h"
#endif
#include "icons/poweroff.h"
#include "icons/reboot.h"
using namespace espgui;
MainMenu::MainMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
#ifdef FEATURE_LEDSTRIP
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&bobbyicons::graph>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>(); }
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWERSUPPLY>, SwitchScreenAction<PowerSupplyDisplay>>>(); }
#endif
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&bobbyicons::bms>>>(); }
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETTINGS>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>(); }
#ifdef FEATURE_MOSFETS
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>();
#ifdef FEATURE_GARAGE
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }
#endif
#ifdef FEATURE_OTA
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>>>();
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>(); }
#ifdef MAINMENU_PLUGIN
GMEN1
#endif
}
void MainMenu::back()
{
switchScreen<StatusDisplay>();
}

View File

@ -1,55 +1,16 @@
#pragma once #pragma once
// local includes // 3rdparty lib includes
#include "menudisplay.h" #include "menudisplay.h"
#include "menuitem.h" #include "menuitem.h"
#include "batterymenu.h"
#include "actions/switchscreenaction.h" // local includes
#include "actions/modesettingsaction.h"
#include "actions/rebootaction.h"
#include "texts.h" #include "texts.h"
#include "icons/back.h"
#include "icons/battery.h"
#include "icons/modes.h"
#include "icons/presets.h"
#include "icons/graph.h"
#ifdef FEATURE_BMS
#include "icons/bms.h"
#endif
#include "icons/settings.h"
#include "icons/lock.h"
#include "icons/demos.h"
#ifdef FEATURE_OTA
#include "icons/update.h"
#endif
#ifdef FEATURE_LEDSTRIP
#include "icons/neopixel.h"
#endif
#include "icons/poweroff.h"
#include "icons/reboot.h"
#ifdef MAINMENU_PLUGIN #ifdef MAINMENU_PLUGIN
#include MAINMENU_PLUGIN #include MAINMENU_PLUGIN
#endif #endif
// forward declares
namespace { namespace {
class StatusDisplay;
class SelectModeMenu;
class LedstripMenu;
class ProfilesMenu;
class PresetsMenu;
class GraphsMenu;
class PowerSupplyDisplay;
class BmsMenu;
class SettingsMenu;
class Lockscreen;
class MosfetsMenu;
class DemosMenu;
class GarageDisplay;
class OtaMenu;
class PoweroffDisplay;
class DebugMenu;
class BatteryMenu;
#ifdef MAINMENU_PLUGIN #ifdef MAINMENU_PLUGIN
GMEN2 GMEN2
#endif #endif
@ -60,51 +21,12 @@ class BatteryMenu;
#endif #endif
} // namespace } // namespace
using namespace espgui;
namespace {
class MainMenu : class MainMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_MAINMENU>, public espgui::StaticText<TEXT_MAINMENU>
public BackActionInterface<SwitchScreenAction<StatusDisplay>>
{ {
public: public:
MainMenu() MainMenu();
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>(); void back() override;
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
#ifdef FEATURE_LEDSTRIP
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&bobbyicons::graph>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>(); }
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWERSUPPLY>, SwitchScreenAction<PowerSupplyDisplay>>>(); }
#endif
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&bobbyicons::bms>>>(); }
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETTINGS>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>(); }
#ifdef FEATURE_MOSFETS
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>();
#ifdef FEATURE_GARAGE
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }
#endif
#ifdef FEATURE_OTA
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>>>();
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>(); }
#ifdef MAINMENU_PLUGIN
GMEN1
#endif
}
}; };
} // namespace

View File

@ -7,15 +7,6 @@
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
// forward declares
namespace {
class DefaultModeSettingsMenu;
class TempomatModeSettingsMenu;
class LarsmModeSettingsMenu;
class GametrakModeSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -11,15 +11,6 @@
#include "texts.h" #include "texts.h"
#include "buildserver.h" #include "buildserver.h"
// forward declares
namespace {
class MainMenu;
class UpdateDisplay;
class SelectBuildMenu;
class SelectBuildServerMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -0,0 +1,35 @@
#include "selectbatterytypemenu.h"
// local includes
#include "battery.h"
#include "globals.h"
#include "utils.h"
#include "displays/menus/batterymenu.h"
namespace {
class CurrentBatteryTypeText : public virtual espgui::TextInterface { public: std::string text() const override { return getBatteryCellTypeString(); } };
template<BatteryCellType T>
class BatterySelectTypeAction : public virtual espgui::ActionInterface
{
public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); }
};
} // namespace
using namespace espgui;
BatteryTypeMenu::BatteryTypeMenu()
{
constructMenuItem<makeComponent<MenuItem, CurrentBatteryTypeText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_22P>, BatterySelectTypeAction<BatteryCellType::_22P>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_HG2>, BatterySelectTypeAction<BatteryCellType::HG2>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_MH1>, BatterySelectTypeAction<BatteryCellType::MH1>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_VTC5>, BatterySelectTypeAction<BatteryCellType::VTC5>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void BatteryTypeMenu::back()
{
espgui::switchScreen<BatteryMenu>();
}

View File

@ -1,48 +1,23 @@
#pragma once #pragma once
// 3rdparty lib includes
#include <menudisplay.h>
#include <menuitem.h>
#include <icons/back.h>
#include <actions/switchscreenaction.h>
#include <actioninterface.h>
// Local includes // Local includes
#include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "actions/switchscreenaction.h"
#include "batterymenu.h" #include "batterymenu.h"
#include "battery.h" #include "displays/menus/mainmenu.h"
#include "actioninterface.h"
// Helper class BatteryTypeMenu :
class currentBatteryType : public virtual TextInterface { public: std::string text() const override { return getBatteryCellTypeString(); } }; public espgui::MenuDisplay,
public espgui::StaticText<TEXT_SELECT_CELL_TYPE>
{
public:
BatteryTypeMenu();
using namespace espgui; void back() override;
};
namespace {
class BatteryTypeMenu;
class BatteryMenu;
template<BatteryCellType T>
class BatterySelectTypeAction : public virtual ActionInterface
{
public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); }
};
} // namespace
namespace {
class BatteryTypeMenu :
public MenuDisplay,
public StaticText<TEXT_SELECT_CELL_TYPE>,
public BackActionInterface<SwitchScreenAction<BatteryMenu>>
{
public:
BatteryTypeMenu()
{
constructMenuItem<makeComponent<MenuItem, currentBatteryType, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_22P>, BatterySelectTypeAction<BatteryCellType::_22P>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_HG2>, BatterySelectTypeAction<BatteryCellType::HG2>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_MH1>, BatterySelectTypeAction<BatteryCellType::MH1>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_VTC5>, BatterySelectTypeAction<BatteryCellType::VTC5>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace

View File

@ -0,0 +1,71 @@
#include "selectbuildservermenu.h"
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <fmt/core.h>
#include <actions/switchscreenaction.h>
// local includes
#include "displays/menus/settingsmenu.h"
namespace {
class BuildserverMenuItem : public espgui::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;
};
} // namespace
using namespace espgui;
SelectBuildServerMenu::SelectBuildServerMenu()
{
for (const auto &otaServer : stringSettings.otaServers)
{
std::string url = otaServer.url;
std::string name = (otaServer.name.empty()) ? url : otaServer.name;
if (!name.empty())
{
auto &menuitem = constructMenuItem<BuildserverMenuItem>();
menuitem.setBuildserverName(name);
menuitem.setBuildserverUrl(url);
}
}
if (menuItemCount() < 1)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void SelectBuildServerMenu::back()
{
espgui::switchScreen<SettingsMenu>();
}

View File

@ -1,87 +1,22 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include <TFT_eSPI.h> #include <menudisplay.h>
#include <actions/dummyaction.h>
#include <icons/back.h>
// local includes // local includes
#include "menudisplay.h"
#include "utils.h" #include "utils.h"
#include "actions/dummyaction.h"
#include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "globals.h" #include "globals.h"
#include "buildserver.h" #include "buildserver.h"
// Debugging
#include "esp_log.h"
#include "fmt/core.h"
// forward declares
namespace {
class SettingsMenu;
} // namespace
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 : class SelectBuildServerMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_SELECTBUILDSERVERMENU>, public espgui::StaticText<TEXT_SELECTBUILDSERVERMENU>
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
{ {
public: public:
SelectBuildServerMenu() { SelectBuildServerMenu();
for (const auto &otaServer : stringSettings.otaServers) void back() override;
{
std::string url = otaServer.url;
std::string name = (otaServer.name.empty()) ? url : otaServer.name;
if (!name.empty()) {
auto &menuitem = constructMenuItem<BuildserverMenuItem>();
menuitem.setBuildserverName(name);
menuitem.setBuildserverUrl(url);
}
}
if (menuItemCount() < 1)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
} // namespace

View File

@ -0,0 +1,94 @@
#include "settingsmenu.h"
// Arduino includes
#include <Arduino.h>
// 3rdparty lib includes
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
// local includes
#include "utils.h"
#include "icons/wifi.h"
#if defined(FEATURE_BLUETOOTH) || defined(FEATURE_BLE)
#include "icons/bluetooth.h"
#endif
#include "icons/time.h"
#include "icons/hardware.h"
#include "icons/buzzer.h"
#include "icons/info.h"
#include "icons/demos.h"
#include "icons/update.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
#include "displays/menus/limitssettingsmenu.h"
#include "displays/menus/wifisettingsmenu.h"
#include "displays/menus/bluetoothsettingsmenu.h"
#include "displays/menus/blesettingsmenu.h"
#include "displays/menus/cloudsettingsmenu.h"
#include "displays/menus/selectbuildservermenu.h"
#include "displays/menus/timesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h"
#include "displays/menus/controllerhardwaresettingsmenu.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
#include "displays/menus/buzzermenu.h"
#include "displays/menus/crashmenu.h"
#include "displays/menus/aboutmenu.h"
#include "displays/menus/mainmenu.h"
namespace {
#ifdef FEATURE_LEDBACKLIGHT
struct BacklightAccessor : public virtual espgui::AccessorInterface<bool>
{
bool getValue() const override { return digitalRead(PINS_LEDBACKLIGHT) != ledBacklightInverted; }
void setValue(bool value) override { digitalWrite(PINS_LEDBACKLIGHT, value != ledBacklightInverted); }
};
#endif
struct FrontLedAccessor : public espgui::RefAccessor<bool> { bool &getRef() const override { return controllers.front.command.led; } };
struct BackLedAccessor : public espgui::RefAccessor<bool> { bool &getRef() const override { return controllers.back.command.led; } };
} // namespace
using namespace espgui;
SettingsMenu::SettingsMenu()
{
#ifdef FEATURE_LEDBACKLIGHT
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLIGHT>, ToggleBoolAction, CheckboxIcon, BacklightAccessor>>();
#endif
if (!simplified)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#ifdef FEATURE_BLUETOOTH
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_BLE
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLESETTINGS>, SwitchScreenAction<BleSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_CLOUD
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDSETTINGS>, SwitchScreenAction<CloudSettingsMenu>>>();
#endif
#ifdef FEATURE_OTA
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>, StaticMenuItemIcon<&bobbyicons::update>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIME>, SwitchScreenAction<TimeSettingsMenu>, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CONTROLLERHARDWARESETTINGS>, SwitchScreenAction<ControllerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, ToggleBoolAction, CheckboxIcon, AutoConnectBmsAccessor>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&bobbyicons::buzzer>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, ToggleBoolAction, CheckboxIcon, FrontLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLED>, ToggleBoolAction, CheckboxIcon, BackLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CRASHMENU>, SwitchScreenAction<CrashMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ABOUT>, SwitchScreenAction<AboutMenu>, StaticMenuItemIcon<&bobbyicons::info>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void SettingsMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,98 +1,17 @@
#pragma once #pragma once
// local includes // 3rdparty lib includes
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h"
#include "actions/toggleboolaction.h" // local includes
#include "actions/switchscreenaction.h"
#include "checkboxicon.h"
#include "icons/wifi.h"
#if defined(FEATURE_BLUETOOTH) || defined(FEATURE_BLE)
#include "icons/bluetooth.h"
#endif
#include "icons/time.h"
#include "icons/hardware.h"
#include "icons/buzzer.h"
#include "icons/info.h"
#include "icons/demos.h"
#include "icons/back.h"
#include "icons/update.h"
#include "texts.h" #include "texts.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class LimitsSettingsMenu;
class WifiSettingsMenu;
class BluetoothSettingsMenu;
class BleSettingsMenu;
class CloudSettingsMenu;
class TimeSettingsMenu;
class ModesSettingsMenu;
class ControllerHardwareSettingsMenu;
class BoardcomputerHardwareSettingsMenu;
class BuzzerMenu;
class AboutMenu;
class MainMenu;
class CrashMenu;
class SelectBuildServerMenu;
}
using namespace espgui;
namespace {
#ifdef FEATURE_LEDBACKLIGHT
struct BacklightAccessor : public virtual AccessorInterface<bool>
{
bool getValue() const override { return digitalRead(PINS_LEDBACKLIGHT) != ledBacklightInverted; }
void setValue(bool value) override { digitalWrite(PINS_LEDBACKLIGHT, value != ledBacklightInverted); }
};
#endif
struct FrontLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return controllers.front.command.led; } };
struct BackLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return controllers.back.command.led; } };
class SettingsMenu : class SettingsMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_SETTINGS>, public espgui::StaticText<TEXT_SETTINGS>
public BackActionInterface<SwitchScreenAction<MainMenu>>
{ {
public: public:
SettingsMenu() SettingsMenu();
{
#ifdef FEATURE_LEDBACKLIGHT void back() override;
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLIGHT>, ToggleBoolAction, CheckboxIcon, BacklightAccessor>>();
#endif
if (!simplified)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#ifdef FEATURE_BLUETOOTH
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_BLE
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLESETTINGS>, SwitchScreenAction<BleSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_CLOUD
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDSETTINGS>, SwitchScreenAction<CloudSettingsMenu>>>();
#endif
#ifdef FEATURE_OTA
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>, StaticMenuItemIcon<&bobbyicons::update>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIME>, SwitchScreenAction<TimeSettingsMenu>, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CONTROLLERHARDWARESETTINGS>, SwitchScreenAction<ControllerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, ToggleBoolAction, CheckboxIcon, AutoConnectBmsAccessor>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&bobbyicons::buzzer>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, ToggleBoolAction, CheckboxIcon, FrontLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLED>, ToggleBoolAction, CheckboxIcon, BackLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CRASHMENU>, SwitchScreenAction<CrashMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ABOUT>, SwitchScreenAction<AboutMenu>, StaticMenuItemIcon<&bobbyicons::info>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
} // namespace

View File

@ -9,11 +9,6 @@
#include "texts.h" #include "texts.h"
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -18,12 +18,6 @@
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
#include "espstrutils.h" #include "espstrutils.h"
// forward declares
namespace {
class SettingsMenu;
class TimeSettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -7,14 +7,6 @@
#include "icons/back.h" #include "icons/back.h"
#include "texts.h" #include "texts.h"
// forward declares
namespace {
class GenericWifiSettingsMenu;
class StationWifiSettingsMenu;
class AccessPointWifiSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui; using namespace espgui;
namespace { namespace {

View File

@ -0,0 +1,70 @@
#include "metersdisplay.h"
// 3rdparty lib includes
#include <tftinstance.h>
#include <fmt/core.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "displays/menus/mainmenu.h"
#include "displays/statusdisplay.h"
#include "displays/bmsdisplay.h"
using namespace espgui;
void MetersDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
m_vuMeter.start();
m_dischargingBar.start();
m_chargingBar.start();
m_sumCurrentLabel.start();
for (auto &meter : meters)
meter.start();
}
void MetersDisplay::redraw()
{
m_vuMeter.redraw(avgSpeedKmh);
m_dischargingBar.redraw(sumCurrent<0.f?(-sumCurrent):0.f);
m_chargingBar.redraw(sumCurrent>0.f?sumCurrent:0.f);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_sumCurrentLabel.redraw(fmt::format("{:.02f}A", sumCurrent));
meters[0].redraw(controllers.front.getCalibratedVoltage(), 35, 50);
meters[1].redraw(controllers.back.getCalibratedVoltage(), 35, 50);
meters[2].redraw(fixCurrent(controllers.front.feedback.left.dcLink), -10, 10);
meters[3].redraw(fixCurrent(controllers.front.feedback.right.dcLink), -10, 10);
meters[4].redraw(fixCurrent(controllers.back.feedback.left.dcLink), -10, 10);
meters[5].redraw(fixCurrent(controllers.back.feedback.right.dcLink), -10, 10);
}
void MetersDisplay::confirm()
{
switchScreen<MainMenu>();
}
void MetersDisplay::back()
{
switchScreen<MainMenu>();
}
void MetersDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<StatusDisplay>();
else if (offset > 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<StatusDisplay>();
#endif
}

View File

@ -1,96 +1,43 @@
#pragma once #pragma once
// system includes
#include <array> #include <array>
#include <Arduino.h> // 3rdparty lib includes
#include <display.h>
#include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/reverseprogressbar.h>
#include <widgets/progressbar.h>
#include <widgets/verticalmeter.h>
#include <widgets/vumeter.h>
#include "display.h" class MetersDisplay :
#include "actions/switchscreenaction.h" public espgui::Display
#include "globals.h"
#include "utils.h"
#include "widgets/label.h"
#include "widgets/reverseprogressbar.h"
#include "widgets/progressbar.h"
#include "widgets/verticalmeter.h"
#include "widgets/vumeter.h"
namespace {
class MainMenu;
class StatusDisplay;
class BmsDisplay;
}
namespace {
class MetersDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public BackActionInterface<SwitchScreenAction<MainMenu>>
{ {
public: public:
void initScreen() override; void initScreen() override;
void redraw() override; void redraw() override;
void confirm() override;
void back() override;
void rotate(int offset) override; void rotate(int offset) override;
private: private:
VuMeter m_vuMeter; espgui::VuMeter m_vuMeter;
ReverseProgressBar m_dischargingBar{10, 135, 90, 15, 0, 40, TFT_GREEN}; espgui::ReverseProgressBar m_dischargingBar{10, 135, 90, 15, 0, 40, TFT_GREEN};
ProgressBar m_chargingBar{100, 135, 90, 15, 0, 40, TFT_RED}; espgui::ProgressBar m_chargingBar{100, 135, 90, 15, 0, 40, TFT_RED};
Label m_sumCurrentLabel{195,135}; espgui::Label m_sumCurrentLabel{195,135};
static constexpr auto x = 40; static constexpr auto x = 40;
std::array<VerticalMeter, 6> meters{{ std::array<espgui::VerticalMeter, 6> meters{{
VerticalMeter{"U f", "%.1f", 0*x, 160}, espgui::VerticalMeter{"U f", "%.1f", 0*x, 160},
VerticalMeter{"U b", "%.1f", 1*x, 160}, espgui::VerticalMeter{"U b", "%.1f", 1*x, 160},
VerticalMeter{"Ibl", "%.1f", 2*x, 160}, espgui::VerticalMeter{"Ibl", "%.1f", 2*x, 160},
VerticalMeter{"Ibr", "%.1f", 3*x, 160}, espgui::VerticalMeter{"Ibr", "%.1f", 3*x, 160},
VerticalMeter{"Ihl", "%.1f", 4*x, 160}, espgui::VerticalMeter{"Ihl", "%.1f", 4*x, 160},
VerticalMeter{"Ihr", "%.1f", 5*x, 160} espgui::VerticalMeter{"Ihr", "%.1f", 5*x, 160}
}}; }};
}; };
void MetersDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
m_vuMeter.start();
m_dischargingBar.start();
m_chargingBar.start();
m_sumCurrentLabel.start();
for (auto &meter : meters)
meter.start();
}
void MetersDisplay::redraw()
{
m_vuMeter.redraw(avgSpeedKmh);
m_dischargingBar.redraw(sumCurrent<0.f?(-sumCurrent):0.f);
m_chargingBar.redraw(sumCurrent>0.f?sumCurrent:0.f);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_sumCurrentLabel.redraw(std::to_string(sumCurrent) + 'A');
meters[0].redraw(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration), 35, 50);
meters[1].redraw(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration), 35, 50);
meters[2].redraw(fixCurrent(controllers.front.feedback.left.dcLink), -10, 10);
meters[3].redraw(fixCurrent(controllers.front.feedback.right.dcLink), -10, 10);
meters[4].redraw(fixCurrent(controllers.back.feedback.left.dcLink), -10, 10);
meters[5].redraw(fixCurrent(controllers.back.feedback.right.dcLink), -10, 10);
}
void MetersDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<StatusDisplay>();
else if (offset > 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<StatusDisplay>();
#endif
}
}

View File

@ -9,11 +9,6 @@
#include "globals.h" #include "globals.h"
#include "widgets/label.h" #include "widgets/label.h"
namespace {
class MainMenu;
class MetersDisplay;
class StatusDisplay;
}
namespace { namespace {
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY) #if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
class PowerSupplyDisplay : public Display, public DummyConfirm, public BackActionInterface<SwitchScreenAction<MainMenu>> class PowerSupplyDisplay : public Display, public DummyConfirm, public BackActionInterface<SwitchScreenAction<MainMenu>>

View File

@ -0,0 +1,261 @@
#include "statusdisplay.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <espwifistack.h>
#include <tftinstance.h>
// local includes
#include "displays/menus/mainmenu.h"
#ifdef FEATURE_BMS
#include "displays/bmsdisplay.h"
#else
#include "displays/metersdisplay.h"
#endif
using namespace espgui;
void StatusDisplay::initScreen()
{
Base::initScreen();
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
tft.drawString("gas", 0, 0);
m_labelRawGas.start();
m_labelGas.start();
m_progressBarGas.start();
tft.drawString("brems", 0, 15);
m_labelRawBrems.start();
m_labelBrems.start();
m_progressBarBrems.start();
m_batterypercent.start();
m_watthoursleft.start();
m_kilometersleft.start();
m_frontStatus.start();
m_backStatus.start();
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Lim0:", 173, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
m_labelSignal.start();
tft.drawString("Lim1:", 173, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Perf:", 0, bottomLines[2]);
m_labelPerformance.start();
m_labelFreeMem.start();
tft.drawString("Mode:", 125, bottomLines[2]);
m_labelMode.start();
tft.drawString("Name:", 0, bottomLines[3]);
m_labelName.start();
m_labelProfile.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
void StatusDisplay::redraw()
{
Base::redraw();
tft.setTextFont(2);
m_labelRawGas.redraw(raw_gas ? std::to_string(*raw_gas) : "?");
m_labelGas.redraw(gas ? fmt::format("{:.2f}", *gas) : "?");
m_progressBarGas.redraw(gas ? *gas : 0);
m_labelRawBrems.redraw(raw_brems ? std::to_string(*raw_brems) : "?");
m_labelBrems.redraw(brems ? fmt::format("{:.2f}", *brems) : "?");
m_progressBarBrems.redraw(brems ? *brems : 0);
m_batterypercent.redraw(getBatteryPercentageString());
m_watthoursleft.redraw(getBatteryRemainingWattHoursString());
m_kilometersleft.redraw(getRemainingRangeString());
m_frontStatus.redraw(controllers.front);
m_backStatus.redraw(controllers.back);
tft.setTextFont(2);
const auto staStatus = wifi_stack::get_sta_status();
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_sta_ap_info(); result)
{
m_labelWifiStatus.redraw(std::string_view{reinterpret_cast<const char*>(result->ssid)});
tft.setTextColor(result->rssi < -80 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelSignal.redraw(fmt::format("{}dB", result->rssi));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
ESP_LOGW("BOBBY", "get_sta_ap_info() failed with %.*s", result.error().size(), result.error().data());
goto showStaStatus;
}
}
else
{
showStaStatus:
m_labelWifiStatus.redraw(wifi_stack::toString(staStatus));
m_labelSignal.clear();
}
m_labelLimit0.redraw(fmt::format("{}A", controllers.front.command.left.iMotMax));
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result)
m_labelIpAddress.redraw(wifi_stack::toString(result->ip));
else
{
ESP_LOGW("BOBBY", "get_ip_info() failed with %.*s", result.error().size(), result.error().data());
goto clearIp;
}
}
else
{
clearIp:
m_labelIpAddress.clear();
}
m_labelLimit1.redraw(fmt::format("{}A", controllers.front.command.left.iDcMax));
tft.setTextColor(performance.last < 35 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelPerformance.redraw(std::to_string(performance.last));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
{
const auto freeMem = heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
tft.setTextColor(freeMem < 70000 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelFreeMem.redraw(fmt::format("{}K", freeMem/1000));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
m_labelMode.redraw(currentMode->displayName());
m_labelName.redraw(deviceName);
const auto profile = settingsPersister.currentlyOpenProfileIndex();
m_labelProfile.redraw(profile ? std::to_string(*profile) : "-");
}
void StatusDisplay::confirm()
{
switchScreen<MainMenu>();
}
void StatusDisplay::rotate(int offset)
{
Base::rotate(offset);
if (offset < 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<MetersDisplay>();
#endif
else if (offset > 0)
switchScreen<MetersDisplay>();
}
StatusDisplay::BoardStatus::BoardStatus(int y) :
m_y{y},
m_labelLeftPwm{65, y}, // 80, 22
m_labelRightPwm{155, y}, // 80, 22
m_labelVoltage{30, y+25}, // 85, 22
m_labelTemperature{150, y+25}, // 85, 22
m_leftMotor{y+50},
m_rightMotor{y+75}
{}
void StatusDisplay::BoardStatus::start()
{
tft.setTextFont(4);
tft.drawString("pwm:", 0, m_y);
m_labelLeftPwm.start();
m_labelRightPwm.start();
m_initialRedraw = true;
}
void StatusDisplay::BoardStatus::redraw(const Controller &controller)
{
tft.setTextFont(4);
m_labelLeftPwm.redraw(std::to_string(controller.command.left.pwm));
m_labelRightPwm.redraw(std::to_string(controller.command.right.pwm));
if (controller.feedbackValid != m_lastFeedbackValid || m_initialRedraw)
{
tft.fillRect(0, m_y+25, tft.width(), 75, TFT_BLACK);
if (controller.feedbackValid)
{
tft.setTextColor(TFT_WHITE);
tft.drawString("U=", 0, m_y+25, 4);
m_labelVoltage.start();
tft.drawString("T=", 120, m_y+25, 4);
m_labelTemperature.start();
tft.drawString("l:", 0, m_y+50, 4);
m_leftMotor.start();
tft.drawString("r:", 0, m_y+75, 4);
m_rightMotor.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
tft.setTextColor(TFT_RED);
tft.drawString("No data!", 60, m_y+50, 4);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setSwapBytes(true);
tft.pushImage(10, m_y+40, bobbyicons::alert.WIDTH, bobbyicons::alert.HEIGHT, bobbyicons::alert.buffer);
tft.setSwapBytes(false);
}
m_lastFeedbackValid = controller.feedbackValid;
m_initialRedraw = false;
}
if (controller.feedbackValid)
{
m_labelVoltage.redraw(fmt::format("{:.2f}V", controller.getCalibratedVoltage()));
m_labelTemperature.redraw(fmt::format("{:.2f}C", fixBoardTemp(controller.feedback.boardTemp)));
m_leftMotor.redraw(controller.feedback.left);
m_rightMotor.redraw(controller.feedback.right);
}
}
StatusDisplay::BoardStatus::MotorStatus::MotorStatus(int y) :
m_labelError{18, y}, // 18, 22,
m_labelCurrent{40, y}, // 85, 22
m_labelSpeed{135, y}, // 75, 22
m_labelHallSensors{210, y} // 30, 15
{}
void StatusDisplay::BoardStatus::MotorStatus::start()
{
m_labelError.start();
m_labelCurrent.start();
m_labelSpeed.start();
m_labelHallSensors.start();
}
void StatusDisplay::BoardStatus::MotorStatus::redraw(const bobbycar::protocol::serial::MotorFeedback &motor)
{
tft.setTextFont(4);
tft.setTextColor(motor.error?TFT_RED:TFT_GREEN, TFT_BLACK);
m_labelError.redraw(std::to_string(motor.error));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labelCurrent.redraw(fmt::format("{:.2f}A", fixCurrent(motor.dcLink)));
m_labelSpeed.redraw(fmt::format("{:.2f}", convertToKmh(motor.speed)));
tft.setTextFont(2);
m_labelHallSensors.redraw(hallString(motor));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}

View File

@ -4,51 +4,36 @@
#include <esp_heap_caps.h> #include <esp_heap_caps.h>
// 3rdparty lib includes // 3rdparty lib includes
#include <fmt/core.h> #include <display.h>
#include <espwifistack.h> #include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/progressbar.h>
// local includes // local includes
#include "display.h"
#include "actions/switchscreenaction.h"
#include "modeinterface.h" #include "modeinterface.h"
#include "globals.h" #include "globals.h"
#include "utils.h" #include "utils.h"
#include "widgets/label.h"
#include "widgets/progressbar.h"
#include "icons/alert.h" #include "icons/alert.h"
#include "battery.h" #include "battery.h"
// forward declares class StatusDisplay :
namespace { public espgui::Display,
class MainMenu; public espgui::DummyBack
class BmsDisplay;
class MetersDisplay;
static uint16_t counter = 24;
}
namespace {
class StatusDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack
{ {
using Base = espgui::Display;
public: public:
void initScreen() override; void initScreen() override;
void redraw() override; void redraw() override;
void confirm() override;
void rotate(int offset) override; void rotate(int offset) override;
private: private:
class BoardStatus class BoardStatus
{ {
public: public:
BoardStatus(int y) : BoardStatus(int y);
m_y{y},
m_labelLeftPwm{65, y}, // 80, 22
m_labelRightPwm{155, y}, // 80, 22
m_labelVoltage{30, y+25}, // 85, 22
m_labelTemperature{150, y+25}, // 85, 22
m_leftMotor{y+50},
m_rightMotor{y+75}
{}
void start(); void start();
void redraw(const Controller &controller); void redraw(const Controller &controller);
@ -57,21 +42,16 @@ private:
class MotorStatus class MotorStatus
{ {
public: public:
MotorStatus(int y) : MotorStatus(int y);
m_labelError{18, y}, // 18, 22,
m_labelCurrent{40, y}, // 85, 22
m_labelSpeed{135, y}, // 75, 22
m_labelHallSensors{210, y} // 30, 15
{}
void start(); void start();
void redraw(const bobbycar::protocol::serial::MotorFeedback &motor); void redraw(const bobbycar::protocol::serial::MotorFeedback &motor);
private: private:
Label m_labelError; espgui::Label m_labelError;
Label m_labelCurrent; espgui::Label m_labelCurrent;
Label m_labelSpeed; espgui::Label m_labelSpeed;
Label m_labelHallSensors; espgui::Label m_labelHallSensors;
}; };
const int m_y; const int m_y;
@ -79,268 +59,41 @@ private:
bool m_initialRedraw; bool m_initialRedraw;
bool m_lastFeedbackValid; bool m_lastFeedbackValid;
Label m_labelLeftPwm; espgui::Label m_labelLeftPwm;
Label m_labelRightPwm; espgui::Label m_labelRightPwm;
Label m_labelVoltage; espgui::Label m_labelVoltage;
Label m_labelTemperature; espgui::Label m_labelTemperature;
MotorStatus m_leftMotor; MotorStatus m_leftMotor;
MotorStatus m_rightMotor; MotorStatus m_rightMotor;
}; };
Label m_labelRawGas{45, 0}; // 40, 15 espgui::Label m_labelRawGas{45, 0}; // 40, 15
Label m_labelGas{90, 0}; // 60, 15 espgui::Label m_labelGas{90, 0}; // 60, 15
ProgressBar m_progressBarGas{150, 0, 90, 15, 0, 1000}; espgui::ProgressBar m_progressBarGas{150, 0, 90, 15, 0, 1000};
Label m_labelRawBrems{45, 15}; // 40, 15 espgui::Label m_labelRawBrems{45, 15}; // 40, 15
Label m_labelBrems{90, 15}; // 60, 15 espgui::Label m_labelBrems{90, 15}; // 60, 15
ProgressBar m_progressBarBrems{150, 15, 90, 15, 0, 1000}; espgui::ProgressBar m_progressBarBrems{150, 15, 90, 15, 0, 1000};
Label m_batterypercent{0, 30}; espgui::Label m_batterypercent{0, 30};
Label m_watthoursleft{110, 30}; espgui::Label m_watthoursleft{110, 30};
Label m_kilometersleft{175, 30}; espgui::Label m_kilometersleft{175, 30};
BoardStatus m_frontStatus{45}; BoardStatus m_frontStatus{45};
BoardStatus m_backStatus{145}; BoardStatus m_backStatus{145};
Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15 espgui::Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15
Label m_labelLimit0{205, bottomLines[0]}; // 35, 15 espgui::Label m_labelLimit0{205, bottomLines[0]}; // 35, 15
Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15 espgui::Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15
Label m_labelSignal{125, bottomLines[1]}; // 130, 15 espgui::Label m_labelSignal{125, bottomLines[1]}; // 130, 15
Label m_labelLimit1{205, bottomLines[1]}; // 35, 15 espgui::Label m_labelLimit1{205, bottomLines[1]}; // 35, 15
Label m_labelPerformance{40, bottomLines[2]}; // 40, 15 espgui::Label m_labelPerformance{40, bottomLines[2]}; // 40, 15
Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15 espgui::Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15
Label m_labelMode{165, bottomLines[2]}; // 75, 15 espgui::Label m_labelMode{165, bottomLines[2]}; // 75, 15
Label m_labelName{40, bottomLines[3]}; // 40, 15 espgui::Label m_labelName{40, bottomLines[3]}; // 40, 15
Label m_labelProfile{205, bottomLines[3]}; // 35, 15 espgui::Label m_labelProfile{205, bottomLines[3]}; // 35, 15
static const constexpr int bottomLines[4] { 251, 266, 281, 296 }; static const constexpr int bottomLines[4] { 251, 266, 281, 296 };
}; };
void StatusDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
tft.drawString("gas", 0, 0);
m_labelRawGas.start();
m_labelGas.start();
m_progressBarGas.start();
tft.drawString("brems", 0, 15);
m_labelRawBrems.start();
m_labelBrems.start();
m_progressBarBrems.start();
m_batterypercent.start();
m_watthoursleft.start();
m_kilometersleft.start();
m_frontStatus.start();
m_backStatus.start();
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Lim0:", 173, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
m_labelSignal.start();
tft.drawString("Lim1:", 173, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Perf:", 0, bottomLines[2]);
m_labelPerformance.start();
m_labelFreeMem.start();
tft.drawString("Mode:", 125, bottomLines[2]);
m_labelMode.start();
tft.drawString("Name:", 0, bottomLines[3]);
m_labelName.start();
m_labelProfile.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
counter = 0;
}
void StatusDisplay::redraw()
{
tft.setTextFont(2);
m_labelRawGas.redraw(raw_gas ? std::to_string(*raw_gas) : "?");
m_labelGas.redraw(gas ? fmt::format("{:.2f}", *gas) : "?");
m_progressBarGas.redraw(gas ? *gas : 0);
m_labelRawBrems.redraw(raw_brems ? std::to_string(*raw_brems) : "?");
m_labelBrems.redraw(brems ? fmt::format("{:.2f}", *brems) : "?");
m_progressBarBrems.redraw(brems ? *brems : 0);
if (counter < 1)
{
counter = 25;
m_batterypercent.redraw(getBatteryPercentageString());
m_watthoursleft.redraw(getBatteryRemainingWattHoursString());
m_kilometersleft.redraw(getRemainingRangeString());
}
else
counter--;
m_frontStatus.redraw(controllers.front);
m_backStatus.redraw(controllers.back);
tft.setTextFont(2);
const auto staStatus = wifi_stack::get_sta_status();
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_sta_ap_info(); result)
{
m_labelWifiStatus.redraw(std::string_view{reinterpret_cast<const char*>(result->ssid)});
tft.setTextColor(result->rssi < -80 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelSignal.redraw(fmt::format("{}dB", result->rssi));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
ESP_LOGW("BOBBY", "get_sta_ap_info() failed with %.*s", result.error().size(), result.error().data());
goto showStaStatus;
}
}
else
{
showStaStatus:
m_labelWifiStatus.redraw(wifi_stack::toString(staStatus));
m_labelSignal.clear();
}
m_labelLimit0.redraw(fmt::format("{}A", controllers.front.command.left.iMotMax));
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result)
m_labelIpAddress.redraw(wifi_stack::toString(result->ip));
else
{
ESP_LOGW("BOBBY", "get_ip_info() failed with %.*s", result.error().size(), result.error().data());
goto clearIp;
}
}
else
{
clearIp:
m_labelIpAddress.clear();
}
m_labelLimit1.redraw(fmt::format("{}A", controllers.front.command.left.iDcMax));
tft.setTextColor(performance.last < 35 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelPerformance.redraw(std::to_string(performance.last));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
{
const auto freeMem = heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
tft.setTextColor(freeMem < 70000 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelFreeMem.redraw(fmt::format("{}K", freeMem/1000));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
m_labelMode.redraw(currentMode->displayName());
m_labelName.redraw(deviceName);
const auto profile = settingsPersister.currentlyOpenProfileIndex();
m_labelProfile.redraw(profile ? std::to_string(*profile) : "-");
}
void StatusDisplay::rotate(int offset)
{
counter = 0;
if (offset < 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<MetersDisplay>();
#endif
else if (offset > 0)
switchScreen<MetersDisplay>();
}
void StatusDisplay::BoardStatus::start()
{
tft.setTextFont(4);
tft.drawString("pwm:", 0, m_y);
m_labelLeftPwm.start();
m_labelRightPwm.start();
m_initialRedraw = true;
}
void StatusDisplay::BoardStatus::redraw(const Controller &controller)
{
tft.setTextFont(4);
m_labelLeftPwm.redraw(std::to_string(controller.command.left.pwm));
m_labelRightPwm.redraw(std::to_string(controller.command.right.pwm));
if (controller.feedbackValid != m_lastFeedbackValid || m_initialRedraw)
{
tft.fillRect(0, m_y+25, tft.width(), 75, TFT_BLACK);
if (controller.feedbackValid)
{
tft.setTextColor(TFT_WHITE);
tft.drawString("U=", 0, m_y+25, 4);
m_labelVoltage.start();
tft.drawString("T=", 120, m_y+25, 4);
m_labelTemperature.start();
tft.drawString("l:", 0, m_y+50, 4);
m_leftMotor.start();
tft.drawString("r:", 0, m_y+75, 4);
m_rightMotor.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
tft.setTextColor(TFT_RED);
tft.drawString("No data!", 60, m_y+50, 4);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setSwapBytes(true);
tft.pushImage(10, m_y+40, bobbyicons::alert.WIDTH, bobbyicons::alert.HEIGHT, bobbyicons::alert.buffer);
tft.setSwapBytes(false);
}
m_lastFeedbackValid = controller.feedbackValid;
m_initialRedraw = false;
}
if (controller.feedbackValid)
{
m_labelVoltage.redraw(fmt::format("{:.2f}V", controller.getCalibratedVoltage(settings.battery.applyCalibration)));
m_labelTemperature.redraw(fmt::format("{:.2f}C", fixBoardTemp(controller.feedback.boardTemp)));
m_leftMotor.redraw(controller.feedback.left);
m_rightMotor.redraw(controller.feedback.right);
}
}
void StatusDisplay::BoardStatus::MotorStatus::start()
{
m_labelError.start();
m_labelCurrent.start();
m_labelSpeed.start();
m_labelHallSensors.start();
}
void StatusDisplay::BoardStatus::MotorStatus::redraw(const bobbycar::protocol::serial::MotorFeedback &motor)
{
tft.setTextFont(4);
tft.setTextColor(motor.error?TFT_RED:TFT_GREEN, TFT_BLACK);
m_labelError.redraw(std::to_string(motor.error));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labelCurrent.redraw(fmt::format("{:.2f}A", fixCurrent(motor.dcLink)));
m_labelSpeed.redraw(fmt::format("{:.2f}", convertToKmh(motor.speed)));
tft.setTextFont(2);
m_labelHallSensors.redraw(hallString(motor));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
}

View File

@ -20,98 +20,6 @@ using namespace std::chrono_literals;
#include "bobbycar-serial.h" #include "bobbycar-serial.h"
#include "macros_bobbycar.h" #include "macros_bobbycar.h"
#include "globals.h" #include "globals.h"
#include "modes/defaultmode.h"
#include "modes/tempomatmode.h"
#include "displays/menus/aboutmenu.h"
#include "displays/menus/accesspointwifisettingsmenu.h"
#ifdef FEATURE_BLUETOOTH
#include "displays/menus/bluetoothsettingsmenu.h"
#endif
#ifdef FEATURE_BLE
#include "displays/menus/blesettingsmenu.h"
#endif
#ifdef FEATURE_CLOUD
#include "displays/menus/cloudsettingsmenu.h"
#endif
#ifdef FEATURE_BMS
#include "displays/menus/bmsmenu.h"
#endif
#include "displays/menus/buzzermenu.h"
#include "displays/menus/commanddebugmenu.h"
#include "displays/menus/crashmenu.h"
#include "displays/menus/debugmenu.h"
#include "displays/menus/defaultmodesettingsmenu.h"
#include "displays/menus/demosmenu.h"
#include "displays/menus/dynamicdebugmenu.h"
#include "displays/menus/enablemenu.h"
#include "displays/menus/feedbackdebugmenu.h"
#ifdef FEATURE_GAMETRAK
#include "displays/menus/gametrakmodesettingsmenu.h"
#endif
#include "displays/menus/genericwifisettingsmenu.h"
#include "displays/menus/graphsmenu.h"
#include "displays/menus/controllerhardwaresettingsmenu.h"
#include "displays/menus/invertmenu.h"
#include "displays/menus/larsmmodesettingsmenu.h"
#ifdef FEATURE_LEDSTRIP
#include "displays/menus/ledstripmenu.h"
#endif
#include "displays/menus/limitssettingsmenu.h"
#include "displays/menus/lockscreensettingsmenu.h"
#include "displays/menus/mainmenu.h"
#include "displays/menus/tempomatmodesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h"
#ifdef FEATURE_LEDSTRIP
#include "displays/ledstripcolorsdisplay.h"
#endif
#ifdef FEATURE_MOSFETS
#include "displays/menus/mosfetsmenu.h"
#endif
#include "displays/menus/motorfeedbackdebugmenu.h"
#include "displays/menus/motorstatedebugmenu.h"
#include "displays/menus/profilesmenu.h"
#include "displays/menus/presetsmenu.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/settingsmenu.h"
#include "displays/menus/stationwifisettingsmenu.h"
#include "displays/menus/timersmenu.h"
#include "displays/menus/timesettingsmenu.h"
#include "displays/menus/wifiscanmenu.h"
#include "displays/menus/wifisettingsmenu.h"
#ifdef FEATURE_BMS
#include "displays/bmsdisplay.h"
#endif
#include "displays/calibratedisplay.h"
#ifdef FEATURE_DPAD_5WIRESW
#include "displays/dpad5wiredebugdisplay.h"
#endif
#ifdef FEATURE_DPAD_5WIRESW_2OUT
#include "displays/dpad5wire2outdebugdisplay.h"
#endif
#ifdef FEATURE_DPAD_6WIRESW
#include "displays/dpad6wiredebugdisplay.h"
#endif
#include "displays/gameoflifedisplay.h"
#ifdef FEATURE_GARAGE
#include "displays/garagedisplay.h"
#endif
#ifdef FEATURE_LOCKSCREEN
#include "displays/gametrakcalibratedisplay.h"
#endif
#include "displays/lockscreen.h"
#include "displays/metersdisplay.h"
#include "displays/pingpongdisplay.h"
#include "displays/poweroffdisplay.h"
#include "displays/powersupplydisplay.h"
#include "displays/spirodisplay.h"
#include "displays/starfielddisplay.h"
#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 "screens.h"
#include "dpad.h" #include "dpad.h"
#ifdef FEATURE_DPAD_3WIRESW #ifdef FEATURE_DPAD_3WIRESW
@ -160,6 +68,9 @@ using namespace std::chrono_literals;
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
#include "ledstrip.h" #include "ledstrip.h"
#endif #endif
#include "modes/defaultmode.h"
#include "displays/statusdisplay.h"
#include "displays/calibratedisplay.h"
namespace { namespace {
std::optional<espchrono::millis_clock::time_point> lastWifiUpdate; std::optional<espchrono::millis_clock::time_point> lastWifiUpdate;
@ -362,9 +273,9 @@ extern "C" void app_main()
#else #else
if (!gas || !brems || *gas > 200.f || *brems > 200.f) if (!gas || !brems || *gas > 200.f || *brems > 200.f)
switchScreen<CalibrateDisplay>(true); espgui::switchScreen<CalibrateDisplay>(true);
else else
switchScreen<StatusDisplay>(); espgui::switchScreen<StatusDisplay>();
#endif #endif
while (true) while (true)

View File

@ -0,0 +1,93 @@
#include "screens.h"
// 3rdparty lib includes
#include <tftinstance.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "icons/logo.h"
#include "buttons.h"
using namespace espgui;
Label bootLabel{32, 250};
void initScreen()
{
tft.init();
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextFont(4);
tft.pushImage(0, 40, bobbyicons::logo.WIDTH, bobbyicons::logo.HEIGHT, bobbyicons::logo.buffer);
tft.drawString("Bobbycar-OS", 32, 200);
tft.drawString("booting...", 32, 225);
bootLabel.start();
}
void updateDisplay()
{
if (rotated)
{
const auto rotatedCopy = rotated;
rotated = 0;
if (currentDisplay)
currentDisplay->rotate(rotatedCopy);
}
if (requestFullRedraw)
{
requestFullRedraw = false;
tft.init();
if (currentDisplay)
currentDisplay->initScreen();
}
if (confirmButtonPressed)
{
confirmButtonPressed = false;
if (currentDisplay)
currentDisplay->confirm();
}
if (confirmButtonLongPressed)
{
confirmButtonLongPressed = false;
//Serial.println("todo: implement long press for confirm");
}
if (backButtonPressed)
{
backButtonPressed = false;
if (currentDisplay)
currentDisplay->back();
}
if (backButtonLongPressed)
{
backButtonLongPressed = false;
//Serial.println("todo: implement long press for back");
}
if (currentDisplay)
currentDisplay->update();
if (changeScreenCallback)
{
changeScreenCallback();
changeScreenCallback = {};
}
}
void redrawDisplay()
{
if (currentDisplay)
{
currentDisplay->redraw();
}
}

View File

@ -3,94 +3,12 @@
// system includes // system includes
#include <optional> #include <optional>
// local includes // 3rdparty lib includes
#include "globals.h" #include <widgets/label.h>
#include "utils.h" #include <screenmanager.h>
#include "widgets/label.h"
#include "icons/logo.h"
#include "screenmanager.h"
using namespace espgui; extern espgui::Label bootLabel;
namespace { void initScreen();
Label bootLabel{32, 250}; void updateDisplay();
void redrawDisplay();
void initScreen()
{
tft.init();
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextFont(4);
tft.pushImage(0, 40, bobbyicons::logo.WIDTH, bobbyicons::logo.HEIGHT, bobbyicons::logo.buffer);
tft.drawString("Bobbycar-OS", 32, 200);
tft.drawString("booting...", 32, 225);
bootLabel.start();
}
void updateDisplay()
{
if (rotated)
{
const auto rotatedCopy = rotated;
rotated = 0;
if (currentDisplay)
currentDisplay->rotate(rotatedCopy);
}
if (requestFullRedraw)
{
requestFullRedraw = false;
tft.init();
if (currentDisplay)
currentDisplay->initScreen();
}
if (confirmButtonPressed)
{
confirmButtonPressed = false;
if (currentDisplay)
currentDisplay->confirm();
}
if (confirmButtonLongPressed)
{
confirmButtonLongPressed = false;
//Serial.println("todo: implement long press for confirm");
}
if (backButtonPressed)
{
backButtonPressed = false;
if (currentDisplay)
currentDisplay->back();
}
if (backButtonLongPressed)
{
backButtonLongPressed = false;
//Serial.println("todo: implement long press for back");
}
if (currentDisplay)
currentDisplay->update();
if (changeScreenCallback)
{
changeScreenCallback();
changeScreenCallback = {};
}
}
void redrawDisplay()
{
if (currentDisplay)
{
currentDisplay->redraw();
}
}
}

View File

@ -0,0 +1,121 @@
#include "serialhandler.h"
// Arduino includes
#include <HardwareSerial.h>
// 3rdparty lib includes
#include <tftinstance.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "screens.h"
#include "buttons.h"
using namespace espgui;
//wl_status_t last_status;
//IPAddress last_ip;
void handleSerial()
{
//const auto status = WiFi.status();
//if (last_status != status)
//{
//Serial.print("Status changed to: ");
//Serial.println(to_string(status).c_str());
//last_status = status;
//}
//const auto ip = WiFi.localIP();
//if (last_ip != ip)
//{
//Serial.print("IP changed to: ");
//Serial.println(to_string(ip).c_str());
//last_ip = ip;
//}
while(Serial.available())
{
const auto c = Serial.read();
switch (c)
{
case 'i':
case 'I':
tft.init();
break;
case 'p':
case 'P':
{
const auto firstPower = controllers.front.command.poweroff;
for (Controller &controller : controllers)
controller.command.poweroff = !firstPower;
break;
}
case 'l':
case 'L':
{
const auto firstLed = controllers.front.command.led;
for (Controller &controller : controllers)
controller.command.led = !firstLed;
break;
}
case 'r':
case 'R':
loadSettings();
break;
case 's':
case 'S':
saveSettings();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (Controller &controller : controllers)
controller.command.buzzer.freq = c-'0';
break;
case 'A':
InputDispatcher::rotate(-1);
break;
case 'B':
InputDispatcher::rotate(1);
break;
case 'C':
InputDispatcher::confirmButton(true);
InputDispatcher::confirmButton(false);
break;
case 'D':
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

@ -1,115 +1,6 @@
#pragma once #pragma once
#include <HardwareSerial.h> //extern wl_status_t last_status;
//extern IPAddress last_ip;
#include "globals.h" void handleSerial();
#include "utils.h"
#include "screens.h"
namespace {
//wl_status_t last_status;
//IPAddress last_ip;
void handleSerial()
{
//const auto status = WiFi.status();
//if (last_status != status)
//{
//Serial.print("Status changed to: ");
//Serial.println(to_string(status).c_str());
//last_status = status;
//}
//const auto ip = WiFi.localIP();
//if (last_ip != ip)
//{
//Serial.print("IP changed to: ");
//Serial.println(to_string(ip).c_str());
//last_ip = ip;
//}
while(Serial.available())
{
const auto c = Serial.read();
switch (c)
{
case 'i':
case 'I':
tft.init();
break;
case 'p':
case 'P':
{
const auto firstPower = controllers.front.command.poweroff;
for (Controller &controller : controllers)
controller.command.poweroff = !firstPower;
break;
}
case 'l':
case 'L':
{
const auto firstLed = controllers.front.command.led;
for (Controller &controller : controllers)
controller.command.led = !firstLed;
break;
}
case 'r':
case 'R':
loadSettings();
break;
case 's':
case 'S':
saveSettings();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (Controller &controller : controllers)
controller.command.buzzer.freq = c-'0';
break;
case 'A':
InputDispatcher::rotate(-1);
break;
case 'B':
InputDispatcher::rotate(1);
break;
case 'C':
InputDispatcher::confirmButton(true);
InputDispatcher::confirmButton(false);
break;
case 'D':
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

@ -30,13 +30,13 @@ void pushStats()
statistics::sumCurrent.push_back(sumCurrent); statistics::sumCurrent.push_back(sumCurrent);
if (controllers.front.feedbackValid) if (controllers.front.feedbackValid)
{ {
statistics::frontVoltage.push_back(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration)); statistics::frontVoltage.push_back(controllers.front.getCalibratedVoltage());
statistics::frontLeftCurrent.push_back(fixCurrent(controllers.front.feedback.left.dcLink)); statistics::frontLeftCurrent.push_back(fixCurrent(controllers.front.feedback.left.dcLink));
statistics::frontRightCurrent.push_back(fixCurrent(controllers.front.feedback.right.dcLink)); statistics::frontRightCurrent.push_back(fixCurrent(controllers.front.feedback.right.dcLink));
} }
if (controllers.back.feedbackValid) if (controllers.back.feedbackValid)
{ {
statistics::backVoltage.push_back(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration)); statistics::backVoltage.push_back(controllers.back.getCalibratedVoltage());
statistics::backLeftCurrent.push_back(fixCurrent(controllers.back.feedback.left.dcLink)); statistics::backLeftCurrent.push_back(fixCurrent(controllers.back.feedback.left.dcLink));
statistics::backRightCurrent.push_back(fixCurrent(controllers.back.feedback.right.dcLink)); statistics::backRightCurrent.push_back(fixCurrent(controllers.back.feedback.right.dcLink));
} }

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
namespace {
//AboutMenu //AboutMenu
constexpr char TEXT_ABOUT[] = "About"; constexpr char TEXT_ABOUT[] = "About";
constexpr char TEXT_BACK[] = "Back"; constexpr char TEXT_BACK[] = "Back";
@ -498,4 +497,3 @@ constexpr char TEXT_LEDSTRIPCOLORMENU[] = "Customize Ledstrip";
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
constexpr char TEXT_POWERSUPPLY[] = "Powersupply"; constexpr char TEXT_POWERSUPPLY[] = "Powersupply";
#endif #endif
}

View File

@ -17,6 +17,7 @@
#include <changevaluedisplay.h> #include <changevaluedisplay.h>
#include <lockhelper.h> #include <lockhelper.h>
#include <tickchrono.h> #include <tickchrono.h>
#include <screenmanager.h>
// local includes // local includes
#include "buttons.h" #include "buttons.h"
@ -91,20 +92,20 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
"<a href=\"/triggerButton?button=profile3\">Profile3</a> "; "<a href=\"/triggerButton?button=profile3\">Profile3</a> ";
} }
if (auto constCurrentDisplay = static_cast<const Display *>(currentDisplay.get())) if (auto currentDisplay = static_cast<const espgui::Display *>(espgui::currentDisplay.get()))
{ {
if (const auto *textInterface = constCurrentDisplay->asTextInterface()) if (const auto *textInterface = currentDisplay->asTextInterface())
{ {
HtmlTag h2Tag{"h2", body}; HtmlTag h2Tag{"h2", body};
body += esphttpdutils::htmlentities(textInterface->text()); body += esphttpdutils::htmlentities(textInterface->text());
} }
if (const auto *menuDisplay = constCurrentDisplay->asMenuDisplay()) if (const auto *menuDisplay = currentDisplay->asMenuDisplay())
{ {
HtmlTag ulTag{"ul", body}; HtmlTag ulTag{"ul", body};
int i{0}; int i{0};
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const MenuItem &menuItem){ menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const espgui::MenuItem &menuItem){
HtmlTag liTag = i == selectedIndex ? HtmlTag liTag = i == selectedIndex ?
HtmlTag{"li", "style=\"border: 1px solid black;\"", body} : HtmlTag{"li", "style=\"border: 1px solid black;\"", body} :
HtmlTag{"li", body}; HtmlTag{"li", body};
@ -113,7 +114,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
i++; i++;
}); });
} }
else if (const auto *changeValueDisplay = constCurrentDisplay->asChangeValueDisplayInterface()) else if (const auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface())
{ {
HtmlTag formTag{"form", "action=\"/setValue\" method=\"GET\"", body}; HtmlTag formTag{"form", "action=\"/setValue\" method=\"GET\"", body};
body += fmt::format("<input type=\"number\" name=\"value\" value=\"{}\" />", changeValueDisplay->shownValue()); body += fmt::format("<input type=\"number\" name=\"value\" value=\"{}\" />", changeValueDisplay->shownValue());
@ -308,17 +309,17 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
} }
} }
if (!currentDisplay) if (!espgui::currentDisplay)
{ {
constexpr const std::string_view msg = "currentDisplay is null"; constexpr const std::string_view msg = "espgui::currentDisplay is null";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data()); ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
} }
auto *menuDisplay = currentDisplay->asMenuDisplay(); auto *menuDisplay = espgui::currentDisplay->asMenuDisplay();
if (!menuDisplay) if (!menuDisplay)
{ {
constexpr const std::string_view msg = "currentDisplay is not a menu display"; constexpr const std::string_view msg = "espgui::currentDisplay is not a menu display";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data()); ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
} }
@ -394,17 +395,17 @@ esp_err_t webserver_setValue_handler(httpd_req_t *req)
} }
} }
if (!currentDisplay) if (!espgui::currentDisplay)
{ {
constexpr const std::string_view msg = "currentDisplay is null"; constexpr const std::string_view msg = "espgui::currentDisplay is null";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data()); ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
} }
auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface(); auto *changeValueDisplay = espgui::currentDisplay->asChangeValueDisplayInterface();
if (!changeValueDisplay) if (!changeValueDisplay)
{ {
constexpr const std::string_view msg = "currentDisplay is not a change value display"; constexpr const std::string_view msg = "espgui::currentDisplay is not a change value display";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data()); ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
} }

View File

@ -5,6 +5,7 @@
#include <esp_http_server.h> #include <esp_http_server.h>
#endif #endif
#include <esp_log.h> #include <esp_log.h>
#include <esp_ota_ops.h>
// 3rdparty lib includes // 3rdparty lib includes
#include <htmlbuilder.h> #include <htmlbuilder.h>
@ -13,6 +14,7 @@
#include <esphttpdutils.h> #include <esphttpdutils.h>
#include <lockhelper.h> #include <lockhelper.h>
#include <tickchrono.h> #include <tickchrono.h>
#include <espstrutils.h>
// local includes // local includes
#ifdef FEATURE_OTA #ifdef FEATURE_OTA