Merge pull request #211 from bobbycar-graz/more-config-updates

This commit is contained in:
CommanderRedYT
2022-01-03 17:27:04 +01:00
committed by GitHub
70 changed files with 801 additions and 1381 deletions

View File

@ -64,12 +64,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
-DFEATURE_POWERSUPPLY
-DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
@ -81,7 +75,6 @@ set(BOBBYCAR_BUILDFLAGS
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=33
-DLEDSTRIP_LENGTH=288
-DHEAP_LRGST_CRASH_TEXT_FIX
-DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=1

View File

@ -64,12 +64,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
@ -81,7 +75,6 @@ set(BOBBYCAR_BUILDFLAGS
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=33
-DLEDSTRIP_LENGTH=288
-DHEAP_LRGST_CRASH_TEXT_FIX
# -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=1

View File

@ -55,12 +55,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
-DFEATURE_POWERSUPPLY
-DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
@ -72,7 +66,6 @@ set(BOBBYCAR_BUILDFLAGS
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=26
-DLEDSTRIP_LENGTH=200
# -DHEAP_LRGST_CRASH_TEXT_FIX
# -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=0

View File

@ -55,12 +55,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
# -DFEATURE_UDPCLOUD
@ -72,7 +66,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DFEATURE_WIRELESS_CONFIG
# -DFEATURE_LEDSTRIP
# -DPINS_LEDSTRIP=33
# -DLEDSTRIP_LENGTH=121
# -DLEDSTRIP_DEFAULT_BRIGHTNESS=100
# -DLEDSTRIP_WRONG_DIRECTION
# -DLEDSTRIP_ANIMATION_DEFAULT=0

View File

@ -55,12 +55,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
@ -71,7 +65,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DFEATURE_NTP
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DLEDSTRIP_LENGTH=288
-DPINS_LEDSTRIP=33
# -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=0

View File

@ -64,12 +64,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
# -DFEATURE_UDPCLOUD
@ -81,7 +75,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DFEATURE_WIRELESS_CONFIG
# -DFEATURE_LEDSTRIP
# -DPINS_LEDSTRIP=33
# -DLEDSTRIP_LENGTH=288
# -DHEAP_LRGST_CRASH_TEXT_FIX
# -DLEDSTRIP_WRONG_DIRECTION
# -DLEDSTRIP_ANIMATION_DEFAULT=1

View File

@ -55,12 +55,6 @@ set(BOBBYCAR_BUILDFLAGS
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
@ -72,7 +66,6 @@ set(BOBBYCAR_BUILDFLAGS
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=33
-DLEDSTRIP_LENGTH=288
# -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=2
-DLEDS_PER_METER=144

View File

@ -20,6 +20,7 @@ set(headers
changevaluedisplay_unifiedmodelmode.h
cloud.h
cloudtexthelpers.h
configutils_bobby.h
controller.h
debugcolorhelpers.h
debuginputhandler.h
@ -45,12 +46,12 @@ set(headers
newsettings.h
ota.h
potis.h
profilesettings.h
presets.h
qrimport.h
rotary.h
screens.h
serial_bobby.h
settings.h
settingspersister.h
settingsutils.h
statistics.h
@ -159,7 +160,6 @@ set(headers
displays/menus/motortestmodesettingsmenu.h
displays/menus/networksettingsmenu.h
displays/menus/otamenu.h
displays/menus/presetsmenu.h
displays/menus/profilesmenu.h
displays/menus/selectbatterytypemenu.h
displays/menus/selectbuildserverbranch.h
@ -250,6 +250,7 @@ set(sources
changevaluedisplay_unifiedmodelmode.cpp
cloud.cpp
cloudtexthelpers.cpp
configwrapper_bobby.cpp
controller.cpp
debugcolorhelpers.cpp
debuginputhandler.cpp
@ -276,12 +277,12 @@ set(sources
newsettings.cpp
ota.cpp
potis.cpp
profilesettings.cpp
presets.cpp
qrimport.cpp
rotary.cpp
screens.cpp
serial_bobby.cpp
settings.cpp
settingspersister.cpp
settingsutils.cpp
statistics.cpp
@ -384,7 +385,6 @@ set(sources
displays/menus/motortestmodesettingsmenu.cpp
displays/menus/networksettingsmenu.cpp
displays/menus/otamenu.cpp
displays/menus/presetsmenu.cpp
displays/menus/profilesmenu.cpp
displays/menus/selectbatterytypemenu.cpp
displays/menus/selectbuildserverbranch.cpp

View File

@ -18,8 +18,8 @@ struct RefAccessorSaveSettings : public virtual espgui::RefAccessor<T>
{
espgui::RefAccessor<T>::setValue(value);
if (!saveSettings())
return tl::make_unexpected("saveSettings() failed!");
if (!saveProfileSettings())
return tl::make_unexpected("saveProfileSettings() failed!");
return {};
};

View File

@ -9,11 +9,6 @@
#include "accessorhelpers.h"
#include "newsettings.h"
// Bms
#ifdef FEATURE_BMS
struct AutoConnectBmsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.autoConnectBms; } };
#endif
// Bluetooth
struct BluetoothNameAccessor : public NewSettingsAccessor<std::string> { ConfigWrapper<std::string> &getConfig() const override { return configs.bluetoothName; } };
@ -25,37 +20,32 @@ struct ReverseBeepDuration0Accessor : public NewSettingsAccessor<int16_t> { Conf
struct ReverseBeepDuration1Accessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.reverseBeepDuration1; } };
// Limits
struct IMotMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iMotMax; } };
struct IDcMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iDcMax; } };
struct IMotMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.limits.iMotMax; } };
struct IDcMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.limits.iDcMax; } };
struct NMotMaxKmhAccessor : public virtual espgui::AccessorInterface<int16_t>
{
int16_t getValue() const override { return convertToKmh(settings.limits.nMotMax); }
int16_t getValue() const override { return convertToKmh(profileSettings.limits.nMotMax); }
espgui::AccessorInterface<int16_t>::setter_result_t setValue(int16_t value) override
{
settings.limits.nMotMax = convertFromKmh(value);
if (!saveSettings())
return tl::make_unexpected("saveSettings() failed!");
profileSettings.limits.nMotMax = convertFromKmh(value);
if (!saveProfileSettings())
return tl::make_unexpected("saveProfileSettings() failed!");
return {};
}
};
struct NMotMaxRpmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.nMotMax; } };
struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } };
struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } };
// Bluetooth
#ifdef FEATURE_BLUETOOTH
struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } };
#endif
struct NMotMaxRpmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.limits.nMotMax; } };
struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.limits.fieldWeakMax; } };
struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.limits.phaseAdvMax; } };
// Bluetooth Low Energy
#ifdef FEATURE_BLE
struct BleEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.bleSettings.bleEnabled; } };
struct BleEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.bleSettings.bleEnabled; } };
#endif
// Cloud
#ifdef FEATURE_CLOUD
struct CloudEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.cloudEnabled; } };
struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } };
struct CloudEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.cloudSettings.cloudEnabled; } };
struct CloudTransmitTimeoutAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.cloudSettings.cloudTransmitTimeout; } };
#endif
// Time
@ -71,42 +61,48 @@ struct TimeSyncIntervalAccessor : public NewSettingsChronoAdaptorAccessor<espchr
#endif
// Controller Hardware
struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } };
struct FrontRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } };
struct BackLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } };
struct BackRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableBackRight; } };
struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.enableFrontLeft; } };
struct FrontRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.enableFrontRight; } };
struct BackLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.enableBackLeft; } };
struct BackRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.enableBackRight; } };
struct FrontLeftInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.invertFrontLeft; } };
struct FrontRightInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.invertFrontRight; } };
struct BackLeftInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.invertBackLeft; } };
struct BackRightInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.invertBackRight; } };
struct FrontLeftInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.invertFrontLeft; } };
struct FrontRightInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.invertFrontRight; } };
struct BackLeftInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.invertBackLeft; } };
struct BackRightInvertedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.controllerHardware.invertBackRight; } };
struct WheelDiameterMmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.wheelDiameter; } };
struct WheelDiameterMmAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.controllerHardware.wheelDiameter; } };
struct WheelDiameterInchAccessor : public virtual espgui::AccessorInterface<float>
{
float getValue() const override { return convertToInch(settings.controllerHardware.wheelDiameter); }
float getValue() const override { return convertToInch(configs.controllerHardware.wheelDiameter.value); }
espgui::AccessorInterface<int16_t>::setter_result_t setValue(float value) override
{
settings.controllerHardware.wheelDiameter = convertFromInch(value);
if (!saveSettings())
return tl::make_unexpected("saveSettings() failed!");
return {};
// profileSettings.controllerHardware.wheelDiameter = convertFromInch(value);
// if (!saveProfileSettings())
// return tl::make_unexpected("saveProfileSettings() failed!");
// return {};
return configs.write_config(configs.controllerHardware.wheelDiameter, convertFromInch(value));
}
};
struct NumMagnetPolesAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.numMagnetPoles; } };
struct SwapFrontBackAccessor : public RefAccessorSaveSettings<bool> {
bool &getRef() const override { return settings.controllerHardware.swapFrontBack; }
struct NumMagnetPolesAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.controllerHardware.numMagnetPoles; } };
struct SwapFrontBackAccessor : public virtual espgui::AccessorInterface<bool> {
bool getValue() const override { return configs.controllerHardware.swapFrontBack.value; }
setter_result_t setValue(bool value) override
{
const auto err = configs.write_config(configs.controllerHardware.swapFrontBack, value);
#ifdef FEATURE_SERIAL
void setValue(bool value) override { RefAccessorSaveSettings<bool>::setValue(value); updateSwapFrontBack(); };
updateSwapFrontBack();
#endif
return err;
}
};
// CAN
#ifdef FEATURE_CAN
struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } };
struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } };
struct CanTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canTransmitTimeout; } };
struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } };
struct SendFrontCanCmdAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.controllerHardware.sendFrontCanCmd; } };
struct SendBackCanCmdAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.controllerHardware.sendBackCanCmd; } };
struct CanTransmitTimeoutAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.controllerHardware.canTransmitTimeout; } };
struct CanReceiveTimeoutAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.controllerHardware.canReceiveTimeout; } };
#endif
// Input devices
@ -119,124 +115,119 @@ struct BremsMaxAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<in
struct DPadDebounceAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.dpadDebounce; } };
#endif
#ifdef FEATURE_GAMETRAK
struct GametrakXMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakXMin; } };
struct GametrakXMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakXMax; } };
struct GametrakYMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakYMin; } };
struct GametrakYMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakYMax; } };
struct GametrakDistMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakDistMin; } };
struct GametrakDistMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gametrakDistMax; } };
struct GametrakXMinAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakXMin; } };
struct GametrakXMaxAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakXMax; } };
struct GametrakYMinAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakYMin; } };
struct GametrakYMaxAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakYMax; } };
struct GametrakDistMinAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakDistMin; } };
struct GametrakDistMaxAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.gametrakDistMax; } };
#endif
struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } };
struct StatsUpdateRateAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.statsUpdateRate; } };
// Cloud
#ifdef FEATURE_CLOUD
struct CloudCollectRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudCollectRate; } };
struct CloudSendRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudSendRate; } };
struct CloudCollectRateAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.cloudCollectRate; } };
struct CloudSendRateAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.cloudSendRate; } };
#endif
#ifdef FEATURE_UDPCLOUD
struct UdpCloudSendIntervalAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.udpSendRateMs; } };
struct UdpCloudEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.udpCloudSettings.udpCloudEnabled; } };
struct CloudDebugEnableAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.udpCloudSettings.enableCloudDebug; } };
struct UdpUseStdStringAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.udpCloudSettings.udpUseStdString; } };
struct UdpCloudSendIntervalAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.udpSendRateMs; } };
struct UdpCloudEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.udpCloudEnabled; } };
struct CloudDebugEnableAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.enableCloudDebug; } };
struct UdpUseStdStringAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.udpUseStdString; } };
#endif
// DefaultMode
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } };
struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } };
struct DefaultModeSquareBremsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareBrems; } };
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return profileSettings.defaultMode.modelMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.squareGas; } };
struct DefaultModeSquareBremsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.squareBrems; } };
struct DefaultModeEnableSmoothingUpAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.enableSmoothingUp; } };
struct DefaultModeEnableSmoothingDownAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.enableSmoothingDown; } };
struct DefaultModeEnableFieldWeakSmoothingUpAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.enableFieldWeakSmoothingUp; } };
struct DefaultModeEnableFieldWeakSmoothingDownAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.enableFieldWeakSmoothingDown; } };
struct DefaultModeEnableFieldWeakSmoothingLowerLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.fwSmoothLowerLimit; } };
struct DefaultModeEnableSmoothingUpAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.enableSmoothingUp; } };
struct DefaultModeEnableSmoothingDownAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.enableSmoothingDown; } };
struct DefaultModeEnableFieldWeakSmoothingUpAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.enableFieldWeakSmoothingUp; } };
struct DefaultModeEnableFieldWeakSmoothingDownAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return profileSettings.defaultMode.enableFieldWeakSmoothingDown; } };
struct DefaultModeEnableFieldWeakSmoothingLowerLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.fwSmoothLowerLimit; } };
struct DefaultModeSmoothingAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.smoothing; } };
struct DefaultModeFrontPercentageAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.frontPercentage; } };
struct DefaultModeBackPercentageAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.backPercentage; } };
struct DefaultModeAddSchwelleAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.add_schwelle; } };
struct DefaultModeGas1WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.gas1_wert; } };
struct DefaultModeGas2WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.gas2_wert; } };
struct DefaultModeBrems1WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.brems1_wert; } };
struct DefaultModeBrems2WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.defaultMode.brems2_wert; } };
struct DefaultModeEnableHybridAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.hybrid.enable; } };
struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.activationLimit; } };
struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } };
struct DefaultModeSmoothingAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.smoothing; } };
struct DefaultModeFrontPercentageAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.frontPercentage; } };
struct DefaultModeBackPercentageAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.backPercentage; } };
struct DefaultModeAddSchwelleAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.add_schwelle; } };
struct DefaultModeGas1WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.gas1_wert; } };
struct DefaultModeGas2WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.gas2_wert; } };
struct DefaultModeBrems1WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.brems1_wert; } };
struct DefaultModeBrems2WertAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return profileSettings.defaultMode.brems2_wert; } };
// TempomatMode
struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } };
struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return profileSettings.tempomatMode.modelMode; } };
// LarsmMode
struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } };
struct LarsmModeModeAccessor : public RefAccessorSaveSettings<LarsmModeMode> { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } };
struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.larsmMode.iterations; } };
struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return profileSettings.larsmMode.modelMode; } };
struct LarsmModeModeAccessor : public RefAccessorSaveSettings<LarsmModeMode> { LarsmModeMode &getRef() const override { return profileSettings.larsmMode.mode; } };
struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return profileSettings.larsmMode.iterations; } };
// MotortestMode
struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.motortestMode.multiplikator; } };
struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.motortestMode.maxPwm; } };
struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return profileSettings.motortestMode.multiplikator; } };
struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return profileSettings.motortestMode.maxPwm; } };
// Ledstrip
#ifdef FEATURE_LEDSTRIP
struct EnableLedAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableLedAnimation; } };
struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } };
struct LedsCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.ledsCount; } };
struct CenterOffsetAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.centerOffset; } };
struct SmallOffsetAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.smallOffset; } };
struct BigOffsetAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.bigOffset; } };
struct LedStripMaxMilliampsAccessor : public NewSettingsAccessor<uint32_t> { ConfigWrapper<uint32_t> &getConfig() const override { return configs.ledStripMaxMilliamps; } };
struct EnableLedAnimationAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableLedAnimation; } };
struct EnableBrakeLightsAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableBrakeLights; } };
struct LedsCountAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.ledsCount; } };
struct CenterOffsetAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.centerOffset; } };
struct SmallOffsetAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.smallOffset; } };
struct BigOffsetAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.bigOffset; } };
struct LedStripMaxMilliampsAccessor : public NewSettingsAccessor<uint32_t> { ConfigWrapper<uint32_t> &getConfig() const override { return configs.ledstrip.maxMilliamps; } };
struct LedStripMaxAmpereAccessor : public virtual espgui::AccessorInterface<float>
{
float getValue() const override
{
return configs.ledStripMaxMilliamps.value / 1000.f;
return configs.ledstrip.maxMilliamps.value / 1000.f;
}
espgui::AccessorInterface<float>::setter_result_t setValue(float value) override
{
return configs.write_config(configs.ledStripMaxMilliamps, value * 1000);
return configs.write_config(configs.ledstrip.maxMilliamps, value * 1000);
}
};
struct EnableBeepWhenBlinkAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableBeepWhenBlink; } };
struct EnableFullBlinkAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableFullBlink; } };
struct EnableLedstripStVOAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableStVO; } };
struct LedsStVOFrontOffsetAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.stvoFrontOffset; } };
struct LedsStVOFrontLengthAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.stvoFrontLength; } };
struct EnableLedstripStVOFrontlight : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.stvoFrontEnable; } };
struct AnimationMultiplierAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.ledstrip.animationMultiplier; } };
struct LedstripBrightnessAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.ledstrip.brightness; } };
struct LedstripEnableBlinkAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableAnimBlink; } };
struct EnableBeepWhenBlinkAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableBeepWhenBlink; } };
struct EnableFullBlinkAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableFullBlink; } };
struct EnableLedstripStVOAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableStVO; } };
struct LedsStVOFrontOffsetAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.stvoFrontOffset; } };
struct LedsStVOFrontLengthAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.stvoFrontLength; } };
struct EnableLedstripStVOFrontlight : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.stvoFrontEnable; } };
struct AnimationMultiplierAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.ledstrip.animationMultiplier; } };
struct LedstripBrightnessAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.ledstrip.brightness; } };
struct LedstripEnableBlinkAnimationAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.ledstrip.enableAnimBlink; } };
#ifdef FEATURE_OTA
struct LedstripOtaAnimationAccessor : public RefAccessorSaveSettings<OtaAnimationModes> { OtaAnimationModes &getRef() const override { return settings.ledstrip.otaMode; } };
struct LedstripOtaAnimationAccessor : public NewSettingsAccessor<OtaAnimationModes> { ConfigWrapper<OtaAnimationModes> &getConfig() const override { return configs.ledstrip.otaMode; } };
#endif
#endif
// Battery
struct BatterySeriesCellsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.battery.cellsSeries; } };
struct BatteryParallelCellsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.battery.cellsParallel; } };
struct BatteryWHperKMAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } };
struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.battery.applyCalibration; } };
struct BatterySeriesCellsAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.battery.cellsSeries; } };
struct BatteryParallelCellsAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.battery.cellsParallel; } };
struct BatteryWHperKMAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.battery.watthoursPerKilometer; } };
struct BatteryApplyCalibrationAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.battery.applyCalibration; } };
// Lockscreen
struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } };
struct LockscreenAllowPresetSwitchAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.lockscreen.allowPresetSwitch; } };
template<uint8_t index>
struct LockscreenPinDigitAccessor : public RefAccessorSaveSettings<int8_t> { int8_t &getRef() const override { return settings.lockscreen.pin[index]; } };
struct LockscreenKeepLockedAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.keepLockedAfterReboot; } };
struct LockscreenPinDigitAccessor : public NewSettingsAccessor<int8_t> { ConfigWrapper<int8_t> &getConfig() const override { return configs.lockscreen.pin[index].digit; } };
struct LockscreenKeepLockedAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.lockscreen.keepLockedAfterReboot; } };
// Handbremse
struct HandbremsEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.enable; } };
struct HandbremsModeAccessor : public RefAccessorSaveSettings<HandbremseMode> { HandbremseMode &getRef() const override { return settings.handbremse.mode; } };
struct HandbremsTimeoutAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.handbremse.triggerTimeout; } };
struct HandbremsAutomaticAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.automatic; } };
struct HandbremsVisualizeAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.visualize; } };
struct HandbremsEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.handbremse.enable; } };
struct HandbremsModeAccessor : public NewSettingsAccessor<HandbremseMode> { ConfigWrapper<HandbremseMode> &getConfig() const override { return configs.handbremse.mode; } };
struct HandbremsTimeoutAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.handbremse.triggerTimeout; } };
struct HandbremsAutomaticAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.handbremse.automatic; } };
struct HandbremsVisualizeAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.handbremse.visualize; } };
// ESP Now
#ifdef FEATURE_ESPNOW
struct ESPNowSyncTimeEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTime; } };
struct ESPNowSyncTimeWithOthersEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTimeWithOthers; } };
struct ESPNowSyncBlinkEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncBlink; } };
struct ESPNowSyncTimeEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.espnow.syncTime; } };
struct ESPNowSyncTimeWithOthersEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.espnow.syncTimeWithOthers; } };
struct ESPNowSyncBlinkEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.espnow.syncBlink; } };
#endif
// Button Mapping accessors

