diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 664dc54..a6a6f90 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -38,6 +38,7 @@ set(headers bluetoothmode.h bluetoothtexthelpers.h bmsutils.h + bobbyblinker.h bobbybuttons.h bobbycheckbox.h bobbyerrorhandler.h @@ -281,6 +282,7 @@ set(sources bluetoothmode.cpp bluetoothtexthelpers.cpp bmsutils.cpp + bobbyblinker.cpp bobbybuttons.cpp bobbyerrorhandler.cpp bobbyhupe.cpp diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index e232a87..2e6176d 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -254,3 +254,6 @@ struct QuickActionExtra1Accessor : public NewSettingsAccessor struct QuickActionExtra2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionExtra2; } }; struct QuickActionExtra3Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionExtra3; } }; struct QuickActionExtra4Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionExtra4; } }; + +// Other +struct AnhaengerIdAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.anhaenger_id; } }; diff --git a/main/bobbyblinker.cpp b/main/bobbyblinker.cpp new file mode 100644 index 0000000..c9bc71e --- /dev/null +++ b/main/bobbyblinker.cpp @@ -0,0 +1,83 @@ +#include "bobbyblinker.h" + +// system includes +#include + +// 3rdparty lib includes +#include + +// local includes +#include "globals.h" +#include "espnowfunctions.h" +#include "ledstrip.h" + +using namespace std::chrono_literals; + +namespace { + constexpr const char * const TAG = "BOBBY_BLINKER"; + + void sendState(const std::string& state) + { + if (const auto error = espnow::send_espnow_message(fmt::format("{}:{}:{}", state, espchrono::utc_clock::now().time_since_epoch().count(), configs.anhaenger_id.value)); error != ESP_OK) + { + ESP_LOGE(TAG, "Error sending blinker message: %s", esp_err_to_name(error)); + } + } + + bool brakeLightsOffSent{false}; +} // namespace + +namespace bobbyblinker { + std::optional blinker_last_time_sent; + std::optional brake_last_time_sent; + + void handle_blinker() + { + if (!configs.espnow.syncBlink.value) + return; + + const bool blinker_state = (cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)); + if ((blinker_state && !blinker_last_time_sent) || (blinker_state && blinker_last_time_sent && espchrono::ago(*blinker_last_time_sent) > 500ms)) + { + blinker_last_time_sent = espchrono::millis_clock::now(); + if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT) + { + sendState("BLINKLEFT"); + } + else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT) + { + sendState("BLINKRIGHT"); + } + else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) + { + sendState("BLINKBOTH"); + } + } + else if (!blinker_state && blinker_last_time_sent) + { + blinker_last_time_sent = std::nullopt; + sendState("BLINKOFF"); + } + if (configs.ledstrip.enableBrakeLights.value && espchrono::ago(*brake_last_time_sent) > 500ms) + { + float avgPwm{}; + for (const Controller &controller: controllers) { + avgPwm += + controller.command.left.pwm * (controller.invertLeft ? -1 : 1) + + controller.command.right.pwm * (controller.invertRight ? -1 : 1); + } + avgPwm /= 4; + + if (avgPwm < -1.f) + { + sendState("BRAKELIGHTSON"); + brakeLightsOffSent = false; + } + else if (!brakeLightsOffSent && avgPwm > -1.f) + { + sendState("BRAKELIGHTSOFF"); + brakeLightsOffSent = true; + } + } + } +} // namespace bobbyblinker diff --git a/main/bobbyblinker.h b/main/bobbyblinker.h new file mode 100644 index 0000000..53abd9f --- /dev/null +++ b/main/bobbyblinker.h @@ -0,0 +1,10 @@ +#pragma once + +// 3rdparty lib includes +#include + +namespace bobbyblinker { + extern std::optional blinker_last_time_sent; + extern std::optional brake_last_time_sent; + void handle_blinker(); +} // namespace bobbyhupe diff --git a/main/debuginputhandler.cpp b/main/debuginputhandler.cpp index c44840a..025f7bf 100644 --- a/main/debuginputhandler.cpp +++ b/main/debuginputhandler.cpp @@ -18,6 +18,7 @@ #include "globals.h" #include "utils.h" #include "bobbybuttons.h" +#include "bobbyquickactions.h" namespace { constexpr const char * const TAG = "DEBUG"; @@ -159,16 +160,14 @@ void handleNormalChar(char c) case 'Z': if (espgui::currentDisplay) { - espgui::currentDisplay->buttonPressed(espgui::Button(BobbyButton::Left2)); - espgui::currentDisplay->buttonReleased(espgui::Button(BobbyButton::Left2)); + quickactions::blink_left(); } break; case 'u': case 'U': if (espgui::currentDisplay) { - espgui::currentDisplay->buttonPressed(espgui::Button(BobbyButton::Right2)); - espgui::currentDisplay->buttonReleased(espgui::Button(BobbyButton::Right2)); + quickactions::blink_right(); } break; } diff --git a/main/displays/menus/settingsmenu.cpp b/main/displays/menus/settingsmenu.cpp index a527c16..50f7c82 100644 --- a/main/displays/menus/settingsmenu.cpp +++ b/main/displays/menus/settingsmenu.cpp @@ -9,35 +9,37 @@ #include "icons/back.h" // local includes -#include "utils.h" -#include "icons/wifi.h" -#include "icons/bluetooth.h" -#include "icons/time.h" -#include "icons/hardware.h" -#include "icons/buzzer.h" -#include "icons/info.h" -#include "icons/demos.h" -#include "icons/update.h" -#include "globals.h" #include "accessors/settingsaccessors.h" -#include "displays/menus/limitssettingsmenu.h" -#include "displays/menus/networksettingsmenu.h" -#include "displays/menus/bluetoothsettingsmenu.h" +#include "bobbycheckbox.h" +#include "displays/bobbychangevaluedisplay.h" +#include "displays/menus/aboutmenu.h" #include "displays/menus/blesettingsmenu.h" -#include "displays/menus/cloudsettingsmenu.h" -#include "displays/menus/udpcloudsettingsmenu.h" -#include "displays/menus/espnowmenu.h" -#include "displays/menus/selectbuildservermenu.h" -#include "displays/menus/timesettingsmenu.h" -#include "displays/menus/modessettingsmenu.h" -#include "displays/menus/controllerhardwaresettingsmenu.h" +#include "displays/menus/bluetoothsettingsmenu.h" #include "displays/menus/boardcomputerhardwaresettingsmenu.h" #include "displays/menus/buzzermenu.h" +#include "displays/menus/cloudsettingsmenu.h" +#include "displays/menus/controllerhardwaresettingsmenu.h" #include "displays/menus/crashmenu.h" -#include "displays/menus/aboutmenu.h" -#include "displays/menus/mainmenu.h" +#include "displays/menus/espnowmenu.h" #include "displays/menus/featureflagsmenu.h" -#include "bobbycheckbox.h" +#include "displays/menus/limitssettingsmenu.h" +#include "displays/menus/mainmenu.h" +#include "displays/menus/modessettingsmenu.h" +#include "displays/menus/networksettingsmenu.h" +#include "displays/menus/selectbuildservermenu.h" +#include "displays/menus/timesettingsmenu.h" +#include "displays/menus/udpcloudsettingsmenu.h" +#include "globals.h" +#include "icons/bluetooth.h" +#include "icons/buzzer.h" +#include "icons/demos.h" +#include "icons/hardware.h" +#include "icons/info.h" +#include "icons/time.h" +#include "icons/update.h" +#include "icons/wifi.h" +#include "textwithvaluehelper.h" +#include "utils.h" namespace { constexpr char TEXT_SETTINGS[] = "Settings"; @@ -55,6 +57,7 @@ constexpr char TEXT_MODESSETTINGS[] = "Modes settings"; constexpr char TEXT_CONTROLLERHARDWARESETTINGS[] = "Controller H/W settings"; constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings"; constexpr char TEXT_FEATUREFLAGS[] = "Feature flags"; +constexpr char TEXT_ANHAENGER_ID[] = "Anhaenger ID"; constexpr char TEXT_AUTOCONNECTBMS[] = "Auto connect BMS"; constexpr char TEXT_BUZZER[] = "Buzzer"; constexpr char TEXT_FRONTLED[] = "Front LED"; @@ -72,6 +75,14 @@ struct BacklightAccessor : public virtual espgui::AccessorInterface #endif struct FrontLedAccessor : public espgui::RefAccessor { bool &getRef() const override { return controllers.front.command.led; } }; struct BackLedAccessor : public espgui::RefAccessor { bool &getRef() const override { return controllers.back.command.led; } }; + +using AnhaengerIdChangeScreen = espgui::makeComponent< + BobbyChangeValueDisplay, + espgui::StaticText, + AnhaengerIdAccessor, + espgui::ConfirmActionInterface, + espgui::BackActionInterface +>; } // namespace using namespace espgui; @@ -106,6 +117,7 @@ SettingsMenu::SettingsMenu() constructMenuItem, PushScreenAction, StaticMenuItemIcon<&bobbyicons::hardware>>>(); } constructMenuItem, PushScreenAction, StaticMenuItemIcon<&bobbyicons::demos>>>(); + constructMenuItem, espgui::PushScreenAction>>(); //#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS) // constructMenuItem, BobbyCheckbox, AutoConnectBmsAccessor>>(); //#endif diff --git a/main/espnowfunctions.cpp b/main/espnowfunctions.cpp index a58b450..93e7ed8 100644 --- a/main/espnowfunctions.cpp +++ b/main/espnowfunctions.cpp @@ -12,6 +12,7 @@ #include "time_bobbycar.h" #include "newsettings.h" #include "bobbyhupe.h" +#include "bobbyblinker.h" namespace espnow { uint16_t lastYear; // Used for esp-now timesync @@ -146,6 +147,7 @@ void initESPNow() void handle() { bobbyhupe::handle_hupe(); + bobbyblinker::handle_blinker(); if (initialized < 255 && espnow_init_allowed()) { initESPNow(); @@ -244,7 +246,7 @@ void handle() } else { - ESP_LOGI(TAG, "Unkown Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str()); + ESP_LOGI(TAG, "Unknown Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str()); } } clear: diff --git a/main/newsettings.h b/main/newsettings.h index 37df91c..047a946 100644 --- a/main/newsettings.h +++ b/main/newsettings.h @@ -368,6 +368,8 @@ public: ConfiguredFeatureFlag esp_now {"featureEspNow", false, false, "espnow"}; } feature; + ConfigWrapper anhaenger_id {0, DoReset, {}, "anhaenger_id" }; + struct { ConfigWrapper bleEnabled {true, DoReset, {}, "bleEnabled" }; } bleSettings;