diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index a29d2cf..313e6c5 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -45,6 +45,7 @@ set(headers buildserver.h can.h changevaluedisplay_bluetoothmode.h + changevaluedisplay_bobbyquickactions.h changevaluedisplay_controlmode.h changevaluedisplay_controltype.h changevaluedisplay_handbremsmode.h @@ -123,6 +124,7 @@ set(headers displays/menus/selectmodemenu.h displays/menus/selectotabuildmenu.h displays/menus/settingsmenu.h + displays/menus/setupquickactionsmenu.h displays/menus/statisticsmenu.h displays/menus/taskmanagermenu.h displays/menus/tempomatmodesettingsmenu.h @@ -273,6 +275,7 @@ set(sources buildserver.cpp can.cpp changevaluedisplay_bluetoothmode.cpp + changevaluedisplay_bobbyquickactions.cpp changevaluedisplay_controlmode.cpp changevaluedisplay_controltype.cpp changevaluedisplay_handbremsmode.cpp @@ -349,6 +352,7 @@ set(sources displays/menus/selectmodemenu.cpp displays/menus/selectotabuildmenu.cpp displays/menus/settingsmenu.cpp + displays/menus/setupquickactionsmenu.cpp displays/menus/statisticsmenu.cpp displays/menus/taskmanagermenu.cpp displays/menus/tempomatmodesettingsmenu.cpp diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index a85579c..42352b2 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -248,3 +248,9 @@ struct ButtonProfile3Accessor : public NewSettingsAccessor { ConfigWrap // Can struct CanResetOnErrorAccessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.canResetOnError; } }; + +// Quick Actions +struct QuickActionLeft2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionLeft2; } }; +struct QuickActionRight2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionRight2; } }; +struct QuickActionUp2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionUp2; } }; +struct QuickActionDown2Accessor : public NewSettingsAccessor { ConfigWrapper &getConfig() const override { return configs.quickActionDown2; } }; diff --git a/main/bobbybuttons.cpp b/main/bobbybuttons.cpp index 262ae4d..a172324 100644 --- a/main/bobbybuttons.cpp +++ b/main/bobbybuttons.cpp @@ -12,6 +12,8 @@ #include "ledstrip.h" #endif +#include "bobbyquickactions.h" + namespace { constexpr const char TAG[] = "BUTTONS"; } // namespace @@ -69,51 +71,12 @@ void buttonPressedCommon(espgui::Button button) case BobbyButton::Profile3: settingsutils::switchProfile(3); break; + case BobbyButton::Left2: -#ifdef FEATURE_LEDSTRIP - if (blinkAnimation == LEDSTRIP_OVERWRITE_NONE) //transition from off to left - { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT; - } - else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT) // transition to warning - { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; - } - else // transition to off - { - blinkAnimation = LEDSTRIP_OVERWRITE_NONE; - } -#endif - break; case BobbyButton::Right2: -#ifdef FEATURE_LEDSTRIP - if (blinkAnimation == LEDSTRIP_OVERWRITE_NONE) //transition from off to right - { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT; - } - else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT) // transition to warning - { - blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; - } - else // transition to off - { - blinkAnimation = LEDSTRIP_OVERWRITE_NONE; - } -#endif - break; case BobbyButton::Up2: - if (configs.handbremse.enable.value) - { - using namespace handbremse; - if (stateWish == StateWish::brake || angezogen) - stateWish = StateWish::release; - else - stateWish = StateWish::brake; - wishTimer = espchrono::millis_clock::now(); - } - break; case BobbyButton::Down2: - /* TODO */ + quickactions::handle_bobby_quickaction(button); break; default:; } diff --git a/main/bobbyquickactions.cpp b/main/bobbyquickactions.cpp new file mode 100644 index 0000000..116265a --- /dev/null +++ b/main/bobbyquickactions.cpp @@ -0,0 +1,119 @@ +#include "bobbyquickactions.h" + +// local includes +#ifdef FEATURE_ESPNOW +#include "espnowfunctions.h" +#endif +#include "newsettings.h" + +namespace quickactions { + +void handle_bobby_quickaction(espgui::Button button) +{ + espconfig::ConfigWrapper *config = nullptr; + switch (BobbyButton(button)) + { + case Left2: + config = &configs.quickActionLeft2; + break; + case Right2: + config = &configs.quickActionRight2; + break; + case Up2: + config = &configs.quickActionUp2; + break; + case Down2: + config = &configs.quickActionDown2; + break; + default: + return; + } + + if (config) + { + switch(config->value) + { + case BobbyQuickActions::BLINK_LEFT: + blink_left(); + break; + case BobbyQuickActions::BLINK_RIGHT: + blink_right(); + break; + case BobbyQuickActions::HANDBREMSE: + handle_handbremse(); + break; + case BobbyQuickActions::OPEN_GARAGE: + open_garage(); + break; + default: + return; + } + } +} + +void open_garage() +{ +#ifdef FEATURE_ESPNOW + if (!espnow::espnow_init_allowed()) + return; + for (const auto &config : configs.wireless_door_configs) + { + if (const auto error = espnow::send_espnow_message(fmt::format("BOBBYOPEN:{}:{}", config.doorId.value, config.doorToken.value)); error != ESP_OK) + { + ESP_LOGE("BOBBY", "send_espnow_message() failed with: %s", esp_err_to_name(error)); + continue; + } + } +#endif +} + +void blink_left() +{ +#ifdef FEATURE_LEDSTRIP + if (blinkAnimation == LEDSTRIP_OVERWRITE_NONE) //transition from off to left + { + blinkAnimation = LEDSTRIP_OVERWRITE_BLINKLEFT; + } + else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT) // transition to warning + { + blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; + } + else // transition to off + { + blinkAnimation = LEDSTRIP_OVERWRITE_NONE; + } +#endif +} + +void blink_right() +{ +#ifdef FEATURE_LEDSTRIP + if (blinkAnimation == LEDSTRIP_OVERWRITE_NONE) //transition from off to right + { + blinkAnimation = LEDSTRIP_OVERWRITE_BLINKRIGHT; + } + else if (blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT) // transition to warning + { + blinkAnimation = LEDSTRIP_OVERWRITE_BLINKBOTH; + } + else // transition to off + { + blinkAnimation = LEDSTRIP_OVERWRITE_NONE; + } +#endif +} + +void handle_handbremse() +{ + if (configs.handbremse.enable.value) + { + using namespace handbremse; + if (stateWish == StateWish::brake || angezogen) + stateWish = StateWish::release; + else + stateWish = StateWish::brake; + wishTimer = espchrono::millis_clock::now(); + } +} + +} // namespace quickactions diff --git a/main/bobbyquickactions.h b/main/bobbyquickactions.h new file mode 100644 index 0000000..bd52b68 --- /dev/null +++ b/main/bobbyquickactions.h @@ -0,0 +1,28 @@ +#pragma once + +// 3rdparty lib includes +#include +#include + +// local includes +#include "bobbybuttons.h" + +#define BobbyQuickActionsValues(x) \ + x(NONE) \ + x(BLINK_LEFT) \ + x(BLINK_RIGHT) \ + x(HANDBREMSE) \ + x(OPEN_GARAGE) +DECLARE_TYPESAFE_ENUM(BobbyQuickActions, : uint8_t, BobbyQuickActionsValues) + +namespace quickactions { + +void handle_bobby_quickaction(espgui::Button button); + +// functions +void open_garage(); +void blink_left(); +void blink_right(); +void handle_handbremse(); + +} // namespace quickactions diff --git a/main/changevaluedisplay_bobbyquickactions.cpp b/main/changevaluedisplay_bobbyquickactions.cpp new file mode 100644 index 0000000..601ad07 --- /dev/null +++ b/main/changevaluedisplay_bobbyquickactions.cpp @@ -0,0 +1,54 @@ +#include "changevaluedisplay_bobbyquickactions.h" + +// esp-idf includes +#include + +// 3rdparty lib includes +#include +#include +#include +#include + +// local includes +#include "utils.h" + +namespace espgui { +namespace { +constexpr const char * const TAG = "ESPGUI"; + +constexpr char TEXT_QUICKACTION_NONE[] = "None"; +constexpr char TEXT_QUICKACTION_BLINK_LEFT[] = "Blink Left"; +constexpr char TEXT_QUICKACTION_BLINK_RIGHT[] = "Blink Right"; +constexpr char TEXT_QUICKACTION_HANDBREMSE[] = "Handbremse"; +constexpr char TEXT_QUICKACTION_OPEN_GARAGE[] = "Open Garage"; +constexpr char TEXT_BACK[] = "Back"; +} // namespace + +ChangeValueDisplay::ChangeValueDisplay() +{ + constructMenuItem, StaticText>>(BobbyQuickActions::NONE, *this, *this, *this); + constructMenuItem, StaticText>>(BobbyQuickActions::BLINK_LEFT, *this, *this, *this); + constructMenuItem, StaticText>>(BobbyQuickActions::BLINK_RIGHT, *this, *this, *this); + constructMenuItem, StaticText>>(BobbyQuickActions::HANDBREMSE, *this, *this, *this); + constructMenuItem, StaticText>>(BobbyQuickActions::OPEN_GARAGE, *this, *this, *this); + constructMenuItem, StaticMenuItemIcon<&espgui::icons::back>>>(*this); +} + +void ChangeValueDisplay::start() +{ + Base::start(); + + switch (const auto value = getValue()) + { + case BobbyQuickActions::NONE: setSelectedIndex(0); break; + case BobbyQuickActions::BLINK_LEFT: setSelectedIndex(1); break; + case BobbyQuickActions::BLINK_RIGHT: setSelectedIndex(2); break; + case BobbyQuickActions::HANDBREMSE: setSelectedIndex(3); break; + case BobbyQuickActions::OPEN_GARAGE: setSelectedIndex(4); break; + default: + ESP_LOGW(TAG, "Unknown BobbyQuickActions: %i", std::to_underlying(value)); + setSelectedIndex(5); + } +} + +} // namespace espgui diff --git a/main/changevaluedisplay_bobbyquickactions.h b/main/changevaluedisplay_bobbyquickactions.h new file mode 100644 index 0000000..d085754 --- /dev/null +++ b/main/changevaluedisplay_bobbyquickactions.h @@ -0,0 +1,29 @@ +#pragma once + +// 3rdparty lib includes +#include +#include +#include +#include + +// local includes +#include "bobbyquickactions.h" + +namespace espgui { + +template<> +class ChangeValueDisplay : + public MenuDisplay, + public virtual AccessorInterface, + public virtual ConfirmInterface, + public virtual ErrorHandlerInterface +{ + using Base = MenuDisplay; + +public: + ChangeValueDisplay(); + + void start() override; +}; + +} // namespace espgui diff --git a/main/configutils_bobby.h b/main/configutils_bobby.h index 938db07..5347054 100644 --- a/main/configutils_bobby.h +++ b/main/configutils_bobby.h @@ -7,7 +7,9 @@ // local includes #include "ledstrip.h" #include "handbremse.h" +#include "bobbyquickactions.h" IMPLEMENT_NVS_GET_SET_ENUM(OtaAnimationModes) IMPLEMENT_NVS_GET_SET_ENUM(HandbremseMode) IMPLEMENT_NVS_GET_SET_ENUM(LedstripAnimation) +IMPLEMENT_NVS_GET_SET_ENUM(BobbyQuickActions) diff --git a/main/configwrapper_bobby.cpp b/main/configwrapper_bobby.cpp index 31289b6..af7a64b 100644 --- a/main/configwrapper_bobby.cpp +++ b/main/configwrapper_bobby.cpp @@ -7,3 +7,4 @@ INSTANTIATE_CONFIGWRAPPER_TEMPLATES(OtaAnimationModes) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(HandbremseMode) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(LedstripAnimation) +INSTANTIATE_CONFIGWRAPPER_TEMPLATES(BobbyQuickActions) diff --git a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp index 6a28f36..0420ed0 100644 --- a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp +++ b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp @@ -19,11 +19,13 @@ #include "displays/menus/settingsmenu.h" #include "displays/buttoncalibratedisplay.h" #include "displays/menus/extrabuttoncalibratemenu.h" +#include "displays/menus/setupquickactionsmenu.h" namespace { constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings"; constexpr char TEXT_BUTTONCALIBRATE[] = "Button Calibrate"; constexpr char TEXT_EXTRABUTTONCALIBRATE[] = "Cal other Buttons"; +constexpr char TEXT_QUICKACTIONS[] = "Quick Actions"; constexpr char TEXT_LOCKSCREENSETTINGS[] = "Lockscreen Settings"; constexpr char TEXT_POTISCALIBRATE[] = "Potis Calibrate"; constexpr char TEXT_SAMPLECOUNT[] = "sampleCount"; @@ -99,6 +101,7 @@ using BremsMaxChangeScreen = espgui::makeComponent< espgui::BackActionInterface> >; + #if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW) using DPadDebounceChangeScreen = espgui::makeComponent< BobbyChangeValueDisplay, @@ -175,6 +178,7 @@ BoardcomputerHardwareSettingsMenu::BoardcomputerHardwareSettingsMenu() constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::lock>>>(); constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); constructMenuItem, DummyAction>>(); constructMenuItem, DummyAction>>(); constructMenuItem, SwitchScreenAction>>(); diff --git a/main/displays/menus/garagenmenu.cpp b/main/displays/menus/garagenmenu.cpp index 61f6d4e..df5baae 100644 --- a/main/displays/menus/garagenmenu.cpp +++ b/main/displays/menus/garagenmenu.cpp @@ -57,7 +57,7 @@ void GarageMenu::back() } namespace { -void SendEspNowMessageAction:: triggered() +void SendEspNowMessageAction::triggered() { if (const auto error = espnow::send_espnow_message(fmt::format("BOBBYOPEN:{}:{}", configs.wireless_door_configs[m_index].doorId.value, configs.wireless_door_configs[m_index].doorToken.value)); error != ESP_OK) { diff --git a/main/displays/menus/setupquickactionsmenu.cpp b/main/displays/menus/setupquickactionsmenu.cpp new file mode 100644 index 0000000..268dc7c --- /dev/null +++ b/main/displays/menus/setupquickactionsmenu.cpp @@ -0,0 +1,52 @@ +#include "setupquickactionsmenu.h" + +// 3rdparty lib includes +#include + +// local includes +#include "actions/switchscreenaction.h" +#include "accessors/settingsaccessors.h" +#include "displays/bobbychangevaluedisplay.h" +#include "changevaluedisplay_bobbyquickactions.h" +#include "displays/menus/boardcomputerhardwaresettingsmenu.h" +#include "icons/back.h" +#include "bobbyquickactions.h" + +using namespace espgui; + +namespace { +constexpr char TEXT_SETUPQUICKACTIONS[] = "Setup QuickActions"; +constexpr char TEXT_SETUPLEFT2[] = "&sSetup Left2"; +constexpr char TEXT_SETUPRIGHT2[] = "&sSetup Right2"; +constexpr char TEXT_SETUPUP2[] = "&sSetup Up2"; +constexpr char TEXT_SETUPDOWN2[] = "&sSetup Down2"; +constexpr char TEXT_BACK[] = "Back"; + +template +using QuickActionChangeValueDisplay = espgui::makeComponent< + BobbyChangeValueDisplay, + espgui::StaticText, + Accessor, + espgui::ConfirmActionInterface>, + espgui::BackActionInterface> +>; +} // namespace + +SetupQuickActionsMenu::SetupQuickActionsMenu() +{ + constructMenuItem, SwitchScreenAction>>>(); + constructMenuItem, SwitchScreenAction>>>(); + constructMenuItem, SwitchScreenAction>>>(); + constructMenuItem, SwitchScreenAction>>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +std::string SetupQuickActionsMenu::text() const +{ + return TEXT_SETUPQUICKACTIONS; +} + +void SetupQuickActionsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/setupquickactionsmenu.h b/main/displays/menus/setupquickactionsmenu.h new file mode 100644 index 0000000..6f12331 --- /dev/null +++ b/main/displays/menus/setupquickactionsmenu.h @@ -0,0 +1,14 @@ +#pragma once + +// local includes +#include "displays/bobbymenudisplay.h" + +class SetupQuickActionsMenu : public BobbyMenuDisplay +{ +public: + SetupQuickActionsMenu(); + + std::string text() const override; + + void back() override; +}; diff --git a/main/espnowfunctions.cpp b/main/espnowfunctions.cpp index 351b5d8..3a27f93 100644 --- a/main/espnowfunctions.cpp +++ b/main/espnowfunctions.cpp @@ -23,8 +23,10 @@ bool receiveTsFromOtherBobbycars{true}; namespace { constexpr const char * const TAG = "BOBBY_ESP_NOW"; +} // namespace -inline bool espnow_init_allowed() { +bool espnow_init_allowed() +{ const auto wifi_mode = wifi_stack::get_wifi_mode(); return ( @@ -46,7 +48,6 @@ inline bool espnow_init_allowed() { ) ); } -} // namespace namespace { extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len) diff --git a/main/espnowfunctions.h b/main/espnowfunctions.h index 99f7726..fa0f5a8 100644 --- a/main/espnowfunctions.h +++ b/main/espnowfunctions.h @@ -19,6 +19,8 @@ struct esp_now_message_t extern bool receiveTimeStamp; extern bool receiveTsFromOtherBobbycars; +extern bool espnow_init_allowed(); + extern std::deque message_queue; extern std::vector peers; diff --git a/main/newsettings.h b/main/newsettings.h index c4fd82d..6086e96 100644 --- a/main/newsettings.h +++ b/main/newsettings.h @@ -25,6 +25,7 @@ #include "unifiedmodelmode.h" #include "displays/lockscreen.h" #include "handbremse.h" +#include "bobbyquickactions.h" using namespace espconfig; @@ -147,6 +148,11 @@ public: ConfigWrapper dpadMappingUp2 {INPUT_MAPPING_NONE, DoReset, {}, "dpadMapUp2" }; ConfigWrapper dpadMappingDown2 {INPUT_MAPPING_NONE, DoReset, {}, "dpadMapDown2" }; + ConfigWrapper quickActionLeft2{ BobbyQuickActions::BLINK_LEFT, DoReset, {}, "quickActleft2" }; + ConfigWrapper quickActionRight2{ BobbyQuickActions::BLINK_RIGHT, DoReset, {}, "quickActright2" }; + ConfigWrapper quickActionUp2{ BobbyQuickActions::NONE, DoReset, {}, "quickActup2" }; + ConfigWrapper quickActionDown2{ BobbyQuickActions::HANDBREMSE, DoReset, {}, "quickActdown2" }; + std::array wireless_door_configs { WirelessDoorsConfig { "door_id0", "door_token0" }, WirelessDoorsConfig { "door_id1", "door_token1" }, @@ -432,6 +438,11 @@ public: x(dpadMappingUp2) \ x(dpadMappingDown2) \ \ + x(quickActionLeft2) \ + x(quickActionRight2) \ + x(quickActionUp2) \ + x(quickActionDown2) \ + \ x(wireless_door_configs[0].doorId) \ x(wireless_door_configs[0].doorToken) \ x(wireless_door_configs[1].doorId) \ diff --git a/main/webserver_newsettings.cpp b/main/webserver_newsettings.cpp index a8df0f8..8b65352 100644 --- a/main/webserver_newsettings.cpp +++ b/main/webserver_newsettings.cpp @@ -23,8 +23,6 @@ // local includes #include "newsettings.h" #include "webserver_lock.h" -#include "ledstrip.h" -#include "handbremse.h" #ifdef FEATURE_WEBSERVER using namespace std::chrono_literals; @@ -56,7 +54,8 @@ typename std::enable_if< !std::is_same_v && !std::is_same_v && !std::is_same_v && - !std::is_same_v + !std::is_same_v && + !std::is_same_v , void>::type showInputForSetting(std::string_view key, T value, std::string &body) { @@ -245,6 +244,20 @@ showInputForSetting(std::string_view key, T value, std::string &body) body += esphttpdutils::htmlentities(enumKey); }); } + +template +typename std::enable_if< + std::is_same_v +, void>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + HtmlTag select{"select", fmt::format("name=\"{}\"", esphttpdutils::htmlentities(key)), body}; + + iterateBobbyQuickActions([&](T enumVal, std::string_view enumKey){ + HtmlTag option{"option", fmt::format("value=\"{}\"{}", std::to_underlying(enumVal), value == enumVal ? " selected" : ""), body}; + body += esphttpdutils::htmlentities(enumKey); + }); +} } // namespace esp_err_t webserver_newSettings_handler(httpd_req_t *req) @@ -393,7 +406,8 @@ typename std::enable_if< !std::is_same_v && !std::is_same_v && !std::is_same_v && - !std::is_same_v + !std::is_same_v && + !std::is_same_v , tl::expected>::type saveSetting(ConfigWrapper &config, std::string_view newValue) { @@ -479,7 +493,8 @@ typename std::enable_if< std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v + std::is_same_v || + std::is_same_v , tl::expected>::type saveSetting(ConfigWrapper &config, std::string_view newValue) {