View File

@ -24,13 +24,7 @@ public:
//return;
}
settings = presets::defaultSettings;
if (!settingsPersister.openCommon())
{
ESP_LOGE("BOBBY", "openCommon() failed");
//return;
}
profileSettings = presets::defaultProfileSettings;
if (profile)
{
@ -41,7 +35,7 @@ public:
}
}
if (!settingsPersister.load(settings))
if (!settingsPersister.load(profileSettings))
{
ESP_LOGE("BOBBY", "load() for settings failed");
//return;

View File

@ -9,6 +9,6 @@ namespace {
class LoadSettingsAction : public virtual ActionInterface
{
public:
void triggered() override { loadSettings(); }
void triggered() override { loadProfileSettings(); }
};
}

View File

@ -9,6 +9,6 @@ namespace {
class SaveSettingsAction : public virtual ActionInterface
{
public:
void triggered() override { saveSettings(); }
void triggered() override { saveProfileSettings(); }
};
}

View File

@ -7,6 +7,7 @@
// local includes
#include "drivingstatistics.h"
#include "globals.h"
#include "newsettings.h"
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
@ -14,7 +15,7 @@ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
float getBatteryPercentage(float batVoltage, BatteryCellType cellType)
{
const float cellVoltage = batVoltage / settings.battery.cellsSeries;
const float cellVoltage = batVoltage / configs.battery.cellsSeries.value;
switch (cellType)
{
@ -129,23 +130,23 @@ float getRemainingWattHours()
}
avgVoltage = avgVoltage / controllers.size();
return (target_mah / 1000.f) * 3.7 * settings.battery.cellsParallel * settings.battery.cellsSeries * (getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)) / 100);
return (target_mah / 1000.f) * 3.7 * configs.battery.cellsParallel.value * configs.battery.cellsSeries.value * (getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)) / 100);
}
float getPercentageByWh(float wh)
{
const float maxWh = (getTarget_mAh() / 1000.f) * 3.7 * settings.battery.cellsParallel * settings.battery.cellsSeries;
const float maxWh = (getTarget_mAh() / 1000.f) * 3.7 * configs.battery.cellsParallel.value * configs.battery.cellsSeries.value;
return maxWh / wh;
}
float getTarget_mAh()
{
float target_mah = 2000; //default
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::_22P) target_mah = 2200;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::HG2) target_mah = 3000;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::MH1) target_mah = 3200;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::VTC5) target_mah = 2600;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::BAK_25R) target_mah = 2500;
if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::_22P) target_mah = 2200;
if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::HG2) target_mah = 3000;
if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::MH1) target_mah = 3200;
if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::VTC5) target_mah = 2600;
if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::BAK_25R) target_mah = 2500;
return target_mah;
}
@ -158,7 +159,7 @@ std::string getBatteryPercentageString()
}
avgVoltage = avgVoltage / controllers.size();
std::string output = fmt::format("Battery: {:.1f}%", getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)));
std::string output = fmt::format("Battery: {:.1f}%", getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)));
return output;
}
@ -175,12 +176,12 @@ std::string getBatteryRemainingWattHoursString()
std::string getBatteryCellTypeString()
{
return fmt::format("Cells: {}", toString(BatteryCellType(settings.battery.cellType)));
return fmt::format("Cells: {}", toString(BatteryCellType(configs.battery.cellType.value)));
}
std::string getRemainingRangeString()
{
return fmt::format("{:.1f} km", getRemainingWattHours() / settings.battery.watthoursPerKilometer);
return fmt::format("{:.1f} km", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value);
}
std::string getBatteryDebugString()

View File

@ -109,14 +109,14 @@ void destroyBle()
void initBle()
{
if (settings.bleSettings.bleEnabled)
if (configs.bleSettings.bleEnabled.value)
createBle();
}
void handleBle()
{
if (settings.bleSettings.bleEnabled)
if (configs.bleSettings.bleEnabled.value)
{
if (!pServer)
createBle();
@ -176,8 +176,8 @@ void handleBle()
auto arr = doc.createNestedArray("s");
if (controllers.front.feedbackValid)
{
arr.add(convertToKmh(controllers.front.feedback.left.speed * (settings.controllerHardware.invertFrontLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.front.feedback.right.speed * (settings.controllerHardware.invertFrontRight ? -1 : 1)));
arr.add(convertToKmh(controllers.front.feedback.left.speed * (profileSettings.controllerHardware.invertFrontLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.front.feedback.right.speed * (profileSettings.controllerHardware.invertFrontRight ? -1 : 1)));
}
else
{
@ -186,8 +186,8 @@ void handleBle()
}
if (controllers.back.feedbackValid)
{
arr.add(convertToKmh(controllers.back.feedback.left.speed * (settings.controllerHardware.invertBackLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.back.feedback.right.speed * (settings.controllerHardware.invertBackRight ? -1 : 1)));
arr.add(convertToKmh(controllers.back.feedback.left.speed * (profileSettings.controllerHardware.invertBackLeft ? -1 : 1)));
arr.add(convertToKmh(controllers.back.feedback.right.speed * (profileSettings.controllerHardware.invertBackRight ? -1 : 1)));
}
else
{
@ -251,7 +251,7 @@ void RemoteControlCallbacks::onWrite(NimBLECharacteristic* pCharacteristic)
if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation;
#endif // FEATURE_LEDSTRIP
const bool isInverted = (settings.controllerHardware.invertFrontLeft && !settings.controllerHardware.invertFrontRight);
const bool isInverted = (profileSettings.controllerHardware.invertFrontLeft && !profileSettings.controllerHardware.invertFrontRight);
if (!simplified)
{

View File

@ -1,5 +1,7 @@
#include "bluetooth_bobby.h"
// compilation will be broken as there is no config parameter
// local includes
#ifdef FEATURE_BLUETOOTH
#include "actions/bluetoothbeginaction.h"
@ -7,24 +9,25 @@
#ifdef FEATURE_BMS
#include "actions/bluetoothconnectbmsaction.h"
#endif
#include "bluetoothmode.h"
#endif
#ifdef FEATURE_BLUETOOTH
void bluetooth_init()
{
if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Master)
if (configs.bluetooth.autoBluetoothMode.value == BluetoothMode::Master)
{
bootLabel.redraw("bluetooth begin master");
BluetoothBeginMasterAction{}.triggered();
#ifdef FEATURE_BMS
if (settings.autoConnectBms)
if (configs.autoConnectBms.value)
{
bootLabel.redraw("connect BMS");
BluetoothConnectBmsAction{}.triggered();
}
#endif
}
else if (settings.bluetoothSettings.autoBluetoothMode == BluetoothMode::Slave)
else if (configs.bluetooth.autoBluetoothMode.value == BluetoothMode::Slave)
{
bootLabel.redraw("bluetooth begin");
BluetoothBeginAction{}.triggered();

View File

@ -1,12 +1,9 @@
#pragma once
#include <cstdint>
#ifdef FEATURE_BLUETOOTH
enum class BluetoothMode : uint8_t
{
Off,
Master,
Slave
};
#endif

View File

@ -102,7 +102,7 @@ void buttonPressedCommon(espgui::Button button)
#endif
break;
case BobbyButton::Up2:
if (settings.handbremse.enable)
if (configs.handbremse.enable.value)
{
using namespace handbremse;
if (stateWish == StateWish::brake || angezogen)

View File

@ -193,7 +193,7 @@ bool parseBoardcomputerCanMessage(const twai_message_t &message)
bool tryParseCanInput()
{
twai_message_t message;
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{settings.controllerHardware.canReceiveTimeout}).count();
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.controllerHardware.canReceiveTimeout.value}).count();
if (const auto result = twai_receive(&message, timeout); result != ESP_OK)
{
if (result != ESP_ERR_TIMEOUT)
@ -210,8 +210,8 @@ bool tryParseCanInput()
return false;
}
Controller &front = settings.controllerHardware.swapFrontBack ? controllers.back : controllers.front;
Controller &back = settings.controllerHardware.swapFrontBack ? controllers.front : controllers.back;
Controller &front = configs.controllerHardware.swapFrontBack.value ? controllers.back : controllers.front;
Controller &back = configs.controllerHardware.swapFrontBack.value ? controllers.front : controllers.back;
if (parseMotorControllerCanMessage<false>(message, front))
{
@ -269,7 +269,7 @@ void sendCanCommands()
std::fill(std::begin(message.data), std::end(message.data), 0);
std::memcpy(message.data, &value, sizeof(value));
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{settings.controllerHardware.canTransmitTimeout}).count();
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.controllerHardware.canTransmitTimeout.value}).count();
const auto timestamp_before = espchrono::millis_clock::now();
const auto result = twai_transmit(&message, timeout);
@ -313,13 +313,13 @@ void sendCanCommands()
return result;
};
const bool swap = settings.controllerHardware.swapFrontBack;
const bool swap = configs.controllerHardware.swapFrontBack.value;
const Controller *front =
(swap ? settings.controllerHardware.sendBackCanCmd : settings.controllerHardware.sendFrontCanCmd ) ?
(swap ? configs.controllerHardware.sendBackCanCmd.value : configs.controllerHardware.sendFrontCanCmd.value ) ?
(swap ? &controllers.back : &controllers.front) :
nullptr;
const Controller *back =
(swap ? settings.controllerHardware.sendFrontCanCmd : settings.controllerHardware.sendBackCanCmd ) ?
(swap ? configs.controllerHardware.sendFrontCanCmd.value : configs.controllerHardware.sendBackCanCmd.value ) ?
(swap ? &controllers.front : &controllers.back) :
nullptr;

View File

@ -36,7 +36,7 @@ std::optional<espchrono::millis_clock::time_point> lastCloudSend;
void initCloud()
{
if (settings.cloudSettings.cloudEnabled &&
if (configs.cloudSettings.cloudEnabled.value &&
!configs.cloudUrl.value.empty())
{
createCloud();
@ -54,14 +54,14 @@ void updateCloud()
{
const auto now = espchrono::millis_clock::now();
if (!lastCloudCollect || now - *lastCloudCollect >= std::chrono::milliseconds{settings.boardcomputerHardware.timersSettings.cloudCollectRate})
if (!lastCloudCollect || now - *lastCloudCollect >= std::chrono::milliseconds{configs.boardcomputerHardware.timersSettings.cloudCollectRate.value})
{
cloudCollect();
lastCloudCollect = now;
}
if (!lastCloudSend || now - *lastCloudSend >= 1000ms/settings.boardcomputerHardware.timersSettings.cloudSendRate)
if (!lastCloudSend || now - *lastCloudSend >= 1000ms/configs.boardcomputerHardware.timersSettings.cloudSendRate.value)
{
cloudSend();
@ -165,7 +165,7 @@ void cloudCollect()
void cloudSend()
{
if (settings.cloudSettings.cloudEnabled &&
if (configs.cloudSettings.cloudEnabled.value &&
!configs.cloudUrl.value.empty())
{
if (!cloudClient)
@ -198,7 +198,7 @@ void cloudSend()
cloudBuffer += ']';
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{settings.cloudSettings.cloudTransmitTimeout}).count();
const auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.cloudSettings.cloudTransmitTimeout.value}).count();
const auto written = cloudClient.send_text(cloudBuffer, timeout);
if (written < 0)

12
main/configutils_bobby.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "sdkconfig.h"
// 3rdparty lib includes
#include <configutils_priv_enum.h>
// local includes
#include "ledstrip.h"
#include "handbremse.h"
IMPLEMENT_NVS_GET_SET_ENUM(OtaAnimationModes)
IMPLEMENT_NVS_GET_SET_ENUM(HandbremseMode)

View File

@ -0,0 +1,8 @@
#include "sdkconfig.h"
#include "configutils_bobby.h"
#define CONFIGWRAPPER_TOSTRING_USINGS using ::toString;
#include <configwrapper_priv.h>
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(OtaAnimationModes)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(HandbremseMode)

View File

@ -8,7 +8,7 @@ Controller::Controller(
HardwareSerial &serial,
#endif
bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight,
int16_t &voltageCalib30V, int16_t &voltageCalib50V
espconfig::ConfigWrapper<int16_t> &voltageCalib30V, espconfig::ConfigWrapper<int16_t> &voltageCalib50V
) :
#ifdef FEATURE_SERIAL
serial{serial},
@ -21,9 +21,9 @@ Controller::Controller(
float Controller::getCalibratedVoltage() const
{
float voltage = feedback.batVoltage;
if (settings.battery.applyCalibration)
if (configs.battery.applyCalibration.value)
{
voltage = ((voltage - float(voltageCalib30V)) * (20.f / (float(voltageCalib50V) - float(voltageCalib30V))) + 30.f);
voltage = ((voltage - float(voltageCalib30V.value)) * (20.f / (float(voltageCalib50V.value) - float(voltageCalib30V.value))) + 30.f);
}
else
{

View File

@ -10,6 +10,7 @@
// 3rdparty lib includes
#include <espchrono.h>
#include <configwrapper.h>
// local includes
#include "bobbycar-common.h"
@ -30,7 +31,7 @@ struct Controller
HardwareSerial &serial,
#endif
bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight,
int16_t &voltageCalib30V, int16_t &voltageCalib50V);
espconfig::ConfigWrapper<int16_t> &voltageCalib30V, espconfig::ConfigWrapper<int16_t> &voltageCalib50V);
// Controller(const Controller &) = delete;
// Controller &operator=(const Controller &) = delete;
@ -38,7 +39,7 @@ struct Controller
std::reference_wrapper<HardwareSerial> serial;
#endif
bool &enableLeft, &enableRight, &invertLeft, &invertRight;
int16_t &voltageCalib30V, &voltageCalib50V;
espconfig::ConfigWrapper<int16_t> &voltageCalib30V, &voltageCalib50V;
bobbycar::protocol::serial::Command command{};

View File

@ -136,11 +136,11 @@ void handleNormalChar(char c)
}
case 'r':
case 'R':
loadSettings();
loadProfileSettings();
break;
case 's':
case 'S':
saveSettings();
saveProfileSettings();
break;
case '0':
case '1':

View File

@ -13,7 +13,7 @@
#include "icons/settings.h"
#include "battery.h"
#include "menus/batterymenu.h"
#include "globals.h"
#include "newsettings.h"
#include "displays/menus/batterymenu.h"
#include "accessors/settingsaccessors.h"
#include "bobbycheckbox.h"
@ -35,9 +35,8 @@ class Save30VCalibrationAction : public virtual espgui::ActionInterface
public:
void triggered() override
{
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
configs.write_config(configs.battery.front30VoltCalibration, controllers.front.feedback.batVoltage);
configs.write_config(configs.battery.back30VoltCalibration, controllers.back.feedback.batVoltage);
}
};
@ -46,9 +45,8 @@ class Save50VCalibrationAction : public virtual espgui::ActionInterface
public:
void triggered() override
{
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
configs.write_config(configs.battery.front50VoltCalibration, controllers.front.feedback.batVoltage);
configs.write_config(configs.battery.back50VoltCalibration, controllers.back.feedback.batVoltage);
}
};
@ -57,11 +55,10 @@ class ResetCalibrationAction : public virtual espgui::ActionInterface
public:
void triggered() override
{
settings.battery.front30VoltCalibration = 3000;
settings.battery.back30VoltCalibration = 3000;
settings.battery.front50VoltCalibration = 5000;
settings.battery.back50VoltCalibration = 5000;
saveSettings();
configs.reset_config(configs.battery.front30VoltCalibration);
configs.reset_config(configs.battery.back30VoltCalibration);
configs.reset_config(configs.battery.front50VoltCalibration);
configs.reset_config(configs.battery.back50VoltCalibration);
}
};
@ -75,7 +72,7 @@ class BatteryVoltageCalibrationFront30VText : public virtual espgui::TextInterfa
public:
std::string text() const override
{
return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration));
return fmt::format("30V Front: {}", convertToFloat(configs.battery.front30VoltCalibration.value));
}
};
@ -84,7 +81,7 @@ class BatteryVoltageCalibrationBack30VText : public virtual espgui::TextInterfac
public:
std::string text() const override
{
return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration));
return fmt::format("30V Back: {}", convertToFloat(configs.battery.back30VoltCalibration.value));
}
};
@ -93,7 +90,7 @@ class BatteryVoltageCalibrationFront50VText : public virtual espgui::TextInterfa
public:
std::string text() const override
{
return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration));
return fmt::format("50V Front: {}", convertToFloat(configs.battery.front50VoltCalibration.value));
}
};
@ -102,7 +99,7 @@ class BatteryVoltageCalibrationBack50VText : public virtual espgui::TextInterfac
public:
std::string text() const override
{
return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration));
return fmt::format("50V Back: {}", convertToFloat(configs.battery.back50VoltCalibration.value));
}
};
@ -111,7 +108,7 @@ class BatteryVoltageCalibratedText : public virtual espgui::TextInterface
public:
std::string text() const override
{
if (settings.battery.applyCalibration)
if (configs.battery.applyCalibration.value)
return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(), controllers.back.getCalibratedVoltage());
else
return "Not activated";

