diff --git a/.gitignore b/.gitignore index 756c3ff..6f35eeb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ desktop.ini /.idea /.ccache /main/certs/* +/.vscode/* diff --git a/.gitmodules b/.gitmodules index 6630b4c..301c25b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "components/cpputils"] path = components/cpputils url = ../../0xFEEDC0DE64/cpputils.git -[submodule "components/espcpputils"] - path = components/espcpputils - url = ../../0xFEEDC0DE64/espcpputils.git [submodule "components/cxx-ring-buffer"] path = components/cxx-ring-buffer url = ../../0xFEEDC0DE64/cxx-ring-buffer.git @@ -61,3 +58,6 @@ [submodule "components/espconfiglib"] path = components/espconfiglib url = ../../0xFEEDC0DE64/espconfiglib.git +[submodule "components/TFT_eSPI_QRcode"] + path = components/TFT_eSPI_QRcode + url = ../TFT_eSPI_QRcode.git diff --git a/components/TFT_eSPI_QRcode b/components/TFT_eSPI_QRcode new file mode 160000 index 0000000..80da304 --- /dev/null +++ b/components/TFT_eSPI_QRcode @@ -0,0 +1 @@ +Subproject commit 80da3047ad397ca9c7ff9d462e848f33f6647af1 diff --git a/config_comred.cmake b/config_comred.cmake index f06480e..212d602 100644 --- a/config_comred.cmake +++ b/config_comred.cmake @@ -118,6 +118,8 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS -DFEATURE_DNS_NS -DSWITCH_BLINK +# -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT + -DFEATURE_ESPNOW ) if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ignore/lockscreen_plugin.cmake") diff --git a/config_feedc0de.cmake b/config_feedc0de.cmake index 7897f01..27c9c97 100644 --- a/config_feedc0de.cmake +++ b/config_feedc0de.cmake @@ -92,10 +92,13 @@ set(BOBBYCAR_BUILDFLAGS -DFEATURE_LEDSTRIP -DPINS_LEDSTRIP=26 -DLEDSTRIP_LENGTH=200 +# -DHEAP_LRGST_CRASH_TEXT_FIX # -DLEDSTRIP_WRONG_DIRECTION -DLEDSTRIP_ANIMATION_DEFAULT=0 -DLEDS_PER_METER=144 -DOLD_NVS # -DFEATURE_DNS_NS +# -DSWITCH_BLINK -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT + -DFEATURE_ESPNOW ) diff --git a/icons/greenpass.png b/icons/greenpass.png new file mode 100644 index 0000000..fbd57d3 Binary files /dev/null and b/icons/greenpass.png differ diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 04d7236..24a7120 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -77,10 +77,13 @@ set(headers displays/menus/demosmenu.h displays/menus/dynamicdebugmenu.h displays/menus/enablemenu.h + displays/menus/espnowmenu.h + displays/menus/espnowsettingsmenu.h displays/menus/feedbackdebugmenu.h displays/menus/gametrakmodesettingsmenu.h displays/menus/genericwifisettingsmenu.h displays/menus/graphsmenu.h + displays/menus/greenpassmenu.h displays/menus/handbremssettingsmenu.h displays/menus/invertmenu.h displays/menus/larsmmodesettingsmenu.h @@ -117,6 +120,7 @@ set(headers displays/popups/alertdisplay.h displays/poweroffdisplay.h displays/powersupplydisplay.h + displays/qrcodedebug.h displays/spirodisplay.h displays/starfielddisplay.h displays/statusdisplay.h @@ -129,6 +133,7 @@ set(headers dpad6wire.h drivingstatistics.h esptexthelpers.h + espnowfunctions.h feedbackparser.h globals.h handbremse.h @@ -141,6 +146,7 @@ set(headers icons/close.h icons/demos.h icons/graph.h + icons/greenpass.h icons/hardware.h icons/info.h icons/lock.h @@ -195,6 +201,7 @@ set(headers webserver_settings.h webserver_stringsettings.h widgets/doubleprogressbar.h + widgets/menudisplaywithtime.h wifi_bobbycar.h wifitexthelpers.h ) @@ -278,10 +285,13 @@ set(sources displays/menus/demosmenu.cpp displays/menus/dynamicdebugmenu.cpp displays/menus/enablemenu.cpp + displays/menus/espnowmenu.cpp + displays/menus/espnowsettingsmenu.cpp displays/menus/feedbackdebugmenu.cpp displays/menus/gametrakmodesettingsmenu.cpp displays/menus/genericwifisettingsmenu.cpp displays/menus/graphsmenu.cpp + displays/menus/greenpassmenu.cpp displays/menus/handbremssettingsmenu.cpp displays/menus/invertmenu.cpp displays/menus/larsmmodesettingsmenu.cpp @@ -318,6 +328,7 @@ set(sources displays/popups/alertdisplay.cpp displays/poweroffdisplay.cpp displays/powersupplydisplay.cpp + displays/qrcodedebug.cpp displays/spirodisplay.cpp displays/starfielddisplay.cpp displays/statusdisplay.cpp @@ -330,6 +341,7 @@ set(sources dpad6wire.cpp drivingstatistics.cpp esptexthelpers.cpp + espnowfunctions.cpp feedbackparser.cpp globals.cpp handbremse.cpp @@ -342,6 +354,7 @@ set(sources icons/close.cpp icons/demos.cpp icons/graph.cpp + icons/greenpass.cpp icons/hardware.cpp icons/info.cpp icons/lock.cpp @@ -397,13 +410,14 @@ set(sources webserver_settings.cpp webserver_stringsettings.cpp widgets/doubleprogressbar.cpp + widgets/menudisplaywithtime.cpp wifi_bobbycar.cpp wifitexthelpers.cpp ) set(dependencies 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 espasynchttpreq espasyncota espchrono espcpputils espconfiglib esp-gui-lib esphttpdutils espwifistack expected fmt ) diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 57a61f3..3e94162 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -14,15 +14,19 @@ struct RefAccessorSaveSettings : public virtual espgui::RefAccessor void setValue(T value) override { espgui::RefAccessor::setValue(value); saveSettings(); }; }; +// Bms #ifdef FEATURE_BMS struct AutoConnectBmsAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.autoConnectBms; } }; #endif + +// Buzzer struct ReverseBeepAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.buzzer.reverseBeep; } }; struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq0; } }; struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq1; } }; struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration0; } }; struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration1; } }; +// Limits struct IMotMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.iMotMax; } }; struct IDcMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.iDcMax; } }; struct NMotMaxKmhAccessor : public virtual espgui::AccessorInterface @@ -34,22 +38,27 @@ struct NMotMaxRpmAccessor : public RefAccessorSaveSettings { int16_t &g struct FieldWeakMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } }; struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } }; +// WiFi struct WifiStaEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.wifiSettings.wifiStaEnabled; } }; struct WifiApEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.wifiSettings.wifiApEnabled; } }; +// Bluetooth #ifdef FEATURE_BLUETOOTH struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } }; #endif +// Bluetooth Low Energy #ifdef FEATURE_BLE struct BleEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.bleSettings.bleEnabled; } }; #endif +// Cloud #ifdef FEATURE_CLOUD struct CloudEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.cloudSettings.cloudEnabled; } }; struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } }; #endif +// Time struct TimezoneOffsetAccessor : public virtual espgui::AccessorInterface { int32_t getValue() const override { return settings.timeSettings.timezoneOffset.count(); } @@ -66,6 +75,7 @@ struct TimeSyncIntervalAccessor : public virtual espgui::AccessorInterface { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } }; struct FrontRightEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } }; struct BackLeftEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } }; @@ -89,6 +99,8 @@ struct SwapFrontBackAccessor : public RefAccessorSaveSettings { void setValue(bool value) override { RefAccessorSaveSettings::setValue(value); updateSwapFrontBack(); }; #endif }; + +// CAN #ifdef FEATURE_CAN struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } }; struct SendBackCanCmdAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } }; @@ -96,6 +108,7 @@ struct CanTransmitTimeoutAccessor : public RefAccessorSaveSettings { in struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } }; #endif +// Input devices struct SampleCountAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } }; struct GasMinAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMin; } }; struct GasMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } }; @@ -117,9 +130,13 @@ struct ModeUpdateRateAccessor : public RefAccessorSaveSettings { int16_ struct StatsUpdateRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } }; struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } }; struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } }; + +// CAN #ifdef FEATURE_CAN struct CanReceiveRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.canReceiveRate; } }; #endif + +// Cloud #ifdef FEATURE_CLOUD struct CloudCollectRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudCollectRate; } }; struct CloudSendRateAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudSendRate; } }; @@ -129,6 +146,7 @@ struct CloudDebugEnableAccessor : public RefAccessorSaveSettings { bool &g struct UdpUseStdStringAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.cloudSettings.udpUseStdString; } }; #endif +// DefaultMode struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } }; struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } }; struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.defaultMode.squareGas; } }; @@ -153,15 +171,19 @@ struct DefaultModeEnableHybridAccessor : public RefAccessorSaveSettings { struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.hybrid.activationLimit; } }; struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } }; +// TempomatMode struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } }; +// LarsmMode struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } }; struct LarsmModeModeAccessor : public RefAccessorSaveSettings { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } }; struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.larsmMode.iterations; } }; +// MotortestMode struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.motortestMode.multiplikator; } }; struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings { uint16_t &getRef() const override { return settings.motortestMode.maxPwm; } }; +// Ledstrip #ifdef FEATURE_LEDSTRIP struct EnableLedAnimationAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.enableLedAnimation; } }; struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } }; @@ -190,13 +212,22 @@ struct BatteryParallelCellsAccessor : public RefAccessorSaveSettings { struct BatteryWHperKMAccessor : public RefAccessorSaveSettings { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } }; struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.battery.applyCalibration; } }; - +// Lockscreen struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } }; template struct LockscreenPinDigitAccessor : public RefAccessorSaveSettings { int8_t &getRef() const override { return settings.lockscreen.pin[index]; } }; +struct LockscreenKeepLockedAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.lockscreen.keepLockedAfterReboot; } }; +// Handbremse struct HandbremsEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.handbremse.enable; } }; struct HandbremsModeAccessor : public RefAccessorSaveSettings { HandbremseMode &getRef() const override { return settings.handbremse.mode; } }; struct HandbremsTimeoutAccessor : public RefAccessorSaveSettings { uint16_t &getRef() const override { return settings.handbremse.triggerTimeout; } }; struct HandbremsAutomaticAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.handbremse.automatic; } }; struct HandbremsVisualizeAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.handbremse.visualize; } }; + +// ESP Now +#ifdef FEATURE_ESPNOW +struct ESPNowSyncTimeEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.espnow.syncTime; } }; +struct ESPNowSyncTimeWithOthersEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.espnow.syncTimeWithOthers; } }; +struct ESPNowSyncBlinkEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.espnow.syncBlink; } }; +#endif diff --git a/main/actions/ledstripanimationactions.h b/main/actions/ledstripanimationactions.h index d79671e..9f705c5 100644 --- a/main/actions/ledstripanimationactions.h +++ b/main/actions/ledstripanimationactions.h @@ -1,40 +1,14 @@ #pragma once #include "actioninterface.h" -#include "utils.h" -#include "globals.h" #include "ledstrip.h" // #include "ledstripdefines.h" -using namespace espgui; - -namespace { #ifdef FEATURE_LEDSTRIP template -class LedStripSetAnimationAction : public virtual ActionInterface +class LedStripSetAnimationAction : public virtual espgui::ActionInterface { public: 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 -} diff --git a/main/actions/ledstripblinkactions.cpp b/main/actions/ledstripblinkactions.cpp index e69de29..8d903b8 100644 --- a/main/actions/ledstripblinkactions.cpp +++ b/main/actions/ledstripblinkactions.cpp @@ -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 diff --git a/main/actions/ledstripblinkactions.h b/main/actions/ledstripblinkactions.h index f22efa5..4ea7541 100644 --- a/main/actions/ledstripblinkactions.h +++ b/main/actions/ledstripblinkactions.h @@ -1,53 +1,37 @@ #pragma once -#include "actioninterface.h" -#include "utils.h" -#include "globals.h" -#include "ledstrip.h" -#include "ledstripdefines.h" - -using namespace espgui; - #ifdef FEATURE_LEDSTRIP -namespace { -class LedstripAnimationBlinkNoneAction : public virtual ActionInterface +#include "actioninterface.h" + +class LedstripAnimationBlinkNoneAction : public virtual espgui::ActionInterface { public: - void triggered() override { blinkAnimation = LEDSTRIP_OVERWRITE_NONE; } + void triggered() override; }; -class LedstripAnimationBlinkLeftAction : public virtual ActionInterface +class LedstripAnimationBlinkLeftAction : public virtual espgui::ActionInterface { public: #ifndef LEDSTRIP_WRONG_DIRECTION - void triggered() override { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT; - } + void triggered() override; #else - void triggered() override { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT; - } + void triggered() override; #endif }; -class LedstripAnimationBlinkRightAction : public virtual ActionInterface +class LedstripAnimationBlinkRightAction : public virtual espgui::ActionInterface { public: #ifndef LEDSTRIP_WRONG_DIRECTION - void triggered() override { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT; - } + void triggered() override; #else - void triggered() override { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT; - } + void triggered() override; #endif }; -class LedstripAnimationBlinkBothAction : public virtual ActionInterface +class LedstripAnimationBlinkBothAction : public virtual espgui::ActionInterface { public: - void triggered() override { blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; } + void triggered() override; }; -} #endif diff --git a/main/actions/switchprofileaction.h b/main/actions/switchprofileaction.h index 735bf06..e321ca4 100644 --- a/main/actions/switchprofileaction.h +++ b/main/actions/switchprofileaction.h @@ -12,7 +12,7 @@ class SwitchProfileAction : public virtual ActionInterface public: void triggered() override { - switchProfile(index); + settingsutils::switchProfile(index); } }; } diff --git a/main/buttons.cpp b/main/buttons.cpp index a9c2670..9abc31a 100644 --- a/main/buttons.cpp +++ b/main/buttons.cpp @@ -1,6 +1,8 @@ #include "buttons.h" #include "modes/defaultmode.h" +using namespace std::chrono_literals; + int rotated{}; bool requestFullRedraw{}; @@ -123,7 +125,7 @@ void InputDispatcher::profileButton(uint8_t index, bool pressed) if (profileButtonDisabled) return; - switchProfile(index); + settingsutils::switchProfile(index); } #ifdef SWITCH_BLINK diff --git a/main/can.cpp b/main/can.cpp index 09d955e..aa9cb82 100644 --- a/main/can.cpp +++ b/main/can.cpp @@ -19,6 +19,8 @@ #include "globals.h" #include "buttons.h" +using namespace std::chrono_literals; + namespace can { namespace { constexpr const char * const TAG = "BOBBYCAN"; diff --git a/main/displays/bmsdisplay.cpp b/main/displays/bmsdisplay.cpp index e69de29..bf89591 100644 --- a/main/displays/bmsdisplay.cpp +++ b/main/displays/bmsdisplay.cpp @@ -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(); + else if (offset > 0) + switchScreen(); +} + +void BmsDisplay::confirm() +{ + switchScreen(); +} +#endif diff --git a/main/displays/bmsdisplay.h b/main/displays/bmsdisplay.h index a9b60c2..46701cc 100644 --- a/main/displays/bmsdisplay.h +++ b/main/displays/bmsdisplay.h @@ -1,5 +1,6 @@ #pragma once +#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS) // 3rdparty lib includes #include @@ -11,122 +12,32 @@ #include "widgets/label.h" #include "screenmanager.h" -namespace { -#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS) -class BmsDisplay : public Display, public ConfirmActionInterface>, public DummyBack +class BmsDisplay : + public espgui::Display, + public espgui::DummyBack { public: void initScreen() override; void redraw() override; - + void confirm() override; void rotate(int offset) override; - Label m_statusLabel{200, 0}; + espgui::Label m_statusLabel{200, 0}; - Label m_voltageLabel{107, 0}; - Label m_capacityLabel{107, 25}; - Label m_socLabel{107, 50}; - Label m_powerLabel{107, 75}; - Label m_currentLabel{107, 100}; - Label m_speedLabel{107, 125}; - Label m_powerPerSpeedLabel{107, 150}; + espgui::Label m_voltageLabel{107, 0}; + espgui::Label m_capacityLabel{107, 25}; + espgui::Label m_socLabel{107, 50}; + espgui::Label m_powerLabel{107, 75}; + espgui::Label m_currentLabel{107, 100}; + espgui::Label m_speedLabel{107, 125}; + espgui::Label m_powerPerSpeedLabel{107, 150}; - std::array m_battLabels{{ - Label{0, 225}, Label{60, 225}, Label{120, 225}, Label{180, 225}, - Label{0, 250}, Label{60, 250}, Label{120, 250}, Label{180, 250}, - Label{0, 275}, Label{60, 275}, Label{120, 275}, Label{180, 275} + std::array m_battLabels{{ + espgui::Label{0, 225}, espgui::Label{60, 225}, espgui::Label{120, 225}, espgui::Label{180, 225}, + espgui::Label{0, 250}, espgui::Label{60, 250}, espgui::Label{120, 250}, espgui::Label{180, 250}, + 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(); - else if (offset > 0) - switchScreen(); -} #endif -} diff --git a/main/displays/calibratedisplay.cpp b/main/displays/calibratedisplay.cpp index a537308..d007897 100644 --- a/main/displays/calibratedisplay.cpp +++ b/main/displays/calibratedisplay.cpp @@ -5,6 +5,7 @@ #include // local includes +#include "displays/menus/mainmenu.h" #include "displays/statusdisplay.h" #include "displays/menus/boardcomputerhardwaresettingsmenu.h" @@ -241,6 +242,12 @@ void CalibrateDisplay::back() case Status::Begin: if (m_bootup) espgui::switchScreen(); + else if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked) + { + espgui::switchScreen(); + settings.lockscreen.locked = false; + saveSettings(); + } else espgui::switchScreen(); break; diff --git a/main/displays/garagedisplay.cpp b/main/displays/garagedisplay.cpp index dba370f..8592dbd 100644 --- a/main/displays/garagedisplay.cpp +++ b/main/displays/garagedisplay.cpp @@ -14,6 +14,7 @@ #include "displays/menus/mainmenu.h" #include "globals.h" #include "texts.h" +#include "espnowfunctions.h" #ifdef FEATURE_GARAGE void GarageDisplay::start() @@ -41,6 +42,14 @@ void GarageDisplay::redraw() 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(); +#endif } void GarageDisplay::back() diff --git a/main/displays/lockscreen.cpp b/main/displays/lockscreen.cpp index beb8d5f..efe33c7 100644 --- a/main/displays/lockscreen.cpp +++ b/main/displays/lockscreen.cpp @@ -10,6 +10,7 @@ #include "texts.h" #include "buttons.h" #include "displays/menus/mainmenu.h" +#include "displays/calibratedisplay.h" void Lockscreen::start() { @@ -23,6 +24,11 @@ void Lockscreen::start() profileButtonDisabled = !settings.lockscreen.allowPresetSwitch; isLocked = true; + if (settings.lockscreen.keepLockedAfterReboot && !settings.lockscreen.locked) + { + settings.lockscreen.locked = true; + saveSettings(); + } } void Lockscreen::initScreen() @@ -64,16 +70,19 @@ void Lockscreen::update() void Lockscreen::redraw() { - if (m_pressed) + if (m_pressed || m_back_pressed) { drawRect(m_currentIndex, 1, 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) { - espgui::switchScreen(); + if (!gas || !brems || *gas > 200.f || *brems > 200.f) + espgui::switchScreen(true); + else + espgui::switchScreen(); #ifdef LOCKSCREEN_PLUGIN #pragma message "Activating Lockscreen Plugin" #include LOCKSCREEN_PLUGIN @@ -83,7 +92,12 @@ void Lockscreen::redraw() m_numbers = {0,0,0,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])); @@ -92,6 +106,7 @@ void Lockscreen::redraw() drawRect(m_currentIndex, 2, TFT_YELLOW); m_pressed = false; + m_back_pressed = false; } if (m_rotated) @@ -124,6 +139,14 @@ void Lockscreen::stop() profileButtonDisabled = 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() @@ -133,6 +156,9 @@ void Lockscreen::confirm() void Lockscreen::back() { + if (m_currentIndex > 0) + m_currentIndex--; + m_back_pressed = true; } void Lockscreen::rotate(int offset) diff --git a/main/displays/lockscreen.h b/main/displays/lockscreen.h index 5af1037..57fd890 100644 --- a/main/displays/lockscreen.h +++ b/main/displays/lockscreen.h @@ -46,6 +46,7 @@ private: uint8_t m_currentIndex{}; bool m_pressed; + bool m_back_pressed; int m_rotated; ModeInterface *m_oldMode; diff --git a/main/displays/menus/accesspointwifisettingsmenu.cpp b/main/displays/menus/accesspointwifisettingsmenu.cpp index e69de29..a37981e 100644 --- a/main/displays/menus/accesspointwifisettingsmenu.cpp +++ b/main/displays/menus/accesspointwifisettingsmenu.cpp @@ -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, ToggleBoolAction, CheckboxIcon, WifiApEnabledAccessor>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void AccessPointWifiSettingsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/accesspointwifisettingsmenu.h b/main/displays/menus/accesspointwifisettingsmenu.h index 11be9f9..49c39f8 100644 --- a/main/displays/menus/accesspointwifisettingsmenu.h +++ b/main/displays/menus/accesspointwifisettingsmenu.h @@ -2,37 +2,13 @@ // local includes #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" -using namespace espgui; - -namespace { class AccessPointWifiSettingsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - AccessPointWifiSettingsMenu() - { - constructMenuItem, ToggleBoolAction, CheckboxIcon, WifiApEnabledAccessor>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + AccessPointWifiSettingsMenu(); + void back() override; }; -} // namespace diff --git a/main/displays/menus/debugmenu.cpp b/main/displays/menus/debugmenu.cpp index 66b6fbb..ad293b8 100644 --- a/main/displays/menus/debugmenu.cpp +++ b/main/displays/menus/debugmenu.cpp @@ -19,6 +19,7 @@ #include "icons/battery.h" #include "debugcolorhelpers.h" #include "esptexthelpers.h" +#include "displays/qrcodedebug.h" #include "displays/menus/commanddebugmenu.h" #include "displays/menus/motorstatedebugmenu.h" #include "displays/menus/feedbackdebugmenu.h" @@ -47,6 +48,7 @@ using namespace espgui; DebugMenu::DebugMenu() { constructMenuItem(); + constructMenuItem, SwitchScreenAction>>(); constructMenuItem, LoadSettingsAction>>(); constructMenuItem, SaveSettingsAction>>(); constructMenuItem, EraseNvsAction>>(); diff --git a/main/displays/menus/espnowmenu.cpp b/main/displays/menus/espnowmenu.cpp new file mode 100644 index 0000000..c9f1aee --- /dev/null +++ b/main/displays/menus/espnowmenu.cpp @@ -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, espnowmenu::SendBobbycarTimesyncMessageAction, StaticMenuItemIcon<&bobbyicons::time>>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTimeStampAccessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTsFromOtherBobbycarsAccessor>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::settings>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void EspNowMenu::back() +{ + switchScreen(); +} +#endif diff --git a/main/displays/menus/espnowmenu.h b/main/displays/menus/espnowmenu.h new file mode 100644 index 0000000..d4155bf --- /dev/null +++ b/main/displays/menus/espnowmenu.h @@ -0,0 +1,42 @@ +#pragma once + +#ifdef FEATURE_ESPNOW + +#include +#include +#include +#include +#include +#include +#include + +#include "espnowfunctions.h" + +using namespace espgui; + +namespace espnowmenu { + +struct ReceiveTimeStampAccessor : public RefAccessor { bool &getRef() const override { return espnow::receiveTimeStamp; } }; +struct ReceiveTsFromOtherBobbycarsAccessor : public RefAccessor { 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 +{ +public: + EspNowMenu(); + void back() override; +}; + +#endif diff --git a/main/displays/menus/espnowsettingsmenu.cpp b/main/displays/menus/espnowsettingsmenu.cpp new file mode 100644 index 0000000..e642012 --- /dev/null +++ b/main/displays/menus/espnowsettingsmenu.cpp @@ -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, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeEnabledAccessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeWithOthersEnabledAccessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, ESPNowSyncBlinkEnabledAccessor>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void EspNowSettingsMenu::back() +{ + switchScreen(); +} +#endif diff --git a/main/displays/menus/espnowsettingsmenu.h b/main/displays/menus/espnowsettingsmenu.h new file mode 100644 index 0000000..577d463 --- /dev/null +++ b/main/displays/menus/espnowsettingsmenu.h @@ -0,0 +1,29 @@ +#pragma once + +#ifdef FEATURE_ESPNOW + +#include +#include +#include +#include +#include +#include +#include + +#include "espnowfunctions.h" + +using namespace espgui; + +namespace espnowsettingsmenu { +} // namespace + +class EspNowSettingsMenu : + public espgui::MenuDisplay, + public espgui::StaticText +{ +public: + EspNowSettingsMenu(); + void back() override; +}; + +#endif diff --git a/main/displays/menus/feedbackdebugmenu.h b/main/displays/menus/feedbackdebugmenu.h index 5e1fb06..92104a6 100644 --- a/main/displays/menus/feedbackdebugmenu.h +++ b/main/displays/menus/feedbackdebugmenu.h @@ -10,6 +10,7 @@ #include "texts.h" #include "debugtexthelpers.h" #include "debugcolorhelpers.h" +#include "displays/menus/debugmenu.h" using namespace espgui; diff --git a/main/displays/menus/greenpassmenu.cpp b/main/displays/menus/greenpassmenu.cpp new file mode 100644 index 0000000..df66874 --- /dev/null +++ b/main/displays/menus/greenpassmenu.cpp @@ -0,0 +1,49 @@ +#include "greenpassmenu.h" + +#include + +// 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, ShowCertAction>>(); + constructMenuItem, SwitchScreenAction, 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(); +} diff --git a/main/displays/menus/greenpassmenu.h b/main/displays/menus/greenpassmenu.h new file mode 100644 index 0000000..a024dc3 --- /dev/null +++ b/main/displays/menus/greenpassmenu.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +// local includes +#include "menudisplay.h" +#include "texts.h" + +namespace greenpassmenu { +extern bool showingQRCode; +} // namespace + +class GreenPassMenu : + public espgui::MenuDisplay, + public espgui::StaticText +{ + 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{}; + }; +}; diff --git a/main/displays/menus/ledstripmenu.cpp b/main/displays/menus/ledstripmenu.cpp index cdeba51..e5d99f1 100644 --- a/main/displays/menus/ledstripmenu.cpp +++ b/main/displays/menus/ledstripmenu.cpp @@ -1,28 +1,30 @@ #include "ledstripmenu.h" +#ifdef FEATURE_LEDSTRIP // 3rdparty lib includes #include -#include "menuitem.h" -#include "actions/toggleboolaction.h" -#include "actions/switchscreenaction.h" -#include "icons/back.h" -#include "checkboxicon.h" -#include "changevaluedisplay.h" -#include "actioninterface.h" +#include +#include +#include +#include +#include +#include +#include // 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 "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 { using LedsCountChangeScreen = makeComponent< ChangeValueDisplay, @@ -109,8 +111,6 @@ public: }; } // namespace -using namespace espgui; - LedstripMenu::LedstripMenu() { constructMenuItem, SwitchScreenAction>>(); diff --git a/main/displays/menus/ledstripmenu.h b/main/displays/menus/ledstripmenu.h index d093463..d6e6a62 100644 --- a/main/displays/menus/ledstripmenu.h +++ b/main/displays/menus/ledstripmenu.h @@ -1,14 +1,14 @@ #pragma once // 3rdparty lib includes -#include "menudisplay.h" +#include "widgets/menudisplaywithtime.h" // local includes #include "texts.h" #ifdef FEATURE_LEDSTRIP class LedstripMenu : - public espgui::MenuDisplay, + public bobbygui::MenuDisplayWithTime, public espgui::StaticText { public: diff --git a/main/displays/menus/ledstripselectblinkmenu.cpp b/main/displays/menus/ledstripselectblinkmenu.cpp index e69de29..6e44234 100644 --- a/main/displays/menus/ledstripselectblinkmenu.cpp +++ b/main/displays/menus/ledstripselectblinkmenu.cpp @@ -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>(); + constructMenuItem>(); + constructMenuItem, LedstripAnimationBlinkNoneAction>>(); + constructMenuItem, LedstripAnimationBlinkLeftAction>>(); + constructMenuItem, LedstripAnimationBlinkRightAction>>(); + constructMenuItem, LedstripAnimationBlinkBothAction>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, LedstripEnableBlinkAnimationAccessor>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void LedstripSelectBlinkMenu::back() +{ + switchScreen(); +} +#endif diff --git a/main/displays/menus/ledstripselectblinkmenu.h b/main/displays/menus/ledstripselectblinkmenu.h index ca37a95..1819c14 100644 --- a/main/displays/menus/ledstripselectblinkmenu.h +++ b/main/displays/menus/ledstripselectblinkmenu.h @@ -2,64 +2,22 @@ // Local includes #include "menudisplay.h" -#include "utils.h" -#include "menuitem.h" -#include "ledstrip.h" -#include "ledstripselectanimationmenu.h" -#include "icons/back.h" #include "texts.h" -#include "actions/dummyaction.h" -#include "actions/ledstripblinkactions.h" -#include "actions/switchscreenaction.h" -#include "actions/toggleboolaction.h" -#include "checkboxicon.h" +#include "ledstrip.h" #include "ledstripdefines.h" -#include "accessors/settingsaccessors.h" -#include "ledstripmenu.h" #ifdef FEATURE_LEDSTRIP -class currentSelectedBlinkAnimationText : public virtual TextInterface { public: std::string text() const override { - 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; - } - }; +class currentSelectedBlinkAnimationText : public virtual espgui::TextInterface +{ +public: std::string text() const override; }; -using namespace espgui; - -namespace { - class LedstripSelectBlinkMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> - { - public: - LedstripSelectBlinkMenu() - { - constructMenuItem>(); - constructMenuItem>(); - constructMenuItem, LedstripAnimationBlinkNoneAction>>(); - constructMenuItem, LedstripAnimationBlinkLeftAction>>(); - constructMenuItem, LedstripAnimationBlinkRightAction>>(); - constructMenuItem, LedstripAnimationBlinkBothAction>>(); - constructMenuItem, ToggleBoolAction, CheckboxIcon, LedstripEnableBlinkAnimationAccessor>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } - }; -} // Namespace +class LedstripSelectBlinkMenu : + public espgui::MenuDisplay, + public espgui::StaticText +{ +public: + LedstripSelectBlinkMenu(); + void back() override; +}; #endif diff --git a/main/displays/menus/ledstripselectotamode.cpp b/main/displays/menus/ledstripselectotamode.cpp index e69de29..97ce863 100644 --- a/main/displays/menus/ledstripselectotamode.cpp +++ b/main/displays/menus/ledstripselectotamode.cpp @@ -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, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, LedstripChangeOtaAnimModeAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void ledstripOtaAnimationChangeMenu::back() +{ + switchScreen(); +} +#endif diff --git a/main/displays/menus/ledstripselectotamode.h b/main/displays/menus/ledstripselectotamode.h index f49e54d..02ffc51 100644 --- a/main/displays/menus/ledstripselectotamode.h +++ b/main/displays/menus/ledstripselectotamode.h @@ -2,20 +2,15 @@ // Local includes #include "menudisplay.h" -#include "utils.h" -#include "menuitem.h" -#include "ledstrip.h" -#include "icons/back.h" #include "texts.h" -#include "actions/switchscreenaction.h" -#include "accessors/settingsaccessors.h" -#include "ledstripmenu.h" +#include "ledstrip.h" +#include "globals.h" +#include "utils.h" #if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA) -using namespace espgui; template -class LedstripChangeOtaAnimModeAction : public virtual ActionInterface +class LedstripChangeOtaAnimModeAction : public virtual espgui::ActionInterface { public: void triggered() override @@ -25,20 +20,12 @@ public: } }; -namespace { - class ledstripOtaAnimationChangeMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> - { - public: - ledstripOtaAnimationChangeMenu() - { - constructMenuItem, LedstripChangeOtaAnimModeAction>>(); - constructMenuItem, LedstripChangeOtaAnimModeAction>>(); - constructMenuItem, LedstripChangeOtaAnimModeAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } - }; -} // Namespace +class ledstripOtaAnimationChangeMenu : + public espgui::MenuDisplay, + public espgui::StaticText +{ +public: + ledstripOtaAnimationChangeMenu(); + void back() override; +}; #endif diff --git a/main/displays/menus/lockscreensettingsmenu.cpp b/main/displays/menus/lockscreensettingsmenu.cpp index 57b9a08..b3fdffa 100644 --- a/main/displays/menus/lockscreensettingsmenu.cpp +++ b/main/displays/menus/lockscreensettingsmenu.cpp @@ -52,6 +52,7 @@ using namespace espgui; LockscreenSettingsMenu::LockscreenSettingsMenu() { constructMenuItem, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, LockscreenKeepLockedAccessor>>(); constructMenuItem>, SwitchScreenAction>>(); constructMenuItem>, SwitchScreenAction>>(); constructMenuItem>, SwitchScreenAction>>(); diff --git a/main/displays/menus/mainmenu.cpp b/main/displays/menus/mainmenu.cpp index 9625b8c..259f234 100644 --- a/main/displays/menus/mainmenu.cpp +++ b/main/displays/menus/mainmenu.cpp @@ -19,6 +19,7 @@ #include "displays/menus/settingsmenu.h" #include "displays/menus/mosfetsmenu.h" #include "displays/menus/demosmenu.h" +#include "displays/menus/greenpassmenu.h" #include "displays/lockscreen.h" #include "displays/garagedisplay.h" #include "displays/menus/otamenu.h" @@ -45,11 +46,28 @@ #include "icons/poweroff.h" #include "icons/reboot.h" #include "icons/statistics.h" +#include "icons/greenpass.h" +#include "icons/time.h" +#include "tftinstance.h" 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() { + // constructMenuItem>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); #ifdef FEATURE_LEDSTRIP constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::neopixel>>>(); @@ -72,6 +90,7 @@ MainMenu::MainMenu() if (SHOWITEM) { constructMenuItem, SwitchScreenAction>>(); } #endif constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::demos>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::greenpass>>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::lock>>>(); #ifdef FEATURE_GARAGE if (SHOWITEM) { constructMenuItem, SwitchScreenAction>>(); } diff --git a/main/displays/menus/mainmenu.h b/main/displays/menus/mainmenu.h index ba241b2..5499ca0 100644 --- a/main/displays/menus/mainmenu.h +++ b/main/displays/menus/mainmenu.h @@ -1,11 +1,11 @@ #pragma once // 3rdparty lib includes -#include "menudisplay.h" #include "menuitem.h" // local includes #include "texts.h" +#include "widgets/menudisplaywithtime.h" #ifdef MAINMENU_PLUGIN #include MAINMENU_PLUGIN #endif @@ -22,11 +22,11 @@ namespace { } // namespace class MainMenu : - public espgui::MenuDisplay, + public bobbygui::MenuDisplayWithTime, public espgui::StaticText { + using Base = espgui::MenuDisplay; public: MainMenu(); - void back() override; }; diff --git a/main/displays/menus/mosfetsmenu.cpp b/main/displays/menus/mosfetsmenu.cpp index e69de29..2c2073d 100644 --- a/main/displays/menus/mosfetsmenu.cpp +++ b/main/displays/menus/mosfetsmenu.cpp @@ -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, ToggleBoolAction, CheckboxIcon, Mosfet0Accessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, Mosfet1Accessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, Mosfet2Accessor>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void MosfetsMenu::back() +{ + switchScreen(); +} + +#endif diff --git a/main/displays/menus/mosfetsmenu.h b/main/displays/menus/mosfetsmenu.h index 92e7587..ee1b88b 100644 --- a/main/displays/menus/mosfetsmenu.h +++ b/main/displays/menus/mosfetsmenu.h @@ -1,22 +1,13 @@ #pragma once -// local includes +#ifdef FEATURE_MOSFETS #include "menudisplay.h" -#include "utils.h" -#include "menuitem.h" -#include "actions/toggleboolaction.h" -#include "actions/switchscreenaction.h" -#include "checkboxicon.h" -#include "icons/back.h" +#include "accessorinterface.h" #include "texts.h" #include "types.h" -using namespace espgui; - -namespace { -#ifdef FEATURE_MOSFETS template -class GPIOAccessor : public virtual AccessorInterface +class GPIOAccessor : public virtual espgui::AccessorInterface { public: bool getValue() const override { return digitalRead(PIN); } @@ -28,18 +19,11 @@ using Mosfet1Accessor = GPIOAccessor; using Mosfet2Accessor = GPIOAccessor; class MosfetsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - MosfetsMenu() - { - constructMenuItem, ToggleBoolAction, CheckboxIcon, Mosfet0Accessor>>(); - constructMenuItem, ToggleBoolAction, CheckboxIcon, Mosfet1Accessor>>(); - constructMenuItem, ToggleBoolAction, CheckboxIcon, Mosfet2Accessor>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + MosfetsMenu(); + void back() override; }; #endif -} // namespace diff --git a/main/displays/menus/selectbuildservermenu.cpp b/main/displays/menus/selectbuildservermenu.cpp index 702a4cc..deff708 100644 --- a/main/displays/menus/selectbuildservermenu.cpp +++ b/main/displays/menus/selectbuildservermenu.cpp @@ -10,7 +10,7 @@ // local includes #include "actions/dummyaction.h" #include "buildserver.h" -#include "displays/menus/settingsmenu.h" +#include "displays/menus/otamenu.h" #include "utils.h" #ifdef FEATURE_OTA @@ -67,11 +67,11 @@ SelectBuildServerMenu::SelectBuildServerMenu() constructMenuItem, DefaultFont, StaticColor, DummyAction>>(); } - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); } void SelectBuildServerMenu::back() { - espgui::switchScreen(); + espgui::switchScreen(); } #endif diff --git a/main/displays/menus/settingsmenu.cpp b/main/displays/menus/settingsmenu.cpp index db53ff4..a4c0901 100644 --- a/main/displays/menus/settingsmenu.cpp +++ b/main/displays/menus/settingsmenu.cpp @@ -28,6 +28,7 @@ #include "displays/menus/bluetoothsettingsmenu.h" #include "displays/menus/blesettingsmenu.h" #include "displays/menus/cloudsettingsmenu.h" +#include "displays/menus/espnowmenu.h" #include "displays/menus/selectbuildservermenu.h" #include "displays/menus/timesettingsmenu.h" #include "displays/menus/modessettingsmenu.h" @@ -61,6 +62,9 @@ SettingsMenu::SettingsMenu() constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::wifi>>>(); +#ifdef FEATURE_ESPNOW + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::wifi>>>(); +#endif #ifdef FEATURE_BLUETOOTH constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::bluetooth>>>(); #endif diff --git a/main/displays/menus/settingsmenu.h b/main/displays/menus/settingsmenu.h index 346ecd5..43b3c31 100644 --- a/main/displays/menus/settingsmenu.h +++ b/main/displays/menus/settingsmenu.h @@ -1,13 +1,13 @@ #pragma once // 3rdparty lib includes -#include "menudisplay.h" +#include "widgets/menudisplaywithtime.h" // local includes #include "texts.h" class SettingsMenu : - public espgui::MenuDisplay, + public bobbygui::MenuDisplayWithTime, public espgui::StaticText { public: diff --git a/main/displays/menus/statisticsmenu.cpp b/main/displays/menus/statisticsmenu.cpp index 4c5075b..4852ad0 100644 --- a/main/displays/menus/statisticsmenu.cpp +++ b/main/displays/menus/statisticsmenu.cpp @@ -3,9 +3,11 @@ // local includes #include "mainmenu.h" #include "actions/dummyaction.h" +#include "actions/switchscreenaction.h" #include "actioninterface.h" #include "fmt/core.h" #include "utils.h" +#include "icons/back.h" #include "icons/time.h" #include "icons/reboot.h" #include "icons/update.h" diff --git a/main/displays/menus/statisticsmenu.h b/main/displays/menus/statisticsmenu.h index 661790d..b03b5ca 100644 --- a/main/displays/menus/statisticsmenu.h +++ b/main/displays/menus/statisticsmenu.h @@ -1,18 +1,14 @@ #pragma once // 3rdparty lib includes -#include +#include "widgets/menudisplaywithtime.h" #include -#include -#include -#include // Local includes -#include "utils.h" #include "texts.h" class StatisticsMenu : - public espgui::MenuDisplay, + public bobbygui::MenuDisplayWithTime, public espgui::StaticText { public: diff --git a/main/displays/menus/timesettingsmenu.cpp b/main/displays/menus/timesettingsmenu.cpp index c71dfe2..ff8ab82 100644 --- a/main/displays/menus/timesettingsmenu.cpp +++ b/main/displays/menus/timesettingsmenu.cpp @@ -37,7 +37,8 @@ public: #ifdef CONFIG_ESPCHRONO_SUPPORT_DEFAULT_TIMEZONE return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::local_clock::now()))); #else - return "TODO"; + // Crude local time implementation + return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::utc_clock::now() + settings.timeSettings.timezoneOffset))); #endif } }; diff --git a/main/displays/menus/timesettingsmenu.h b/main/displays/menus/timesettingsmenu.h index b8b238c..1ea7eb7 100644 --- a/main/displays/menus/timesettingsmenu.h +++ b/main/displays/menus/timesettingsmenu.h @@ -1,13 +1,13 @@ #pragma once // 3rdparty lib includes -#include "menudisplay.h" +#include "widgets/menudisplaywithtime.h" // local includes #include "texts.h" class TimeSettingsMenu : - public espgui::MenuDisplay, + public bobbygui::MenuDisplayWithTime, public espgui::StaticText { public: diff --git a/main/displays/qrcodedebug.cpp b/main/displays/qrcodedebug.cpp new file mode 100644 index 0000000..f59a3fc --- /dev/null +++ b/main/displays/qrcodedebug.cpp @@ -0,0 +1,36 @@ +#include "qrcodedebug.h" + +#include + +#include "displays/menus/debugmenu.h" +#include "globals.h" +#include "screenmanager.h" + +using namespace espgui; + +QrCodeDebugDisplay::QrCodeDebugDisplay() +{ +} + +void QrCodeDebugDisplay::back() +{ + switchScreen(); +} + +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!"); +} diff --git a/main/displays/qrcodedebug.h b/main/displays/qrcodedebug.h new file mode 100644 index 0000000..84ff09e --- /dev/null +++ b/main/displays/qrcodedebug.h @@ -0,0 +1,21 @@ +#pragma once + +// 3rdparty lib includes +#include +#include + +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}; +}; diff --git a/main/dpad3wire.h b/main/dpad3wire.h index a507729..c2403d7 100644 --- a/main/dpad3wire.h +++ b/main/dpad3wire.h @@ -11,6 +11,7 @@ #include "dpad.h" #include "buttons.h" #include "types.h" +#include "globals.h" namespace { namespace dpad3wire diff --git a/main/dpad5wire.h b/main/dpad5wire.h index 7666f98..1296e8c 100644 --- a/main/dpad5wire.h +++ b/main/dpad5wire.h @@ -13,6 +13,7 @@ // local includes #include "buttons.h" #include "types.h" +#include "globals.h" namespace { namespace dpad5wire { diff --git a/main/dpad5wire_2out.h b/main/dpad5wire_2out.h index 96e870b..34c1aff 100644 --- a/main/dpad5wire_2out.h +++ b/main/dpad5wire_2out.h @@ -13,6 +13,7 @@ // local includes #include "buttons.h" #include "types.h" +#include "globals.h" namespace { namespace dpad5wire_2out { diff --git a/main/dpad6wire.h b/main/dpad6wire.h index 8eb1eef..b353811 100644 --- a/main/dpad6wire.h +++ b/main/dpad6wire.h @@ -12,6 +12,7 @@ // local includes #include "buttons.h" #include "types.h" +#include "globals.h" namespace { namespace dpad6wire { diff --git a/main/espnowfunctions.cpp b/main/espnowfunctions.cpp new file mode 100644 index 0000000..841a2b6 --- /dev/null +++ b/main/espnowfunctions.cpp @@ -0,0 +1,290 @@ +#ifdef FEATURE_ESPNOW +#include "espnowfunctions.h" + +#include + +#include +#include +#include +#include + +#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 message_queue{}; +std::vector 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(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(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 diff --git a/main/espnowfunctions.h b/main/espnowfunctions.h new file mode 100644 index 0000000..99f7726 --- /dev/null +++ b/main/espnowfunctions.h @@ -0,0 +1,30 @@ +#pragma once +#ifdef FEATURE_ESPNOW +#include +#include +#include +#include +#include +#include + +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 message_queue; +extern std::vector 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 diff --git a/main/icons/greenpass.cpp b/main/icons/greenpass.cpp new file mode 100644 index 0000000..0a24589 --- /dev/null +++ b/main/icons/greenpass.cpp @@ -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 diff --git a/main/icons/greenpass.h b/main/icons/greenpass.h new file mode 100644 index 0000000..437b069 --- /dev/null +++ b/main/icons/greenpass.h @@ -0,0 +1,7 @@ +#pragma once + +#include "icon.h" + +namespace bobbyicons { +extern const espgui::Icon<24, 24> greenpass; +} // namespace bobbyicons diff --git a/main/main.cpp b/main/main.cpp index 85ba933..36240dd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -59,12 +59,16 @@ using namespace std::chrono_literals; #endif #include "modes/defaultmode.h" #include "displays/statusdisplay.h" +#include "displays/lockscreen.h" #include "displays/calibratedisplay.h" #ifdef FEATURE_DNS_NS #include "dnsannounce.h" #endif #include "drivingstatistics.h" #include "newsettings.h" +#ifdef FEATURE_ESPNOW +#include "espnowfunctions.h" +#endif #include "taskmanager.h" namespace { @@ -230,10 +234,22 @@ extern "C" void app_main() switchScreen(); #else - if (!gas || !brems || *gas > 200.f || *brems > 200.f) - espgui::switchScreen(true); + if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked) + { + espgui::switchScreen(); + } else - espgui::switchScreen(); + { + if (!gas || !brems || *gas > 200.f || *brems > 200.f) + espgui::switchScreen(true); + else + { + espgui::switchScreen(); + } + } +#endif +#ifdef FEATURE_ESPNOW + espnow::initESPNow(); #endif while (true) @@ -330,6 +346,10 @@ extern "C" void app_main() } #endif +#ifdef FEATURE_ESPNOW + espnow::handle(); +#endif + #ifdef FEATURE_CLOUD if (!lastCloudCollect || now - *lastCloudCollect >= std::chrono::milliseconds{settings.boardcomputerHardware.timersSettings.cloudCollectRate}) { diff --git a/main/presets.h b/main/presets.h index 34c1f72..7997adf 100644 --- a/main/presets.h +++ b/main/presets.h @@ -274,6 +274,8 @@ constexpr Settings::Ledstrip defaultLedstrip { constexpr Settings::LockscreenSettings defaultLockscreen { .allowPresetSwitch = true, + .keepLockedAfterReboot = false, + .locked = false, .pin = { 1, 2, 3, 4 } }; @@ -300,6 +302,19 @@ constexpr Settings::SavedStatistics defaultSavedStatistics { .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 { #ifdef FEATURE_BMS .autoConnectBms = false, @@ -330,7 +345,10 @@ constexpr Settings defaultSettings { .hybrid = defaultHybrid, .lockscreen = defaultLockscreen, .savedStatistics = defaultSavedStatistics, - .handbremse = defaultHandbremse + .handbremse = defaultHandbremse, +#ifdef FEATURE_ESPNOW + .espnow = defaultEspNowSettings, +#endif }; StringSettings makeDefaultStringSettings(); diff --git a/main/settings.h b/main/settings.h index 87549e4..93915ae 100644 --- a/main/settings.h +++ b/main/settings.h @@ -210,6 +210,8 @@ struct Settings struct LockscreenSettings { bool allowPresetSwitch; + bool keepLockedAfterReboot; + bool locked; std::array pin; } lockscreen; @@ -224,6 +226,13 @@ struct Settings bool enable; bool visualize; } handbremse; +#ifdef FEATURE_ESPNOW + struct ESPNOW { + bool syncTime; + bool syncTimeWithOthers; + bool syncBlink; + } espnow; +#endif template void executeForEveryCommonSetting(T &&callable); @@ -353,6 +362,8 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("hybridDeacL", hybrid.deactivationLimit); callable("lockAlwPresetSw", lockscreen.allowPresetSwitch); + callable("keepLocked", lockscreen.keepLockedAfterReboot); + callable("currentlyLocked", lockscreen.locked); callable("lockscreenPin", lockscreen.pin); callable("totalCentimeter", savedStatistics.totalCentimeters); @@ -362,6 +373,14 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("handBremsM", handbremse.mode); callable("handBremsT", handbremse.triggerTimeout); 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 diff --git a/main/settingsutils.cpp b/main/settingsutils.cpp index e69de29..87b64bb 100644 --- a/main/settingsutils.cpp +++ b/main/settingsutils.cpp @@ -0,0 +1,45 @@ +#include "settingsutils.h" + +// esp-idf includes +#include + +// 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 diff --git a/main/settingsutils.h b/main/settingsutils.h index a72191e..54dba3d 100644 --- a/main/settingsutils.h +++ b/main/settingsutils.h @@ -1,45 +1,7 @@ #pragma once -// esp-idf includes -#include +#include -// local includes -#include "globals.h" -#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; - } -} +namespace settingsutils { +void switchProfile(uint8_t index); } diff --git a/main/texts.cpp b/main/texts.cpp index baed3b2..71da3e8 100644 --- a/main/texts.cpp +++ b/main/texts.cpp @@ -332,6 +332,7 @@ char TEXT_ANIMATION_BLINKBOTH[] = "Blink Both"; //LockscreenSettingsMenu char TEXT_LOCKSCREENSETTINGS[] = "Lockscreen Settings"; char TEXT_ALLOWPRESETSWITCH[] = "Allow preset switch"; +char TEXT_KEEPLOCKED[] = "Keep locked"; char TEXT_PINDIGIT0[] = "PIN digit0"; char TEXT_PINDIGIT1[] = "PIN digit1"; char TEXT_PINDIGIT2[] = "PIN digit2"; @@ -537,4 +538,23 @@ char TEXT_REENABLE_MENUITEMS[] = "Show advanced"; //SelectBuildserverBranchMenu char TEXT_SELECT_BRANCH[] = "Select 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 diff --git a/main/texts.h b/main/texts.h index b3b9a74..42d2bd4 100644 --- a/main/texts.h +++ b/main/texts.h @@ -332,6 +332,7 @@ extern char TEXT_ANIMATION_BLINKBOTH[]; //LockscreenSettingsMenu extern char TEXT_LOCKSCREENSETTINGS[]; extern char TEXT_ALLOWPRESETSWITCH[]; +extern char TEXT_KEEPLOCKED[]; extern char TEXT_PINDIGIT0[]; extern char TEXT_PINDIGIT1[]; extern char TEXT_PINDIGIT2[]; @@ -536,6 +537,26 @@ extern char TEXT_REENABLE_MENUITEMS[]; //SelectBuildserverBranchMenu extern char TEXT_SELECT_BRANCH[]; 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 using namespace bobbytexts; diff --git a/main/udpcloud.cpp b/main/udpcloud.cpp index fc67270..9397570 100644 --- a/main/udpcloud.cpp +++ b/main/udpcloud.cpp @@ -25,7 +25,6 @@ constexpr const char * const TAG = "bobbycloud"; using namespace std::chrono_literals; // Little "flash" on statusdisplay when udp stuff is happening bool visualSendUdpPacket; - espchrono::millis_clock::time_point timestampLastFailed; void spamUdpBroadcast() @@ -294,7 +293,7 @@ std::string buildUdpCloudString() void sendUdpCloudPacket() { EVERY_N_MILLIS(settings.boardcomputerHardware.timersSettings.udpSendRateMs) { - if (espchrono::ago(timestampLastFailed) < 3s) + if (espchrono::ago(timestampLastFailed) < 2s) { visualSendUdpPacket = false; return; @@ -332,6 +331,7 @@ void sendUdpCloudPacket() if (udpCloudIp.type != IPADDR_TYPE_V4) { ESP_LOGE(TAG, "unsupported ip type: %hhu", udpCloudIp.type); + timestampLastFailed = espchrono::millis_clock::now(); visualSendUdpPacket = false; return; } @@ -348,6 +348,7 @@ void sendUdpCloudPacket() 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()); } diff --git a/main/utils.cpp b/main/utils.cpp index 358e768..0c8edea 100644 --- a/main/utils.cpp +++ b/main/utils.cpp @@ -337,3 +337,26 @@ uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::millisecond else 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(now.time_since_epoch()).count(), time_valid(now) ? "":" (probably invalid)"); + const auto seconds = std::chrono::floor(now.time_since_epoch()); + + timeval ts { + .tv_sec = (long int)seconds.count(), + .tv_usec = (long int)std::chrono::floor(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); +} diff --git a/main/utils.h b/main/utils.h index 1b35324..ba20812 100644 --- a/main/utils.h +++ b/main/utils.h @@ -59,3 +59,5 @@ void readPotis(); float wattToAmpere(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); +void time_set_now(espchrono::utc_clock::time_point now); +std::string local_clock_string(); diff --git a/main/webserver.cpp b/main/webserver.cpp index 233a1f2..e9fe6e2 100644 --- a/main/webserver.cpp +++ b/main/webserver.cpp @@ -1,6 +1,8 @@ #include "webserver.h" #include "sdkconfig.h" +using namespace std::chrono_literals; + #ifdef FEATURE_WEBSERVER namespace { constexpr const char * const TAG = "BOBBYWEB"; diff --git a/main/webserver_displaycontrol.cpp b/main/webserver_displaycontrol.cpp index d7757b7..78f96f8 100644 --- a/main/webserver_displaycontrol.cpp +++ b/main/webserver_displaycontrol.cpp @@ -2,6 +2,7 @@ #ifdef FEATURE_WEBSERVER using esphttpdutils::HtmlTag; +using namespace std::chrono_literals; namespace { constexpr const char * const TAG = "BOBBYWEB"; diff --git a/main/webserver_dumpnvs.cpp b/main/webserver_dumpnvs.cpp index 506a5af..8750640 100644 --- a/main/webserver_dumpnvs.cpp +++ b/main/webserver_dumpnvs.cpp @@ -2,6 +2,7 @@ using esphttpdutils::HtmlTag; using namespace espchrono; +using namespace std::chrono_literals; namespace { constexpr const char * const TAG = "BOBBYWEB"; @@ -148,7 +149,7 @@ esp_err_t webserver_dump_nvs_handler(httpd_req_t *req) continue; } #endif - switchProfile(profile_num); + settingsutils::switchProfile(profile_num); const auto cur_profile = settingsPersister.currentlyOpenProfileIndex(); 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; serializeJson(doc, body); diff --git a/main/widgets/menudisplaywithtime.cpp b/main/widgets/menudisplaywithtime.cpp new file mode 100644 index 0000000..d27294b --- /dev/null +++ b/main/widgets/menudisplaywithtime.cpp @@ -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 diff --git a/main/widgets/menudisplaywithtime.h b/main/widgets/menudisplaywithtime.h new file mode 100644 index 0000000..6964beb --- /dev/null +++ b/main/widgets/menudisplaywithtime.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +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 diff --git a/sdkconfig_comred b/sdkconfig_comred index 34a523b..fcdd9ef 100644 --- a/sdkconfig_comred +++ b/sdkconfig_comred @@ -701,19 +701,8 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20 # Core dump # # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y -# CONFIG_ESP_COREDUMP_ENABLE_TO_NONE is not set -# 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" +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y # end of Core dump # @@ -1473,19 +1462,8 @@ CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_SW_COEXIST_ENABLE=y # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y -# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set -# 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_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 CONFIG_MB_QUEUE_LENGTH=20