Lots of improvements with newsettings

This commit is contained in:
2021-12-29 18:53:59 +01:00
parent f50f6eaf1e
commit 9540898ced
7 changed files with 200 additions and 40 deletions

View File

@ -2,6 +2,7 @@
// local includes
#include "displays/bobbymenudisplay.h"
#include "debugmenu.h"
#include "utils.h"
#include "menuitem.h"
#include "actions/dummyaction.h"
@ -30,7 +31,7 @@ public:
}
};
class FrontCommandDebugMenu : public CommandDebugMenu<TEXT_FRONTCOMMAND, FrontTexts> {};
class BackCommandDebugMenu : public CommandDebugMenu<TEXT_BACKCOMMAND, BackTexts> {};
using FrontCommandDebugMenu = CommandDebugMenu<TEXT_FRONTCOMMAND, FrontTexts>;
using BackCommandDebugMenu = CommandDebugMenu<TEXT_BACKCOMMAND, BackTexts>;
} // namespace

View File

@ -2,6 +2,7 @@
// local includes
#include "displays/bobbymenudisplay.h"
#include "debugmenu.h"
#include "utils.h"
#include "menuitem.h"
#include "actions/dummyaction.h"
@ -33,7 +34,7 @@ public:
}
};
class FrontFeedbackDebugMenu : public FeedbackDebugMenu<TEXT_FRONTFEEDBACK, FrontTexts, FrontFeedbackColor> {};
class BackFeedbackDebugMenu : public FeedbackDebugMenu<TEXT_BACKFEEDBACK, BackTexts, FrontFeedbackColor> {};
using FrontFeedbackDebugMenu = FeedbackDebugMenu<TEXT_FRONTFEEDBACK, FrontTexts, FrontFeedbackColor>;
using BackFeedbackDebugMenu = FeedbackDebugMenu<TEXT_BACKFEEDBACK, BackTexts, FrontFeedbackColor>;
} // namespace

View File

@ -2,6 +2,7 @@
// local includes
#include "displays/bobbymenudisplay.h"
#include "debugmenu.h"
#include "utils.h"
#include "menuitem.h"
#include "actions/dummyaction.h"
@ -40,7 +41,7 @@ public:
}
};
class FrontLeftMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_FRONTLEFTFEEDBACK, FrontTexts::LeftFeedback, FrontFeedbackColor> {};
class FrontRightMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_FRONTRIGHTFEEDBACK, FrontTexts::RightFeedback, FrontFeedbackColor> {};
class BackLeftMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_BACKLEFTFEEDBACK, BackTexts::LeftFeedback, BackFeedbackColor> {};
class BackRightMotorFeedbackDebugMenu : public MotorFeedbackDebugMenu<TEXT_BACKRIGHTFEEDBACK, BackTexts::RightFeedback, BackFeedbackColor> {};
using FrontLeftMotorFeedbackDebugMenu = MotorFeedbackDebugMenu<TEXT_FRONTLEFTFEEDBACK, FrontTexts::LeftFeedback, FrontFeedbackColor>;
using FrontRightMotorFeedbackDebugMenu = MotorFeedbackDebugMenu<TEXT_FRONTRIGHTFEEDBACK, FrontTexts::RightFeedback, FrontFeedbackColor>;
using BackLeftMotorFeedbackDebugMenu = MotorFeedbackDebugMenu<TEXT_BACKLEFTFEEDBACK, BackTexts::LeftFeedback, BackFeedbackColor>;
using BackRightMotorFeedbackDebugMenu = MotorFeedbackDebugMenu<TEXT_BACKRIGHTFEEDBACK, BackTexts::RightFeedback, BackFeedbackColor>;

View File

