Merge pull request #148 from bobbycar-graz/cpp-refactor

Refactoring and many new features!
This commit is contained in:
2021-12-18 00:46:51 +01:00
committed by GitHub
74 changed files with 1396 additions and 415 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ desktop.ini
/.idea /.idea
/.ccache /.ccache
/main/certs/* /main/certs/*
/.vscode/*

6
.gitmodules vendored
View File

@ -7,9 +7,6 @@
[submodule "components/cpputils"] [submodule "components/cpputils"]
path = components/cpputils path = components/cpputils
url = ../../0xFEEDC0DE64/cpputils.git url = ../../0xFEEDC0DE64/cpputils.git
[submodule "components/espcpputils"]
path = components/espcpputils
url = ../../0xFEEDC0DE64/espcpputils.git
[submodule "components/cxx-ring-buffer"] [submodule "components/cxx-ring-buffer"]
path = components/cxx-ring-buffer path = components/cxx-ring-buffer
url = ../../0xFEEDC0DE64/cxx-ring-buffer.git url = ../../0xFEEDC0DE64/cxx-ring-buffer.git
@ -61,3 +58,6 @@
[submodule "components/espconfiglib"] [submodule "components/espconfiglib"]
path = components/espconfiglib path = components/espconfiglib
url = ../../0xFEEDC0DE64/espconfiglib.git url = ../../0xFEEDC0DE64/espconfiglib.git
[submodule "components/TFT_eSPI_QRcode"]
path = components/TFT_eSPI_QRcode
url = ../TFT_eSPI_QRcode.git

View File

@ -118,6 +118,8 @@ set(BOBBYCAR_BUILDFLAGS
-DOLD_NVS -DOLD_NVS
-DFEATURE_DNS_NS -DFEATURE_DNS_NS
-DSWITCH_BLINK -DSWITCH_BLINK
# -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT
-DFEATURE_ESPNOW
) )
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ignore/lockscreen_plugin.cmake") if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ignore/lockscreen_plugin.cmake")

View File

@ -92,10 +92,13 @@ set(BOBBYCAR_BUILDFLAGS
-DFEATURE_LEDSTRIP -DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=26 -DPINS_LEDSTRIP=26
-DLEDSTRIP_LENGTH=200 -DLEDSTRIP_LENGTH=200
# -DHEAP_LRGST_CRASH_TEXT_FIX
# -DLEDSTRIP_WRONG_DIRECTION # -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=0 -DLEDSTRIP_ANIMATION_DEFAULT=0
-DLEDS_PER_METER=144 -DLEDS_PER_METER=144
-DOLD_NVS -DOLD_NVS
# -DFEATURE_DNS_NS # -DFEATURE_DNS_NS
# -DSWITCH_BLINK
-DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT
-DFEATURE_ESPNOW
) )

BIN
icons/greenpass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

View File

@ -77,10 +77,13 @@ set(headers
displays/menus/demosmenu.h displays/menus/demosmenu.h
displays/menus/dynamicdebugmenu.h displays/menus/dynamicdebugmenu.h
displays/menus/enablemenu.h displays/menus/enablemenu.h
displays/menus/espnowmenu.h
displays/menus/espnowsettingsmenu.h
displays/menus/feedbackdebugmenu.h displays/menus/feedbackdebugmenu.h
displays/menus/gametrakmodesettingsmenu.h displays/menus/gametrakmodesettingsmenu.h
displays/menus/genericwifisettingsmenu.h displays/menus/genericwifisettingsmenu.h
displays/menus/graphsmenu.h displays/menus/graphsmenu.h
displays/menus/greenpassmenu.h
displays/menus/handbremssettingsmenu.h displays/menus/handbremssettingsmenu.h
displays/menus/invertmenu.h displays/menus/invertmenu.h
displays/menus/larsmmodesettingsmenu.h displays/menus/larsmmodesettingsmenu.h
@ -117,6 +120,7 @@ set(headers
displays/popups/alertdisplay.h displays/popups/alertdisplay.h
displays/poweroffdisplay.h displays/poweroffdisplay.h
displays/powersupplydisplay.h displays/powersupplydisplay.h
displays/qrcodedebug.h
displays/spirodisplay.h displays/spirodisplay.h
displays/starfielddisplay.h displays/starfielddisplay.h
displays/statusdisplay.h displays/statusdisplay.h
@ -129,6 +133,7 @@ set(headers
dpad6wire.h dpad6wire.h
drivingstatistics.h drivingstatistics.h
esptexthelpers.h esptexthelpers.h
espnowfunctions.h
feedbackparser.h feedbackparser.h
globals.h globals.h
handbremse.h handbremse.h
@ -141,6 +146,7 @@ set(headers
icons/close.h icons/close.h
icons/demos.h icons/demos.h
icons/graph.h icons/graph.h
icons/greenpass.h
icons/hardware.h icons/hardware.h
icons/info.h icons/info.h
icons/lock.h icons/lock.h
@ -195,6 +201,7 @@ set(headers
webserver_settings.h webserver_settings.h
webserver_stringsettings.h webserver_stringsettings.h
widgets/doubleprogressbar.h widgets/doubleprogressbar.h
widgets/menudisplaywithtime.h
wifi_bobbycar.h wifi_bobbycar.h
wifitexthelpers.h wifitexthelpers.h
) )
@ -278,10 +285,13 @@ set(sources
displays/menus/demosmenu.cpp displays/menus/demosmenu.cpp
displays/menus/dynamicdebugmenu.cpp displays/menus/dynamicdebugmenu.cpp
displays/menus/enablemenu.cpp displays/menus/enablemenu.cpp
displays/menus/espnowmenu.cpp
displays/menus/espnowsettingsmenu.cpp
displays/menus/feedbackdebugmenu.cpp displays/menus/feedbackdebugmenu.cpp
displays/menus/gametrakmodesettingsmenu.cpp displays/menus/gametrakmodesettingsmenu.cpp
displays/menus/genericwifisettingsmenu.cpp displays/menus/genericwifisettingsmenu.cpp
displays/menus/graphsmenu.cpp displays/menus/graphsmenu.cpp
displays/menus/greenpassmenu.cpp
displays/menus/handbremssettingsmenu.cpp displays/menus/handbremssettingsmenu.cpp
displays/menus/invertmenu.cpp displays/menus/invertmenu.cpp
displays/menus/larsmmodesettingsmenu.cpp displays/menus/larsmmodesettingsmenu.cpp
@ -318,6 +328,7 @@ set(sources
displays/popups/alertdisplay.cpp displays/popups/alertdisplay.cpp
displays/poweroffdisplay.cpp displays/poweroffdisplay.cpp
displays/powersupplydisplay.cpp displays/powersupplydisplay.cpp
displays/qrcodedebug.cpp
displays/spirodisplay.cpp displays/spirodisplay.cpp
displays/starfielddisplay.cpp displays/starfielddisplay.cpp
displays/statusdisplay.cpp displays/statusdisplay.cpp
@ -330,6 +341,7 @@ set(sources
dpad6wire.cpp dpad6wire.cpp
drivingstatistics.cpp drivingstatistics.cpp
esptexthelpers.cpp esptexthelpers.cpp
espnowfunctions.cpp
feedbackparser.cpp feedbackparser.cpp
globals.cpp globals.cpp
handbremse.cpp handbremse.cpp
@ -342,6 +354,7 @@ set(sources
icons/close.cpp icons/close.cpp
icons/demos.cpp icons/demos.cpp
icons/graph.cpp icons/graph.cpp
icons/greenpass.cpp
icons/hardware.cpp icons/hardware.cpp
icons/info.cpp icons/info.cpp
icons/lock.cpp icons/lock.cpp
@ -397,13 +410,14 @@ set(sources
webserver_settings.cpp webserver_settings.cpp
webserver_stringsettings.cpp webserver_stringsettings.cpp
widgets/doubleprogressbar.cpp widgets/doubleprogressbar.cpp
widgets/menudisplaywithtime.cpp
wifi_bobbycar.cpp wifi_bobbycar.cpp
wifitexthelpers.cpp wifitexthelpers.cpp
) )
set(dependencies set(dependencies
libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver
arduino-esp32 ArduinoJson esp-nimble-cpp FastLED-idf TFT_eSPI arduino-esp32 ArduinoJson esp-nimble-cpp FastLED-idf TFT_eSPI TFT_eSPI_QRcode
bobbycar-protocol cpputils cxx-ring-buffer date bobbycar-protocol cpputils cxx-ring-buffer date
espasynchttpreq espasyncota espchrono espcpputils espconfiglib esp-gui-lib esphttpdutils espwifistack expected fmt espasynchttpreq espasyncota espchrono espcpputils espconfiglib esp-gui-lib esphttpdutils espwifistack expected fmt
) )

View File

@ -14,15 +14,19 @@ struct RefAccessorSaveSettings : public virtual espgui::RefAccessor<T>
void setValue(T value) override { espgui::RefAccessor<T>::setValue(value); saveSettings(); }; void setValue(T value) override { espgui::RefAccessor<T>::setValue(value); saveSettings(); };
}; };
// Bms
#ifdef FEATURE_BMS #ifdef FEATURE_BMS
struct AutoConnectBmsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.autoConnectBms; } }; struct AutoConnectBmsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.autoConnectBms; } };
#endif #endif
// Buzzer
struct ReverseBeepAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.buzzer.reverseBeep; } }; struct ReverseBeepAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.buzzer.reverseBeep; } };
struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq0; } }; struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq0; } };
struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq1; } }; struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq1; } };
struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration0; } }; struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration0; } };
struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration1; } }; struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration1; } };
// Limits
struct IMotMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iMotMax; } }; struct IMotMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iMotMax; } };
struct IDcMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iDcMax; } }; struct IDcMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iDcMax; } };
struct NMotMaxKmhAccessor : public virtual espgui::AccessorInterface<int16_t> struct NMotMaxKmhAccessor : public virtual espgui::AccessorInterface<int16_t>
@ -34,22 +38,27 @@ struct NMotMaxRpmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &g
struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } }; struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } };
struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } }; struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } };
// WiFi
struct WifiStaEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiStaEnabled; } }; struct WifiStaEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiStaEnabled; } };
struct WifiApEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiApEnabled; } }; struct WifiApEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiApEnabled; } };
// Bluetooth
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } }; struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } };
#endif #endif
// Bluetooth Low Energy
#ifdef FEATURE_BLE #ifdef FEATURE_BLE
struct BleEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.bleSettings.bleEnabled; } }; struct BleEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.bleSettings.bleEnabled; } };
#endif #endif
// Cloud
#ifdef FEATURE_CLOUD #ifdef FEATURE_CLOUD
struct CloudEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.cloudEnabled; } }; struct CloudEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.cloudEnabled; } };
struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } }; struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } };
#endif #endif
// Time
struct TimezoneOffsetAccessor : public virtual espgui::AccessorInterface<int32_t> struct TimezoneOffsetAccessor : public virtual espgui::AccessorInterface<int32_t>
{ {
int32_t getValue() const override { return settings.timeSettings.timezoneOffset.count(); } int32_t getValue() const override { return settings.timeSettings.timezoneOffset.count(); }
@ -66,6 +75,7 @@ struct TimeSyncIntervalAccessor : public virtual espgui::AccessorInterface<int32
}; };
#endif #endif
// Controller Hardware
struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } }; struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } };
struct FrontRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } }; struct FrontRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } };
struct BackLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } }; struct BackLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } };
@ -89,6 +99,8 @@ struct SwapFrontBackAccessor : public RefAccessorSaveSettings<bool> {
void setValue(bool value) override { RefAccessorSaveSettings<bool>::setValue(value); updateSwapFrontBack(); }; void setValue(bool value) override { RefAccessorSaveSettings<bool>::setValue(value); updateSwapFrontBack(); };
#endif #endif
}; };
// CAN
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } }; struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } };
struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } }; struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } };
@ -96,6 +108,7 @@ struct CanTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { in
struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } }; struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } };
#endif #endif
// Input devices
struct SampleCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } }; struct SampleCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } };
struct GasMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMin; } }; struct GasMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMin; } };
struct GasMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } }; struct GasMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } };
@ -117,9 +130,13 @@ struct ModeUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_
struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } }; struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } };
struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } }; struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } };
struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } }; struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } };
// CAN
#ifdef FEATURE_CAN #ifdef FEATURE_CAN
struct CanReceiveRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.canReceiveRate; } }; struct CanReceiveRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.canReceiveRate; } };
#endif #endif
// Cloud
#ifdef FEATURE_CLOUD #ifdef FEATURE_CLOUD
struct CloudCollectRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudCollectRate; } }; struct CloudCollectRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudCollectRate; } };
struct CloudSendRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudSendRate; } }; struct CloudSendRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudSendRate; } };
@ -129,6 +146,7 @@ struct CloudDebugEnableAccessor : public RefAccessorSaveSettings<bool> { bool &g
struct UdpUseStdStringAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.udpUseStdString; } }; struct UdpUseStdStringAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.udpUseStdString; } };
#endif #endif
// DefaultMode
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } }; struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } };
struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } }; struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } }; struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } };
@ -153,15 +171,19 @@ struct DefaultModeEnableHybridAccessor : public RefAccessorSaveSettings<bool> {
struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.activationLimit; } }; struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.activationLimit; } };
struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } }; struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } };
// TempomatMode
struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } }; struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } };
// LarsmMode
struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } }; struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } };
struct LarsmModeModeAccessor : public RefAccessorSaveSettings<LarsmModeMode> { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } }; struct LarsmModeModeAccessor : public RefAccessorSaveSettings<LarsmModeMode> { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } };
struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.larsmMode.iterations; } }; struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.larsmMode.iterations; } };
// MotortestMode
struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.motortestMode.multiplikator; } }; struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.motortestMode.multiplikator; } };
struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.motortestMode.maxPwm; } }; struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.motortestMode.maxPwm; } };
// Ledstrip
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
struct EnableLedAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableLedAnimation; } }; struct EnableLedAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableLedAnimation; } };
struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } }; struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } };
@ -190,13 +212,22 @@ struct BatteryParallelCellsAccessor : public RefAccessorSaveSettings<uint8_t> {
struct BatteryWHperKMAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } }; struct BatteryWHperKMAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } };
struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.battery.applyCalibration; } }; struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.battery.applyCalibration; } };
// Lockscreen
struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } }; struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } };
template<uint8_t index> template<uint8_t index>
struct LockscreenPinDigitAccessor : public RefAccessorSaveSettings<int8_t> { int8_t &getRef() const override { return settings.lockscreen.pin[index]; } }; struct LockscreenPinDigitAccessor : public RefAccessorSaveSettings<int8_t> { int8_t &getRef() const override { return settings.lockscreen.pin[index]; } };
struct LockscreenKeepLockedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.keepLockedAfterReboot; } };
// Handbremse
struct HandbremsEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.enable; } }; struct HandbremsEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.enable; } };
struct HandbremsModeAccessor : public RefAccessorSaveSettings<HandbremseMode> { HandbremseMode &getRef() const override { return settings.handbremse.mode; } }; struct HandbremsModeAccessor : public RefAccessorSaveSettings<HandbremseMode> { HandbremseMode &getRef() const override { return settings.handbremse.mode; } };
struct HandbremsTimeoutAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.handbremse.triggerTimeout; } }; struct HandbremsTimeoutAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.handbremse.triggerTimeout; } };
struct HandbremsAutomaticAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.automatic; } }; struct HandbremsAutomaticAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.automatic; } };
struct HandbremsVisualizeAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.visualize; } }; struct HandbremsVisualizeAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.visualize; } };
// ESP Now
#ifdef FEATURE_ESPNOW
struct ESPNowSyncTimeEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTime; } };
struct ESPNowSyncTimeWithOthersEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTimeWithOthers; } };
struct ESPNowSyncBlinkEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncBlink; } };
#endif

View File

@ -1,40 +1,14 @@
#pragma once #pragma once
#include "actioninterface.h" #include "actioninterface.h"
#include "utils.h"
#include "globals.h"
#include "ledstrip.h" #include "ledstrip.h"
// #include "ledstripdefines.h" // #include "ledstripdefines.h"
using namespace espgui;
namespace {
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
template<uint16_t type> template<uint16_t type>
class LedStripSetAnimationAction : public virtual ActionInterface class LedStripSetAnimationAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override { animation_type = type; } void triggered() override { animation_type = type; }
}; };
/*
class LedstripAnimationDefaultRainbowAction : public virtual ActionInterface
{
public:
void triggered() override { animation_type = LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW; }
};
class LedstripAnimationBetterRainbowAction : public virtual ActionInterface
{
public:
void triggered() override { animation_type = LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW; }
};
class LedstripAnimationSyncToSpeedAction : public virtual ActionInterface
{
public:
void triggered() override { animation_type = LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION; }
};
*/
#endif #endif
}