View File

@ -14,6 +14,18 @@
#include "ledstripdefines.h"
#endif
bool isValidPin(std::array<int8_t,4> enteredPin)
{
for (int i = 0; i < 4; i++)
{
if (enteredPin[i] != configs.lockscreen.pin[i].digit.value)
{
return false;
}
}
return true;
}
void Lockscreen::start()
{
Base::start();
@ -27,10 +39,9 @@ void Lockscreen::start()
currentMode = &m_mode;
isLocked = true;
if (settings.lockscreen.keepLockedAfterReboot && !settings.lockscreen.locked)
if (configs.lockscreen.keepLockedAfterReboot.value && !configs.lockscreen.locked.value)
{
settings.lockscreen.locked = true;
saveSettings();
configs.write_config(configs.lockscreen.locked, true);
}
}
@ -85,7 +96,7 @@ void Lockscreen::redraw()
if (!m_back_pressed && ++m_currentIndex>=4)
{
if (m_numbers == settings.lockscreen.pin)
if (isValidPin(m_numbers))
{
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
espgui::switchScreen<PotisCalibrateDisplay>(true);
@ -148,17 +159,16 @@ void Lockscreen::stop()
isLocked = false;
if (!(!gas || !brems || *gas > 200.f || *brems > 200.f))
{
if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
if (configs.lockscreen.keepLockedAfterReboot.value && configs.lockscreen.locked.value)
{
settings.lockscreen.locked = false;
saveSettings();
configs.write_config(configs.lockscreen.locked, false);
}
}
}
void Lockscreen::buttonPressed(espgui::Button button)
{
if (settings.lockscreen.allowPresetSwitch ||
if (configs.lockscreen.allowPresetSwitch.value ||
!cpputils::is_in(button, BobbyButton::Profile0, BobbyButton::Profile1, BobbyButton::Profile2, BobbyButton::Profile3))
Base::buttonPressed(button);

View File

@ -101,7 +101,7 @@ void BatteryMenu::redraw()
}
avgVoltage = avgVoltage / controllers.size();
const auto batPercent = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType));
const auto batPercent = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
m_doubleProgressBarBatPercentage.redraw(batPercent, battery::bootBatPercentage);
}

View File

@ -1,5 +1,7 @@
#pragma once
// compilation will be broken as there is no config parameter
// local includes
#include "changevaluedisplay.h"
#ifdef FEATURE_BLUETOOTH
@ -27,13 +29,13 @@ namespace {
#ifdef FEATURE_BLUETOOTH
class BluetoothSettingsMenu;
using AutoBluetoothModeChangeDisplay = makeComponent<
ChangeValueDisplay<BluetoothMode>,
StaticText<TEXT_AUTOBLUETOOTHMODE>,
AutoBluetoothModeAccessor,
BackActionInterface<SwitchScreenAction<BluetoothSettingsMenu>>,
SwitchScreenAction<BluetoothSettingsMenu>
>;
//using AutoBluetoothModeChangeDisplay = makeComponent<
// ChangeValueDisplay<BluetoothMode>,
// StaticText<TEXT_AUTOBLUETOOTHMODE>,
// AutoBluetoothModeAccessor,
// BackActionInterface<SwitchScreenAction<BluetoothSettingsMenu>>,
// SwitchScreenAction<BluetoothSettingsMenu>
//>;
class BluetoothSettingsMenu :
public BobbyMenuDisplay,
@ -53,7 +55,7 @@ public:
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHFLUSH>, BluetoothFlushAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHEND>, BluetoothEndAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHDISCONNECT>, BluetoothDisconnectAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOBLUETOOTHMODE>, SwitchScreenAction<AutoBluetoothModeChangeDisplay>>>();
// constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOBLUETOOTHMODE>, SwitchScreenAction<AutoBluetoothModeChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};

View File

@ -56,13 +56,6 @@ using DefaultModeModelModeChangeDisplay = espgui::makeComponent<
espgui::ConfirmActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>,
espgui::BackActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>
>;
using DefaultModeHybridModelModeChangeDisplay = espgui::makeComponent<
BobbyChangeValueDisplay<UnifiedModelMode>,
espgui::StaticText<TEXT_HYBRIDMODE>,
DefaultModeHybridModelModeAccessor,
espgui::ConfirmActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>,
espgui::BackActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>
>;
using DefaultModeSmoothingChangeDisplay = espgui::makeComponent<
BobbyChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SMOOTHINGVAL>,
@ -126,37 +119,19 @@ using DefaultModeBrems2WertChangeDisplay = espgui::makeComponent<
espgui::ConfirmActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>,
espgui::BackActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>
>;
using DefaultModeHybridActivationLimitChangeDisplay = espgui::makeComponent<
BobbyChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_HYBRIDACTIVATIONLIMIT>,
DefaultModeHybridActivationLimitAccessor,
espgui::ConfirmActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>,
espgui::BackActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>
>;
using DefaultModeHybridDeactivationLimitChangeDisplay = espgui::makeComponent<
BobbyChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_HYBRIDDEACTIVATIONLIMIT>,
DefaultModeHybridDeactivationLimitAccessor,
espgui::ConfirmActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>,
espgui::BackActionInterface<espgui::SwitchScreenAction<DefaultModeSettingsMenu>>
>;
} // namespace
using namespace espgui;
DefaultModeSettingsMenu::DefaultModeSettingsMenu()
{
auto diff = std::abs(settings.hybrid.activationLimit - settings.hybrid.deactivationLimit);
if (diff < 20) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITS_TO_NEAR>, StaticFont<2>, StaticColor<TFT_RED>, DummyAction>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODELMODE>, SwitchScreenAction<DefaultModeModelModeChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_HYBRIDMODE>, SwitchScreenAction<DefaultModeHybridModelModeChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SQUAREGAS>, BobbyCheckbox, DefaultModeSquareGasAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SQUAREBREMS>, BobbyCheckbox, DefaultModeSquareBremsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLESMOOTHINGUP>, BobbyCheckbox, DefaultModeEnableSmoothingUpAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLESMOOTHINGDOWN>, BobbyCheckbox, DefaultModeEnableSmoothingDownAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLEFWSMOOTHINGUP>, BobbyCheckbox, DefaultModeEnableFieldWeakSmoothingUpAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ENABLEFWSMOOTHINGDOWN>, BobbyCheckbox, DefaultModeEnableFieldWeakSmoothingDownAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_HYBRIDENABLE>, BobbyCheckbox, DefaultModeEnableHybridAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_HANDBREMSE>, SwitchScreenAction<HandbremsSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_FWSMOOTHING_LIMIT, DefaultModeEnableFieldWeakSmoothingLowerLimitAccessor>, SwitchScreenAction<DefaultModeFwSmoothingLowerLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SMOOTHINGVAL, DefaultModeSmoothingAccessor>, SwitchScreenAction<DefaultModeSmoothingChangeDisplay>>>();
@ -167,8 +142,6 @@ DefaultModeSettingsMenu::DefaultModeSettingsMenu()
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SUBBRAKEVAL, DefaultModeBrems2WertAccessor>, SwitchScreenAction<DefaultModeBrems2WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ADDGASVAL, DefaultModeGas1WertAccessor>, SwitchScreenAction<DefaultModeGas1WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ADDBRAKEVAL, DefaultModeBrems1WertAccessor>, SwitchScreenAction<DefaultModeBrems1WertChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_HYBRIDACTIVATIONLIMIT, DefaultModeHybridActivationLimitAccessor>, SwitchScreenAction<DefaultModeHybridActivationLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_HYBRIDDEACTIVATIONLIMIT, DefaultModeHybridDeactivationLimitAccessor>, SwitchScreenAction<DefaultModeHybridDeactivationLimitChangeDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<ModesSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}

View File

@ -42,7 +42,7 @@ class HandBremsModeText : public virtual espgui::TextInterface
public:
std::string text() const override
{
return fmt::format("Mode: &2{}", toString(settings.handbremse.mode));
return fmt::format("Mode: &2{}", configs.handbremse.mode.valueAsString());
}
};
}

View File

@ -136,7 +136,7 @@ class LedStripMaxCurrentText : public virtual espgui::TextInterface
public:
std::string text() const override
{
return fmt::format("&sLedstrip max current: &f&2{:.02f}A", configs.ledStripMaxMilliamps.value / 1000.f);
return fmt::format("&sLedstrip max current: &f&2{:.02f}A", configs.ledstrip.maxMilliamps.value / 1000.f);
}
};
} // namespace

View File

@ -6,7 +6,7 @@
// local includes
#include "ledstrip.h"
#include "globals.h"
#include "newsettings.h"
#include "utils.h"
#include "ledstripmenu.h"
@ -24,8 +24,7 @@ class LedstripChangeOtaAnimModeAction : public virtual espgui::ActionInterface
public:
void triggered() override
{
settings.ledstrip.otaMode = mode;
saveSettings();
configs.write_config(configs.ledstrip.otaMode, mode);
}
};
} // namespace

View File

@ -10,7 +10,6 @@
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/ledstripmenu.h"
#include "actions/modesettingsaction.h"
#include "displays/menus/presetsmenu.h"
#include "displays/menus/profilesmenu.h"
#include "displays/menus/graphsmenu.h"
#include "displays/menus/batterymenu.h"
@ -116,7 +115,6 @@ MainMenu::MainMenu()
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&bobbyicons::poweroff>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();

View File

@ -1,115 +0,0 @@
#include "presetsmenu.h"
// local includes
#include "actioninterface.h"
#include "actions/multiaction.h"
#include "actions/switchscreenaction.h"
#include "globals.h"
#include "icons/back.h"
#include "mainmenu.h"
#include "menudisplay.h"
#include "presets.h"
#include "settings.h"
#include "utils.h"
namespace {
constexpr char TEXT_PRESETS[] = "Presets";
constexpr char TEXT_DEFAULTEVERYTHING[] = "Default everything";
constexpr char TEXT_DEFAULTLIMITS[] = "Default limits";
constexpr char TEXT_KIDSLIMITS[] = "Kids limits";
constexpr char TEXT_DEFAULTPOTI[] = "Default poti";
constexpr char TEXT_DEFAULTCONTROLLERHARDWARE[] = "Default controller H/W";
constexpr char TEXT_MOSFETSOFFCONTROLLERHARDWARE[] = "MOSFETs off controller H/W";
constexpr char TEXT_SPINNERCONTROLLERHARDWARE[] = "Spinner controller H/W";
constexpr char TEXT_DEFAULTBOARDCOMPUTERHARDWARE[] = "Default boardcomputer H/W";
constexpr char TEXT_DEFAULTDEFAULTMODE[] = "Default defaultMode";
constexpr char TEXT_SINUSOIDALDEFAULTMODE[] = "Sinusoidal defaultMode";
constexpr char TEXT_DEFAULTTEMPOMATMODE[] = "Default tempomatMode";
constexpr char TEXT_DEFAULTLARSMMODE[] = "Default larsmMode";
constexpr char TEXT_STREET[] = "Street";
constexpr char TEXT_SIDEWALK[] = "Sidewalk";
constexpr char TEXT_POLICE[] = "Police";
constexpr char TEXT_RACE[] = "Race";
constexpr char TEXT_BACK[] = "Back";
class ApplyPresetAction : public virtual ActionInterface
{
public:
void triggered() override { saveSettings(); switchScreen<MainMenu>(); }
};
template<const Settings *preset>
class ApplySettingsPresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::Limits *preset>
class ApplyLimitsPresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.limits = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::ControllerHardware *preset>
class ApplyControllerHardwarePresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.controllerHardware = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::BoardcomputerHardware *preset>
class ApplyBoardcomputerHardwarePresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.boardcomputerHardware = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::DefaultMode *preset>
class ApplyDefaultModePresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.defaultMode = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::TempomatMode *preset>
class ApplyTempomatModePresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.tempomatMode = *preset; ApplyPresetAction::triggered(); }
};
template<const Settings::LarsmMode *preset>
class ApplyLarsmModePresetAction : public virtual ApplyPresetAction
{
public:
void triggered() override { settings.larsmMode = *preset; ApplyPresetAction::triggered(); }
};
} // namespace
PresetsMenu::PresetsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTEVERYTHING>, MultiAction<ApplySettingsPresetAction<&presets::defaultSettings>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTLIMITS>, MultiAction<ApplyLimitsPresetAction<&presets::defaultLimits>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_KIDSLIMITS>, MultiAction<ApplyLimitsPresetAction<&presets::kidsLimits>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::defaultControllerHardware>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETSOFFCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::mosfetsOffControllerHardware>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SPINNERCONTROLLERHARDWARE>, MultiAction<ApplyControllerHardwarePresetAction<&presets::spinnerControllerHardware>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTBOARDCOMPUTERHARDWARE>, MultiAction<ApplyBoardcomputerHardwarePresetAction<&presets::defaultBoardcomputerHardware>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTDEFAULTMODE>, MultiAction<ApplyDefaultModePresetAction<&presets::defaultDefaultMode>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SINUSOIDALDEFAULTMODE>, MultiAction<ApplyDefaultModePresetAction<&presets::sinusoidalDefaultMode>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTTEMPOMATMODE>, MultiAction<ApplyTempomatModePresetAction<&presets::defaultTempomatMode>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEFAULTLARSMMODE>, MultiAction<ApplyLarsmModePresetAction<&presets::defaultLarsmMode>, SwitchScreenAction<MainMenu>>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
std::string PresetsMenu::text() const
{
return TEXT_PRESETS;
}
void PresetsMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,14 +0,0 @@
#pragma once
// local includes
#include "displays/bobbymenudisplay.h"
class PresetsMenu : public BobbyMenuDisplay
{
public:
PresetsMenu();
std::string text() const override;
void back() override;
};

View File

@ -9,7 +9,7 @@
// local includes
#include "battery.h"
#include "globals.h"
#include "newsettings.h"
#include "utils.h"
#include "displays/menus/batterymenu.h"
#include "batterymenu.h"
@ -44,7 +44,7 @@ template<BatteryCellType T>
class BatterySelectTypeAction : public virtual espgui::ActionInterface
{
public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); }
void triggered() override { configs.write_config(configs.battery.cellType, uint8_t(T)); }
};
} // namespace

View File

@ -110,9 +110,9 @@ SettingsMenu::SettingsMenu()
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CONTROLLERHARDWARESETTINGS>, SwitchScreenAction<ControllerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, BobbyCheckbox, AutoConnectBmsAccessor>>();
#endif
//#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
// constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, BobbyCheckbox, AutoConnectBmsAccessor>>();
//#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&bobbyicons::buzzer>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, BobbyCheckbox, FrontLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLED>, BobbyCheckbox, BackLedAccessor>>();

View File

@ -104,7 +104,7 @@ public:
class SavedTotalCentimetersText : public virtual espgui::TextInterface {
public: std::string text() const override {
return fmt::format("saved: {}cm", settings.savedStatistics.totalCentimeters );
return fmt::format("saved: {}cm", configs.savedStatistics.totalCentimeters.value );
}
};
@ -140,8 +140,7 @@ public:
void triggered() override
{
drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100;
settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written;
saveSettings();
configs.write_config(configs.savedStatistics.totalCentimeters, drivingStatistics.last_cm_written);
}
};

View File

@ -198,11 +198,10 @@ void PotisCalibrateDisplay::buttonPressed(espgui::Button button)
case Status::Begin:
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
else if (configs.lockscreen.keepLockedAfterReboot.value && configs.lockscreen.locked.value)
{
espgui::switchScreen<MainMenu>();
settings.lockscreen.locked = false;
saveSettings();
configs.write_config(configs.lockscreen.locked, false);
}
else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
@ -260,7 +259,7 @@ void PotisCalibrateDisplay::buttonPressed(espgui::Button button)
if (*m_gas > 100 || *m_brems > 100)
return;
copyToSettings();
saveSettings();
saveProfileSettings();
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else

View File

@ -85,9 +85,9 @@ void StatusDisplay::redraw()
lastRedraw = now;
}
if (settings.handbremse.enable && settings.handbremse.visualize && handbremse::angezogen)
if (configs.handbremse.enable.value && configs.handbremse.visualize.value && handbremse::angezogen)
tft.fillRect(0, tft.height()-6, tft.width(), 6, TFT_RED);
else if (settings.handbremse.enable && settings.handbremse.visualize && handbremse::stateWish == handbremse::StateWish::brake)
else if (configs.handbremse.enable.value && configs.handbremse.visualize.value && handbremse::stateWish == handbremse::StateWish::brake)
tft.fillRect(0, tft.height()-6, tft.width(), 6, TFT_YELLOW);
else
tft.fillRect(0, tft.height()-6, tft.width(), 6, TFT_BLACK);
@ -115,7 +115,7 @@ void StatusDisplay::redraw()
tft.setTextFont(2);
#ifdef FEATURE_UDPCLOUD
if(settings.udpCloudSettings.udpCloudEnabled && settings.udpCloudSettings.enableCloudDebug)
if(configs.udpCloudSettings.udpCloudEnabled.value && configs.udpCloudSettings.enableCloudDebug.value)
{
tft.fillRect(125, 258, 8, 8, (visualSendUdpPacket) ? TFT_DARKGREY : TFT_BLACK);
}

View File

