From 162f95ab1335ce62120ed71bd240b52e45eebbee Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Wed, 11 Aug 2021 22:41:37 +0200 Subject: [PATCH] Implemented time settings --- icons/time.png | Bin 0 -> 12686 bytes main/CMakeLists.txt | 4 ++ main/accessors/settingsaccessors.h | 3 + main/changevaluedisplay.h | 3 + main/changevaluedisplay_bluetoothmode.h | 1 + main/changevaluedisplay_bool.h | 1 + main/changevaluedisplay_controlmode.h | 2 + main/changevaluedisplay_controltype.h | 2 + main/changevaluedisplay_daylightsavingmode.h | 55 ++++++++++++++++ main/displays/menus/settingsmenu.h | 3 + main/displays/menus/timesettingsmenu.h | 65 +++++++++++++++++++ main/icons/time.h | 46 +++++++++++++ main/main.cpp | 2 + main/presets.h | 9 +++ main/settings.h | 8 +++ main/settingspersister.h | 17 +++++ main/texts.h | 13 ++++ main/time_bobbycar.h | 12 ++++ 18 files changed, 246 insertions(+) create mode 100644 icons/time.png create mode 100644 main/changevaluedisplay_daylightsavingmode.h create mode 100644 main/displays/menus/timesettingsmenu.h create mode 100644 main/icons/time.h create mode 100644 main/time_bobbycar.h diff --git a/icons/time.png b/icons/time.png new file mode 100644 index 0000000000000000000000000000000000000000..3703066467aa2a989ad1f0d4dda1c0c338a5636c GIT binary patch literal 12686 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 fsW+?t*gu}{>uK!w`{%{Opm8!!S3j3^P6 { bool &getRe struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } }; #endif +struct TimezoneOffsetAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.timeSettings.timezoneOffset; } }; +struct DaylightSavingModeAccessor : public RefAccessorSaveSettings { espchrono::DayLightSavingMode &getRef() const override { return settings.timeSettings.daylightSavingMode; } }; + struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } }; struct FrontRightEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } }; struct BackLeftEnabledAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } }; diff --git a/main/changevaluedisplay.h b/main/changevaluedisplay.h index f2d8416..b36f6f4 100644 --- a/main/changevaluedisplay.h +++ b/main/changevaluedisplay.h @@ -1,7 +1,9 @@ #pragma once +// 3rdparty lib includes #include +// local includes #include "display.h" #include "textinterface.h" #include "actioninterface.h" @@ -155,6 +157,7 @@ void ChangeValueDisplay::confirm() #endif #include "changevaluedisplay_controlmode.h" #include "changevaluedisplay_controltype.h" +#include "changevaluedisplay_daylightsavingmode.h" #include "changevaluedisplay_larsmmode_mode.h" #include "changevaluedisplay_unifiedmodelmode.h" #include "changevaluedisplay_wifi_mode_t.h" diff --git a/main/changevaluedisplay_bluetoothmode.h b/main/changevaluedisplay_bluetoothmode.h index 250bdcb..1d61c31 100644 --- a/main/changevaluedisplay_bluetoothmode.h +++ b/main/changevaluedisplay_bluetoothmode.h @@ -1,5 +1,6 @@ #pragma once +// local includes #include "changevaluedisplay.h" #include "menudisplay.h" #include "utils.h" diff --git a/main/changevaluedisplay_bool.h b/main/changevaluedisplay_bool.h index d7196e7..483e3f5 100644 --- a/main/changevaluedisplay_bool.h +++ b/main/changevaluedisplay_bool.h @@ -1,5 +1,6 @@ #pragma once +// local includes #include "changevaluedisplay.h" #include "menudisplay.h" #include "actioninterface.h" diff --git a/main/changevaluedisplay_controlmode.h b/main/changevaluedisplay_controlmode.h index 01f1ddf..c0398ba 100644 --- a/main/changevaluedisplay_controlmode.h +++ b/main/changevaluedisplay_controlmode.h @@ -1,7 +1,9 @@ #pragma once +// esp-idf includes #include +// local includes #include "changevaluedisplay.h" #include "menudisplay.h" #include "utils.h" diff --git a/main/changevaluedisplay_controltype.h b/main/changevaluedisplay_controltype.h index a9dd249..094b4d6 100644 --- a/main/changevaluedisplay_controltype.h +++ b/main/changevaluedisplay_controltype.h @@ -1,7 +1,9 @@ #pragma once +// esp-idf includes #include +// local includes #include "changevaluedisplay.h" #include "menudisplay.h" #include "utils.h" diff --git a/main/changevaluedisplay_daylightsavingmode.h b/main/changevaluedisplay_daylightsavingmode.h new file mode 100644 index 0000000..1783be6 --- /dev/null +++ b/main/changevaluedisplay_daylightsavingmode.h @@ -0,0 +1,55 @@ +#pragma once + +// esp-idf includes +#include + +// 3rdparty lib includes +#include + +// local includes +#include "changevaluedisplay.h" +#include "menudisplay.h" +#include "utils.h" +#include "actions/setvalueaction.h" +#include "actions/backproxyaction.h" +#include "icons/back.h" +#include "texts.h" + +namespace { +template<> +class ChangeValueDisplay : + public MenuDisplay, + public virtual AccessorInterface, + public virtual ActionInterface +{ + using Base = MenuDisplay; + +public: + ChangeValueDisplay(); + + void start() override; +}; + +ChangeValueDisplay::ChangeValueDisplay() +{ + constructMenuItem, StaticText>>(espchrono::DayLightSavingMode::None, *this, *this); + constructMenuItem, StaticText>>(espchrono::DayLightSavingMode::EuropeanSummerTime, *this, *this); + constructMenuItem, StaticText>>(espchrono::DayLightSavingMode::UsDaylightTime, *this, *this); + constructMenuItem, StaticMenuItemIcon<&icons::back>>>(*this); +} + +void ChangeValueDisplay::start() +{ + Base::start(); + + switch (const auto value = getValue()) + { + case espchrono::DayLightSavingMode::None: setSelectedIndex(0); break; + case espchrono::DayLightSavingMode::EuropeanSummerTime: setSelectedIndex(1); break; + case espchrono::DayLightSavingMode::UsDaylightTime: setSelectedIndex(2); break; + default: + ESP_LOGW("BOBBY", "Unknown DayLightSavingMode: %i", int(value)); + setSelectedIndex(3); + } +} +} diff --git a/main/displays/menus/settingsmenu.h b/main/displays/menus/settingsmenu.h index e96fe0b..c9e138e 100644 --- a/main/displays/menus/settingsmenu.h +++ b/main/displays/menus/settingsmenu.h @@ -10,6 +10,7 @@ #if defined(FEATURE_BLUETOOTH) || defined(FEATURE_BLE) #include "icons/bluetooth.h" #endif +#include "icons/time.h" #include "icons/hardware.h" #include "icons/buzzer.h" #include "icons/info.h" @@ -25,6 +26,7 @@ class WifiSettingsMenu; class BluetoothSettingsMenu; class BleSettingsMenu; class CloudSettingsMenu; +class TimeSettingsMenu; class ModesSettingsMenu; class ControllerHardwareSettingsMenu; class BoardcomputerHardwareSettingsMenu; @@ -66,6 +68,7 @@ public: #ifdef FEATURE_CLOUD constructMenuItem, SwitchScreenAction>>(); #endif + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::time>>>(); constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::hardware>>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::hardware>>>(); diff --git a/main/displays/menus/timesettingsmenu.h b/main/displays/menus/timesettingsmenu.h new file mode 100644 index 0000000..fd81cb4 --- /dev/null +++ b/main/displays/menus/timesettingsmenu.h @@ -0,0 +1,65 @@ +#pragma once + +// 3rdparty lib includes +#include +#include + +// local includes +#include "menudisplay.h" +#include "utils.h" +#include "actions/switchscreenaction.h" +#include "icons/back.h" +#include "texts.h" +#include "accessors/settingsaccessors.h" + +// forward declares +namespace { +class SettingsMenu; +class TimeSettingsMenu; +} // namespace + +namespace { +class CurrentUtcDateTime : public virtual TextInterface +{ +public: + std::string text() const override { return fmt::format("utc: {}", espchrono::toString(espchrono::toDateTime(espchrono::utc_clock::now()))); } +}; + +class CurrentLocalDateTime : public virtual TextInterface +{ +public: + std::string text() const override { return fmt::format("local: {}", espchrono::toString(espchrono::toDateTime(espchrono::local_clock::now()))); } +}; + +using TimezoneOffsetChangeDisplay = makeComponent< + ChangeValueDisplay, + StaticText, + TimezoneOffsetAccessor, + BackActionInterface>, + SwitchScreenAction +>; + +using DaylightSavingModeChangeDisplay = makeComponent< + ChangeValueDisplay, + StaticText, + DaylightSavingModeAccessor, + BackActionInterface>, + SwitchScreenAction +>; + +class TimeSettingsMenu : + public MenuDisplay, + public StaticText, + public BackActionInterface> +{ +public: + TimeSettingsMenu() + { + constructMenuItem, DummyAction>>(); + constructMenuItem, DummyAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::back>>>(); + } +}; +} // namespace diff --git a/main/icons/time.h b/main/icons/time.h new file mode 100644 index 0000000..20da2bb --- /dev/null +++ b/main/icons/time.h @@ -0,0 +1,46 @@ +#pragma once + +#include "icon.h" + +namespace { +namespace icons { +const Icon<24, 24> time{{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5AAE, 0x6B2F, 0x7391, 0x7391, 0x7391, 0x7391, 0x7370, 0x7350, 0x62EF, // 0x0010 (16) pixels + 0x5AAE, 0x528E, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x62AE, 0x62EF, 0x8C53, // 0x0020 (32) pixels + 0x9CD6, 0x9CF6, 0x9D17, 0x9CF6, 0x9CF6, 0x94B5, 0x8C74, 0x8C34, 0x7BB1, 0x83CC, 0xDE85, 0xFFA1, 0xFFA1, 0xFFA1, 0xFFA0, 0x0000, // 0x0030 (48) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x62CE, 0x7370, 0xAD57, 0xAD58, 0x9CD6, 0x9CF5, 0xA515, 0xA514, 0xA535, 0xA535, 0x94B4, 0x8433, // 0x0040 (64) pixels + 0x9CD2, 0xBDAC, 0xD646, 0xF764, 0xFFA3, 0xFFA2, 0xFFA1, 0xFFA0, 0x0000, 0x0000, 0x0000, 0x62EF, 0x7BD2, 0xAD98, 0xA517, 0xA516, // 0x0050 (80) pixels + 0xB595, 0xCE57, 0xDE94, 0xDE51, 0xE71A, 0xEF5D, 0xDEDA, 0xC617, 0xBDCF, 0xD668, 0xF749, 0xF76D, 0xFFAB, 0xFFA5, 0xFFA2, 0xFF81, // 0x0060 (96) pixels + 0x0000, 0x0000, 0x62CE, 0x7BB1, 0xAD57, 0x9D16, 0xAD56, 0xD656, 0xD60F, 0xD5EB, 0xDE2E, 0xC614, 0xCE79, 0xF79D, 0xEF7D, 0xEF5B, // 0x0070 (112) pixels + 0xEF30, 0xF748, 0xF78F, 0xFFB8, 0xFFB4, 0xFFA9, 0xFFA2, 0xFF81, 0x0000, 0x0000, 0x62EF, 0xA517, 0x9CF6, 0xAD56, 0xDEB8, 0xD5CB, // 0x0080 (128) pixels + 0xDE70, 0xE6B2, 0xE692, 0xDE92, 0xEF7D, 0xF79E, 0xEF7D, 0xEF7C, 0xF771, 0xFF88, 0xFFAF, 0xFFB7, 0xFFB4, 0xF76A, 0xFF82, 0xFFA1, // 0x0090 (144) pixels + 0x0000, 0x5A8D, 0x8C33, 0xA537, 0x9CF5, 0xE71B, 0x8BE8, 0x9C8C, 0xDE72, 0xE690, 0xDE6F, 0xDE6F, 0xF7BE, 0xF79E, 0xF79D, 0xEF7C, // 0x00A0 (160) pixels + 0xF774, 0xF78C, 0xFF8A, 0xFF8D, 0xF76B, 0xEF06, 0xE6E4, 0xFFA0, 0x0000, 0x62EF, 0xA537, 0x8C74, 0xCE59, 0xF79D, 0xE6F8, 0x8C71, // 0x00B0 (176) pixels + 0x942A, 0xD60E, 0xDE2D, 0xDE2C, 0xF7BE, 0xF7BE, 0xF79D, 0xEF7D, 0xEF5A, 0xF772, 0xF76C, 0xF769, 0xDE87, 0xC5EA, 0x9CCA, 0x0000, // 0x00C0 (192) pixels + 0x0000, 0x7BD2, 0x9CD6, 0x9CD4, 0xDEFB, 0xF79E, 0xF7BE, 0xF79D, 0x94B1, 0x7B67, 0xCD89, 0xD5CA, 0xF7BE, 0xF79E, 0xF79D, 0xEF7D, // 0x00D0 (208) pixels + 0xEF5C, 0xEF5A, 0xEF56, 0xEF53, 0xBDD0, 0x8C50, 0x7370, 0x0000, 0x0000, 0x8C33, 0x9475, 0xAD76, 0xEF5D, 0xF79D, 0xF79E, 0xF7BE, // 0x00E0 (224) pixels + 0xF7BE, 0xA533, 0x7B47, 0xB4E7, 0xE71B, 0xEF7D, 0xEF7D, 0xEF7D, 0xEF5D, 0xE73C, 0xE73C, 0xE71B, 0xD69A, 0x7391, 0x7391, 0x0000, // 0x00F0 (240) pixels + 0x0000, 0x8C53, 0x8C54, 0xB5B7, 0xE73C, 0xDEFB, 0xF79D, 0xF79E, 0xF7BE, 0xF79E, 0x9CD3, 0x8C71, 0x94B2, 0xC618, 0xEF7D, 0xEF5D, // 0x0100 (256) pixels + 0xEF5C, 0xE73C, 0xD6BA, 0xDEDA, 0xE71C, 0x7370, 0x7BB2, 0x0000, 0x0000, 0x8433, 0x8433, 0xBDD7, 0xDEDA, 0xC638, 0xEF7D, 0xF79D, // 0x0110 (272) pixels + 0xF79E, 0xF79D, 0xA534, 0xC618, 0xC618, 0xAD75, 0xEF7D, 0xEF5D, 0xE73C, 0xE73C, 0xC617, 0xD699, 0xE73C, 0x7370, 0x7BD2, 0x0000, // 0x0120 (288) pixels + 0x0000, 0x83F3, 0x8413, 0xBDD7, 0xEF5C, 0xEF5D, 0xEF7D, 0xEF7D, 0xEF7D, 0xBDD6, 0x0020, 0x630C, 0x8430, 0xD6BA, 0xEF5D, 0xEF5C, // 0x0130 (304) pixels + 0xE73C, 0xE71C, 0xE71B, 0xDEFB, 0xE71C, 0x7370, 0x73B1, 0x0000, 0x0000, 0x7BB2, 0x8433, 0xAD56, 0xE71B, 0xEF5C, 0xEF5D, 0xEF7D, // 0x0140 (320) pixels + 0xB596, 0x0000, 0x738E, 0xDEDB, 0xEF7D, 0xEF5D, 0xEF5C, 0xE73C, 0xE73C, 0xE71B, 0xDEFB, 0xE71C, 0xC619, 0x7391, 0x7371, 0x0000, // 0x0150 (336) pixels + 0x0000, 0x6B0F, 0x8C54, 0x8C53, 0xD6BA, 0xE73C, 0xEF5C, 0xEF5D, 0x7BEF, 0x6B4D, 0xD6BA, 0xEF5C, 0xEF5C, 0xE73C, 0xE73C, 0xE71C, // 0x0160 (352) pixels + 0xE71B, 0xDEFB, 0xDEFB, 0xE71C, 0x9493, 0x83F3, 0x0000, 0x0000, 0x0000, 0x0000, 0x7BF3, 0x8412, 0xBDD7, 0xE71B, 0xE73C, 0xE73C, // 0x0170 (368) pixels + 0xE73C, 0xE73C, 0xE73C, 0xE73C, 0xE73C, 0xE73C, 0xE71C, 0xE71B, 0xDEFB, 0xDEFB, 0xDEFB, 0xCE7A, 0x7BD2, 0x7BB2, 0x0000, 0x0000, // 0x0180 (384) pixels + 0x0000, 0x0000, 0x630F, 0x8413, 0x9473, 0xD69A, 0xE71C, 0xE71C, 0xE71C, 0xE73C, 0xE73C, 0xE73C, 0xE71C, 0xE71C, 0xE71B, 0xDEFB, // 0x0190 (400) pixels + 0xDEFB, 0xDEDB, 0xDEFB, 0x9CD4, 0x7BD2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7371, 0x83F3, 0x9CD4, 0xD6BA, 0xE71B, // 0x01A0 (416) pixels + 0xE71B, 0xE71B, 0xE71B, 0xCE79, 0xCE79, 0xDEFB, 0xDEFB, 0xDEFB, 0xDEFB, 0xE73C, 0xAD36, 0x7BB2, 0x6B50, 0x4A2B, 0x0000, 0x0000, // 0x01B0 (432) pixels + 0x0000, 0x0000, 0x18A3, 0x528D, 0x7BB2, 0x7BD2, 0x94B4, 0xD69A, 0xDEFB, 0xDEFB, 0xDEFB, 0xCE58, 0xCE58, 0xDEFB, 0xDEFB, 0xDEFB, // 0x01C0 (448) pixels + 0xDEFC, 0x9CD5, 0x73B1, 0x73B1, 0x524C, 0x1062, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2926, 0x526C, 0x7391, 0x7BF3, 0x8C53, // 0x01D0 (464) pixels + 0xAD56, 0xC639, 0xDEFB, 0xE73C, 0xE73C, 0xE71C, 0xCE59, 0xB597, 0x8C53, 0x7BB2, 0x7391, 0x524C, 0x20E5, 0x0000, 0x0000, 0x0000, // 0x01E0 (480) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x18C4, 0x41EA, 0x630F, 0x7BB2, 0x8434, 0x8413, 0x8C53, 0x8C53, 0x8C53, 0x8C53, 0x8413, 0x8413, // 0x01F0 (496) pixels + 0x7391, 0x630F, 0x41EA, 0x18A3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2926, 0x524C, // 0x0200 (512) pixels + 0x5AAE, 0x6B50, 0x7BB2, 0x83F3, 0x83F3, 0x7BB2, 0x6B30, 0x5AAD, 0x524C, 0x2105, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0210 (528) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x18A3, 0x41C9, 0x4A2B, 0x524C, 0x524C, 0x4A2B, 0x39A9, 0x10A3, // 0x0220 (544) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels +}}; +} +} diff --git a/main/main.cpp b/main/main.cpp index 8b27520..2b960dc 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -68,6 +68,7 @@ using namespace std::chrono_literals; #include "displays/menus/settingsmenu.h" #include "displays/menus/stationwifisettingsmenu.h" #include "displays/menus/timersmenu.h" +#include "displays/menus/timesettingsmenu.h" #include "displays/menus/wifiscanmenu.h" #include "displays/menus/wifisettingsmenu.h" #ifdef FEATURE_BMS @@ -132,6 +133,7 @@ using namespace std::chrono_literals; #include "cloud.h" #endif #include "wifi_bobbycar.h" +#include "time_bobbycar.h" namespace { std::optional lastWifiUpdate; diff --git a/main/presets.h b/main/presets.h index 7e7817b..93712d3 100644 --- a/main/presets.h +++ b/main/presets.h @@ -1,5 +1,8 @@ #pragma once +// 3rdparty lib includes +#include + // local includes #include "settings.h" #include "stringsettings.h" @@ -21,6 +24,11 @@ constexpr Settings::Limits kidsLimits { .phaseAdvMax = 20 }; +constexpr Settings::TimeSettings defaultTimeSettings { + .timezoneOffset = 60, + .daylightSavingMode = espchrono::DayLightSavingMode::EuropeanSummerTime +}; + constexpr Settings::ControllerHardware defaultControllerHardware { .enableFrontLeft = true, .enableFrontRight = true, @@ -202,6 +210,7 @@ constexpr Settings defaultSettings { #ifdef FEATURE_BLE .bleSettings = defaultBleSettings, #endif + .timeSettings = defaultTimeSettings, .controllerHardware = defaultControllerHardware, .boardcomputerHardware = defaultBoardcomputerHardware, #ifdef FEATURE_CLOUD diff --git a/main/settings.h b/main/settings.h index 6d696a4..0219943 100644 --- a/main/settings.h +++ b/main/settings.h @@ -53,6 +53,11 @@ struct Settings } bleSettings; #endif + struct TimeSettings { + int16_t timezoneOffset; + espchrono::DayLightSavingMode daylightSavingMode; + } timeSettings; + struct ControllerHardware { bool enableFrontLeft, enableFrontRight, enableBackLeft, enableBackRight; bool invertFrontLeft, invertFrontRight, invertBackLeft, invertBackRight; @@ -153,6 +158,9 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("bleEnabled", bleSettings.bleEnabled); #endif + callable("timezoneOffset", timeSettings.timezoneOffset); + callable("daylightSaving", timeSettings.daylightSavingMode); + callable("wheelDiameter", controllerHardware.wheelDiameter); callable("numMagnetPoles", controllerHardware.numMagnetPoles); callable("swapFrontBack", controllerHardware.swapFrontBack); diff --git a/main/settingspersister.h b/main/settingspersister.h index ffb8649..6e84400 100644 --- a/main/settingspersister.h +++ b/main/settingspersister.h @@ -1,15 +1,20 @@ #pragma once +// system includes #include #include +// esp-idf includes #include #include #include +// 3rdparty lib includes #include #include +#include +// local includes #include "settings.h" #ifdef FEATURE_BLUETOOTH #include "bluetoothmode.h" @@ -217,6 +222,14 @@ template<> struct nvsGetterHelper { static esp_err_t nvs_get(nvs_ha *out_value = wifi_mode_t(tempValue); return err; }}; +template<> struct nvsGetterHelper { static esp_err_t nvs_get(nvs_handle handle, const char* key, espchrono::DayLightSavingMode* out_value) +{ + uint8_t tempValue; + esp_err_t err = nvs_get_u8(handle, key, &tempValue); + if (err == ESP_OK) + *out_value = espchrono::DayLightSavingMode(tempValue); + return err; +}}; template bool SettingsPersister::load(T &settings) @@ -300,6 +313,10 @@ template<> struct nvsSetterHelper { static esp_err_t nvs_set(nvs_ha { return nvs_set_u8(handle, key, uint8_t(value)); }}; +template<> struct nvsSetterHelper { static esp_err_t nvs_set(nvs_handle handle, const char* key, espchrono::DayLightSavingMode value) +{ + return nvs_set_u8(handle, key, uint8_t(value)); +}}; template bool SettingsPersister::save(T &settings) diff --git a/main/texts.h b/main/texts.h index 3cdf88d..efe1766 100644 --- a/main/texts.h +++ b/main/texts.h @@ -93,6 +93,7 @@ constexpr char TEXT_WIFISETTINGS[] = "WiFi settings"; //constexpr char TEXT_BLUETOOTHSETTINGS[] = "Bluetooth settings"; //constexpr char TEXT_BLESETTINGS[] = "BLE settings"; //constexpr char TEXT_CLOUDSETTINGS[] = "Cloud settings"; +constexpr char TEXT_TIME[] = "Time"; constexpr char TEXT_MODESSETTINGS[] = "Modes settings"; constexpr char TEXT_CONTROLLERHARDWARESETTINGS[] = "Controller H/W settings"; constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings"; @@ -328,6 +329,12 @@ constexpr char TEXT_CLOUDSENDRATE[] = "Cloud send rate"; #endif //constexpr char TEXT_BACK[] = "Back"; +//TimeSettingsMenu +//constexpr char TEXT_TIME[] = "Time"; +constexpr char TEXT_OFFSET[] = "Offset"; +constexpr char TEXT_DAYLIGHTSAVINGMODE[] = "Daylight Saving Mode"; +//constexpr char TEXT_BACK[] = "Back"; + //ChangeValueDisplay constexpr char TEXT_OFF[] = "Off"; constexpr char TEXT_MASTER[] = "Master"; @@ -351,6 +358,12 @@ constexpr char TEXT_SINUSOIDAL[] = "Sinusoidal"; constexpr char TEXT_FIELDORIENTEDCONTROL[] = "Field oriented control"; //constexpr char TEXT_BACK[] = "Back"; +//ChangeValueDisplay +constexpr char TEXT_NONE[] = "None"; +constexpr char TEXT_EUROPEANSUMMERTIME[] = "EuropeanSummerTime"; +constexpr char TEXT_USDAYLIGHTTIME[] = "UsDaylightTime"; +//constexpr char TEXT_BACK[] = "Back"; + //ChangeValueDisplay constexpr char TEXT_LARSMMODE1[] = "Mode1"; constexpr char TEXT_LARSMMODE2[] = "Mode2"; diff --git a/main/time_bobbycar.h b/main/time_bobbycar.h new file mode 100644 index 0000000..c5e1215 --- /dev/null +++ b/main/time_bobbycar.h @@ -0,0 +1,12 @@ +#pragma once + +// 3rdparty lib includes +#include + +// local includes +#include "globals.h" + +auto espchrono::local_clock::timezone() noexcept -> time_zone +{ + return time_zone{minutes32{settings.timeSettings.timezoneOffset}, settings.timeSettings.daylightSavingMode}; +}