View File

@ -0,0 +1,42 @@
#include "ledstripblinkactions.h"
#ifdef FEATURE_LEDSTRIP
#include "ledstrip.h"
#include "ledstripdefines.h"
using namespace espgui;
void LedstripAnimationBlinkNoneAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_NONE;
}
#ifndef LEDSTRIP_WRONG_DIRECTION
void LedstripAnimationBlinkLeftAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT;
}
#else
void LedstripAnimationBlinkLeftAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT;
}
#endif
#ifndef LEDSTRIP_WRONG_DIRECTION
void LedstripAnimationBlinkRightAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT;
}
#else
void LedstripAnimationBlinkRightAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT;
}
#endif
void LedstripAnimationBlinkBothAction::triggered()
{
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH;
}
#endif

View File

@ -1,53 +1,37 @@
#pragma once #pragma once
#include "actioninterface.h"
#include "utils.h"
#include "globals.h"
#include "ledstrip.h"
#include "ledstripdefines.h"
using namespace espgui;
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
namespace { #include "actioninterface.h"
class LedstripAnimationBlinkNoneAction : public virtual ActionInterface
class LedstripAnimationBlinkNoneAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override { blinkAnimation = LEDSTRIP_OVERWRITE_NONE; } void triggered() override;
}; };
class LedstripAnimationBlinkLeftAction : public virtual ActionInterface class LedstripAnimationBlinkLeftAction : public virtual espgui::ActionInterface
{ {
public: public:
#ifndef LEDSTRIP_WRONG_DIRECTION #ifndef LEDSTRIP_WRONG_DIRECTION
void triggered() override { void triggered() override;
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT;
}
#else #else
void triggered() override { void triggered() override;
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT;
}
#endif #endif
}; };
class LedstripAnimationBlinkRightAction : public virtual ActionInterface class LedstripAnimationBlinkRightAction : public virtual espgui::ActionInterface
{ {
public: public:
#ifndef LEDSTRIP_WRONG_DIRECTION #ifndef LEDSTRIP_WRONG_DIRECTION
void triggered() override { void triggered() override;
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT;
}
#else #else
void triggered() override { void triggered() override;
blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT;
}
#endif #endif
}; };
class LedstripAnimationBlinkBothAction : public virtual ActionInterface class LedstripAnimationBlinkBothAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override { blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; } void triggered() override;
}; };
}
#endif #endif

View File

@ -12,7 +12,7 @@ class SwitchProfileAction : public virtual ActionInterface
public: public:
void triggered() override void triggered() override
{ {
switchProfile(index); settingsutils::switchProfile(index);
} }
}; };
} }

View File

@ -1,6 +1,8 @@
#include "buttons.h" #include "buttons.h"
#include "modes/defaultmode.h" #include "modes/defaultmode.h"
using namespace std::chrono_literals;
int rotated{}; int rotated{};
bool requestFullRedraw{}; bool requestFullRedraw{};
@ -123,7 +125,7 @@ void InputDispatcher::profileButton(uint8_t index, bool pressed)
if (profileButtonDisabled) if (profileButtonDisabled)
return; return;
switchProfile(index); settingsutils::switchProfile(index);
} }
#ifdef SWITCH_BLINK #ifdef SWITCH_BLINK

View File