@ -71,25 +71,25 @@ void update()
ButtonBack = 3
};
if (std::get<ButtonUp>(lastState) != std::get<ButtonUp>(state) && now-debounceUp > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonUp>(lastState) != std::get<ButtonUp>(state) && now-debounceUp > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::upButton(std::get<ButtonUp>(state));
std::get<ButtonUp>(lastState) = std::get<ButtonUp>(state);
debounceUp = now;
}
if (std::get<ButtonDown>(lastState) != std::get<ButtonDown>(state) && now-debounceDown > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonDown>(lastState) != std::get<ButtonDown>(state) && now-debounceDown > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::downButton(std::get<ButtonDown>(state));
std::get<ButtonDown>(lastState) = std::get<ButtonDown>(state);
debounceDown = now;
}
if (std::get<ButtonConfirm>(lastState) != std::get<ButtonConfirm>(state) && now-debounceConfirm > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonConfirm>(lastState) != std::get<ButtonConfirm>(state) && now-debounceConfirm > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::confirmButton(std::get<ButtonConfirm>(state));
std::get<ButtonConfirm>(lastState) = std::get<ButtonConfirm>(state);
debounceConfirm = now;
}
if (std::get<ButtonBack>(lastState) != std::get<ButtonBack>(state) && now-debounceBack > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonBack>(lastState) != std::get<ButtonBack>(state) && now-debounceBack > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::backButton(std::get<ButtonBack>(state));
std::get<ButtonBack>(lastState) = std::get<ButtonBack>(state);

View File

@ -86,25 +86,25 @@ void update()
ButtonBack = 2
};
if (std::get<ButtonUp>(lastState) != std::get<ButtonUp>(state) && now-debounceUp > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonUp>(lastState) != std::get<ButtonUp>(state) && now-debounceUp > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::upButton(std::get<ButtonUp>(state));
std::get<ButtonUp>(lastState) = std::get<ButtonUp>(state);
debounceUp = now;
}
if (std::get<ButtonDown>(lastState) != std::get<ButtonDown>(state) && now-debounceDown > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonDown>(lastState) != std::get<ButtonDown>(state) && now-debounceDown > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::downButton(std::get<ButtonDown>(state));
std::get<ButtonDown>(lastState) = std::get<ButtonDown>(state);
debounceDown = now;
}
if (std::get<ButtonConfirm>(lastState) != std::get<ButtonConfirm>(state) && now-debounceConfirm > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonConfirm>(lastState) != std::get<ButtonConfirm>(state) && now-debounceConfirm > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::confirmButton(std::get<ButtonConfirm>(state));
std::get<ButtonConfirm>(lastState) = std::get<ButtonConfirm>(state);
debounceConfirm = now;
}
if (std::get<ButtonBack>(lastState) != std::get<ButtonBack>(state) && now-debounceBack > settings.boardcomputerHardware.dpadDebounce)
if (std::get<ButtonBack>(lastState) != std::get<ButtonBack>(state) && now-debounceBack > profileSettings.boardcomputerHardware.dpadDebounce)
{
InputDispatcher::backButton(std::get<ButtonBack>(state));
std::get<ButtonBack>(lastState) = std::get<ButtonBack>(state);

View File

@ -59,10 +59,10 @@ void calculateStatistics()
EVERY_N_MILLIS( 10 ) {
static bool saveTotal = false;
if ((settings.savedStatistics.totalCentimeters / 100.f) > drivingStatistics.totalMeters)
if ((configs.savedStatistics.totalCentimeters.value / 100.f) > drivingStatistics.totalMeters)
{
drivingStatistics.totalMeters = settings.savedStatistics.totalCentimeters / 100.f;
drivingStatistics.last_cm_written = settings.savedStatistics.totalCentimeters;
drivingStatistics.totalMeters = configs.savedStatistics.totalCentimeters.value / 100.f;
drivingStatistics.last_cm_written = configs.savedStatistics.totalCentimeters.value;
}
static auto last_km_calculation = espchrono::millis_clock::now();
@ -106,8 +106,7 @@ void calculateStatistics()
saveTotal = false;
}
drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100; // Save total Meters
settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written;
saveSettings();
configs.write_config(configs.savedStatistics.totalCentimeters, drivingStatistics.last_cm_written);
}
}
}

View File

@ -18,6 +18,7 @@ constexpr const char * const TAG = "BOBBY_ESP_NOW";
uint16_t lastYear; // Used for esp-now timesync
std::deque<esp_now_message_t> message_queue{};
std::vector<esp_now_peer_info_t> peers{};
uint8_t initialized{0};
@ -40,39 +41,7 @@ extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data
ESP_LOGD(TAG, "Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str());
if (msg.type == "T")
{
if (!receiveTimeStamp || !settings.espnow.syncTime)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
onRecvTs(*result);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else if (msg.type == "BOBBYT")
{
if (!receiveTsFromOtherBobbycars || !settings.espnow.syncTimeWithOthers)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
ESP_LOGI(TAG, "setting current time to %" PRIu64, *result);
onRecvTs(*result, true);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else
{
ESP_LOGI(TAG, "Unkown Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str());
}
message_queue.push_back(msg);
}
else
{
@ -212,6 +181,47 @@ void handle()
}
return;
}
if (message_queue.size())
{
for (const esp_now_message_t &msg : message_queue)
{
if (msg.type == "T")
{
if (!receiveTimeStamp || !configs.espnow.syncTime.value)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
onRecvTs(*result);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else if (msg.type == "BOBBYT")
{
if (!receiveTsFromOtherBobbycars || !configs.espnow.syncTimeWithOthers.value)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
ESP_LOGI(TAG, "setting current time to %" PRIu64, *result);
onRecvTs(*result, true);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else
{
ESP_LOGI(TAG, "Unkown Type: %s - Message: %s", msg.type.c_str(), msg.content.c_str());
}
}
message_queue.clear();
}
}
void onRecvTs(uint64_t millis, bool isFromBobbycar)

View File

@ -1,6 +1,7 @@
#pragma once
#ifdef FEATURE_ESPNOW
#include <cstdint>
#include <deque>
#include <string>
#include <string_view>
#include <vector>
@ -18,6 +19,7 @@ struct esp_now_message_t
extern bool receiveTimeStamp;
extern bool receiveTsFromOtherBobbycars;
extern std::deque<esp_now_message_t> message_queue;
extern std::vector<esp_now_peer_info_t> peers;
void initESPNow();

View File

@ -24,7 +24,7 @@ bool simplified =
#endif
;
Settings settings;
ProfileSettings profileSettings;
SettingsPersister settingsPersister;
std::array<CRGB, 8> ledstrip_custom_colors;

View File

@ -22,7 +22,8 @@
#include "controller.h"
#include "display.h"
#include "modeinterface.h"
#include "settings.h"
#include "profilesettings.h"
#include "newsettings.h"
#include "settingspersister.h"
#include "macros_bobbycar.h"
@ -49,7 +50,7 @@ extern bool isLocked;
extern bool simplified;
extern Settings settings;
extern ProfileSettings profileSettings;
extern SettingsPersister settingsPersister;
extern std::array<CRGB, 8> ledstrip_custom_colors;
@ -63,15 +64,15 @@ public:
#ifdef FEATURE_SERIAL
Serial1,
#endif
settings.controllerHardware.enableFrontLeft, settings.controllerHardware.enableFrontRight, settings.controllerHardware.invertFrontLeft, settings.controllerHardware.invertFrontRight,
settings.battery.front30VoltCalibration, settings.battery.front50VoltCalibration
profileSettings.controllerHardware.enableFrontLeft, profileSettings.controllerHardware.enableFrontRight, profileSettings.controllerHardware.invertFrontLeft, profileSettings.controllerHardware.invertFrontRight,
configs.battery.front30VoltCalibration, configs.battery.front50VoltCalibration
},
Controller {
#ifdef FEATURE_SERIAL
Serial2,
#endif
settings.controllerHardware.enableBackLeft, settings.controllerHardware.enableBackRight, settings.controllerHardware.invertBackLeft, settings.controllerHardware.invertBackRight,
settings.battery.back30VoltCalibration, settings.battery.back50VoltCalibration
profileSettings.controllerHardware.enableBackLeft, profileSettings.controllerHardware.enableBackRight, profileSettings.controllerHardware.invertBackLeft, profileSettings.controllerHardware.invertBackRight,
configs.battery.back30VoltCalibration, configs.battery.back50VoltCalibration
}
}}
{}

View File

@ -23,8 +23,8 @@ LedstripAnimation animation_type = LedstripAnimation::DefaultRainbow;
void initLedStrip()
{
animation_type = LedstripAnimation(settings.ledstrip.animationType);
leds.resize(settings.ledstrip.ledsCount);
animation_type = LedstripAnimation(configs.ledstrip.animationType.value);
leds.resize(configs.ledstrip.ledsCount.value);
FastLED.addLeds<NEOPIXEL, PINS_LEDSTRIP>(&*std::begin(leds), leds.size())
.setCorrection(TypicalSMD5050);
}
@ -33,15 +33,15 @@ void updateLedStrip()
{
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
static bool have_disabled_beeper = false;
const bool enAnim = settings.ledstrip.enableAnimBlink;
const bool enAnim = configs.ledstrip.enableAnimBlink.value;
if (cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH))
{
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
if (espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms || enAnim)
{
const auto anim_to_fill = time_to_percent(750ms, 500ms, 100ms, settings.ledstrip.enableFullBlink ? (leds.size() / 2) : settings.ledstrip.bigOffset - settings.ledstrip.smallOffset, settings.ledstrip.enableFullBlink);
if (settings.ledstrip.enableBeepWhenBlink)
const auto anim_to_fill = time_to_percent(750ms, 500ms, 100ms, configs.ledstrip.enableFullBlink.value ? (leds.size() / 2) : configs.ledstrip.bigOffset.value - configs.ledstrip.smallOffset.value, configs.ledstrip.enableFullBlink.value);
if (configs.ledstrip.enableBeepWhenBlink.value)
{
if (espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms)
for (Controller &controller : controllers)
@ -51,9 +51,9 @@ void updateLedStrip()
controller.command.buzzer.freq = 0;
}
auto color = CRGB{255, 200, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
const auto center = (std::begin(leds) + (leds.size() / 2) + configs.ledstrip.centerOffset.value);
if (settings.ledstrip.enableFullBlink)
if (configs.ledstrip.enableFullBlink.value)
{
// Full
if (BLINK_LEFT_EXPR)
@ -89,11 +89,11 @@ void updateLedStrip()
// Blink left
if (!enAnim)
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color);
std::fill(center - configs.ledstrip.bigOffset.value, center - configs.ledstrip.smallOffset.value, color);
}
else
{
std::fill(center - settings.ledstrip.smallOffset - anim_to_fill, center - settings.ledstrip.smallOffset, color);
std::fill(center - configs.ledstrip.smallOffset.value - anim_to_fill, center - configs.ledstrip.smallOffset.value, color);
}
}
if (BLINK_RIGHT_EXPR)
@ -101,35 +101,16 @@ void updateLedStrip()
// Blink right
if (!enAnim)
{
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color);
std::fill(center + configs.ledstrip.smallOffset.value, center + configs.ledstrip.bigOffset.value, color);
}
else
{
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.smallOffset + anim_to_fill, color);
std::fill(center + configs.ledstrip.smallOffset.value, center + configs.ledstrip.smallOffset.value + anim_to_fill, color);
}
}
}
// Old way to blink
// if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && !settings.ledstrip.enableFullBlink)
// {
// std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color);
// }
// else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && settings.ledstrip.enableFullBlink)
// {
// std::fill(std::begin(leds), center, color);
// }
// if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && !settings.ledstrip.enableFullBlink)
// {
// std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color);
// }
// else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && settings.ledstrip.enableFullBlink)
// {
// std::fill(center, std::end(leds), color);
// }
} else {
if (settings.ledstrip.enableBeepWhenBlink)
if (configs.ledstrip.enableBeepWhenBlink.value)
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
@ -138,7 +119,7 @@ void updateLedStrip()
}
else
{
if (settings.ledstrip.enableBrakeLights)
if (configs.ledstrip.enableBrakeLights.value)
{
float avgPwm{};
for (const Controller &controller : controllers)
@ -153,17 +134,17 @@ void updateLedStrip()
{
auto color = avgSpeedKmh < -0.1f ? CRGB{255, 255, 255} : CRGB{255, 0, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
const auto center = (std::begin(leds) + (leds.size() / 2) + configs.ledstrip.centerOffset.value);
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
if (settings.ledstrip.enableFullBlink)
if (configs.ledstrip.enableFullBlink.value)
{
std::fill(std::begin(leds), std::end(leds), color);
}
else if(!settings.ledstrip.enableAnimBlink)
else if(!configs.ledstrip.enableAnimBlink.value)
{
std::fill(center - settings.ledstrip.bigOffset - 2, center - settings.ledstrip.smallOffset + 2, color);
std::fill(center + settings.ledstrip.smallOffset - 2, center + settings.ledstrip.bigOffset + 2, color);
std::fill(center - configs.ledstrip.bigOffset.value - 2, center - configs.ledstrip.smallOffset.value + 2, color);
std::fill(center + configs.ledstrip.smallOffset.value - 2, center + configs.ledstrip.bigOffset.value + 2, color);
}
}
else
@ -177,47 +158,47 @@ void updateLedStrip()
}
}
if (have_disabled_beeper == false && (!(cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) || !settings.ledstrip.enableBeepWhenBlink))
if (have_disabled_beeper == false && (!(cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) || !configs.ledstrip.enableBeepWhenBlink.value))
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
have_disabled_beeper = true;
}
else if ((cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) && settings.ledstrip.enableBeepWhenBlink) have_disabled_beeper = false;
else if ((cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) && configs.ledstrip.enableBeepWhenBlink.value) have_disabled_beeper = false;
if (simplified || settings.ledstrip.enableStVO)
if (simplified || configs.ledstrip.enableStVO.value)
{
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
const auto center = (std::begin(leds) + (leds.size() / 2) + configs.ledstrip.centerOffset.value);
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for right
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms) || configs.ledstrip.enableFullBlink.value) // Condition for right
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, CRGB{0, 0, 0});
std::fill(center - settings.ledstrip.bigOffset - 1U, center - settings.ledstrip.smallOffset - 1U, CRGB{255, 0, 0}); // Right
std::fill(center - configs.ledstrip.bigOffset.value, center - configs.ledstrip.smallOffset.value, CRGB{0, 0, 0});
std::fill(center - configs.ledstrip.bigOffset.value - 1U, center - configs.ledstrip.smallOffset.value - 1U, CRGB{255, 0, 0}); // Right
}
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for left
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::utc_clock::now().time_since_epoch() % 750ms < 375ms) || configs.ledstrip.enableFullBlink.value) // Condition for left
{
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, CRGB{0, 0, 0});
std::fill(center + settings.ledstrip.smallOffset + 1U, center + settings.ledstrip.bigOffset + 1U, CRGB{255, 0, 0}); // Left
std::fill(center + configs.ledstrip.smallOffset.value, center + configs.ledstrip.bigOffset.value, CRGB{0, 0, 0});
std::fill(center + configs.ledstrip.smallOffset.value + 1U, center + configs.ledstrip.bigOffset.value + 1U, CRGB{255, 0, 0}); // Left
}
if (settings.ledstrip.stvoFrontEnable)
if (configs.ledstrip.stvoFrontEnable.value)
{
std::fill(std::begin(leds) + settings.ledstrip.stvoFrontOffset, std::begin(leds) + settings.ledstrip.stvoFrontOffset + settings.ledstrip.stvoFrontLength, CRGB{255, 255, 255});
std::fill(std::end(leds) - settings.ledstrip.stvoFrontOffset - settings.ledstrip.stvoFrontLength, std::end(leds) - settings.ledstrip.stvoFrontOffset, CRGB{255, 255, 255});
std::fill(std::begin(leds) + configs.ledstrip.stvoFrontOffset.value, std::begin(leds) + configs.ledstrip.stvoFrontOffset.value + configs.ledstrip.stvoFrontLength.value, CRGB{255, 255, 255});
std::fill(std::end(leds) - configs.ledstrip.stvoFrontOffset.value - configs.ledstrip.stvoFrontLength.value, std::end(leds) - configs.ledstrip.stvoFrontOffset.value, CRGB{255, 255, 255});
}
}
FastLED.setMaxPowerInVoltsAndMilliamps(5, configs.ledStripMaxMilliamps.value);
FastLED.setBrightness(settings.ledstrip.brightness);
FastLED.setMaxPowerInVoltsAndMilliamps(5, configs.ledstrip.maxMilliamps.value);
FastLED.setBrightness(configs.ledstrip.brightness.value);
FastLED.show();
}
void showAnimation()
{
if (settings.ledstrip.enableLedAnimation
if (configs.ledstrip.enableLedAnimation.value
&& !simplified
#ifdef FEATURE_OTA
&& !(asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None)
&& !(asyncOtaTaskStarted && configs.ledstrip.otaMode.value != OtaAnimationModes::None)
#endif
)
{
@ -228,7 +209,7 @@ void showAnimation()
else showDefaultLedstrip();
}
#ifdef FEATURE_OTA
else if (asyncOtaTaskStarted && settings.ledstrip.otaMode != OtaAnimationModes::None)
else if (asyncOtaTaskStarted && configs.ledstrip.otaMode.value != OtaAnimationModes::None)
{
// show ota animation
showOtaAnimation();
@ -251,7 +232,7 @@ void showOtaAnimation()
if (const auto totalSize = asyncOta->totalSize(); totalSize && *totalSize > 0)
{
percentage = (float(progress) / *totalSize * 100);
if (settings.ledstrip.otaMode == OtaAnimationModes::GreenProgressBar)
if (configs.ledstrip.otaMode.value == OtaAnimationModes::GreenProgressBar)
{
int numLeds = (leds_count * percentage) / 100;
if (numLeds >= leds_count)
@ -260,7 +241,7 @@ void showOtaAnimation()
}
std::fill(std::begin(leds), std::begin(leds) + numLeds, CRGB{0,255,0});
}
else if (settings.ledstrip.otaMode == OtaAnimationModes::ColorChangeAll)
else if (configs.ledstrip.otaMode.value == OtaAnimationModes::ColorChangeAll)
{
const uint8_t redChannel = 255 - (2.55 * percentage);
const uint8_t greenChannel = 2.55 * percentage;
@ -309,7 +290,7 @@ void showSpeedSyncAnimation()
static float hue_result = 0;
const float hue_per_led = 1. / std::max(uint8_t(1), uint8_t(settings.ledstrip.animationMultiplier));
const float hue_per_led = 1. / std::max(uint8_t(1), uint8_t(configs.ledstrip.animationMultiplier.value));
const float meter_per_second = avgSpeedKmh / 3.6;
const float leds_per_second = meter_per_second * leds_per_meter;
const float hue_per_second = leds_per_second * hue_per_led;
@ -336,7 +317,7 @@ void showDefaultLedstrip()
void showCustomColor()
{
const auto eighth_length = leds.size() / 8;
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
const auto center = (std::begin(leds) + (leds.size() / 2) + configs.ledstrip.centerOffset.value);
std::fill(std::begin(leds), std::end(leds), ledstrip_custom_colors[int(Bobbycar_Side::FRONT)]); // Front
std::fill(center - (eighth_length / 2), center + (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK)]); // Back

View File

@ -4,11 +4,18 @@
#include <vector>
// 3rdparty lib includes
#include <cpptypesafeenum.h>
#include <FastLED.h>
// local includes
#include "ledstripdefines.h"
#define OtaAnimationModesValues(x) \
x(None) \
x(GreenProgressBar) \
x(ColorChangeAll)
DECLARE_TYPESAFE_ENUM(OtaAnimationModes, : uint8_t, OtaAnimationModesValues)
#ifdef FEATURE_LEDSTRIP
enum Bobbycar_Side
{
@ -22,15 +29,6 @@ enum Bobbycar_Side
FRONT
};
#ifdef FEATURE_OTA
enum OtaAnimationModes
{
None,
GreenProgressBar,
ColorChangeAll
};
#endif
extern std::vector<CRGB> leds;
extern uint8_t gHue;

View File

@ -47,17 +47,14 @@ extern "C" void app_main()
if (const auto result = configs.init("bobbycar"); result != ESP_OK)
ESP_LOGE(TAG, "config_init_settings() failed with %s", esp_err_to_name(result));
settings = presets::defaultSettings;
profileSettings = presets::defaultProfileSettings;
if (settingsPersister.init())
{
if (!settingsPersister.openCommon())
ESP_LOGE("BOBBY", "openCommon() failed");
if (!settingsPersister.openProfile(0))
ESP_LOGE("BOBBY", "openProfile(0) failed");
loadSettings();
loadProfileSettings();
}
else
ESP_LOGE("BOBBY", "init() failed");
@ -79,7 +76,7 @@ extern "C" void app_main()
{
espgui::switchScreen<ButtonCalibrateDisplay>(true);
}
else if (settings.lockscreen.keepLockedAfterReboot && settings.lockscreen.locked)
else if (configs.lockscreen.keepLockedAfterReboot.value && configs.lockscreen.locked.value)
{
espgui::switchScreen<Lockscreen>();
}
@ -102,7 +99,7 @@ extern "C" void app_main()
schedulerTask.loop();
}
if (!lastStatsUpdate || now - *lastStatsUpdate >= 1000ms/settings.boardcomputerHardware.timersSettings.statsUpdateRate)
if (!lastStatsUpdate || now - *lastStatsUpdate >= 1000ms/configs.boardcomputerHardware.timersSettings.statsUpdateRate.value)
{
updateAccumulators();
pushStats();
@ -127,7 +124,7 @@ extern "C" void app_main()
}
avgVoltage = avgVoltage / controllers.size();
if (avgVoltage > 30)
battery::bootBatPercentage = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType));
battery::bootBatPercentage = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
}
}
}