@ -8,6 +8,7 @@
// local includes
#include "displays/bobbymenudisplay.h"
#include "debugmenu.h"
#include "utils.h"
#include "texts.h"
#include "debugtexthelpers.h"
@ -37,7 +38,7 @@ public:
}
};
class FrontLeftMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_FRONTLEFTCOMMAND, FrontTexts::LeftCommand> {};
class FrontRightMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_FRONTRIGHTCOMMAND, FrontTexts::RightCommand> {};
class BackLeftMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_BACKLEFTCOMMAND, BackTexts::LeftCommand> {};
class BackRightMotorStateDebugMenu : public MotorStateDebugMenu<TEXT_BACKRIGHTCOMMAND, BackTexts::RightCommand> {};
using FrontLeftMotorStateDebugMenu = MotorStateDebugMenu<TEXT_FRONTLEFTCOMMAND, FrontTexts::LeftCommand>;
using FrontRightMotorStateDebugMenu = MotorStateDebugMenu<TEXT_FRONTRIGHTCOMMAND, FrontTexts::RightCommand>;
using BackLeftMotorStateDebugMenu = MotorStateDebugMenu<TEXT_BACKLEFTCOMMAND, BackTexts::LeftCommand>;
using BackRightMotorStateDebugMenu = MotorStateDebugMenu<TEXT_BACKRIGHTCOMMAND, BackTexts::RightCommand>;

View File