@ -19,6 +19,8 @@
#include "globals.h" #include "globals.h"
#include "buttons.h" #include "buttons.h"
using namespace std::chrono_literals;
namespace can { namespace can {
namespace { namespace {
constexpr const char * const TAG = "BOBBYCAN"; constexpr const char * const TAG = "BOBBYCAN";

View File

@ -0,0 +1,105 @@
#include "bmsdisplay.h"
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
#include "displays/menus/mainmenu.h"
#include "displays/metersdisplay.h"
#include "displays/statusdisplay.h"
#include "screenmanager.h"
#include "tftinstance.h"
using namespace espgui;
void BmsDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_statusLabel.start();
m_statusLabel.redraw("init");
tft.setTextFont(4);
tft.drawString("Voltage:", 0, m_voltageLabel.y());
m_voltageLabel.start();
tft.drawString("Capacity:", 0, m_capacityLabel.y());
m_capacityLabel.start();
tft.drawString("SOC:", 0, m_socLabel.y());
m_socLabel.start();
tft.drawString("Power:", 0, m_powerLabel.y());
m_powerLabel.start();
tft.drawString("Current:", 0, m_currentLabel.y());
m_currentLabel.start();
tft.drawString("Speed:", 0, m_speedLabel.y());
m_speedLabel.start();
tft.drawString("PpS:", 0, m_powerPerSpeedLabel.y());
m_powerPerSpeedLabel.start();
for (auto &label : m_battLabels)
label.start();
tft.drawString("Cycle:", 0, m_cycleLabel.y());
m_cycleLabel.start();
}
void BmsDisplay::redraw()
{
if (bluetoothSerial.hasClient())
tft.setTextColor(TFT_GREEN, TFT_BLACK);
else
{
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextFont(2);
}
m_statusLabel.redraw(bluetoothSerial.hasClient() ? "OK" : "FAIL");
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (!bluetoothSerial.hasClient())
tft.setTextFont(4);
if (bluetoothSerial.hasClient())
{
m_voltageLabel.redraw(fmt::format("{:.02f}V", bms::voltage));
m_capacityLabel.redraw(fmt::format("{:.02f} mAh", bms::capacity));
m_socLabel.redraw(fmt::format("{:.02f}%", bms::soc));
m_powerLabel.redraw(fmt::format("{:.02f}W", bms::power));
m_currentLabel.redraw(fmt::format("{:.02f}A", bms::current));
}
else
{
m_voltageLabel.clear();
m_capacityLabel.clear();
m_socLabel.clear();
m_powerLabel.clear();
m_currentLabel.clear();
}
m_speedLabel.redraw(fmt::format("{:.02f}kmh", avgSpeedKmh));
if (bluetoothSerial.hasClient())
m_powerPerSpeedLabel.redraw(fmt::format("{:.02f}W/kmh", avgSpeedKmh < 1 ? 0 : bms::power / avgSpeedKmh));
else
m_powerPerSpeedLabel.clear();
for (int i = 0; i < 12; i++)
m_battLabels[i].redraw(fmt::format("{:.02f}", bms::batt[i]));
if (bluetoothSerial.hasClient())
m_cycleLabel.redraw(fmt::format("{:.02f}AH", bms::cycle));
else
m_cycleLabel.clear();
}
void BmsDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<MetersDisplay>();
else if (offset > 0)
switchScreen<StatusDisplay>();
}
void BmsDisplay::confirm()
{
switchScreen<MainMenu>();
}
#endif

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
// 3rdparty lib includes // 3rdparty lib includes
#include <fmt/core.h> #include <fmt/core.h>
@ -11,122 +12,32 @@
#include "widgets/label.h" #include "widgets/label.h"
#include "screenmanager.h" #include "screenmanager.h"
namespace { class BmsDisplay :
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS) public espgui::Display,
class BmsDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack public espgui::DummyBack
{ {
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;
Label m_statusLabel{200, 0}; espgui::Label m_statusLabel{200, 0};
Label m_voltageLabel{107, 0}; espgui::Label m_voltageLabel{107, 0};
Label m_capacityLabel{107, 25}; espgui::Label m_capacityLabel{107, 25};
Label m_socLabel{107, 50}; espgui::Label m_socLabel{107, 50};
Label m_powerLabel{107, 75}; espgui::Label m_powerLabel{107, 75};
Label m_currentLabel{107, 100}; espgui::Label m_currentLabel{107, 100};
Label m_speedLabel{107, 125}; espgui::Label m_speedLabel{107, 125};
Label m_powerPerSpeedLabel{107, 150}; espgui::Label m_powerPerSpeedLabel{107, 150};
std::array<Label, 12> m_battLabels{{ std::array<espgui::Label, 12> m_battLabels{{
Label{0, 225}, Label{60, 225}, Label{120, 225}, Label{180, 225}, espgui::Label{0, 225}, espgui::Label{60, 225}, espgui::Label{120, 225}, espgui::Label{180, 225},
Label{0, 250}, Label{60, 250}, Label{120, 250}, Label{180, 250}, espgui::Label{0, 250}, espgui::Label{60, 250}, espgui::Label{120, 250}, espgui::Label{180, 250},
Label{0, 275}, Label{60, 275}, Label{120, 275}, Label{180, 275} espgui::Label{0, 275}, espgui::Label{60, 275}, espgui::Label{120, 275}, espgui::Label{180, 275}
}}; }};
Label m_cycleLabel{105, 300}; espgui::Label m_cycleLabel{105, 300};
}; };
void BmsDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_statusLabel.start();
m_statusLabel.redraw("init");
tft.setTextFont(4);
tft.drawString("Voltage:", 0, m_voltageLabel.y());
m_voltageLabel.start();
tft.drawString("Capacity:", 0, m_capacityLabel.y());
m_capacityLabel.start();
tft.drawString("SOC:", 0, m_socLabel.y());
m_socLabel.start();
tft.drawString("Power:", 0, m_powerLabel.y());
m_powerLabel.start();
tft.drawString("Current:", 0, m_currentLabel.y());
m_currentLabel.start();
tft.drawString("Speed:", 0, m_speedLabel.y());
m_speedLabel.start();
tft.drawString("PpS:", 0, m_powerPerSpeedLabel.y());
m_powerPerSpeedLabel.start();
for (auto &label : m_battLabels)
label.start();
tft.drawString("Cycle:", 0, m_cycleLabel.y());
m_cycleLabel.start();
}
void BmsDisplay::redraw()
{
if (bluetoothSerial.hasClient())
tft.setTextColor(TFT_GREEN, TFT_BLACK);
else
{
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.setTextFont(2);
}
m_statusLabel.redraw(bluetoothSerial.hasClient() ? "OK" : "FAIL");
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (!bluetoothSerial.hasClient())
tft.setTextFont(4);
if (bluetoothSerial.hasClient())
{
m_voltageLabel.redraw(fmt::format("{:.02f}V", bms::voltage));
m_capacityLabel.redraw(fmt::format("{:.02f} mAh", bms::capacity));
m_socLabel.redraw(fmt::format("{:.02f}%", bms::soc));
m_powerLabel.redraw(fmt::format("{:.02f}W", bms::power));
m_currentLabel.redraw(fmt::format("{:.02f}A", bms::current));
}
else
{
m_voltageLabel.clear();
m_capacityLabel.clear();
m_socLabel.clear();
m_powerLabel.clear();
m_currentLabel.clear();
}
m_speedLabel.redraw(fmt::format("{:.02f}kmh", avgSpeedKmh));
if (bluetoothSerial.hasClient())
m_powerPerSpeedLabel.redraw(fmt::format("{:.02f}W/kmh", avgSpeedKmh < 1 ? 0 : bms::power / avgSpeedKmh));
else
m_powerPerSpeedLabel.clear();
for (int i = 0; i < 12; i++)
m_battLabels[i].redraw(fmt::format("{:.02f}", bms::batt[i]));
if (bluetoothSerial.hasClient())
m_cycleLabel.redraw(fmt::format("{:.02f}AH", bms::cycle));
else
m_cycleLabel.clear();
}
void BmsDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<MetersDisplay>();
else if (offset > 0)
switchScreen<StatusDisplay>();
}
#endif #endif
}

View File

@ -5,6 +5,7 @@
#include <screenmanager.h> #include <screenmanager.h>
// local includes // local includes
#include "displays/menus/mainmenu.h"
#include "displays/statusdisplay.h" #include "displays/statusdisplay.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h" #include "displays/menus/boardcomputerhardwaresettingsmenu.h"
@ -241,6 +242,12 @@ void CalibrateDisplay::back()
case Status::Begin: case Status::Begin:
if (m_bootup) if (m_bootup)
espgui::switchScreen<StatusDisplay>(); espgui::switchScreen<StatusDisplay>();
else if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
{
espgui::switchScreen<MainMenu>();
settings.lockscreen.locked = false;
saveSettings();
}
else else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>(); espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
break; break;

View File

@ -14,6 +14,7 @@
#include "displays/menus/mainmenu.h" #include "displays/menus/mainmenu.h"
#include "globals.h" #include "globals.h"
#include "texts.h" #include "texts.h"
#include "espnowfunctions.h"
#ifdef FEATURE_GARAGE #ifdef FEATURE_GARAGE
void GarageDisplay::start() void GarageDisplay::start()
@ -41,6 +42,14 @@ void GarageDisplay::redraw()
void GarageDisplay::confirm() void GarageDisplay::confirm()
{ {
#ifdef FEATURE_ESPNOW
if (const auto error = espnow::send_espnow_message(fmt::format("BOBBYOPEN:garage:{}", "TOKEN")); error != ESP_OK)
{
ESP_LOGE("BOBBY", "send_espnow_message() failed with: %s", esp_err_to_name(error));
return;
}
espgui::switchScreen<MainMenu>();
#endif
} }
void GarageDisplay::back() void GarageDisplay::back()

View File