View File

@ -13,7 +13,7 @@ void DefaultMode::start()
void DefaultMode::update()
{
auto pair = split(settings.defaultMode.modelMode);
auto pair = split(profileSettings.defaultMode.modelMode);
if (!gas || !brems)
{
start();
@ -48,14 +48,14 @@ void DefaultMode::update()
local_brems = 0;
}
auto gas_processed = settings.defaultMode.squareGas ? (local_gas * local_gas) / 1000.f : local_gas;
auto brems_processed = settings.defaultMode.squareBrems ? (local_brems * local_brems) / 1000 : local_brems;
auto gas_processed = profileSettings.defaultMode.squareGas ? (local_gas * local_gas) / 1000.f : local_gas;
auto brems_processed = profileSettings.defaultMode.squareBrems ? (local_brems * local_brems) / 1000 : local_brems;
const auto now = espchrono::millis_clock::now();
float pwm;
if (settings.handbremse.enable && handbremse::stateWish == handbremse::StateWish::brake)
if (configs.handbremse.enable.value && handbremse::stateWish == handbremse::StateWish::brake)
{
using namespace handbremse;
@ -68,7 +68,7 @@ void DefaultMode::update()
}
}
if (settings.handbremse.enable && settings.handbremse.automatic && !handbremse::angezogen)
if (configs.handbremse.enable.value && configs.handbremse.automatic.value && !handbremse::angezogen)
{
using namespace handbremse;
const auto speed = abs(avgSpeedKmh);
@ -84,7 +84,7 @@ void DefaultMode::update()
standStillFirstDetected = std::nullopt;
if (standStillFirstDetected && lastAutoRelease)
if (espchrono::ago(*standStillFirstDetected) > 100ms * settings.handbremse.triggerTimeout && espchrono::ago(*lastAutoRelease) > 5s )
if (espchrono::ago(*standStillFirstDetected) > 100ms * configs.handbremse.triggerTimeout.value && espchrono::ago(*lastAutoRelease) > 5s )
{
angezogen = true;
}
@ -148,7 +148,7 @@ void DefaultMode::update()
for (bobbycar::protocol::serial::MotorState &motor : motors())
{
motor.ctrlTyp = bobbycar::protocol::ControlType::FieldOrientedControl;
switch (settings.handbremse.mode)
switch (configs.handbremse.mode.value)
{
case HandbremseMode::MOSFETS_OFF:
motor.ctrlMod = bobbycar::protocol::ControlMode::Torque;
@ -169,43 +169,43 @@ void DefaultMode::update()
}
else
{
if (gas_processed >= settings.defaultMode.add_schwelle)
if (gas_processed >= profileSettings.defaultMode.add_schwelle)
{
pwm = (gas_processed/1000.*settings.defaultMode.gas1_wert) + (brems_processed/1000.*settings.defaultMode.brems1_wert);
pwm = (gas_processed/1000.*profileSettings.defaultMode.gas1_wert) + (brems_processed/1000.*profileSettings.defaultMode.brems1_wert);
if ((settings.defaultMode.enableSmoothingUp || settings.defaultMode.enableSmoothingDown) && (pwm > 1000. || m_lastPwm > 1000.))
if ((profileSettings.defaultMode.enableSmoothingUp || profileSettings.defaultMode.enableSmoothingDown) && (pwm > 1000. || m_lastPwm > 1000.))
{
if (m_lastPwm < pwm && settings.defaultMode.enableSmoothingUp)
if (m_lastPwm < pwm && profileSettings.defaultMode.enableSmoothingUp)
{
pwm = std::min(pwm, m_lastPwm + (settings.defaultMode.smoothing * std::chrono::milliseconds{now - m_lastTime}.count() / 100.f));
pwm = std::min(pwm, m_lastPwm + (profileSettings.defaultMode.smoothing * std::chrono::milliseconds{now - m_lastTime}.count() / 100.f));
if (pwm < 1000.)
pwm = 1000.;
}
else if (m_lastPwm > pwm && settings.defaultMode.enableSmoothingDown)
else if (m_lastPwm > pwm && profileSettings.defaultMode.enableSmoothingDown)
{
pwm = std::max(pwm, m_lastPwm - (settings.defaultMode.smoothing * std::chrono::milliseconds{now - m_lastTime}.count() / 100.f));
pwm = std::max(pwm, m_lastPwm - (profileSettings.defaultMode.smoothing * std::chrono::milliseconds{now - m_lastTime}.count() / 100.f));
}
}
}
else
{
pwm = (gas_processed/1000.*settings.defaultMode.gas2_wert) - (brems_processed/1000.*settings.defaultMode.brems2_wert);
pwm = (gas_processed/1000.*profileSettings.defaultMode.gas2_wert) - (brems_processed/1000.*profileSettings.defaultMode.brems2_wert);
if (
(settings.defaultMode.enableFieldWeakSmoothingUp || settings.defaultMode.enableFieldWeakSmoothingDown) &&
(m_lastPwm > settings.defaultMode.fwSmoothLowerLimit) &&
(profileSettings.defaultMode.enableFieldWeakSmoothingUp || profileSettings.defaultMode.enableFieldWeakSmoothingDown) &&
(m_lastPwm > profileSettings.defaultMode.fwSmoothLowerLimit) &&
brems_processed > 0)
{
if (m_lastPwm < pwm && settings.defaultMode.enableFieldWeakSmoothingUp)
if (m_lastPwm < pwm && profileSettings.defaultMode.enableFieldWeakSmoothingUp)
{
auto effective_smoothing = settings.defaultMode.smoothing;
auto effective_smoothing = profileSettings.defaultMode.smoothing;
auto difference_to_target = std::abs(pwm-m_lastPwm);
effective_smoothing *= std::max((difference_to_target / 500),0.5f);
pwm = std::min(pwm, m_lastPwm + (effective_smoothing * std::chrono::milliseconds{now - m_lastTime}.count() / 100.f));
}
else if (m_lastPwm > pwm && settings.defaultMode.enableFieldWeakSmoothingDown)
else if (m_lastPwm > pwm && profileSettings.defaultMode.enableFieldWeakSmoothingDown)
{
auto effective_smoothing = settings.defaultMode.smoothing;
auto effective_smoothing = profileSettings.defaultMode.smoothing;
auto difference_to_target = std::abs(pwm-m_lastPwm);
effective_smoothing *= std::max((difference_to_target / 500),0.5f);
@ -217,39 +217,11 @@ void DefaultMode::update()
m_lastPwm = pwm;
m_lastTime = now;
if (settings.hybrid.enable)
{
auto activationLimit = settings.hybrid.activationLimit;
auto deactivationLimit = settings.hybrid.deactivationLimit;
auto diff = std::abs(activationLimit - deactivationLimit);
if (diff < 20)
{
int half = (diff / 2) + 0.5;
deactivationLimit -= half;
activationLimit += half;
}
if (!hybridModeActivated && (pwm > activationLimit))
{
hybridModeActivated = true;
}
else if (hybridModeActivated && (pwm < deactivationLimit))
{
hybridModeActivated = false;
}
if (hybridModeActivated)
{
pair = split(settings.hybrid.hybridMode);
}
}
for (bobbycar::protocol::serial::MotorState &motor : motorsInController(controllers.front))
{
motor.ctrlTyp = pair.first;
motor.ctrlMod = pair.second;
motor.pwm = pwm / 100. * settings.defaultMode.frontPercentage;
motor.pwm = pwm / 100. * profileSettings.defaultMode.frontPercentage;
motor.cruiseCtrlEna = false;
motor.nCruiseMotTgt = 0;
}
@ -257,7 +229,7 @@ void DefaultMode::update()
{
motor.ctrlTyp = pair.first;
motor.ctrlMod = pair.second;
motor.pwm = pwm / 100. * settings.defaultMode.backPercentage;
motor.pwm = pwm / 100. * profileSettings.defaultMode.backPercentage;
motor.cruiseCtrlEna = false;
motor.nCruiseMotTgt = 0;
}

View File

@ -35,7 +35,7 @@ void LarsmMode::update()
}
else
{
for (uint8_t i = 0; i < settings.larsmMode.iterations; i++) // run multiple times to emulate higher refreshrate
for (uint8_t i = 0; i < profileSettings.larsmMode.iterations; i++) // run multiple times to emulate higher refreshrate
{
// ####### larsm's bobby car code #######
@ -59,25 +59,25 @@ void LarsmMode::update()
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
if (settings.larsmMode.mode == LarsmModeMode::Mode1) { // Mode 1, links: 3 kmh
if (profileSettings.larsmMode.mode == LarsmModeMode::Mode1) { // Mode 1, links: 3 kmh
speed = (float)speed * LOSLASS_BREMS_ACC // bremsen wenn kein poti gedrueckt
- (CLAMP(*brems - ADC2_MIN, 0, ADC2_DELTA) / (ADC2_DELTA / 280.0f)) * DRUECK_ACC2 // links gedrueckt = zusatzbremsen oder rueckwaertsfahren
+ (CLAMP(*gas - ADC1_MIN, 0, ADC1_DELTA) / (ADC1_DELTA / 350.0f)) * DRUECK_ACC1; // vorwaerts gedrueckt = beschleunigen 12s: 350=3kmh
weak = 0;
} else if (settings.larsmMode.mode == LarsmModeMode::Mode2) { // Mode 2, default: 6 kmh
} else if (profileSettings.larsmMode.mode == LarsmModeMode::Mode2) { // Mode 2, default: 6 kmh
speed = (float)speed * LOSLASS_BREMS_ACC
- (CLAMP(*brems - ADC2_MIN, 0, ADC2_DELTA) / (ADC2_DELTA / 310.0f)) * DRUECK_ACC2
+ (CLAMP(*gas - ADC1_MIN, 0, ADC1_DELTA) / (ADC1_DELTA / 420.0f)) * DRUECK_ACC1; // 12s: 400=5-6kmh 450=7kmh
weak = 0;
} else if (settings.larsmMode.mode == LarsmModeMode::Mode3) { // Mode 3, rechts: 12 kmh
} else if (profileSettings.larsmMode.mode == LarsmModeMode::Mode3) { // Mode 3, rechts: 12 kmh
speed = (float)speed * LOSLASS_BREMS_ACC
- (CLAMP(*brems - ADC2_MIN, 0, ADC2_DELTA) / (ADC2_DELTA / 340.0f)) * DRUECK_ACC2
+ (CLAMP(*gas - ADC1_MIN, 0, ADC1_DELTA) / (ADC1_DELTA / 600.0f)) * DRUECK_ACC1; // 12s: 600=12kmh
weak = 0;
} else if (settings.larsmMode.mode == LarsmModeMode::Mode4) { // Mode 4, l + r: full kmh
} else if (profileSettings.larsmMode.mode == LarsmModeMode::Mode4) { // Mode 4, l + r: full kmh
// Feldschwaechung wird nur aktiviert wenn man schon sehr schnell ist. So gehts: Rechts voll druecken und warten bis man schnell ist, dann zusaetzlich links schnell voll druecken.
if (adc2_filtered > (ADC2_MAX - 450) && speed > 800) { // field weakening at high speeds
speed = (float)speed * LOSLASS_BREMS_ACC
@ -97,7 +97,7 @@ void LarsmMode::update()
for (bobbycar::protocol::serial::MotorState &motor : motors())
{
const auto pair = split(settings.larsmMode.modelMode);
const auto pair = split(profileSettings.larsmMode.modelMode);
motor.ctrlTyp = pair.first;
motor.ctrlMod = pair.second;
motor.pwm = speed + weak;

View File

@ -16,8 +16,8 @@ void MotortestMode::start()
void MotortestMode::update()
{
const auto m_pwmMax = settings.motortestMode.maxPwm;
m_pwm += m_dir * settings.motortestMode.multiplikator;
const auto m_pwmMax = profileSettings.motortestMode.maxPwm;
m_pwm += m_dir * profileSettings.motortestMode.multiplikator;
if (m_pwm > m_pwmMax) {
m_pwm = m_pwmMax;
m_dir = -m_dir;

View File

@ -45,7 +45,7 @@ void TempomatMode::update()
for (bobbycar::protocol::serial::MotorState &motor : motors())
{
const auto pair = split(settings.tempomatMode.modelMode);
const auto pair = split(profileSettings.tempomatMode.modelMode);
motor.ctrlTyp = pair.first;
motor.ctrlMod = pair.second;
motor.pwm = 0;

View File

@ -20,6 +20,12 @@
#include <espchrono.h>
#include <makearray.h>
// local includes
#include "ledstrip.h"
#include "unifiedmodelmode.h"
#include "displays/lockscreen.h"
#include "handbremse.h"
using namespace espconfig;
std::string defaultHostname();
@ -80,6 +86,15 @@ public:
ConfigWrapper<std::string> url;
};
class ConfiguredLockscreenDigit
{
public:
ConfiguredLockscreenDigit(const char *digitKey) :
digit{0, DoReset, MinMaxOrZeroValue<int8_t, 1,9>, digitKey }
{}
ConfigWrapper<int8_t> digit;
};
class ConfigContainer
{
using mac_t = wifi_stack::mac_t;
@ -176,7 +191,109 @@ public:
ConfigWrapper<std::string> dns_announce_key {std::string{}, DoReset, {}, "dnsAnnounceKey" };
ConfigWrapper<std::string> webserverPassword {std::string{}, DoReset, {}, "websPassword" };
ConfigWrapper<uint32_t> ledStripMaxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" };
struct {
ConfigWrapper<int16_t> wheelDiameter {DEFAULT_WHEELDIAMETER, DoReset, {}, "wheelDiameter" };
ConfigWrapper<int16_t> numMagnetPoles {15, DoReset, {}, "numMagnetPoles" };
ConfigWrapper<bool> swapFrontBack {false, DoReset, {}, "swapFrontBack" };
ConfigWrapper<bool> sendFrontCanCmd {true, DoReset, {}, "sendFrontCanCmd" };
ConfigWrapper<bool> sendBackCanCmd {true, DoReset, {}, "sendBackCanCmd" };
ConfigWrapper<int16_t> canTransmitTimeout {200, DoReset, {}, "canTransmitTime" };
ConfigWrapper<int16_t> canReceiveTimeout {0, DoReset, {}, "canReceiveTimeo" };
} controllerHardware;
struct {
ConfigWrapper<int16_t> gametrakXMin {0, DoReset, {}, "gametrakXMin" };
ConfigWrapper<int16_t> gametrakXMax {4095, DoReset, {}, "gametrakXMax" };
ConfigWrapper<int16_t> gametrakYMin {0, DoReset, {}, "gametrakYMin" };
ConfigWrapper<int16_t> gametrakYMax {4095, DoReset, {}, "gametrakYMax" };
ConfigWrapper<int16_t> gametrakDistMin {0, DoReset, {}, "gametrakDistMin" };
ConfigWrapper<int16_t> gametrakDistMax {4095, DoReset, {}, "gametrakDistMax" };
struct {
ConfigWrapper<int16_t> statsUpdateRate{50, DoReset, {}, "statsUpdateRate" };
ConfigWrapper<int16_t> cloudCollectRate{100, DoReset, {}, "cloudCollectRat" };
ConfigWrapper<int16_t> cloudSendRate {1, DoReset, {}, "cloudSendRate" };
ConfigWrapper<int16_t> udpSendRateMs {65, DoReset, {}, "udpSendRate" };
} timersSettings;
} boardcomputerHardware;
struct {
ConfigWrapper<bool> cloudEnabled {false, DoReset, {}, "cloudEnabled" };
ConfigWrapper<int16_t> cloudTransmitTimeout{10, DoReset, {}, "clodTransmTmout" };
} cloudSettings;
struct {
ConfigWrapper<uint32_t> udpUid {0, DoReset, {}, "cloudUDPUid" };
ConfigWrapper<bool> udpCloudEnabled {false, DoReset, {}, "enUdpCloud" };
ConfigWrapper<bool> enableCloudDebug {false, DoReset, {}, "debugCloud" };
ConfigWrapper<bool> udpUseStdString {false, DoReset, {}, "udpusestdstr" };
} udpCloudSettings;
struct {
ConfigWrapper<bool> enableLedAnimation {true, DoReset, {}, "enableLedAnimat" };
ConfigWrapper<bool> enableBrakeLights {true, DoReset, {}, "enableBrakeLigh" };
ConfigWrapper<int16_t> ledsCount {288, DoReset, {}, "ledsCount" };
ConfigWrapper<int16_t> centerOffset {1, DoReset, {}, "centerOffset" };
ConfigWrapper<int16_t> smallOffset {4, DoReset, {}, "smallOffset" };
ConfigWrapper<int16_t> bigOffset {10, DoReset, {}, "bigOffset" };
ConfigWrapper<bool> enableBeepWhenBlink {true, DoReset, {}, "beepwhenblink" };
ConfigWrapper<int16_t> animationType {1, DoReset, {}, "animationType" };
ConfigWrapper<bool> enableFullBlink {true, DoReset, {}, "fullblink" };
ConfigWrapper<bool> enableStVO {true, DoReset, {}, "ledstvo" };
ConfigWrapper<int16_t> stvoFrontOffset {0, DoReset, {}, "ledstvofoff" };
ConfigWrapper<int16_t> stvoFrontLength {10, DoReset, {}, "ledstvoflen" };
ConfigWrapper<bool> stvoFrontEnable {false, DoReset, {}, "ledstvoen" };
ConfigWrapper<int16_t> animationMultiplier{10, DoReset, {}, "ledAnimMul" };
ConfigWrapper<uint8_t> brightness {255, DoReset, {}, "ledbrightness" };
ConfigWrapper<bool> enableAnimBlink {false, DoReset, {}, "enAnimBlink" };
ConfigWrapper<OtaAnimationModes> otaMode {OtaAnimationModes::GreenProgressBar, DoReset, {}, "ledOtaAnim" };
ConfigWrapper<uint32_t> maxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" };
} ledstrip;
struct {
ConfigWrapper<uint8_t> cellsSeries {12, DoReset, {}, "batteryCS" };
ConfigWrapper<uint8_t> cellsParallel {10, DoReset, {}, "batteryCP" };
ConfigWrapper<uint8_t> cellType {0, DoReset, {}, "batteryType" };
ConfigWrapper<uint16_t> watthoursPerKilometer{25, DoReset, {}, "whkm" };
ConfigWrapper<int16_t> front30VoltCalibration{3000, DoReset, {}, "batF30VCal" };
ConfigWrapper<int16_t> back30VoltCalibration {3000, DoReset, {}, "batB30VCal" };
ConfigWrapper<int16_t> front50VoltCalibration{5000, DoReset, {}, "batF50VCal" };
ConfigWrapper<int16_t> back50VoltCalibration {5000, DoReset, {}, "batB50VCal" };
ConfigWrapper<bool> applyCalibration {true, DoReset, {}, "applyBatCal" };
} battery;
struct {
ConfigWrapper<bool> allowPresetSwitch {true, DoReset, {}, "lockAlwPresetSw" };
ConfigWrapper<bool> keepLockedAfterReboot {false, DoReset, {}, "keepLocked" };
ConfigWrapper<bool> locked {false, DoReset, {}, "currentlyLocked" };
std::array<ConfiguredLockscreenDigit, 4> pin {
ConfiguredLockscreenDigit {"lockscreenPin0"},
ConfiguredLockscreenDigit {"lockscreenPin1"},
ConfiguredLockscreenDigit {"lockscreenPin2"},
ConfiguredLockscreenDigit {"lockscreenPin3"}
};
} lockscreen;
struct {
ConfigWrapper<uint32_t> totalCentimeters {0, DoReset, {}, "totalCentimeter" };
} savedStatistics;
struct {
ConfigWrapper<HandbremseMode> mode {HandbremseMode::MOSFETS_OFF, DoReset, {}, "handBremsM" };
ConfigWrapper<uint16_t> triggerTimeout {10, DoReset, {}, "handBremsT" };
ConfigWrapper<bool> automatic {false, DoReset, {}, "handBremsA" };
ConfigWrapper<bool> enable {false, DoReset, {}, "handBremsE" };
ConfigWrapper<bool> visualize {false, DoReset, {}, "handBremsV" };
} handbremse;
struct {
ConfigWrapper<bool> syncTime {false, DoReset, {}, "espnowSyncT" };
ConfigWrapper<bool> syncTimeWithOthers {false, DoReset, {}, "espnowSyncTWO" };
ConfigWrapper<bool> syncBlink {false, DoReset, {}, "espnowSyncBl" };
} espnow;
struct {
ConfigWrapper<bool> bleEnabled {true, DoReset, {}, "bleEnabled" };
} bleSettings;
#define NEW_SETTINGS(x) \
x(baseMacAddressOverride) \
@ -365,7 +482,83 @@ public:
x(dns_announce_key) \
x(webserverPassword) \
\
//x(ledStripMaxMilliamps)
x(controllerHardware.wheelDiameter) \
x(controllerHardware.numMagnetPoles) \
x(controllerHardware.swapFrontBack) \
x(controllerHardware.sendFrontCanCmd) \
x(controllerHardware.sendBackCanCmd) \
x(controllerHardware.canTransmitTimeout) \
x(controllerHardware.canReceiveTimeout) \
\
x(boardcomputerHardware.gametrakXMin) \
x(boardcomputerHardware.gametrakYMin) \
x(boardcomputerHardware.gametrakXMax) \
x(boardcomputerHardware.gametrakYMax) \
x(boardcomputerHardware.gametrakDistMin) \
x(boardcomputerHardware.gametrakDistMax) \
\
x(boardcomputerHardware.timersSettings.statsUpdateRate) \
x(boardcomputerHardware.timersSettings.cloudCollectRate) \
x(boardcomputerHardware.timersSettings.cloudSendRate) \
x(boardcomputerHardware.timersSettings.udpSendRateMs) \
\
x(cloudSettings.cloudEnabled) \
x(cloudSettings.cloudTransmitTimeout) \
\
x(udpCloudSettings.udpUid) \
x(udpCloudSettings.udpCloudEnabled) \
x(udpCloudSettings.enableCloudDebug) \
x(udpCloudSettings.udpUseStdString) \
\
x(ledstrip.enableLedAnimation) \
x(ledstrip.enableBrakeLights) \
x(ledstrip.ledsCount) \
x(ledstrip.centerOffset) \
x(ledstrip.smallOffset) \
x(ledstrip.bigOffset) \
x(ledstrip.enableBeepWhenBlink) \
x(ledstrip.animationType) \
x(ledstrip.enableFullBlink) \
x(ledstrip.enableStVO) \
x(ledstrip.stvoFrontOffset) \
x(ledstrip.stvoFrontLength) \
x(ledstrip.stvoFrontEnable) \
x(ledstrip.animationMultiplier) \
x(ledstrip.brightness) \
x(ledstrip.enableAnimBlink) \
x(ledstrip.otaMode) \
x(ledstrip.maxMilliamps) \
\
x(battery.cellsSeries) \
x(battery.cellsParallel) \
x(battery.cellType) \
x(battery.watthoursPerKilometer) \
x(battery.front30VoltCalibration) \
x(battery.back30VoltCalibration) \
x(battery.front50VoltCalibration) \
x(battery.back50VoltCalibration) \
x(battery.applyCalibration) \
\
x(lockscreen.allowPresetSwitch) \
x(lockscreen.keepLockedAfterReboot) \
x(lockscreen.locked) \
x(lockscreen.pin[0].digit) \
x(lockscreen.pin[1].digit) \
x(lockscreen.pin[2].digit) \
x(lockscreen.pin[3].digit) \
\
x(savedStatistics.totalCentimeters) \
\
x(handbremse.mode) \
x(handbremse.triggerTimeout) \
x(handbremse.automatic) \
x(handbremse.enable) \
x(handbremse.visualize) \
\
x(espnow.syncTime) \
x(espnow.syncTimeWithOthers) \
x(espnow.syncBlink)
//x(bleSettings.bleEnabled)
template<typename T>
void callForEveryConfig(T &&callback)
@ -373,7 +566,6 @@ public:
#define HELPER(x) callback(x);
NEW_SETTINGS(HELPER)
#undef HELPER
callback(ledStripMaxMilliamps);
}
auto getAllConfigParams()
@ -382,7 +574,7 @@ public:
#define HELPER(x) std::ref<ConfigWrapperInterface>(x),
NEW_SETTINGS(HELPER)
#undef HELPER
std::ref<ConfigWrapperInterface>(ledStripMaxMilliamps)
std::ref<ConfigWrapperInterface>(bleSettings.bleEnabled)
);
}
};

View File

@ -76,12 +76,12 @@ void readPotis()
#ifdef FEATURE_GAMETRAK
raw_gametrakX = sampleMultipleTimes(PINS_GAMETRAKX);
gametrakX = cpputils::mapValueClamped<float>(raw_gametrakX, settings.boardcomputerHardware.gametrakXMin, settings.boardcomputerHardware.gametrakXMax, 0., 1000.);
gametrakX = cpputils::mapValueClamped<float>(raw_gametrakX, configs.boardcomputerHardware.gametrakXMin.value, configs.boardcomputerHardware.gametrakXMax.value, 0., 1000.);
raw_gametrakY = sampleMultipleTimes(PINS_GAMETRAKY);
gametrakY = cpputils::mapValueClamped<float>(raw_gametrakY, settings.boardcomputerHardware.gametrakYMin, settings.boardcomputerHardware.gametrakYMax, 0., 1000.);
gametrakY = cpputils::mapValueClamped<float>(raw_gametrakY, configs.boardcomputerHardware.gametrakYMin.value, configs.boardcomputerHardware.gametrakYMax.value, 0., 1000.);
raw_gametrakDist = sampleMultipleTimes(PINS_GAMETRAKDIST);
gametrakDist = cpputils::mapValueClamped<float>(raw_gametrakDist, settings.boardcomputerHardware.gametrakDistMin, settings.boardcomputerHardware.gametrakDistMax, 0., 1000.);
gametrakDist = cpputils::mapValueClamped<float>(raw_gametrakDist, configs.boardcomputerHardware.gametrakDistMin.value, configs.boardcomputerHardware.gametrakDistMax.value, 0., 1000.);
#endif
}

View File

@ -10,22 +10,22 @@
#include <espchrono.h>
// local includes
#include "settings.h"
#include "profilesettings.h"
#include "ledstripdefines.h"
#include "ledstrip.h"
using namespace std::chrono_literals;
namespace presets {
constexpr Settings::Limits defaultLimits {
.iMotMax = DEFAULT_IMOTMAX,
.iDcMax = DEFAULT_IDCMAX,
.nMotMax = DEFAULT_NMOTMAX,
.fieldWeakMax = DEFAULT_FIELDWEAKMAX,
.phaseAdvMax = DEFAULT_FIELDADVMAX
constexpr ProfileSettings::Limits defaultLimits {
.iMotMax = DEFAULT_IMOTMAX, // profileSetting
.iDcMax = DEFAULT_IDCMAX, // profileSetting
.nMotMax = DEFAULT_NMOTMAX, // profileSetting
.fieldWeakMax = DEFAULT_FIELDWEAKMAX, // profileSetting
.phaseAdvMax = DEFAULT_FIELDADVMAX // profileSetting
};
constexpr Settings::Limits kidsLimits {
constexpr ProfileSettings::Limits kidsLimits {
.iMotMax = 5,
.iDcMax = 7,
.nMotMax = 500,
@ -33,29 +33,19 @@ constexpr Settings::Limits kidsLimits {
.phaseAdvMax = 20
};
constexpr Settings::ControllerHardware defaultControllerHardware {
.enableFrontLeft = true,
.enableFrontRight = true,
.enableBackLeft = true,
.enableBackRight = true,
constexpr ProfileSettings::ControllerHardware defaultControllerHardware {
.enableFrontLeft = true, // profileSetting
.enableFrontRight = true, // profileSetting
.enableBackLeft = true, // profileSetting
.enableBackRight = true, // profileSetting
.invertFrontLeft = DEFAULT_INVERTFRONTLEFT,
.invertFrontRight = DEFAULT_INVERTFRONTRIGHT,
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
.invertBackRight = DEFAULT_INVERTBACKRIGHT,
.wheelDiameter = DEFAULT_WHEELDIAMETER,
.numMagnetPoles = 15,
.swapFrontBack = false,
#ifdef FEATURE_CAN
.sendFrontCanCmd = true,
.sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif
.invertFrontLeft = DEFAULT_INVERTFRONTLEFT, // profileSetting
.invertFrontRight = DEFAULT_INVERTFRONTRIGHT, // profileSetting
.invertBackLeft = DEFAULT_INVERTBACKLEFT, // profileSetting
.invertBackRight = DEFAULT_INVERTBACKRIGHT, // profileSetting
};
constexpr Settings::ControllerHardware mosfetsOffControllerHardware {
constexpr ProfileSettings::ControllerHardware mosfetsOffControllerHardware {
.enableFrontLeft = false,
.enableFrontRight = false,
.enableBackLeft = false,
@ -65,31 +55,9 @@ constexpr Settings::ControllerHardware mosfetsOffControllerHardware {
.invertFrontRight = DEFAULT_INVERTFRONTRIGHT,
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
.invertBackRight = DEFAULT_INVERTBACKRIGHT,
.wheelDiameter = 165,
.numMagnetPoles = 15,
.swapFrontBack = false,
#ifdef FEATURE_CAN
.sendFrontCanCmd = true,
.sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif
};
#ifdef FEATURE_BLUETOOTH
constexpr Settings::BluetoothSettings defaultBluetoothSettings {
.autoBluetoothMode = BluetoothMode::Master
};
#endif
#ifdef FEATURE_BLE
constexpr Settings::BleSettings defaultBleSettings {
.bleEnabled = true
};
#endif
constexpr Settings::ControllerHardware spinnerControllerHardware {
constexpr ProfileSettings::ControllerHardware spinnerControllerHardware {
.enableFrontLeft = true,
.enableFrontRight = true,
.enableBackLeft = true,
@ -99,77 +67,28 @@ constexpr Settings::ControllerHardware spinnerControllerHardware {
.invertFrontRight = !DEFAULT_INVERTFRONTRIGHT,
.invertBackLeft = DEFAULT_INVERTBACKLEFT,
.invertBackRight = !DEFAULT_INVERTBACKRIGHT,
.wheelDiameter = 165,
.numMagnetPoles = 15,
.swapFrontBack = false,
#ifdef FEATURE_CAN
.sendFrontCanCmd = true,
.sendBackCanCmd = true,
.canTransmitTimeout = 200,
.canReceiveTimeout = 0,
#endif
};
constexpr Settings::BoardcomputerHardware::TimersSettings defaultTimersSettings {
.statsUpdateRate = 50,
#ifdef FEATURE_CLOUD
.cloudCollectRate = 100,
.cloudSendRate = 1,
#endif
#ifdef FEATURE_UDPCLOUD
.udpSendRateMs = 65,
#endif
};
constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware {
#ifdef FEATURE_GAMETRAK
.gametrakXMin = DEFAULT_GAMETRAKXMIN,
.gametrakXMax = DEFAULT_GAMETRAKXMAX,
.gametrakYMin = DEFAULT_GAMETRAKYMIN,
.gametrakYMax = DEFAULT_GAMETRAKYMAX,
.gametrakDistMin = DEFAULT_GAMETRAKDISTMIN,
.gametrakDistMax = DEFAULT_GAMETRAKDISTMAX,
#endif
.timersSettings = defaultTimersSettings
};
#ifdef FEATURE_CLOUD
constexpr Settings::CloudSettings defaultCloudSettings {
.cloudEnabled = false,
.cloudTransmitTimeout = 10
};
#endif
#ifdef FEATURE_UDPCLOUD
constexpr Settings::UdpCloudSettings defaultUdpCloudSettings {
.udpUid = 0,
.udpCloudEnabled = false,
.enableCloudDebug = false,
.udpUseStdString = false
};
#endif
constexpr Settings::DefaultMode defaultDefaultMode {
.modelMode = UnifiedModelMode::FocTorque,
constexpr ProfileSettings::DefaultMode defaultDefaultMode {
.modelMode = UnifiedModelMode::FocTorque, // profileSetting
.squareGas = true,
.squareBrems = true,
.enableSmoothingUp = true,
.enableSmoothingDown = true,
.enableFieldWeakSmoothingUp = false,
.enableFieldWeakSmoothingDown = false,
.smoothing = 20,
.frontPercentage = 100,
.backPercentage = 100,
.add_schwelle = 750,
.gas1_wert = 1250,
.gas2_wert = 1250,
.brems1_wert = 250,
.brems2_wert = 750,
.fwSmoothLowerLimit = 800
.enableSmoothingUp = true, // profileSetting
.enableSmoothingDown = true, // profileSetting
.enableFieldWeakSmoothingUp = false, // profileSetting
.enableFieldWeakSmoothingDown = false, // profileSetting
.smoothing = 20, // profileSetting
.frontPercentage = 100, // profileSetting
.backPercentage = 100, // profileSetting
.add_schwelle = 750, // profileSetting
.gas1_wert = 1250, // profileSetting
.gas2_wert = 1250, // profileSetting
.brems1_wert = 250, // profileSetting
.brems2_wert = 750, // profileSetting
.fwSmoothLowerLimit = 800 // profileSetting
};
constexpr Settings::DefaultMode sinusoidalDefaultMode {
constexpr ProfileSettings::DefaultMode sinusoidalDefaultMode {
.modelMode = UnifiedModelMode::Sinusoidal,
.squareGas = true,
.squareBrems = true,
@ -188,133 +107,27 @@ constexpr Settings::DefaultMode sinusoidalDefaultMode {
.fwSmoothLowerLimit = 800
};
constexpr Settings::TempomatMode defaultTempomatMode {
constexpr ProfileSettings::TempomatMode defaultTempomatMode {
.modelMode = UnifiedModelMode::FocSpeed
};
constexpr Settings::LarsmMode defaultLarsmMode {
constexpr ProfileSettings::LarsmMode defaultLarsmMode {
.modelMode = UnifiedModelMode::Commutation,
.mode = LarsmModeMode::Mode4,
.iterations = 100
};
constexpr Settings::MotortestMode defaultMotortestMode {
constexpr ProfileSettings::MotortestMode defaultMotortestMode {
.multiplikator = 2,
.maxPwm = 400
};
constexpr Settings::Handbremse defaultHandbremse {
.mode = HandbremseMode::MOSFETS_OFF,
.triggerTimeout = 10,
.automatic = false,
.enable = false,
.visualize = true,
};
#ifdef FEATURE_LEDSTRIP
constexpr Settings::Ledstrip defaultLedstrip {
.enableLedAnimation = true,
.enableBrakeLights = true,
.ledsCount = LEDSTRIP_LENGTH,
.centerOffset = 1,
.smallOffset = 4,
.bigOffset = 10,
.enableBeepWhenBlink = false,
#ifdef LEDSTRIP_ANIMATION_DEFAULT
.animationType = LEDSTRIP_ANIMATION_DEFAULT,
#else
.animationType = LedstripAnimation::DefaultRainbow,
#endif
.enableFullBlink = false,
.enableStVO = false,
.stvoFrontOffset = 0,
.stvoFrontLength = 10,
.stvoFrontEnable = false,
.animationMultiplier = 10,
.brightness = 255,
.enableAnimBlink = false,
#ifdef FEATURE_OTA
.otaMode = OtaAnimationModes::GreenProgressBar
#endif
};
#endif
constexpr Settings::LockscreenSettings defaultLockscreen {
.allowPresetSwitch = true,
.keepLockedAfterReboot = false,
.locked = false,
.pin = { 1, 2, 3, 4 }
};
constexpr Settings::Battery defaultBattery {
.cellsSeries = 12,
.cellsParallel = 4,
.cellType = 0,
.watthoursPerKilometer = 20,
.front30VoltCalibration = 3000,
.back30VoltCalibration = 3000,
.front50VoltCalibration = 5000,
.back50VoltCalibration = 5000,
.applyCalibration = true
};
constexpr Settings::Hybrid defaultHybrid {
.hybridMode = UnifiedModelMode::FocTorque,
.enable = false,
.activationLimit = 1000,
.deactivationLimit = 950,
};
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,
#endif
constexpr ProfileSettings defaultProfileSettings {
.limits = defaultLimits,
#ifdef FEATURE_BLUETOOTH
.bluetoothSettings = defaultBluetoothSettings,
#endif
#ifdef FEATURE_BLE
.bleSettings = defaultBleSettings,
#endif
.controllerHardware = defaultControllerHardware,
.boardcomputerHardware = defaultBoardcomputerHardware,
#ifdef FEATURE_CLOUD
.cloudSettings = defaultCloudSettings,
#endif
#ifdef FEATURE_UDPCLOUD
.udpCloudSettings = defaultUdpCloudSettings,
#endif
.defaultMode = defaultDefaultMode,
.tempomatMode = defaultTempomatMode,
.larsmMode = defaultLarsmMode,
.motortestMode = defaultMotortestMode,
#ifdef FEATURE_LEDSTRIP
.ledstrip = defaultLedstrip,
#endif
.battery = defaultBattery,
.hybrid = defaultHybrid,
.lockscreen = defaultLockscreen,
.savedStatistics = defaultSavedStatistics,
.handbremse = defaultHandbremse,
#ifdef FEATURE_ESPNOW
.espnow = defaultEspNowSettings,
#endif
.motortestMode = defaultMotortestMode
};
} // namespace presets

117
main/profilesettings.h Normal file
View File

@ -0,0 +1,117 @@
#pragma once
// system includes
#include <cstdint>
#include <array>
#include <FastLED.h>
// esp-idf includes
#include <esp_wifi_types.h>
#ifdef FEATURE_NTP
#include <lwip/apps/snmp.h>
#include <esp_sntp.h>
#endif
// 3rdparty lib includes
#include <espchrono.h>
// local includes
#include "bobbycar-common.h"
#include "unifiedmodelmode.h"
#include "modes/larsmmode.h"
struct ProfileSettings
{
struct Limits {
int16_t iMotMax; // [A] Maximum motor current limit
int16_t iDcMax; // [A] Maximum DC Link current limit (This is the current protection. Above this value, current chopping is applied. To avoid this make sure that I_DC_MAX = I_MOT_MAX + 2A)
int16_t nMotMax; // [rpm] Maximum motor speed limit
int16_t fieldWeakMax; // [A] Maximum Field Weakening D axis current (only for FOC). Higher current results in higher maximum speed.
int16_t phaseAdvMax; // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed.
} limits;
struct ControllerHardware {
bool enableFrontLeft, enableFrontRight, enableBackLeft, enableBackRight;
bool invertFrontLeft, invertFrontRight, invertBackLeft, invertBackRight;
} controllerHardware;
struct DefaultMode {
UnifiedModelMode modelMode;
bool squareGas;
bool squareBrems;
bool enableSmoothingUp;
bool enableSmoothingDown;
bool enableFieldWeakSmoothingUp;
bool enableFieldWeakSmoothingDown;
int16_t smoothing;
int16_t frontPercentage;
int16_t backPercentage;
int16_t add_schwelle;
int16_t gas1_wert;
int16_t gas2_wert;
int16_t brems1_wert;
int16_t brems2_wert;
int16_t fwSmoothLowerLimit;
} defaultMode;
struct TempomatMode {
UnifiedModelMode modelMode;
} tempomatMode;
struct LarsmMode {
UnifiedModelMode modelMode;
LarsmModeMode mode;
uint8_t iterations;
} larsmMode;
struct MotortestMode {
uint8_t multiplikator;
uint16_t maxPwm;
} motortestMode;
template<typename T>
void executeForEveryProfileSetting(T &&callable);
};
template<typename T>
void ProfileSettings::executeForEveryProfileSetting(T &&callable)
{
callable("iMotMax", limits.iMotMax);
callable("iDcMax", limits.iDcMax);
callable("nMotMax", limits.nMotMax);
callable("fieldWeakMax", limits.fieldWeakMax);
callable("phaseAdvMax", limits.phaseAdvMax);
callable("enableFrontLeft", controllerHardware.enableFrontLeft);
callable("enableFrontRigh", controllerHardware.enableFrontRight);
callable("enableBackLeft", controllerHardware.enableBackLeft);
callable("enableBackRight", controllerHardware.enableBackRight);
callable("invertFrontLeft", controllerHardware.invertFrontLeft);
callable("invertFrontRigh", controllerHardware.invertFrontRight);
callable("invertBackLeft", controllerHardware.invertBackLeft);
callable("invertBackRight", controllerHardware.invertBackRight);
callable("default.modelMo", defaultMode.modelMode);
callable("default.enSmUp_", defaultMode.enableSmoothingUp);
callable("default.enSmDow", defaultMode.enableSmoothingDown);
callable("default.enSmFUp", defaultMode.enableFieldWeakSmoothingUp);
callable("default.enSmFDo", defaultMode.enableFieldWeakSmoothingDown);
callable("default.fwSmLLi", defaultMode.fwSmoothLowerLimit);
callable("default.smoothi", defaultMode.smoothing);
callable("default.frontPe", defaultMode.frontPercentage);
callable("default.backPer", defaultMode.backPercentage);
callable("default.add_sch", defaultMode.add_schwelle);
callable("default.gas1_we", defaultMode.gas1_wert);
callable("default.gas2_we", defaultMode.gas2_wert);
callable("default.brems1_", defaultMode.brems1_wert);
callable("default.brems2_", defaultMode.brems2_wert);
callable("default.squareG", defaultMode.squareGas);
callable("default.squareB", defaultMode.squareBrems);
callable("tempoma.modelMo", tempomatMode.modelMode);
callable("larsm.modelMode", larsmMode.modelMode);
callable("larsm.mode", larsmMode.mode);
callable("larsm.iters", larsmMode.iterations);
}

View File

@ -25,7 +25,7 @@ cpputils::DelayedConstruction<AsyncHttpRequest> http_request;
// nvs
bool has_qr_code(std::string_view key)
{
const auto handle = settingsPersister.getCommonHandle();
const auto handle = configs.nvs_handle_user;
size_t length;
if (const esp_err_t result = nvs_get_str(handle, key.data(), nullptr, &length); result != ESP_OK)
@ -40,7 +40,7 @@ bool has_qr_code(std::string_view key)
tl::expected<std::string, esp_err_t> get_qr_code(std::string_view key)
{
const auto handle = settingsPersister.getCommonHandle();
const auto handle = configs.nvs_handle_user;
size_t length;
if (const esp_err_t result = nvs_get_str(handle, key.data(), nullptr, &length); result != ESP_OK)
@ -70,7 +70,7 @@ tl::expected<std::string, esp_err_t> get_qr_code(std::string_view key)
tl::expected<void, esp_err_t> set_qr_code(std::string_view key, std::string_view qrcode)
{
const auto handle = settingsPersister.getCommonHandle();
const auto handle = configs.nvs_handle_user;
if (const esp_err_t result = nvs_set_str(handle, key.data(), qrcode.data()); result != ESP_OK)
{
@ -83,7 +83,7 @@ tl::expected<void, esp_err_t> set_qr_code(std::string_view key, std::string_view
tl::expected<void, esp_err_t> delete_qr_code(std::string_view key)
{
const auto handle = settingsPersister.getCommonHandle();
const auto handle = configs.nvs_handle_user;
if (const esp_err_t result = nvs_erase_key(handle, key.data()); result != ESP_OK)
{

View File

@ -1,367 +0,0 @@
#pragma once
// system includes
#include <cstdint>
#include <array>
#include <FastLED.h>
// esp-idf includes
#include <esp_wifi_types.h>
#ifdef FEATURE_NTP
#include <lwip/apps/snmp.h>
#include <esp_sntp.h>
#endif
// 3rdparty lib includes
#include <espchrono.h>
// local includes
#include "bobbycar-common.h"
#ifdef FEATURE_BLUETOOTH
#include "bluetoothmode.h"
#endif
#include "unifiedmodelmode.h"
#include "handbremse.h"
#include "ledstrip.h"
#include "modes/larsmmode.h"
struct Settings
{
#ifdef FEATURE_BMS
bool autoConnectBms;
#endif
struct Limits {
int16_t iMotMax; // [A] Maximum motor current limit
int16_t iDcMax; // [A] Maximum DC Link current limit (This is the current protection. Above this value, current chopping is applied. To avoid this make sure that I_DC_MAX = I_MOT_MAX + 2A)
int16_t nMotMax; // [rpm] Maximum motor speed limit
int16_t fieldWeakMax; // [A] Maximum Field Weakening D axis current (only for FOC). Higher current results in higher maximum speed.
int16_t phaseAdvMax; // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed.
} limits;
#ifdef FEATURE_BLUETOOTH
struct BluetoothSettings {
BluetoothMode autoBluetoothMode;
} bluetoothSettings;
#endif
#ifdef FEATURE_BLE
struct BleSettings {
bool bleEnabled;
} bleSettings;
#endif
struct ControllerHardware {
bool enableFrontLeft, enableFrontRight, enableBackLeft, enableBackRight;
bool invertFrontLeft, invertFrontRight, invertBackLeft, invertBackRight;
int16_t wheelDiameter; // in mm
int16_t numMagnetPoles; // virtual RPM per one real RPM
bool swapFrontBack;
#ifdef FEATURE_CAN
bool sendFrontCanCmd;
bool sendBackCanCmd;
int16_t canTransmitTimeout; // in ms
int16_t canReceiveTimeout; // in ms
#endif
} controllerHardware;
struct BoardcomputerHardware {
#ifdef FEATURE_GAMETRAK
int16_t gametrakXMin, gametrakXMax, gametrakYMin, gametrakYMax, gametrakDistMin, gametrakDistMax;
#endif
struct TimersSettings {
int16_t statsUpdateRate;
#ifdef FEATURE_CLOUD
int16_t cloudCollectRate;
int16_t cloudSendRate;
#endif
#ifdef FEATURE_UDPCLOUD
int16_t udpSendRateMs;
#endif
} timersSettings;
} boardcomputerHardware;
#ifdef FEATURE_CLOUD
struct CloudSettings {
bool cloudEnabled;
int16_t cloudTransmitTimeout; // in ms
} cloudSettings;
#endif
#ifdef FEATURE_UDPCLOUD
struct UdpCloudSettings {
uint32_t udpUid;
bool udpCloudEnabled;
bool enableCloudDebug;
bool udpUseStdString;
} udpCloudSettings;
#endif
struct DefaultMode {
UnifiedModelMode modelMode;
bool squareGas;
bool squareBrems;
bool enableSmoothingUp;
bool enableSmoothingDown;
bool enableFieldWeakSmoothingUp;
bool enableFieldWeakSmoothingDown;
int16_t smoothing;
int16_t frontPercentage;
int16_t backPercentage;
int16_t add_schwelle;
int16_t gas1_wert;
int16_t gas2_wert;
int16_t brems1_wert;
int16_t brems2_wert;
int16_t fwSmoothLowerLimit;
} defaultMode;
struct TempomatMode {
UnifiedModelMode modelMode;
} tempomatMode;
struct LarsmMode {
UnifiedModelMode modelMode;
LarsmModeMode mode;
uint8_t iterations;
} larsmMode;
struct MotortestMode {
uint8_t multiplikator;
uint16_t maxPwm;
} motortestMode;
#ifdef FEATURE_LEDSTRIP
struct Ledstrip {
bool enableLedAnimation;
bool enableBrakeLights;
int16_t ledsCount;
int16_t centerOffset;
int16_t smallOffset;
int16_t bigOffset;
bool enableBeepWhenBlink;
int16_t animationType;
bool enableFullBlink;
bool enableStVO;
int16_t stvoFrontOffset;
int16_t stvoFrontLength;
bool stvoFrontEnable;
int16_t animationMultiplier;
uint8_t brightness;
bool enableAnimBlink;
#ifdef FEATURE_OTA
OtaAnimationModes otaMode;
#endif
} ledstrip;
#endif
struct Battery {
uint8_t cellsSeries;
uint8_t cellsParallel;
uint8_t cellType;
uint16_t watthoursPerKilometer;
int16_t front30VoltCalibration;
int16_t back30VoltCalibration;
int16_t front50VoltCalibration;
int16_t back50VoltCalibration;
bool applyCalibration;
} battery;
struct Hybrid {
UnifiedModelMode hybridMode;
bool enable;
int16_t activationLimit;
int16_t deactivationLimit;
} hybrid;
struct LockscreenSettings {
bool allowPresetSwitch;
bool keepLockedAfterReboot;
bool locked;
std::array<int8_t, 4> pin;
} lockscreen;
struct SavedStatistics {
uint32_t totalCentimeters;
} savedStatistics;
struct Handbremse {
HandbremseMode mode;
uint16_t triggerTimeout;
bool automatic;
bool enable;
bool visualize;
} handbremse;
#ifdef FEATURE_ESPNOW
struct ESPNOW {
bool syncTime;
bool syncTimeWithOthers;
bool syncBlink;
} espnow;
#endif
template<typename T>
void executeForEveryCommonSetting(T &&callable);
template<typename T>
void executeForEveryProfileSetting(T &&callable);
};
template<typename T>
void Settings::executeForEveryCommonSetting(T &&callable)
{
#ifdef FEATURE_BMS
callable("autoConnectBms", autoConnectBms);
#endif
#ifdef FEATURE_BLUETOOTH
callable("autoBluetoothMo", bluetoothSettings.autoBluetoothMode);
#endif
#ifdef FEATURE_BLE
callable("bleEnabled", bleSettings.bleEnabled);
#endif
callable("wheelDiameter", controllerHardware.wheelDiameter);
callable("numMagnetPoles", controllerHardware.numMagnetPoles);
callable("swapFrontBack", controllerHardware.swapFrontBack);
#ifdef FEATURE_CAN
callable("sendFrontCanCmd", controllerHardware.sendFrontCanCmd);
callable("sendBackCanCmd", controllerHardware.sendBackCanCmd);
callable("canTransmitTime", controllerHardware.canTransmitTimeout);
callable("canReceiveTimeo", controllerHardware.canReceiveTimeout);
#endif
#ifdef FEATURE_GAMETRAK
callable("gametrakXMin", boardcomputerHardware.gametrakXMin);
callable("gametrakXMax", boardcomputerHardware.gametrakXMax);
callable("gametrakYMin", boardcomputerHardware.gametrakYMin);
callable("gametrakYMax", boardcomputerHardware.gametrakYMax);
callable("gametrakDistMin", boardcomputerHardware.gametrakDistMin);
callable("gametrakDistMax", boardcomputerHardware.gametrakDistMax);
#endif
callable("statsUpdateRate", boardcomputerHardware.timersSettings.statsUpdateRate);
#ifdef FEATURE_CLOUD
callable("cloudCollectRat", boardcomputerHardware.timersSettings.cloudCollectRate);
callable("cloudSendRate", boardcomputerHardware.timersSettings.cloudSendRate);
#endif
#ifdef FEATURE_UDPCLOUD
callable("udpSendRate", boardcomputerHardware.timersSettings.udpSendRateMs);
#endif
#ifdef FEATURE_CLOUD
callable("cloudEnabled", cloudSettings.cloudEnabled);
callable("clodTransmTmout", cloudSettings.cloudTransmitTimeout);
#endif
#ifdef FEATURE_UDPCLOUD
callable("cloudUDPUid", udpCloudSettings.udpUid);
callable("enUdpCloud", udpCloudSettings.udpCloudEnabled);
callable("debugCloud", udpCloudSettings.enableCloudDebug);
callable("udpusestdstr", udpCloudSettings.udpUseStdString);
#endif
#ifdef FEATURE_LEDSTRIP
callable("enableLedAnimat", ledstrip.enableLedAnimation);
callable("enableBrakeLigh", ledstrip.enableBrakeLights);
callable("ledsCount", ledstrip.ledsCount);
callable("centerOffset", ledstrip.centerOffset);
callable("smallOffset", ledstrip.smallOffset);
callable("bigOffset", ledstrip.bigOffset);
callable("beeppwhenblink", ledstrip.enableBeepWhenBlink);
// callable("animationType", ledstrip.animationType);
callable("fullblink", ledstrip.enableFullBlink);
callable("ledstvo", ledstrip.enableStVO);
callable("ledstvofoff", ledstrip.stvoFrontOffset);
callable("ledstvoflen", ledstrip.stvoFrontLength);
callable("ledstvoen", ledstrip.stvoFrontEnable);
callable("ledAnimMul", ledstrip.animationMultiplier);
callable("ledbrightness", ledstrip.brightness);
callable("enAnimBlink", ledstrip.enableAnimBlink);
#ifdef FEATURE_OTA
callable("ledOtaAnim", ledstrip.otaMode);
#endif
#endif
callable("batteryCS", battery.cellsSeries);
callable("batteryCP", battery.cellsParallel);
callable("batteryType", battery.cellType);
callable("whkm", battery.watthoursPerKilometer);
callable("batF30VCal", battery.front30VoltCalibration);
callable("batB30VCal", battery.back30VoltCalibration);
callable("batF50VCal", battery.front50VoltCalibration);
callable("batB50VCal", battery.back50VoltCalibration);
callable("applyBatCal", battery.applyCalibration);
callable("hybridMode", hybrid.hybridMode);
callable("hybridEn", hybrid.enable);
callable("hybridAcL", hybrid.activationLimit);
callable("hybridDeacL", hybrid.deactivationLimit);
callable("lockAlwPresetSw", lockscreen.allowPresetSwitch);
callable("keepLocked", lockscreen.keepLockedAfterReboot);
callable("currentlyLocked", lockscreen.locked);
callable("lockscreenPin", lockscreen.pin);
callable("totalCentimeter", savedStatistics.totalCentimeters);
callable("handBremsE", handbremse.enable);
callable("handBremsA", handbremse.automatic);
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<typename T>
void Settings::executeForEveryProfileSetting(T &&callable)
{
callable("iMotMax", limits.iMotMax);
callable("iDcMax", limits.iDcMax);
callable("nMotMax", limits.nMotMax);
callable("fieldWeakMax", limits.fieldWeakMax);
callable("phaseAdvMax", limits.phaseAdvMax);
callable("enableFrontLeft", controllerHardware.enableFrontLeft);
callable("enableFrontRigh", controllerHardware.enableFrontRight);
callable("enableBackLeft", controllerHardware.enableBackLeft);
callable("enableBackRight", controllerHardware.enableBackRight);
callable("invertFrontLeft", controllerHardware.invertFrontLeft);
callable("invertFrontRigh", controllerHardware.invertFrontRight);
callable("invertBackLeft", controllerHardware.invertBackLeft);
callable("invertBackRight", controllerHardware.invertBackRight);
callable("default.modelMo", defaultMode.modelMode);
callable("default.enSmUp_", defaultMode.enableSmoothingUp);
callable("default.enSmDow", defaultMode.enableSmoothingDown);
callable("default.enSmFUp", defaultMode.enableFieldWeakSmoothingUp);
callable("default.enSmFDo", defaultMode.enableFieldWeakSmoothingDown);
callable("default.fwSmLLi", defaultMode.fwSmoothLowerLimit);
callable("default.smoothi", defaultMode.smoothing);
callable("default.frontPe", defaultMode.frontPercentage);
callable("default.backPer", defaultMode.backPercentage);
callable("default.add_sch", defaultMode.add_schwelle);
callable("default.gas1_we", defaultMode.gas1_wert);
callable("default.gas2_we", defaultMode.gas2_wert);
callable("default.brems1_", defaultMode.brems1_wert);
callable("default.brems2_", defaultMode.brems2_wert);
callable("tempoma.modelMo", tempomatMode.modelMode);
callable("larsm.modelMode", larsmMode.modelMode);
callable("larsm.mode", larsmMode.mode);
callable("larsm.iters", larsmMode.iterations);
}

View File

@ -18,12 +18,12 @@
#include <futurecpp.h>
// local includes
#include "settings.h"
#include "profilesettings.h"
#ifdef FEATURE_BLUETOOTH
#include "bluetoothmode.h"
#endif
#include "unifiedmodelmode.h"
#include "settings.h"
#include "globals.h"
bool SettingsPersister::init()
{
@ -45,7 +45,6 @@ bool SettingsPersister::init()
bool SettingsPersister::erase()
{
closeProfile();
closeCommon();
bool result{true};
@ -64,32 +63,6 @@ bool SettingsPersister::erase()
return result;
}
bool SettingsPersister::openCommon()
{
closeCommon();
nvs_handle handle;
if (esp_err_t result = nvs_open("bobbycar", NVS_READWRITE, &handle); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_open() COMMON %s failed with %s", "bobbycar", esp_err_to_name(result));
return false;
}
m_handle = handle;
return true;
}
void SettingsPersister::closeCommon()
{
if (!m_handle)
return;
nvs_close(m_handle);
m_handle = {};
}
bool SettingsPersister::openProfile(uint8_t index)
{
closeProfile();
@ -188,24 +161,6 @@ template<> struct nvsGetterHelper<UnifiedModelMode> { static esp_err_t nvs_get(n
*out_value = UnifiedModelMode(tempValue);
return err;
}};
template<> struct nvsGetterHelper<HandbremseMode> { static esp_err_t nvs_get(nvs_handle handle, const char* key, HandbremseMode* out_value)
{
uint8_t tempValue;
esp_err_t err = nvs_get_u8(handle, key, &tempValue);
if (err == ESP_OK)
*out_value = HandbremseMode(tempValue);
return err;
}};
#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA)
template<> struct nvsGetterHelper<OtaAnimationModes> { static esp_err_t nvs_get(nvs_handle handle, const char* key, OtaAnimationModes* out_value)
{
uint8_t tempValue;
esp_err_t err = nvs_get_u8(handle, key, &tempValue);
if (err == ESP_OK)
*out_value = OtaAnimationModes(tempValue);
return err;
}};
#endif
template<> struct nvsGetterHelper<wifi_mode_t> { static esp_err_t nvs_get(nvs_handle handle, const char* key, wifi_mode_t* out_value)
{
uint8_t tempValue;
@ -286,27 +241,9 @@ bool SettingsPersister::load(T &settings)
{
bool result{true};
if (m_handle)
{
settings.executeForEveryCommonSetting([&](const char *key, auto &value)
{
if (esp_err_t result = nvsGetterHelper<std::decay_t<decltype(value)>>::nvs_get(m_handle, key, &value); result != ESP_OK)
{
if (result != ESP_ERR_NVS_NOT_FOUND)
ESP_LOGE("BOBBY", "nvs_get() COMMON %s failed with %s", key, esp_err_to_name(result));
result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "common nvs handle not valid!");
result = false;
}
if (m_profile)
{
settings.executeForEveryProfileSetting([&](const char *key, auto &value)
profileSettings.executeForEveryProfileSetting([&](const char *key, auto &value)
{
if (esp_err_t result = nvsGetterHelper<std::decay_t<decltype(value)>>::nvs_get(m_profile->handle, key, &value); result != ESP_OK)
{
@ -325,7 +262,7 @@ bool SettingsPersister::load(T &settings)
return result;
}
template bool SettingsPersister::load<Settings>(Settings &settings);
template bool SettingsPersister::load<ProfileSettings>(ProfileSettings &profileSettings);
template<typename T> struct nvsSetterHelper;
template<> struct nvsSetterHelper<int8_t> { static constexpr auto nvs_set = &nvs_set_i8; };
@ -361,16 +298,6 @@ template<> struct nvsSetterHelper<UnifiedModelMode> { static esp_err_t nvs_set(n
{
return nvs_set_u8(handle, key, uint8_t(value));
}};
template<> struct nvsSetterHelper<HandbremseMode> { static esp_err_t nvs_set(nvs_handle handle, const char* key, HandbremseMode value)
{
return nvs_set_u8(handle, key, uint8_t(value));
}};
#if defined(FEATURE_LEDSTRIP) && defined(FEATURE_OTA)
template<> struct nvsSetterHelper<OtaAnimationModes> { static esp_err_t nvs_set(nvs_handle handle, const char* key, OtaAnimationModes value)
{
return nvs_set_u8(handle, key, uint8_t(value));
}};
#endif
template<> struct nvsSetterHelper<wifi_mode_t> { static esp_err_t nvs_set(nvs_handle handle, const char* key, wifi_mode_t value)
{
return nvs_set_u8(handle, key, uint8_t(value));
@ -415,26 +342,9 @@ bool SettingsPersister::save(T &settings)
{
bool result{true};
if (m_handle)
{
settings.executeForEveryCommonSetting([&](const char *key, const auto &value)
{
if (esp_err_t result = nvsSetterHelper<std::decay_t<decltype(value)>>::nvs_set(m_handle, key, value); result != ESP_OK)
{
ESP_LOGE("BOBBY", "nvs_set() COMMON %s failed with %s", key, esp_err_to_name(result));
result = false;
}
});
}
else
{
ESP_LOGW("BOBBY", "common nvs handle not valid!");
result = false;
}
if (m_profile)
{
settings.executeForEveryProfileSetting([&](const char *key, const auto &value)
profileSettings.executeForEveryProfileSetting([&](const char *key, const auto &value)
{
if (esp_err_t result = nvsSetterHelper<std::decay_t<decltype(value)>>::nvs_set(m_profile->handle, key, value); result != ESP_OK)
{
@ -452,7 +362,7 @@ bool SettingsPersister::save(T &settings)
return result;
}
template bool SettingsPersister::save<Settings>(Settings &settings);
template bool SettingsPersister::save<ProfileSettings>(ProfileSettings &settings);
std::optional<uint8_t> SettingsPersister::currentlyOpenProfileIndex() const
{

View File

@ -9,24 +9,18 @@ class SettingsPersister
public:
bool init();
bool erase();
bool openCommon();
void closeCommon();
bool openProfile(uint8_t index);
void closeProfile();
template<typename T>
bool load(T &settings);
bool load(T &profileSettings);
template<typename T>
bool save(T &settings);
bool save(T &profileSettings);
std::optional<uint8_t> currentlyOpenProfileIndex() const;
nvs_handle getCommonHandle() { return m_handle; }
private:
// for common settings
nvs_handle m_handle{};
struct CurrentlyOpenProfile {
nvs_handle handle;

View File

@ -21,7 +21,7 @@ void switchProfile(uint8_t index)
}
#endif
settings = presets::defaultSettings;
profileSettings = presets::defaultProfileSettings;
if (!settingsPersister.openProfile(index))
{
@ -29,7 +29,7 @@ void switchProfile(uint8_t index)
return;
}
if (!settingsPersister.load(settings))
if (!settingsPersister.load(profileSettings))
{
ESP_LOGE("BOBBY", "load() for settings failed");
return;

View File

@ -40,7 +40,7 @@ void udpCloudInit()
void udpCloudUpdate()
{
if (settings.udpCloudSettings.udpCloudEnabled)
if (configs.udpCloudSettings.udpCloudEnabled.value && configs.udpCloudSettings.udpUid.touched())
sendUdpCloudPacket();
}
@ -94,7 +94,7 @@ std::string buildUdpCloudJson()
// const auto w_per_kmh = watt / avgSpeedKmh;
// User ID
doc["uid"] = settings.udpCloudSettings.udpUid;
doc["uid"] = configs.udpCloudSettings.udpUid.value;
doc["upt"] = uptime;
const auto addController = [&](const Controller &controller, const bool isBack) {
@ -142,7 +142,7 @@ std::string buildUdpCloudJson()
}
// Statistics
doc["bP"] = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType));
doc["bP"] = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
doc["bV"] = avgVoltage;
doc["l"] = isLocked;
doc["mN"] = drivingStatistics.meters_driven;
@ -151,7 +151,7 @@ std::string buildUdpCloudJson()
doc["cW"] = watt;
doc["wN"] = drivingStatistics.wh_used;
doc["wL"] = getRemainingWattHours();
doc["kmL"] = getRemainingWattHours() / settings.battery.watthoursPerKilometer;
doc["kmL"] = getRemainingWattHours() / configs.battery.watthoursPerKilometer.value;
doc["ver"] = version_string.substr(0, 6);
serializeJson(doc, buf);
@ -192,8 +192,8 @@ std::string buildUdpCloudString()
buf += "{";
// User ID
if(settings.udpCloudSettings.udpUid)
buf += fmt::format("\"uid\":{},", settings.udpCloudSettings.udpUid);
if(configs.udpCloudSettings.udpUid.value)
buf += fmt::format("\"uid\":{},", configs.udpCloudSettings.udpUid.value);
else
buf += "\"uid\":null,";
@ -290,7 +290,7 @@ std::string buildUdpCloudString()
}
// Statistics
buf += fmt::format("\"bP\":{},", getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)));
buf += fmt::format("\"bP\":{},", getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)));
buf += fmt::format("\"bV\":{},", avgVoltage);
buf += fmt::format("\"l\":{},", isLocked);
buf += fmt::format("\"mN\":{},", drivingStatistics.meters_driven);
@ -299,7 +299,7 @@ std::string buildUdpCloudString()
buf += fmt::format("\"cW\":{},", watt);
buf += fmt::format("\"wN\":{},", drivingStatistics.wh_used);
buf += fmt::format("\"wL\":{},", getRemainingWattHours());
buf += fmt::format("\"kmL\":{},", getRemainingWattHours() / settings.battery.watthoursPerKilometer);
buf += fmt::format("\"kmL\":{},", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value);
buf += fmt::format("\"ver\":{}", version_string.substr(0, 6));
buf += "}";
@ -309,7 +309,7 @@ std::string buildUdpCloudString()
void sendUdpCloudPacket()
{
EVERY_N_MILLIS(settings.boardcomputerHardware.timersSettings.udpSendRateMs) {
EVERY_N_MILLIS(configs.boardcomputerHardware.timersSettings.udpSendRateMs.value) {
if (espchrono::ago(timestampLastFailed) < 2s)
{
visualSendUdpPacket = false;
@ -360,7 +360,7 @@ void sendUdpCloudPacket()
wifi_stack::UdpSender udpCloudSender;
std::string buf;
buf = settings.udpCloudSettings.udpUseStdString ? buildUdpCloudString() : buildUdpCloudJson();
buf = configs.udpCloudSettings.udpUseStdString.value ? buildUdpCloudString() : buildUdpCloudJson();
if (const auto result = udpCloudSender.send(receipient, buf); !result)

View File

@ -12,12 +12,12 @@ espchrono::millis_clock::time_point lastReverseBeepToggle;
float convertToKmh(float val)
{
return val /* / settings.controllerHardware.numMagnetPoles */ / 60.f * settings.controllerHardware.wheelDiameter / 1000.f * 3.14159265359f * 3.6f;
return val /* / profileSettings.controllerHardware.numMagnetPoles */ / 60.f * configs.controllerHardware.wheelDiameter.value / 1000.f * 3.14159265359f * 3.6f;
}
float convertFromKmh(float val)
{
return val /* * settings.controllerHardware.numMagnetPoles */ * 60.f / settings.controllerHardware.wheelDiameter * 1000.f / 3.14159265359f / 3.6f;
return val /* * profileSettings.controllerHardware.numMagnetPoles */ * 60.f / configs.controllerHardware.wheelDiameter.value * 1000.f / 3.14159265359f / 3.6f;
}
float convertToInch(float val)
@ -102,11 +102,11 @@ void fixCommonParams()
{
for (bobbycar::protocol::serial::MotorState &motor : motors())
{
motor.iMotMax = settings.limits.iMotMax;
motor.iDcMax = settings.limits.iDcMax;
motor.nMotMax = settings.limits.nMotMax;
motor.fieldWeakMax = settings.limits.fieldWeakMax;
motor.phaseAdvMax = settings.limits.phaseAdvMax;
motor.iMotMax = profileSettings.limits.iMotMax;
motor.iDcMax = profileSettings.limits.iDcMax;
motor.nMotMax = profileSettings.limits.nMotMax;
motor.fieldWeakMax = profileSettings.limits.fieldWeakMax;
motor.phaseAdvMax = profileSettings.limits.phaseAdvMax;
}
if (configs.reverseBeep.value)
@ -146,27 +146,27 @@ void fixCommonParams()
currentlyReverseBeeping = false;
}
controllers.front.command.left.enable = settings.controllerHardware.enableFrontLeft;
controllers.front.command.right.enable = settings.controllerHardware.enableFrontRight;
controllers.back.command.left.enable = settings.controllerHardware.enableBackLeft;
controllers.back.command.right.enable = settings.controllerHardware.enableBackRight;
controllers.front.command.left.enable = profileSettings.controllerHardware.enableFrontLeft;
controllers.front.command.right.enable = profileSettings.controllerHardware.enableFrontRight;
controllers.back.command.left.enable = profileSettings.controllerHardware.enableBackLeft;
controllers.back.command.right.enable = profileSettings.controllerHardware.enableBackRight;
if (settings.controllerHardware.invertFrontLeft)
if (profileSettings.controllerHardware.invertFrontLeft)
{
controllers.front.command.left.pwm = -controllers.front.command.left.pwm;
controllers.front.command.left.nCruiseMotTgt = -controllers.front.command.left.nCruiseMotTgt;
}
if (settings.controllerHardware.invertFrontRight)
if (profileSettings.controllerHardware.invertFrontRight)
{
controllers.front.command.right.pwm = -controllers.front.command.right.pwm;
controllers.front.command.right.nCruiseMotTgt = -controllers.front.command.right.nCruiseMotTgt;
}
if (settings.controllerHardware.invertBackLeft)
if (profileSettings.controllerHardware.invertBackLeft)
{
controllers.back.command.left.pwm = -controllers.back.command.left.pwm;
controllers.back.command.left.nCruiseMotTgt = -controllers.back.command.left.nCruiseMotTgt;
}
if (settings.controllerHardware.invertBackRight)
if (profileSettings.controllerHardware.invertBackRight)
{
controllers.back.command.right.pwm = -controllers.back.command.right.pwm;
controllers.back.command.right.nCruiseMotTgt = -controllers.back.command.right.nCruiseMotTgt;
@ -192,24 +192,24 @@ void sendCommands()
#ifdef FEATURE_SERIAL
void updateSwapFrontBack()
{
controllers.front.serial = settings.controllerHardware.swapFrontBack ? Serial2 : Serial1;
controllers.back.serial = settings.controllerHardware.swapFrontBack ? Serial1 : Serial2;
controllers.front.serial = configs.controllerHardware.swapFrontBack.value ? Serial2 : Serial1;
controllers.back.serial = configs.controllerHardware.swapFrontBack.value ? Serial1 : Serial2;
}
#endif
bool loadSettings()
bool loadProfileSettings()
{
bool result{true};
if (!settingsPersister.load(settings))
if (!settingsPersister.load(profileSettings))
result = false;
return result;
}
bool saveSettings()
bool saveProfileSettings()
{
if (simplified) return true;
bool result{true};
if (!settingsPersister.save(settings))
if (!settingsPersister.save(profileSettings))
result = false;
return result;
}

View File

@ -52,8 +52,8 @@ void sendCommands();
#ifdef FEATURE_SERIAL
void updateSwapFrontBack();
#endif
bool loadSettings();
bool saveSettings();
bool loadProfileSettings();
bool saveProfileSettings();
void updateAccumulators();
void readPotis();
float wattToAmpere(float watt);

View File

@ -149,11 +149,6 @@ esp_err_t webserver_dump_nvs_handler(httpd_req_t *req)
const auto profile = settingsPersister.currentlyOpenProfileIndex();
const auto switchBackProfile = profile ? int(*profile) : 0;
JsonObject json_settings = doc.createNestedObject("settings");
settings.executeForEveryCommonSetting([&](std::string_view key, const auto &value){
showInputForSetting(key, value, json_settings);
});
JsonObject profiles = doc.createNestedObject("profiles");
// Profile settings
@ -172,7 +167,7 @@ esp_err_t webserver_dump_nvs_handler(httpd_req_t *req)
JsonObject profile = profiles.createNestedObject(profile_str);
JsonObject profile_settings = profile.createNestedObject("settings");
settings.executeForEveryProfileSetting([&](const char *key, auto &value){
profileSettings.executeForEveryProfileSetting([&](const char *key, auto &value){
showInputForSetting(key, value, profile_settings);
});
}

View File

@ -151,7 +151,7 @@ esp_err_t webserver_settings_handler(httpd_req_t *req)
}
HtmlTag divTag{"div", "class=\"form-table\"", body};
settings.executeForEveryCommonSetting([&](std::string_view key, const auto &value){
profileSettings.executeForEveryProfileSetting([&](std::string_view key, const auto &value){
HtmlTag formTag{"form", "class=\"form-table-row\" action=\"/saveSettings\" method=\"GET\"", body};
{
@ -279,7 +279,7 @@ esp_err_t webserver_saveSettings_handler(httpd_req_t *req)
std::string body;
bool success{true};
settings.executeForEveryCommonSetting([&](std::string_view key, auto &value){
profileSettings.executeForEveryProfileSetting([&](std::string_view key, auto &value){
char valueBufEncoded[256];
if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK)
{
@ -306,7 +306,7 @@ esp_err_t webserver_saveSettings_handler(httpd_req_t *req)
if (body.empty())
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "nothing changed?!")
if (settingsPersister.save(settings))
if (settingsPersister.save(profileSettings))
body += "settings persisted successfully";
else
{