@ -13,6 +13,7 @@
#include "buttons.h"
#include "types.h"
#include "globals.h"
#include "newsettings.h"
namespace {
namespace dpad6wire {
@ -135,7 +136,7 @@ void update()
const auto now = espchrono::millis_clock::now();
const std::chrono::milliseconds dpadDebounce{settings.boardcomputerHardware.dpadDebounce};
const std::chrono::milliseconds dpadDebounce{configs.dpadDebounce.value};
if (lastState.up != newState.up && now - debounceUp > dpadDebounce)
{

View File

@ -84,7 +84,7 @@ class ConfigContainer
public:
// default allowReset constraints nvsName
ConfigWrapper<std::optional<mac_t>> baseMacAddressOverride{std::nullopt, NoReset, {}, "baseMacAddrOver" };
ConfigWrapper<std::optional<mac_t>> baseMacAddressOverride{std::nullopt, DoReset, {}, "baseMacAddrOver" };
ConfigWrapper<std::string> hostname {defaultHostname, DoReset, StringMinMaxSize<4, 32>, "hostname" };
ConfigWrapper<bool> wifiStaEnabled {true, DoReset, {}, "wifiStaEnabled" };
std::array<WiFiConfig, 10> wifi_configs {
@ -108,9 +108,9 @@ public:
ConfigWrapper<wifi_auth_mode_t> wifiApAuthmode{WIFI_AUTH_WPA2_PSK, DoReset, {}, "wifiApAuthmode" };
ConfigWrapper<bool> timeServerEnabled {false, DoReset, {}, "timeServerEnabl" };
ConfigWrapper<std::string> timeServer {"europe.pool.ntp.org", NoReset, StringMaxSize<64>, "timeServer" };
ConfigWrapper<sntp_sync_mode_t> timeSyncMode {SNTP_SYNC_MODE_IMMED, NoReset, {}, "timeSyncMode" };
ConfigWrapper<espchrono::milliseconds32> timeSyncInterval{espchrono::milliseconds32{CONFIG_LWIP_SNTP_UPDATE_DELAY}, NoReset, MinTimeSyncInterval, "timeSyncInterva" };
ConfigWrapper<std::string> timeServer {"europe.pool.ntp.org", DoReset, StringMaxSize<64>, "timeServer" };
ConfigWrapper<sntp_sync_mode_t> timeSyncMode {SNTP_SYNC_MODE_IMMED, DoReset, {}, "timeSyncMode" };
ConfigWrapper<espchrono::milliseconds32> timeSyncInterval{espchrono::milliseconds32{CONFIG_LWIP_SNTP_UPDATE_DELAY}, DoReset, MinTimeSyncInterval, "timeSyncInterva" };
ConfigWrapper<espchrono::minutes32> timezoneOffset{espchrono::minutes32{60}, DoReset, {}, "timezoneOffset" }; // MinMaxValue<minutes32, -1440m, 1440m>
ConfigWrapper<espchrono::DayLightSavingMode>timeDst{espchrono::DayLightSavingMode::EuropeanSummerTime, DoReset, {}, "time_dst" };

View File

@ -17,6 +17,7 @@
#include <numberparsing.h>
#include <lockhelper.h>
#include <tickchrono.h>
#include <futurecpp.h>
// local includes
#include "newsettings.h"
@ -29,13 +30,26 @@ using esphttpdutils::HtmlTag;
namespace {
constexpr const char * const TAG = "BOBBYWEB";
template<class T>
struct is_duration : std::false_type {};
template<class Rep, class Period>
struct is_duration<std::chrono::duration<Rep, Period>> : std::true_type {};
template <typename _Tp>
inline constexpr bool is_duration_v = is_duration<_Tp>::value;
template<typename T>
typename std::enable_if<
!std::is_same<T, bool>::value &&
!std::is_integral<T>::value &&
!std::is_same<T, std::string>::value &&
!std::is_same<T, wifi_stack::ip_address_t>::value &&
!std::is_same<T, wifi_stack::mac_t>::value
!std::is_same_v<T, bool> &&
!std::is_integral_v<T> &&
!is_duration_v<T> &&
!std::is_same_v<T, std::string> &&
!std::is_same_v<T, wifi_stack::ip_address_t> &&
!std::is_same_v<T, wifi_stack::mac_t> &&
!std::is_same_v<T, std::optional<wifi_stack::mac_t>> &&
!std::is_same_v<T, wifi_auth_mode_t> &&
!std::is_same_v<T, sntp_sync_mode_t>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
@ -46,7 +60,7 @@ showInputForSetting(std::string_view key, T value, std::string &body)
template<typename T>
typename std::enable_if<
std::is_same<T, bool>::value
std::is_same_v<T, bool>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
@ -60,8 +74,8 @@ showInputForSetting(std::string_view key, T value, std::string &body)
template<typename T>
typename std::enable_if<
!std::is_same<T, bool>::value &&
std::is_integral<T>::value
!std::is_same_v<T, bool> &&
std::is_integral_v<T>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
@ -75,7 +89,19 @@ showInputForSetting(std::string_view key, T value, std::string &body)
template<typename T>
typename std::enable_if<
std::is_same<T, std::string>::value
is_duration_v<T>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
body += fmt::format("<input type=\"number\" name=\"{}\" value=\"{}\" step=\"1\" />",
esphttpdutils::htmlentities(key),
value.count());
return true;
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, std::string>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
@ -87,7 +113,7 @@ showInputForSetting(std::string_view key, T value, std::string &body)
template<typename T>
typename std::enable_if<
std::is_same<T, wifi_stack::ip_address_t>::value
std::is_same_v<T, wifi_stack::ip_address_t>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
@ -99,20 +125,79 @@ showInputForSetting(std::string_view key, T value, std::string &body)
template<typename T>
typename std::enable_if<
std::is_same<T, wifi_stack::mac_t>::value
std::is_same_v<T, wifi_stack::mac_t>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
body += fmt::format("<input type=\"text\" name=\"{}\" value=\"{}\" pattern=\"[0-9a-fA-F]{2}(?:\\:[0-9a-fA-F]{2}){5}\" />",
body += fmt::format("<input type=\"text\" name=\"{}\" value=\"{}\" pattern=\"[0-9a-fA-F]{{2}}(?:\\:[0-9a-fA-F]{{2}}){{5}}\" />",
esphttpdutils::htmlentities(key),
esphttpdutils::htmlentities(wifi_stack::toString(value)));
return true;
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, std::optional<wifi_stack::mac_t>>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
body += fmt::format("<input type=\"text\" name=\"{}\" value=\"{}\" pattern=\"(?:[0-9a-fA-F]{{2}}(?:\\:[0-9a-fA-F]{{2}}){{5}})?\" /> ?",
esphttpdutils::htmlentities(key),
value ? esphttpdutils::htmlentities(wifi_stack::toString(*value)) : std::string{});
return true;
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, wifi_auth_mode_t>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
HtmlTag select{"select", fmt::format("name=\"{}\"", esphttpdutils::htmlentities(key)), body};
#define HANDLE_ENUM_KEY(x) \
{ \
HtmlTag option{"option", fmt::format("value=\"{}\"{}", std::to_underlying(x), value == x ? " selected" : ""), body}; \
body += esphttpdutils::htmlentities(#x); \
}
HANDLE_ENUM_KEY(WIFI_AUTH_OPEN)
HANDLE_ENUM_KEY(WIFI_AUTH_WEP)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA2_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA_WPA2_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA2_ENTERPRISE)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA3_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_WPA2_WPA3_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_WAPI_PSK)
HANDLE_ENUM_KEY(WIFI_AUTH_MAX)
#undef HANDLE_ENUM_KEY
return true;
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, sntp_sync_mode_t>
, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
HtmlTag select{"select", fmt::format("name=\"{}\"", esphttpdutils::htmlentities(key)), body};
#define HANDLE_ENUM_KEY(x) \
{ \
HtmlTag option{"option", fmt::format("value=\"{}\"{}", std::to_underlying(x), value == x ? " selected" : ""), body}; \
body += esphttpdutils::htmlentities(#x); \
}
HANDLE_ENUM_KEY(SNTP_SYNC_MODE_IMMED)
HANDLE_ENUM_KEY(SNTP_SYNC_MODE_SMOOTH)
#undef HANDLE_ENUM_KEY
return true;
}
} // namespace
esp_err_t webserver_newSettings_handler(httpd_req_t *req)
{
#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET
ESP_LOGI(TAG, "trying to lock...");
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
@ -238,11 +323,14 @@ esp_err_t webserver_newSettings_handler(httpd_req_t *req)
namespace {
template<typename T>
typename std::enable_if<
!std::is_same<T, bool>::value &&
!std::is_integral<T>::value &&
!std::is_same<T, std::string>::value &&
!std::is_same<T, wifi_stack::ip_address_t>::value &&
!std::is_same<T, wifi_stack::mac_t>::value
!std::is_same_v<T, bool> &&
!std::is_integral_v<T> &&
!std::is_same_v<T, std::string> &&
!std::is_same_v<T, wifi_stack::ip_address_t> &&
!std::is_same_v<T, wifi_stack::mac_t> &&
!std::is_same_v<T, std::optional<wifi_stack::mac_t>> &&
!std::is_same_v<T, wifi_auth_mode_t> &&
!std::is_same_v<T, sntp_sync_mode_t>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -252,7 +340,7 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
template<typename T>
typename std::enable_if<
std::is_same<T, bool>::value
std::is_same_v<T, bool>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -291,8 +379,8 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
template<typename T>
typename std::enable_if<
!std::is_same<T, bool>::value &&
std::is_integral<T>::value
!std::is_same_v<T, bool> &&
std::is_integral_v<T>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -318,7 +406,7 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
template<typename T>
typename std::enable_if<
std::is_same<T, std::string>::value
std::is_same_v<T, std::string>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -336,7 +424,7 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
template<typename T>
typename std::enable_if<
std::is_same<T, wifi_stack::ip_address_t>::value
std::is_same_v<T, wifi_stack::ip_address_t>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -362,7 +450,7 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
template<typename T>
typename std::enable_if<
std::is_same<T, wifi_stack::mac_t>::value
std::is_same_v<T, wifi_stack::mac_t>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
@ -385,6 +473,72 @@ saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &bo
return false;
}
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, std::optional<wifi_stack::mac_t>>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
if (newValue.empty())
{
if (const auto result = configs.write_config(config, std::nullopt); result)
{
body += "applied";
return true;
}
else
{
body += result.error();
return false;
}
}
else if (const auto parsed = wifi_stack::fromString<wifi_stack::mac_t>(newValue); parsed)
{
if (const auto result = configs.write_config(config, *parsed); result)
{
body += "applied";
return true;
}
else
{
body += result.error();
return false;
}
}
else
{
body += parsed.error();
return false;
}
}
template<typename T>
typename std::enable_if<
std::is_same_v<T, wifi_auth_mode_t> ||
std::is_same_v<T, sntp_sync_mode_t>
, bool>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue, std::string &body)
{
if (auto parsed = cpputils::fromString<std::underlying_type_t<T>>(newValue))
{
if (const auto result = configs.write_config(config, T(*parsed)); result)
{
body += "applied";
return true;
}
else
{
body += result.error();
return false;
}
}
else
{
body += fmt::format("could not parse {}", newValue);
return false;
}
}
} // namespace
esp_err_t webserver_saveNewSettings_handler(httpd_req_t *req)
@ -432,6 +586,7 @@ esp_err_t webserver_saveNewSettings_handler(httpd_req_t *req)
esphttpdutils::urldecode(valueBuf, valueBufEncoded);
body += nvsName;
body += ": ";
if (!saveSetting(config, valueBuf, body))
success = false;
body += '\n';