@ -10,6 +10,7 @@
#include "texts.h" #include "texts.h"
#include "buttons.h" #include "buttons.h"
#include "displays/menus/mainmenu.h" #include "displays/menus/mainmenu.h"
#include "displays/calibratedisplay.h"
void Lockscreen::start() void Lockscreen::start()
{ {
@ -23,6 +24,11 @@ void Lockscreen::start()
profileButtonDisabled = !settings.lockscreen.allowPresetSwitch; profileButtonDisabled = !settings.lockscreen.allowPresetSwitch;
isLocked = true; isLocked = true;
if (settings.lockscreen.keepLockedAfterReboot && !settings.lockscreen.locked)
{
settings.lockscreen.locked = true;
saveSettings();
}
} }
void Lockscreen::initScreen() void Lockscreen::initScreen()
@ -64,16 +70,19 @@ void Lockscreen::update()
void Lockscreen::redraw() void Lockscreen::redraw()
{ {
if (m_pressed) if (m_pressed || m_back_pressed)
{ {
drawRect(m_currentIndex, 1, TFT_BLACK); drawRect(m_currentIndex, 1, TFT_BLACK);
drawRect(m_currentIndex, 2, TFT_BLACK); drawRect(m_currentIndex, 2, TFT_BLACK);
if (++m_currentIndex>=4) if (!m_back_pressed && ++m_currentIndex>=4)
{ {
if (m_numbers == settings.lockscreen.pin) if (m_numbers == settings.lockscreen.pin)
{ {
espgui::switchScreen<MainMenu>(); if (!gas || !brems || *gas > 200.f || *brems > 200.f)
espgui::switchScreen<CalibrateDisplay>(true);
else
espgui::switchScreen<MainMenu>();
#ifdef LOCKSCREEN_PLUGIN #ifdef LOCKSCREEN_PLUGIN
#pragma message "Activating Lockscreen Plugin" #pragma message "Activating Lockscreen Plugin"
#include LOCKSCREEN_PLUGIN #include LOCKSCREEN_PLUGIN
@ -83,7 +92,12 @@ void Lockscreen::redraw()
m_numbers = {0,0,0,0}; m_numbers = {0,0,0,0};
m_currentIndex = 0; m_currentIndex = 0;
std::for_each(std::begin(m_labels) + 1, std::end(m_labels), [](auto &label){ label.redraw({}); }); std::for_each(std::begin(m_labels) + 1, std::end(m_labels), [](auto &label){ label.redraw("0"); });
}
else if (m_back_pressed && m_currentIndex < 3)
{
drawRect(m_currentIndex+1, 1, TFT_BLACK);
drawRect(m_currentIndex+1, 2, TFT_BLACK);
} }
m_labels[m_currentIndex].redraw(std::to_string(m_numbers[m_currentIndex])); m_labels[m_currentIndex].redraw(std::to_string(m_numbers[m_currentIndex]));
@ -92,6 +106,7 @@ void Lockscreen::redraw()
drawRect(m_currentIndex, 2, TFT_YELLOW); drawRect(m_currentIndex, 2, TFT_YELLOW);
m_pressed = false; m_pressed = false;
m_back_pressed = false;
} }
if (m_rotated) if (m_rotated)
@ -124,6 +139,14 @@ void Lockscreen::stop()
profileButtonDisabled = false; profileButtonDisabled = false;
isLocked = false; isLocked = false;
if (!(!gas || !brems || *gas > 200.f || *brems > 200.f))
{
if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
{
settings.lockscreen.locked = false;
saveSettings();
}
}
} }
void Lockscreen::confirm() void Lockscreen::confirm()
@ -133,6 +156,9 @@ void Lockscreen::confirm()
void Lockscreen::back() void Lockscreen::back()
{ {
if (m_currentIndex > 0)
m_currentIndex--;
m_back_pressed = true;
} }
void Lockscreen::rotate(int offset) void Lockscreen::rotate(int offset)

View File

@ -46,6 +46,7 @@ private:
uint8_t m_currentIndex{}; uint8_t m_currentIndex{};
bool m_pressed; bool m_pressed;
bool m_back_pressed;
int m_rotated; int m_rotated;
ModeInterface *m_oldMode; ModeInterface *m_oldMode;

View File

@ -0,0 +1,33 @@
#include "accesspointwifisettingsmenu.h"
// local includes
#include "accessors/settingsaccessors.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "displays/menus/wifisettingsmenu.h"
#include "icons/back.h"
#include "menuitem.h"
#include "wifitexthelpers.h"
using namespace espgui;
AccessPointWifiSettingsMenu::AccessPointWifiSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFIAPENABLED>, ToggleBoolAction, CheckboxIcon, WifiApEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApGetStationNumText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApBroadcastIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApNetworkIdText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApSubnetCidrText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApIpV6Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApHostnameText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApMacAddressText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void AccessPointWifiSettingsMenu::back()
{
switchScreen<WifiSettingsMenu>();
}

View File

@ -2,37 +2,13 @@
// local includes // local includes
#include "menudisplay.h" #include "menudisplay.h"
#include "menuitem.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "wifitexthelpers.h"
#include "accessors/settingsaccessors.h"
#include "texts.h" #include "texts.h"
using namespace espgui;
namespace {
class AccessPointWifiSettingsMenu : class AccessPointWifiSettingsMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_ACCESSPOINTWIFISETTINGS>, public espgui::StaticText<TEXT_ACCESSPOINTWIFISETTINGS>
public BackActionInterface<SwitchScreenAction<WifiSettingsMenu>>
{ {
public: public:
AccessPointWifiSettingsMenu() AccessPointWifiSettingsMenu();
{ void back() override;
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFIAPENABLED>, ToggleBoolAction, CheckboxIcon, WifiApEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApGetStationNumText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApBroadcastIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApNetworkIdText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApSubnetCidrText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApIpV6Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApHostnameText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSoftApMacAddressText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
} // namespace

View File

@ -19,6 +19,7 @@
#include "icons/battery.h" #include "icons/battery.h"
#include "debugcolorhelpers.h" #include "debugcolorhelpers.h"
#include "esptexthelpers.h" #include "esptexthelpers.h"
#include "displays/qrcodedebug.h"
#include "displays/menus/commanddebugmenu.h" #include "displays/menus/commanddebugmenu.h"
#include "displays/menus/motorstatedebugmenu.h" #include "displays/menus/motorstatedebugmenu.h"
#include "displays/menus/feedbackdebugmenu.h" #include "displays/menus/feedbackdebugmenu.h"
@ -47,6 +48,7 @@ using namespace espgui;
DebugMenu::DebugMenu() DebugMenu::DebugMenu()
{ {
constructMenuItem<AlertAction>(); constructMenuItem<AlertAction>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_QRCODE_DEBUG>, SwitchScreenAction<QrCodeDebugDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>>();

View File

@ -0,0 +1,31 @@
#include "espnowmenu.h"
#ifdef FEATURE_ESPNOW
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "icons/settings.h"
#include "icons/time.h"
#include "displays/menus/espnowsettingsmenu.h"
#include "displays/menus/settingsmenu.h"
using namespace espgui;
namespace espnowmenu {
} // namespace
EspNowMenu::EspNowMenu() {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SENDTSMSG>, espnowmenu::SendBobbycarTimesyncMessageAction, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_RECEIVETS>, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTimeStampAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_RECEIVETSFROMBOBBY>, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTsFromOtherBobbycarsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SETTINGS>, SwitchScreenAction<EspNowSettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void EspNowMenu::back()
{
switchScreen<SettingsMenu>();
}
#endif

View File

@ -0,0 +1,42 @@
#pragma once
#ifdef FEATURE_ESPNOW
#include <accessorinterface.h>
#include <actioninterface.h>
#include <espchrono.h>
#include <fmt/core.h>
#include <menudisplay.h>
#include <textinterface.h>
#include <texts.h>
#include "espnowfunctions.h"
using namespace espgui;
namespace espnowmenu {
struct ReceiveTimeStampAccessor : public RefAccessor<bool> { bool &getRef() const override { return espnow::receiveTimeStamp; } };
struct ReceiveTsFromOtherBobbycarsAccessor : public RefAccessor<bool> { bool &getRef() const override { return espnow::receiveTsFromOtherBobbycars; } };
class SendBobbycarTimesyncMessageAction : public virtual ActionInterface {
public:
void triggered() override
{
const auto message = fmt::format("BOBBYT:{}", espchrono::utc_clock::now().time_since_epoch().count());
espnow::send_espnow_message(message);
}
};
} // namespace
class EspNowMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_ESPNOW_MENU>
{
public:
EspNowMenu();
void back() override;
};
#endif

View File

@ -0,0 +1,29 @@
#include "espnowsettingsmenu.h"
#ifdef FEATURE_ESPNOW
#include "accessors/settingsaccessors.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "icons/time.h"
#include "espnowmenu.h"
using namespace espgui;
namespace espnowsettingsmenu {
} // namespace
EspNowSettingsMenu::EspNowSettingsMenu() {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCTIME>, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCWITHOTHERS>, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeWithOthersEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCBLINK>, ToggleBoolAction, CheckboxIcon, ESPNowSyncBlinkEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<EspNowMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void EspNowSettingsMenu::back()
{
switchScreen<EspNowMenu>();
}
#endif

View File

@ -0,0 +1,29 @@
#pragma once
#ifdef FEATURE_ESPNOW
#include <accessorinterface.h>
#include <actioninterface.h>
#include <espchrono.h>
#include <fmt/core.h>
#include <menudisplay.h>
#include <textinterface.h>
#include <texts.h>
#include "espnowfunctions.h"
using namespace espgui;
namespace espnowsettingsmenu {
} // namespace
class EspNowSettingsMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_ESPNOW_SETTINGS>
{
public:
EspNowSettingsMenu();
void back() override;
};
#endif

View File

@ -10,6 +10,7 @@
#include "texts.h" #include "texts.h"
#include "debugtexthelpers.h" #include "debugtexthelpers.h"
#include "debugcolorhelpers.h" #include "debugcolorhelpers.h"
#include "displays/menus/debugmenu.h"
using namespace espgui; using namespace espgui;

View File

@ -0,0 +1,49 @@
#include "greenpassmenu.h"
#include <actioninterface.h>
// local includes
#include "actions/switchscreenaction.h"
#include "displays/menus/mainmenu.h"
#include "icons/back.h"
using namespace espgui;
namespace greenpassmenu {
bool showingQRCode{false};
} // namespace
void GreenPassMenu::ShowCertAction::triggered() {
greenpassmenu::showingQRCode = true;
m_qrcode.init();
m_qrcode.createScaleToFit("");
}
GreenPassMenu::GreenPassMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SHOWCERT>, ShowCertAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void GreenPassMenu::initScreen()
{
Base::initScreen();
greenpassmenu::showingQRCode = false;
}
void GreenPassMenu::rotate(int offset)
{
if (greenpassmenu::showingQRCode)
GreenPassMenu::initScreen();
Base::rotate(offset);
}
void GreenPassMenu::back()
{
if (greenpassmenu::showingQRCode)
{
GreenPassMenu::initScreen();
}
else
switchScreen<MainMenu>();
}

View File

@ -0,0 +1,30 @@
#pragma once
#include <qrcode.h>
// local includes
#include "menudisplay.h"
#include "texts.h"
namespace greenpassmenu {
extern bool showingQRCode;
} // namespace
class GreenPassMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_GREENPASS>
{
using Base = espgui::MenuDisplay;
public:
GreenPassMenu();
void back() override;
void rotate(int offset) override;
void initScreen() override;
class ShowCertAction : public virtual espgui::ActionInterface {
public:
void triggered() override;
private:
qrcode::QRcode m_qrcode{};
};
};

View File

@ -1,28 +1,30 @@
#include "ledstripmenu.h" #include "ledstripmenu.h"
#ifdef FEATURE_LEDSTRIP
// 3rdparty lib includes // 3rdparty lib includes
#include <FastLED.h> #include <FastLED.h>
#include "menuitem.h" #include <actioninterface.h>
#include "actions/toggleboolaction.h" #include <actions/switchscreenaction.h>
#include "actions/switchscreenaction.h" #include <actions/toggleboolaction.h>
#include "icons/back.h" #include <changevaluedisplay.h>
#include "checkboxicon.h" #include <checkboxicon.h>
#include "changevaluedisplay.h" #include <icons/back.h>
#include "actioninterface.h" #include <menuitem.h>
// local includes // local includes
#include "accessors/settingsaccessors.h"
#include "displays/ledstripcolorsdisplay.h"
#include "displays/menus/ledstripselectotamode.h"
#include "displays/menus/mainmenu.h"
#include "globals.h"
#include "ledstrip.h"
#include "ledstripselectanimationmenu.h" #include "ledstripselectanimationmenu.h"
#include "ledstripselectblinkmenu.h" #include "ledstripselectblinkmenu.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
#ifdef FEATURE_LEDSTRIP
#include "ledstrip.h"
#include "displays/menus/ledstripselectotamode.h"
#endif
#include "displays/ledstripcolorsdisplay.h"
#include "displays/menus/mainmenu.h"
#ifdef FEATURE_LEDSTRIP // clang-format off
using namespace espgui;
namespace { namespace {
using LedsCountChangeScreen = makeComponent< using LedsCountChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>, ChangeValueDisplay<int16_t>,
@ -109,8 +111,6 @@ public:
}; };
} // namespace } // namespace
using namespace espgui;
LedstripMenu::LedstripMenu() LedstripMenu::LedstripMenu()
{ {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIPCOLORMENU>, SwitchScreenAction<LedstripColorsDisplay>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIPCOLORMENU>, SwitchScreenAction<LedstripColorsDisplay>>>();

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include "menudisplay.h" #include "widgets/menudisplaywithtime.h"
// local includes // local includes
#include "texts.h" #include "texts.h"
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
class LedstripMenu : class LedstripMenu :
public espgui::MenuDisplay, public bobbygui::MenuDisplayWithTime,
public espgui::StaticText<TEXT_LEDSTRIP> public espgui::StaticText<TEXT_LEDSTRIP>
{ {
public: public:

View File

@ -0,0 +1,53 @@
#include "ledstripselectblinkmenu.h"
#ifdef FEATURE_LEDSTRIP
// Local includes
#include "accessors/settingsaccessors.h"
#include "actions/dummyaction.h"
#include "actions/ledstripblinkactions.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "displays/menus/ledstripmenu.h"
#include "icons/back.h"
using namespace espgui;
std::string currentSelectedBlinkAnimationText::text() const {
switch (blinkAnimation) {
case LEDSTRIP_OVERWRITE_BLINKLEFT:
#ifndef LEDSTRIP_WRONG_DIRECTION
return TEXT_ANIMATION_BLINKLEFT;
#else
return TEXT_ANIMATION_BLINKRIGHT;
#endif
case LEDSTRIP_OVERWRITE_BLINKRIGHT:
#ifndef LEDSTRIP_WRONG_DIRECTION
return TEXT_ANIMATION_BLINKRIGHT;
#else
return TEXT_ANIMATION_BLINKLEFT;
#endif
case LEDSTRIP_OVERWRITE_BLINKBOTH:
return TEXT_ANIMATION_BLINKBOTH;
default:
return TEXT_ANIMATION_BLINKNONE;
}
}
LedstripSelectBlinkMenu::LedstripSelectBlinkMenu()
{
constructMenuItem<makeComponent<MenuItem, currentSelectedBlinkAnimationText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKNONE>, LedstripAnimationBlinkNoneAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKLEFT>, LedstripAnimationBlinkLeftAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKRIGHT>, LedstripAnimationBlinkRightAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKBOTH>, LedstripAnimationBlinkBothAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_EN_BLINK_ANIM>, ToggleBoolAction, CheckboxIcon, LedstripEnableBlinkAnimationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void LedstripSelectBlinkMenu::back()
{
switchScreen<LedstripMenu>();
}
#endif

View File

@ -2,64 +2,22 @@
// Local includes // Local includes
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "ledstrip.h"
#include "ledstripselectanimationmenu.h"
#include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "actions/dummyaction.h" #include "ledstrip.h"
#include "actions/ledstripblinkactions.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "ledstripdefines.h" #include "ledstripdefines.h"
#include "accessors/settingsaccessors.h"
#include "ledstripmenu.h"
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
class currentSelectedBlinkAnimationText : public virtual TextInterface { public: std::string text() const override { class currentSelectedBlinkAnimationText : public virtual espgui::TextInterface
switch (blinkAnimation) { {
case LEDSTRIP_OVERWRITE_BLINKLEFT: public: std::string text() const override;
#ifndef LEDSTRIP_WRONG_DIRECTION
return TEXT_ANIMATION_BLINKLEFT;
#else
return TEXT_ANIMATION_BLINKRIGHT;
#endif
case LEDSTRIP_OVERWRITE_BLINKRIGHT:
#ifndef LEDSTRIP_WRONG_DIRECTION
return TEXT_ANIMATION_BLINKRIGHT;
#else
return TEXT_ANIMATION_BLINKLEFT;
#endif
case LEDSTRIP_OVERWRITE_BLINKBOTH:
return TEXT_ANIMATION_BLINKBOTH;
default:
return TEXT_ANIMATION_BLINKNONE;
}
};
}; };
using namespace espgui; class LedstripSelectBlinkMenu :
public espgui::MenuDisplay,
namespace { public espgui::StaticText<TEXT_BLINKANIMATION>
class LedstripSelectBlinkMenu : {
public MenuDisplay, public:
public StaticText<TEXT_BLINKANIMATION>, LedstripSelectBlinkMenu();
public BackActionInterface<SwitchScreenAction<LedstripMenu>> void back() override;
{ };
public:
LedstripSelectBlinkMenu()
{
constructMenuItem<makeComponent<MenuItem, currentSelectedBlinkAnimationText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKNONE>, LedstripAnimationBlinkNoneAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKLEFT>, LedstripAnimationBlinkLeftAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKRIGHT>, LedstripAnimationBlinkRightAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_BLINKBOTH>, LedstripAnimationBlinkBothAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_EN_BLINK_ANIM>, ToggleBoolAction, CheckboxIcon, LedstripEnableBlinkAnimationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace
#endif #endif

View File

@ -0,0 +1,24 @@
#include "ledstripselectotamode.h"
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "ledstripmenu.h"
// Local includes
#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA)
using namespace espgui;
ledstripOtaAnimationChangeMenu::ledstripOtaAnimationChangeMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_NONE>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::None>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_PROGRESS>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::GreenProgressBar>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_COLOR>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::ColorChangeAll>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void ledstripOtaAnimationChangeMenu::back()
{
switchScreen<LedstripMenu>();
}
#endif

View File

@ -2,20 +2,15 @@
// Local includes // Local includes
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "ledstrip.h"
#include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "actions/switchscreenaction.h" #include "ledstrip.h"
#include "accessors/settingsaccessors.h" #include "globals.h"
#include "ledstripmenu.h" #include "utils.h"
#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA) #if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA)
using namespace espgui;
template <OtaAnimationModes mode> template <OtaAnimationModes mode>
class LedstripChangeOtaAnimModeAction : public virtual ActionInterface class LedstripChangeOtaAnimModeAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override void triggered() override
@ -25,20 +20,12 @@ public:
} }
}; };
namespace { class ledstripOtaAnimationChangeMenu :
class ledstripOtaAnimationChangeMenu : public espgui::MenuDisplay,
public MenuDisplay, public espgui::StaticText<TEXT_BLINKANIMATION>
public StaticText<TEXT_BLINKANIMATION>, {
public BackActionInterface<SwitchScreenAction<LedstripMenu>> public:
{ ledstripOtaAnimationChangeMenu();
public: void back() override;
ledstripOtaAnimationChangeMenu() };
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_NONE>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::None>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_PROGRESS>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::GreenProgressBar>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_OTAANIM_COLOR>, LedstripChangeOtaAnimModeAction<OtaAnimationModes::ColorChangeAll>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace
#endif #endif

View File

@ -52,6 +52,7 @@ using namespace espgui;
LockscreenSettingsMenu::LockscreenSettingsMenu() LockscreenSettingsMenu::LockscreenSettingsMenu()
{ {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ALLOWPRESETSWITCH>, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ALLOWPRESETSWITCH>, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_KEEPLOCKED>, ToggleBoolAction, CheckboxIcon, LockscreenKeepLockedAccessor>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT0, LockscreenPinDigitAccessor<0>>, SwitchScreenAction<LockscreenPinDigit0ChangeScreen>>>(); constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT0, LockscreenPinDigitAccessor<0>>, SwitchScreenAction<LockscreenPinDigit0ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT1, LockscreenPinDigitAccessor<1>>, SwitchScreenAction<LockscreenPinDigit1ChangeScreen>>>(); constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT1, LockscreenPinDigitAccessor<1>>, SwitchScreenAction<LockscreenPinDigit1ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT2, LockscreenPinDigitAccessor<2>>, SwitchScreenAction<LockscreenPinDigit2ChangeScreen>>>(); constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT2, LockscreenPinDigitAccessor<2>>, SwitchScreenAction<LockscreenPinDigit2ChangeScreen>>>();

View File

@ -19,6 +19,7 @@
#include "displays/menus/settingsmenu.h" #include "displays/menus/settingsmenu.h"
#include "displays/menus/mosfetsmenu.h" #include "displays/menus/mosfetsmenu.h"
#include "displays/menus/demosmenu.h" #include "displays/menus/demosmenu.h"
#include "displays/menus/greenpassmenu.h"
#include "displays/lockscreen.h" #include "displays/lockscreen.h"
#include "displays/garagedisplay.h" #include "displays/garagedisplay.h"
#include "displays/menus/otamenu.h" #include "displays/menus/otamenu.h"
@ -45,11 +46,28 @@
#include "icons/poweroff.h" #include "icons/poweroff.h"
#include "icons/reboot.h" #include "icons/reboot.h"
#include "icons/statistics.h" #include "icons/statistics.h"
#include "icons/greenpass.h"
#include "icons/time.h"
#include "tftinstance.h"
using namespace espgui; using namespace espgui;
namespace mainmenu {
/*
class CurrentTimeText : public virtual TextInterface
{
public:
std::string text() const override
{
return fmt::format("&7Time: {}", local_clock_string());
}
};
*/
} // namespace
MainMenu::MainMenu() MainMenu::MainMenu()
{ {
// constructMenuItem<makeComponent<MenuItem, mainmenu::CurrentTimeText, DummyAction, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>();
#ifdef FEATURE_LEDSTRIP #ifdef FEATURE_LEDSTRIP
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
@ -72,6 +90,7 @@ MainMenu::MainMenu()
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); } if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); }
#endif #endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GREENPASS>, SwitchScreenAction<GreenPassMenu>, StaticMenuItemIcon<&bobbyicons::greenpass>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>();
#ifdef FEATURE_GARAGE #ifdef FEATURE_GARAGE
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); } if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include "menudisplay.h"
#include "menuitem.h" #include "menuitem.h"
// local includes // local includes
#include "texts.h" #include "texts.h"
#include "widgets/menudisplaywithtime.h"
#ifdef MAINMENU_PLUGIN #ifdef MAINMENU_PLUGIN
#include MAINMENU_PLUGIN #include MAINMENU_PLUGIN
#endif #endif
@ -22,11 +22,11 @@ namespace {
} // namespace } // namespace
class MainMenu : class MainMenu :
public espgui::MenuDisplay, public bobbygui::MenuDisplayWithTime,
public espgui::StaticText<TEXT_MAINMENU> public espgui::StaticText<TEXT_MAINMENU>
{ {
using Base = espgui::MenuDisplay;
public: public:
MainMenu(); MainMenu();
void back() override; void back() override;
}; };

View File

@ -0,0 +1,26 @@
#include "mosfetsmenu.h"
#ifdef FEATURE_MOSFETS
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "displays/menus/mainmenu.h"
#include "icons/back.h"
using namespace espgui;
MosfetsMenu::MosfetsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET0>, ToggleBoolAction, CheckboxIcon, Mosfet0Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET1>, ToggleBoolAction, CheckboxIcon, Mosfet1Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET2>, ToggleBoolAction, CheckboxIcon, Mosfet2Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void MosfetsMenu::back()
{
switchScreen<MainMenu>();
}
#endif

View File

@ -1,22 +1,13 @@
#pragma once #pragma once
// local includes #ifdef FEATURE_MOSFETS
#include "menudisplay.h" #include "menudisplay.h"
#include "utils.h" #include "accessorinterface.h"
#include "menuitem.h"
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "texts.h" #include "texts.h"
#include "types.h" #include "types.h"
using namespace espgui;
namespace {
#ifdef FEATURE_MOSFETS
template<pin_t PIN> template<pin_t PIN>
class GPIOAccessor : public virtual AccessorInterface<bool> class GPIOAccessor : public virtual espgui::AccessorInterface<bool>
{ {
public: public:
bool getValue() const override { return digitalRead(PIN); } bool getValue() const override { return digitalRead(PIN); }
@ -28,18 +19,11 @@ using Mosfet1Accessor = GPIOAccessor<PINS_MOSFET1>;
using Mosfet2Accessor = GPIOAccessor<PINS_MOSFET2>; using Mosfet2Accessor = GPIOAccessor<PINS_MOSFET2>;
class MosfetsMenu : class MosfetsMenu :
public MenuDisplay, public espgui::MenuDisplay,
public StaticText<TEXT_MOSFETS>, public espgui::StaticText<TEXT_MOSFETS>
public BackActionInterface<SwitchScreenAction<MainMenu>>
{ {
public: public:
MosfetsMenu() MosfetsMenu();
{ void back() override;
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET0>, ToggleBoolAction, CheckboxIcon, Mosfet0Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET1>, ToggleBoolAction, CheckboxIcon, Mosfet1Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFET2>, ToggleBoolAction, CheckboxIcon, Mosfet2Accessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
}; };
#endif #endif
} // namespace

View File

@ -10,7 +10,7 @@
// local includes // local includes
#include "actions/dummyaction.h" #include "actions/dummyaction.h"
#include "buildserver.h" #include "buildserver.h"
#include "displays/menus/settingsmenu.h" #include "displays/menus/otamenu.h"
#include "utils.h" #include "utils.h"
#ifdef FEATURE_OTA #ifdef FEATURE_OTA
@ -67,11 +67,11 @@ SelectBuildServerMenu::SelectBuildServerMenu()
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
} }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
} }
void SelectBuildServerMenu::back() void SelectBuildServerMenu::back()
{ {
espgui::switchScreen<SettingsMenu>(); espgui::switchScreen<OtaMenu>();
} }
#endif #endif

View File

@ -28,6 +28,7 @@
#include "displays/menus/bluetoothsettingsmenu.h" #include "displays/menus/bluetoothsettingsmenu.h"
#include "displays/menus/blesettingsmenu.h" #include "displays/menus/blesettingsmenu.h"
#include "displays/menus/cloudsettingsmenu.h" #include "displays/menus/cloudsettingsmenu.h"
#include "displays/menus/espnowmenu.h"
#include "displays/menus/selectbuildservermenu.h" #include "displays/menus/selectbuildservermenu.h"
#include "displays/menus/timesettingsmenu.h" #include "displays/menus/timesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h" #include "displays/menus/modessettingsmenu.h"
@ -61,6 +62,9 @@ SettingsMenu::SettingsMenu()
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#ifdef FEATURE_ESPNOW
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW>, SwitchScreenAction<EspNowMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#endif
#ifdef FEATURE_BLUETOOTH #ifdef FEATURE_BLUETOOTH
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>(); constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif #endif

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include "menudisplay.h" #include "widgets/menudisplaywithtime.h"
// local includes // local includes
#include "texts.h" #include "texts.h"
class SettingsMenu : class SettingsMenu :
public espgui::MenuDisplay, public bobbygui::MenuDisplayWithTime,
public espgui::StaticText<TEXT_SETTINGS> public espgui::StaticText<TEXT_SETTINGS>
{ {
public: public:

View File

@ -3,9 +3,11 @@
// local includes // local includes
#include "mainmenu.h" #include "mainmenu.h"
#include "actions/dummyaction.h" #include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actioninterface.h" #include "actioninterface.h"
#include "fmt/core.h" #include "fmt/core.h"
#include "utils.h" #include "utils.h"
#include "icons/back.h"
#include "icons/time.h" #include "icons/time.h"
#include "icons/reboot.h" #include "icons/reboot.h"
#include "icons/update.h" #include "icons/update.h"

View File

@ -1,18 +1,14 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include <menudisplay.h> #include "widgets/menudisplaywithtime.h"
#include <menuitem.h> #include <menuitem.h>
#include <icons/back.h>
#include <actions/dummyaction.h>
#include <actions/switchscreenaction.h>
// Local includes // Local includes
#include "utils.h"
#include "texts.h" #include "texts.h"
class StatisticsMenu : class StatisticsMenu :
public espgui::MenuDisplay, public bobbygui::MenuDisplayWithTime,
public espgui::StaticText<TEXT_STATISTICSMENU> public espgui::StaticText<TEXT_STATISTICSMENU>
{ {
public: public:

View File

@ -37,7 +37,8 @@ public:
#ifdef CONFIG_ESPCHRONO_SUPPORT_DEFAULT_TIMEZONE #ifdef CONFIG_ESPCHRONO_SUPPORT_DEFAULT_TIMEZONE
return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::local_clock::now()))); return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::local_clock::now())));
#else #else
return "TODO"; // Crude local time implementation
return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::utc_clock::now() + settings.timeSettings.timezoneOffset)));
#endif #endif
} }
}; };

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
// 3rdparty lib includes // 3rdparty lib includes
#include "menudisplay.h" #include "widgets/menudisplaywithtime.h"
// local includes // local includes
#include "texts.h" #include "texts.h"
class TimeSettingsMenu : class TimeSettingsMenu :
public espgui::MenuDisplay, public bobbygui::MenuDisplayWithTime,
public espgui::StaticText<TEXT_TIME> public espgui::StaticText<TEXT_TIME>
{ {
public: public:

View File

@ -0,0 +1,36 @@
#include "qrcodedebug.h"
#include <fmt/core.h>
#include "displays/menus/debugmenu.h"
#include "globals.h"
#include "screenmanager.h"
using namespace espgui;
QrCodeDebugDisplay::QrCodeDebugDisplay()
{
}
void QrCodeDebugDisplay::back()
{
switchScreen<DebugMenu>();
}
void QrCodeDebugDisplay::initScreen()
{
Base::initScreen();
m_qrcode.init();
}
void QrCodeDebugDisplay::confirm()
{
m_qrcode.createScaleToFit(fmt::format("WIFI:T:WPA;S:{};P:{};", deviceName, stringSettings.ap_password));
}
void QrCodeDebugDisplay::rotate(int offset)
{
m_mult += offset;
m_qrcode.setMultiply(m_mult);
m_qrcode.create("Hello World!");
}

View File

@ -0,0 +1,21 @@
#pragma once
// 3rdparty lib includes
#include <display.h>
#include <qrcode.h>
class QrCodeDebugDisplay :
public espgui::Display
{
using Base = espgui::Display;
public:
QrCodeDebugDisplay();
// std::string text() const override;
void initScreen() override;
void confirm() override;
void back() override;
void rotate(int offset) override;
private:
qrcode::QRcode m_qrcode{};
uint8_t m_mult{2};
};

View File

@ -11,6 +11,7 @@
#include "dpad.h" #include "dpad.h"
#include "buttons.h" #include "buttons.h"
#include "types.h" #include "types.h"
#include "globals.h"
namespace { namespace {
namespace dpad3wire namespace dpad3wire

View File

@ -13,6 +13,7 @@
// local includes // local includes
#include "buttons.h" #include "buttons.h"
#include "types.h" #include "types.h"
#include "globals.h"
namespace { namespace {
namespace dpad5wire { namespace dpad5wire {

View File

@ -13,6 +13,7 @@
// local includes // local includes
#include "buttons.h" #include "buttons.h"
#include "types.h" #include "types.h"
#include "globals.h"
namespace { namespace {
namespace dpad5wire_2out { namespace dpad5wire_2out {

View File

@ -12,6 +12,7 @@
// local includes // local includes
#include "buttons.h" #include "buttons.h"
#include "types.h" #include "types.h"
#include "globals.h"
namespace { namespace {
namespace dpad6wire { namespace dpad6wire {

290
main/espnowfunctions.cpp Normal file
View File

@ -0,0 +1,290 @@
#ifdef FEATURE_ESPNOW
#include "espnowfunctions.h"
#include <string>
#include <espchrono.h>
#include <esp_log.h>
#include <numberparsing.h>
#include <espwifistack.h>
#include "globals.h"
#include "utils.h"
#include "time_bobbycar.h"
namespace espnow {
namespace {
constexpr const char * const TAG = "BOBBY_ESP_NOW";
} // namespace
uint16_t lastYear; // Used for esp-now timesync
std::deque<esp_now_message_t> message_queue{};
std::vector<esp_now_peer_info_t> peers{};
uint8_t initialized{0};
bool receiveTimeStamp{true};
bool receiveTsFromOtherBobbycars{true};
namespace {
extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len)
{
ESP_LOGD(TAG, "Received data");
const std::string_view data_str{(const char *)data, size_t(data_len)};
size_t sep_pos = data_str.find(":");
if (std::string_view::npos != sep_pos)
{
std::string_view msg_type = data_str.substr(0, sep_pos);
std::string_view msg = data_str.substr(sep_pos+1, data_str.length()-3); // - 3 may needs to be converted to sep_pos+1
ESP_LOGD(TAG, "Type: %.*s - Message: %.*s", msg_type.size(), msg_type.data(), msg.size(), msg.data());
message_queue.push_back(esp_now_message_t {
.content = std::string{msg},
.type = std::string{msg_type}
});
}
else
{
ESP_LOGW(TAG, "Invalid message: Could not find ':' (%.*s)", data_str.size(), data_str.data());
}
}
} // namespace
void initESPNow()
{
ESP_LOGI(TAG, "Initializing esp-now...");
if (initialized < 1)
{
if (!settings.wifiSettings.wifiApEnabled && (!settings.wifiSettings.wifiStaEnabled && wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::NO_SHIELD) || (wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_STA && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_AP && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_APSTA))
{
ESP_LOGW(TAG, "cannot execute esp_now_init(): tcp stack is down.");
return;
}
else
initialized = 1;
}
if (initialized < 2)
{
if (const auto error = esp_now_init(); error != ESP_OK)
{
ESP_LOGE(TAG, "esp_now_init() failed with %s", esp_err_to_name(error));
return;
}
else
initialized = 2;
}
if (initialized < 3)
{
if (const auto error = esp_now_register_recv_cb(onReceive); error != ESP_OK)
{
ESP_LOGE(TAG, "esp_now_register_recv_cb() failed with %s", esp_err_to_name(error));
return;
}
else
initialized = 3;
}
if (initialized < 4)
{
peers.push_back(esp_now_peer_info_t{});
esp_now_peer_info_t &peer = peers.back();
std::memcpy(peer.peer_addr, broadcast_address, sizeof(peer.peer_addr));
peer.channel = 0;
if (settings.wifiSettings.wifiApEnabled)
peer.ifidx = WIFI_IF_AP;
else if (settings.wifiSettings.wifiStaEnabled)
peer.ifidx = WIFI_IF_STA;
else
{
ESP_LOGE(TAG, "Interfaces not ready.");
return;
}
if (const auto error = esp_now_add_peer(&peers.back()); error != ESP_OK)
{
ESP_LOGE(TAG, "esp_now_add_peer() failed with %s", esp_err_to_name(error));
return;
}
else
initialized = 4;
}
initialized = 255;
ESP_LOGI(TAG, "Init done.");
}
void handle()
{
if (initialized < 255 && !(!settings.wifiSettings.wifiApEnabled && (!settings.wifiSettings.wifiStaEnabled && wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::NO_SHIELD) || (wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_STA && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_AP && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_APSTA)))
{
initESPNow();
return;
}
else if (!settings.wifiSettings.wifiApEnabled && (!settings.wifiSettings.wifiStaEnabled && wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::NO_SHIELD) || (wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_STA && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_AP && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_APSTA))
{
if (initialized > 0)
{
if (initialized >= 4) // peer
{
for (const auto &peer : peers)
{
if (const auto error = esp_now_del_peer(peer.peer_addr); error != ESP_OK)
{
if (error == ESP_ERR_ESPNOW_NOT_FOUND)
{
initialized = 0;
return;
}
ESP_LOGE(TAG, "esp_now_del_peer() failed with %s", esp_err_to_name(error));
return;
}
}
initialized--;
}
if (initialized >= 3) // callback
{
if (const auto error = esp_now_unregister_recv_cb(); error != ESP_OK)
{
ESP_LOGE(TAG, "esp_now_unregister_recv_cb() failed with %s", esp_err_to_name(error));
return;
}
else if (error == ESP_ERR_ESPNOW_NOT_FOUND)
{
initialized = 0;
}
else
initialized--;
}
if (initialized >= 2) // esp deinit
{
if (const auto error = esp_now_deinit(); error != ESP_OK)
{
ESP_LOGE(TAG, "esp_now_deinit() failed with %s", esp_err_to_name(error));
return;
}
else if (error == ESP_ERR_ESPNOW_NOT_FOUND)
{
initialized = 0;
}
else
initialized--;
}
initialized = 0;
ESP_LOGI(TAG, "Deinit done.");
}
return;
}
if(message_queue.size())
{
for (const esp_now_message_t &msg : message_queue)
{
ESP_LOGD(TAG, "queue has processed message of type '%s' with content '%s'", msg.type.c_str(), msg.content.c_str());
message_queue.pop_front();
if (msg.type == "T")
{
if (!receiveTimeStamp || !settings.espnow.syncTime)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
onRecvTs(*result);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else if (msg.type == "BOBBYT")
{
if (!receiveTsFromOtherBobbycars || !settings.espnow.syncTimeWithOthers)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
ESP_LOGI(TAG, "setting current time to %" PRIu64, *result);
onRecvTs(*result, true);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else
{
ESP_LOGI(TAG, "Unkown Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str());
}
}
}
}
void onRecvTs(uint64_t millis, bool isFromBobbycar)
{
const auto milliseconds = std::chrono::milliseconds(millis);
const auto timepoint = espchrono::utc_clock::time_point(milliseconds);
// ESP_LOGW(TAG, "setting current time to %s", espchrono::toString(timepoint.time_since_epoch()).c_str());
time_set_now(timepoint);
if (receiveTimeStamp)
{
if (const auto thisYear = int(espchrono::toDateTime(espchrono::utc_clock::now()).date.year()); abs(thisYear - espnow::lastYear) > 1)
{
espnow::lastYear = thisYear;
receiveTimeStamp = false;
}
}
receiveTsFromOtherBobbycars = false;
}
esp_err_t send_espnow_message(std::string_view message)
{
if (initialized < 255)
return ESP_ERR_ESPNOW_NOT_INIT;
if (!settings.wifiSettings.wifiApEnabled && !settings.wifiSettings.wifiStaEnabled)
{
return ESP_ERR_ESPNOW_IF;
}
if (peers.size() < 1)
{
return ESP_FAIL;
}
for (auto &peer : peers)
{
if (settings.wifiSettings.wifiApEnabled)
peer.ifidx = WIFI_IF_AP;
else if (settings.wifiSettings.wifiStaEnabled)
peer.ifidx = WIFI_IF_STA;
else
return ESP_ERR_ESPNOW_IF;
const auto timeBefore = espchrono::millis_clock::now();
if(const auto error = esp_now_send(broadcast_address, (const uint8_t*)message.data(), message.size()); error != ESP_OK)
{
return error;
}
else
{
const auto timeAfter = espchrono::millis_clock::now();
ESP_LOGI(TAG, "Successfully executed esp_now_send(): Took %lldms", std::chrono::milliseconds{timeAfter-timeBefore}.count());
}
}
return ESP_OK;
}
} // namespace espnow
#endif

30
main/espnowfunctions.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#ifdef FEATURE_ESPNOW
#include <cstdint>
#include <deque>
#include <string>
#include <string_view>
#include <vector>
#include <esp_now.h>
namespace espnow {
extern uint16_t lastYear;
constexpr const uint8_t broadcast_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
struct esp_now_message_t
{
std::string content;
std::string type;
};
extern bool receiveTimeStamp;
extern bool receiveTsFromOtherBobbycars;
extern std::deque<esp_now_message_t> message_queue;
extern std::vector<esp_now_peer_info_t> peers;
void initESPNow();
void handle();
void onRecvTs(uint64_t millis, bool isFromBobbycar = false);
esp_err_t send_espnow_message(std::string_view message);
} // namespace espnow
#endif

42
main/icons/greenpass.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "greenpass.h"
namespace bobbyicons {
const espgui::Icon<24, 24> greenpass{{
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0010 (16) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0020 (32) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, // 0x0030 (48) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0040 (64) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0050 (80) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x0060 (96) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0070 (112) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0080 (128) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x0090 (144) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x00A0 (160) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00B0 (176) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650D, 0x4CAA, // 0x00C0 (192) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x00D0 (208) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x650D, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00E0 (224) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x00F0 (240) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0100 (256) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0110 (272) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0120 (288) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0130 (304) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0140 (320) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0xB676, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0150 (336) pixels
0x4CAA, 0x4CAA, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x54CB, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0160 (352) pixels
0xF7BE, 0xF7BE, 0x4CAA, 0x54CB, 0x54CB, 0x54CB, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0170 (368) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, // 0x0180 (384) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, // 0x0190 (400) pixels
0xF7BE, 0xF7BE, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x650C, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01A0 (416) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0x8590, 0x4CAA, // 0x01B0 (432) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x01C0 (448) pixels
0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01D0 (464) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x6D2E, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x8590, // 0x01E0 (480) pixels
0x4CAA, 0x6D2E, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, // 0x01F0 (496) pixels
0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0200 (512) pixels
0xF7BE, 0x650C, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x6D2E, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, 0xF7BE, // 0x0210 (528) pixels
0x4CAA, 0x54CB, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x54CB, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x54CB, 0x7D6F, // 0x0220 (544) pixels
0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0x7D6F, 0xF79D, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0230 (560) pixels
0x4CAA, 0x4CAA, 0x4CAA, 0xF7BE, 0xF7BE, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, 0x4CAA, // 0x0240 (576) pixels
}, "greenpass"};
} // namespace bobbyicons

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

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

View File

@ -59,12 +59,16 @@ using namespace std::chrono_literals;
#endif #endif
#include "modes/defaultmode.h" #include "modes/defaultmode.h"
#include "displays/statusdisplay.h" #include "displays/statusdisplay.h"
#include "displays/lockscreen.h"
#include "displays/calibratedisplay.h" #include "displays/calibratedisplay.h"
#ifdef FEATURE_DNS_NS #ifdef FEATURE_DNS_NS
#include "dnsannounce.h" #include "dnsannounce.h"
#endif #endif
#include "drivingstatistics.h" #include "drivingstatistics.h"
#include "newsettings.h" #include "newsettings.h"
#ifdef FEATURE_ESPNOW
#include "espnowfunctions.h"
#endif
#include "taskmanager.h" #include "taskmanager.h"
namespace { namespace {
@ -230,10 +234,22 @@ extern "C" void app_main()
switchScreen<DPad6WireDebugDisplay>(); switchScreen<DPad6WireDebugDisplay>();
#else #else
if (!gas || !brems || *gas > 200.f || *brems > 200.f) if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
espgui::switchScreen<CalibrateDisplay>(true); {
espgui::switchScreen<Lockscreen>();
}
else else
espgui::switchScreen<StatusDisplay>(); {
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
espgui::switchScreen<CalibrateDisplay>(true);
else
{
espgui::switchScreen<StatusDisplay>();
}
}
#endif
#ifdef FEATURE_ESPNOW
espnow::initESPNow();
#endif #endif
while (true) while (true)
@ -330,6 +346,10 @@ extern "C" void app_main()
} }
#endif #endif
#ifdef FEATURE_ESPNOW
espnow::handle();
#endif
#ifdef FEATURE_CLOUD #ifdef FEATURE_CLOUD
if (!lastCloudCollect || now - *lastCloudCollect >= std::chrono::milliseconds{settings.boardcomputerHardware.timersSettings.cloudCollectRate}) if (!lastCloudCollect || now - *lastCloudCollect >= std::chrono::milliseconds{settings.boardcomputerHardware.timersSettings.cloudCollectRate})
{ {

View File

@ -274,6 +274,8 @@ constexpr Settings::Ledstrip defaultLedstrip {
constexpr Settings::LockscreenSettings defaultLockscreen { constexpr Settings::LockscreenSettings defaultLockscreen {
.allowPresetSwitch = true, .allowPresetSwitch = true,
.keepLockedAfterReboot = false,
.locked = false,
.pin = { 1, 2, 3, 4 } .pin = { 1, 2, 3, 4 }
}; };
@ -300,6 +302,19 @@ constexpr Settings::SavedStatistics defaultSavedStatistics {
.totalCentimeters = 0, .totalCentimeters = 0,
}; };
#ifdef FEATURE_ESPNOW
constexpr Settings::ESPNOW defaultEspNowSettings {
#ifndef FEATURE_NTP
.syncTime = true,
.syncTimeWithOthers = true,
#else
.syncTime = false,
.syncTimeWithOthers = false,
#endif
.syncBlink = false
};
#endif
constexpr Settings defaultSettings { constexpr Settings defaultSettings {
#ifdef FEATURE_BMS #ifdef FEATURE_BMS
.autoConnectBms = false, .autoConnectBms = false,
@ -330,7 +345,10 @@ constexpr Settings defaultSettings {
.hybrid = defaultHybrid, .hybrid = defaultHybrid,
.lockscreen = defaultLockscreen, .lockscreen = defaultLockscreen,
.savedStatistics = defaultSavedStatistics, .savedStatistics = defaultSavedStatistics,
.handbremse = defaultHandbremse .handbremse = defaultHandbremse,
#ifdef FEATURE_ESPNOW
.espnow = defaultEspNowSettings,
#endif
}; };
StringSettings makeDefaultStringSettings(); StringSettings makeDefaultStringSettings();

View File

@ -210,6 +210,8 @@ struct Settings
struct LockscreenSettings { struct LockscreenSettings {
bool allowPresetSwitch; bool allowPresetSwitch;
bool keepLockedAfterReboot;
bool locked;
std::array<int8_t, 4> pin; std::array<int8_t, 4> pin;
} lockscreen; } lockscreen;
@ -224,6 +226,13 @@ struct Settings
bool enable; bool enable;
bool visualize; bool visualize;
} handbremse; } handbremse;
#ifdef FEATURE_ESPNOW
struct ESPNOW {
bool syncTime;
bool syncTimeWithOthers;
bool syncBlink;
} espnow;
#endif
template<typename T> template<typename T>
void executeForEveryCommonSetting(T &&callable); void executeForEveryCommonSetting(T &&callable);
@ -353,6 +362,8 @@ void Settings::executeForEveryCommonSetting(T &&callable)
callable("hybridDeacL", hybrid.deactivationLimit); callable("hybridDeacL", hybrid.deactivationLimit);
callable("lockAlwPresetSw", lockscreen.allowPresetSwitch); callable("lockAlwPresetSw", lockscreen.allowPresetSwitch);
callable("keepLocked", lockscreen.keepLockedAfterReboot);
callable("currentlyLocked", lockscreen.locked);
callable("lockscreenPin", lockscreen.pin); callable("lockscreenPin", lockscreen.pin);
callable("totalCentimeter", savedStatistics.totalCentimeters); callable("totalCentimeter", savedStatistics.totalCentimeters);
@ -362,6 +373,14 @@ void Settings::executeForEveryCommonSetting(T &&callable)
callable("handBremsM", handbremse.mode); callable("handBremsM", handbremse.mode);
callable("handBremsT", handbremse.triggerTimeout); callable("handBremsT", handbremse.triggerTimeout);
callable("handBremsV", handbremse.visualize); callable("handBremsV", handbremse.visualize);
#ifdef FEATURE_ESPNOW
callable("espnowSyncT", espnow.syncTime);
callable("espnowSyncTWO", espnow.syncTimeWithOthers);
#ifdef FEATURE_LEDSTRIP
callable("espnowSyncBl", espnow.syncBlink);
#endif
#endif
} }
template<typename T> template<typename T>

View File

@ -0,0 +1,45 @@
#include "settingsutils.h"
// esp-idf includes
#include <esp_log.h>
// local includes
#include "globals.h"
#include "presets.h"
namespace settingsutils {
void switchProfile(uint8_t index)
{
#ifdef SIMPLIFIED_TRIGGER_TRIGGERONPRESET
if (index == SIMPLIFIED_TRIGGER_TRIGGERONPRESET)
{
simplified = true;
#ifdef SETTINGSUTILS_PLUGIN
#include SETTINGSUTILS_PLUGIN
#endif
return;
}
#endif
settings = presets::defaultSettings;
stringSettings = presets::makeDefaultStringSettings();
if (!settingsPersister.openProfile(index))
{
ESP_LOGE("BOBBY", "openProfile() failed");
return;
}
if (!settingsPersister.load(settings))
{
ESP_LOGE("BOBBY", "load() for settings failed");
return;
}
if (!settingsPersister.load(stringSettings))
{
ESP_LOGE("BOBBY", "load() for stringSettings failed");
return;
}
}
} // namespace

View File

@ -1,45 +1,7 @@
#pragma once #pragma once
// esp-idf includes #include <cstdint>
#include <esp_log.h>
// local includes namespace settingsutils {
#include "globals.h" void switchProfile(uint8_t index);
#include "presets.h"
namespace {
void switchProfile(uint8_t index)
{
#ifdef SIMPLIFIED_TRIGGER_TRIGGERONPRESET
if (index == SIMPLIFIED_TRIGGER_TRIGGERONPRESET)
{
simplified = true;
#ifdef SETTINGSUTILS_PLUGIN
#include SETTINGSUTILS_PLUGIN
#endif
return;
}
#endif
settings = presets::defaultSettings;
stringSettings = presets::makeDefaultStringSettings();
if (!settingsPersister.openProfile(index))
{
ESP_LOGE("BOBBY", "openProfile() failed");
return;
}
if (!settingsPersister.load(settings))
{
ESP_LOGE("BOBBY", "load() for settings failed");
return;
}
if (!settingsPersister.load(stringSettings))
{
ESP_LOGE("BOBBY", "load() for stringSettings failed");
return;
}
}
} }

View File

@ -332,6 +332,7 @@ char TEXT_ANIMATION_BLINKBOTH[] = "Blink Both";
//LockscreenSettingsMenu //LockscreenSettingsMenu
char TEXT_LOCKSCREENSETTINGS[] = "Lockscreen Settings"; char TEXT_LOCKSCREENSETTINGS[] = "Lockscreen Settings";
char TEXT_ALLOWPRESETSWITCH[] = "Allow preset switch"; char TEXT_ALLOWPRESETSWITCH[] = "Allow preset switch";
char TEXT_KEEPLOCKED[] = "Keep locked";
char TEXT_PINDIGIT0[] = "PIN digit0"; char TEXT_PINDIGIT0[] = "PIN digit0";
char TEXT_PINDIGIT1[] = "PIN digit1"; char TEXT_PINDIGIT1[] = "PIN digit1";
char TEXT_PINDIGIT2[] = "PIN digit2"; char TEXT_PINDIGIT2[] = "PIN digit2";
@ -537,4 +538,23 @@ char TEXT_REENABLE_MENUITEMS[] = "Show advanced";
//SelectBuildserverBranchMenu //SelectBuildserverBranchMenu
char TEXT_SELECT_BRANCH[] = "Select Branch"; char TEXT_SELECT_BRANCH[] = "Select Branch";
char TEXT_SELECT_BRANCH_CLEAR[] = "Clear Branch"; char TEXT_SELECT_BRANCH_CLEAR[] = "Clear Branch";
char TEXT_QRCODE_DEBUG[] = "QR Debug";
//GreenPassMenu
char TEXT_GREENPASS[] = "Green Pass";
char TEXT_SHOWCERT[] = "Show cert";
//EspNowMenu
char TEXT_ESPNOW[] = "ESP-Now";
char TEXT_ESPNOW_MENU[] = "ESP-Now Menu";
char TEXT_ESPNOW_RECEIVETS[] = "Recv Ts State";
char TEXT_ESPNOW_RECEIVETSFROMBOBBY[] = "Recv BobbyTs State";
char TEXT_ESPNOW_SENDTSMSG[] = "Broadcast Time";
//EspNowSettingsMenu
char TEXT_ESPNOW_SETTINGS[] = "ESP-Now settings";
char TEXT_ESPNOW_SYNCTIME[] = "Sync time (no NTP)";
char TEXT_ESPNOW_SYNCWITHOTHERS[] = "Sync time with others";
char TEXT_ESPNOW_SYNCBLINK[] = "Sync blink";
} // namespace } // namespace

View File

@ -332,6 +332,7 @@ extern char TEXT_ANIMATION_BLINKBOTH[];
//LockscreenSettingsMenu //LockscreenSettingsMenu
extern char TEXT_LOCKSCREENSETTINGS[]; extern char TEXT_LOCKSCREENSETTINGS[];
extern char TEXT_ALLOWPRESETSWITCH[]; extern char TEXT_ALLOWPRESETSWITCH[];
extern char TEXT_KEEPLOCKED[];
extern char TEXT_PINDIGIT0[]; extern char TEXT_PINDIGIT0[];
extern char TEXT_PINDIGIT1[]; extern char TEXT_PINDIGIT1[];
extern char TEXT_PINDIGIT2[]; extern char TEXT_PINDIGIT2[];
@ -536,6 +537,26 @@ extern char TEXT_REENABLE_MENUITEMS[];
//SelectBuildserverBranchMenu //SelectBuildserverBranchMenu
extern char TEXT_SELECT_BRANCH[]; extern char TEXT_SELECT_BRANCH[];
extern char TEXT_SELECT_BRANCH_CLEAR[]; extern char TEXT_SELECT_BRANCH_CLEAR[];
//QrCodeDebug
extern char TEXT_QRCODE_DEBUG[];
//GreenPassMenu
extern char TEXT_GREENPASS[];
extern char TEXT_SHOWCERT[];
//EspNowMenu
extern char TEXT_ESPNOW[];
extern char TEXT_ESPNOW_MENU[];
extern char TEXT_ESPNOW_RECEIVETS[];
extern char TEXT_ESPNOW_RECEIVETSFROMBOBBY[];
extern char TEXT_ESPNOW_SENDTSMSG[];
//EspNowSettingsMenu
extern char TEXT_ESPNOW_SETTINGS[];
extern char TEXT_ESPNOW_SYNCTIME[];
extern char TEXT_ESPNOW_SYNCWITHOTHERS[];
extern char TEXT_ESPNOW_SYNCBLINK[];
} // namespace } // namespace
using namespace bobbytexts; using namespace bobbytexts;

View File

@ -25,7 +25,6 @@ constexpr const char * const TAG = "bobbycloud";
using namespace std::chrono_literals; using namespace std::chrono_literals;
// Little "flash" on statusdisplay when udp stuff is happening // Little "flash" on statusdisplay when udp stuff is happening
bool visualSendUdpPacket; bool visualSendUdpPacket;
espchrono::millis_clock::time_point timestampLastFailed; espchrono::millis_clock::time_point timestampLastFailed;
void spamUdpBroadcast() void spamUdpBroadcast()
@ -294,7 +293,7 @@ std::string buildUdpCloudString()
void sendUdpCloudPacket() void sendUdpCloudPacket()
{ {
EVERY_N_MILLIS(settings.boardcomputerHardware.timersSettings.udpSendRateMs) { EVERY_N_MILLIS(settings.boardcomputerHardware.timersSettings.udpSendRateMs) {
if (espchrono::ago(timestampLastFailed) < 3s) if (espchrono::ago(timestampLastFailed) < 2s)
{ {
visualSendUdpPacket = false; visualSendUdpPacket = false;
return; return;
@ -332,6 +331,7 @@ void sendUdpCloudPacket()
if (udpCloudIp.type != IPADDR_TYPE_V4) if (udpCloudIp.type != IPADDR_TYPE_V4)
{ {
ESP_LOGE(TAG, "unsupported ip type: %hhu", udpCloudIp.type); ESP_LOGE(TAG, "unsupported ip type: %hhu", udpCloudIp.type);
timestampLastFailed = espchrono::millis_clock::now();
visualSendUdpPacket = false; visualSendUdpPacket = false;
return; return;
} }
@ -348,6 +348,7 @@ void sendUdpCloudPacket()
if (const auto result = udpCloudSender.send(receipient, buf); !result) if (const auto result = udpCloudSender.send(receipient, buf); !result)
{ {
timestampLastFailed = espchrono::millis_clock::now();
ESP_LOGE(TAG, "send to cloud failed: %.*s (ip=%s)", result.error().size(), result.error().data(), wifi_stack::toString(udpCloudIp.u_addr.ip4).c_str()); ESP_LOGE(TAG, "send to cloud failed: %.*s (ip=%s)", result.error().size(), result.error().data(), wifi_stack::toString(udpCloudIp.u_addr.ip4).c_str());
} }

View File

@ -337,3 +337,26 @@ uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::millisecond
else else
return invert ? numLeds : 0; return invert ? numLeds : 0;
} }
void time_set_now(espchrono::utc_clock::time_point now)
{
using namespace espchrono;
// ESP_LOGI("BOBBY", "%s (%lld)%s", toString(toDateTime(now)).c_str(), std::chrono::floor<std::chrono::seconds>(now.time_since_epoch()).count(), time_valid(now) ? "":" (probably invalid)");
const auto seconds = std::chrono::floor<std::chrono::seconds>(now.time_since_epoch());
timeval ts {
.tv_sec = (long int)seconds.count(),
.tv_usec = (long int)std::chrono::floor<std::chrono::microseconds>(now.time_since_epoch() - seconds).count()
};
timezone tz {
.tz_minuteswest = 0,
.tz_dsttime = 0
};
settimeofday(&ts, &tz);
}
std::string local_clock_string()
{
const auto dt = espchrono::toDateTime(espchrono::utc_clock::now() + settings.timeSettings.timezoneOffset);
return fmt::format("{:02d}:{:02d}:{:02d}", dt.hour, dt.minute, dt.second);
}

View File

@ -59,3 +59,5 @@ void readPotis();
float wattToAmpere(float watt); float wattToAmpere(float watt);
float wattToMotorCurrent(float watt); float wattToMotorCurrent(float watt);
uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::milliseconds32 riseTime, espchrono::milliseconds32 fullTime, size_t numLeds, bool invert); uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::milliseconds32 riseTime, espchrono::milliseconds32 fullTime, size_t numLeds, bool invert);
void time_set_now(espchrono::utc_clock::time_point now);
std::string local_clock_string();

View File

@ -1,6 +1,8 @@
#include "webserver.h" #include "webserver.h"
#include "sdkconfig.h" #include "sdkconfig.h"
using namespace std::chrono_literals;
#ifdef FEATURE_WEBSERVER #ifdef FEATURE_WEBSERVER
namespace { namespace {
constexpr const char * const TAG = "BOBBYWEB"; constexpr const char * const TAG = "BOBBYWEB";

View File

@ -2,6 +2,7 @@
#ifdef FEATURE_WEBSERVER #ifdef FEATURE_WEBSERVER
using esphttpdutils::HtmlTag; using esphttpdutils::HtmlTag;
using namespace std::chrono_literals;
namespace { namespace {
constexpr const char * const TAG = "BOBBYWEB"; constexpr const char * const TAG = "BOBBYWEB";

View File

@ -2,6 +2,7 @@
using esphttpdutils::HtmlTag; using esphttpdutils::HtmlTag;
using namespace espchrono; using namespace espchrono;
using namespace std::chrono_literals;
namespace { namespace {
constexpr const char * const TAG = "BOBBYWEB"; constexpr const char * const TAG = "BOBBYWEB";
@ -148,7 +149,7 @@ esp_err_t webserver_dump_nvs_handler(httpd_req_t *req)
continue; continue;
} }
#endif #endif
switchProfile(profile_num); settingsutils::switchProfile(profile_num);
const auto cur_profile = settingsPersister.currentlyOpenProfileIndex(); const auto cur_profile = settingsPersister.currentlyOpenProfileIndex();
const auto profile_str = cur_profile ? std::to_string(*cur_profile) : "-"; const auto profile_str = cur_profile ? std::to_string(*cur_profile) : "-";
@ -166,7 +167,7 @@ esp_err_t webserver_dump_nvs_handler(httpd_req_t *req)
}); });
} }
switchProfile(switchBackProfile); settingsutils::switchProfile(switchBackProfile);
std::string body; std::string body;
serializeJson(doc, body); serializeJson(doc, body);

View File

@ -0,0 +1,21 @@
#include "menudisplaywithtime.h"
#include "tftinstance.h"
#include "utils.h"
using namespace espgui;
namespace bobbygui {
void MenuDisplayWithTime::start()
{
Base::start();
m_label_currentTime.start();
}
void MenuDisplayWithTime::redraw()
{
Base::redraw();
tft.setTextFont(m_use_big_font() ? 4 : 2);
m_label_currentTime.redraw(fmt::format("&7Time: {}", local_clock_string()));
}
} // namespace

View File

@ -0,0 +1,25 @@
#pragma once
#include <menudisplay.h>
#include <cstdint>
namespace bobbygui {
class MenuDisplayWithTime :
public espgui::MenuDisplay
{
using Base = espgui::MenuDisplay;
public:
void start() override;
void redraw() override;
espgui::Label m_label_currentTime{145, 6};
private:
virtual bool m_use_big_font() const
{
#ifdef MENU_DISPLAY_USE_BIG_TIME
return true;
#else
return false;
#endif
}
};
} // namespace

View File

@ -701,19 +701,8 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20
# Core dump # Core dump
# #
# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set
CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set
# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y
# CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN is not set
CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y
# CONFIG_ESP_COREDUMP_CHECKSUM_CRC32 is not set
CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y
CONFIG_ESP_COREDUMP_ENABLE=y
CONFIG_ESP_COREDUMP_MAX_TASKS_NUM=64
CONFIG_ESP_COREDUMP_UART_DELAY=0
CONFIG_ESP_COREDUMP_STACK_SIZE=0
CONFIG_ESP_COREDUMP_DECODE_INFO=y
# CONFIG_ESP_COREDUMP_DECODE_DISABLE is not set
CONFIG_ESP_COREDUMP_DECODE="info"
# end of Core dump # end of Core dump
# #
@ -1473,19 +1462,8 @@ CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y
CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_TIMER_TASK_STACK_SIZE=3584
CONFIG_SW_COEXIST_ENABLE=y CONFIG_SW_COEXIST_ENABLE=y
# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
# CONFIG_ESP32_COREDUMP_DATA_FORMAT_BIN is not set
CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y
# CONFIG_ESP32_COREDUMP_CHECKSUM_CRC32 is not set
CONFIG_ESP32_COREDUMP_CHECKSUM_SHA256=y
CONFIG_ESP32_ENABLE_COREDUMP=y
CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64
CONFIG_ESP32_CORE_DUMP_UART_DELAY=0
CONFIG_ESP32_CORE_DUMP_STACK_SIZE=0
CONFIG_ESP32_CORE_DUMP_DECODE_INFO=y
# CONFIG_ESP32_CORE_DUMP_DECODE_DISABLE is not set
CONFIG_ESP32_CORE_DUMP_DECODE="info"
CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150
CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 CONFIG_MB_MASTER_DELAY_MS_CONVERT=200
CONFIG_MB_QUEUE_LENGTH=20 CONFIG_MB_QUEUE_LENGTH=20