diff --git a/main/displays/menus/statisticsmenu.cpp b/main/displays/menus/statisticsmenu.cpp index 5a17227..d68d4be 100644 --- a/main/displays/menus/statisticsmenu.cpp +++ b/main/displays/menus/statisticsmenu.cpp @@ -11,50 +11,83 @@ #include "icons/update.h" #include "drivingstatistics.h" -using namespace espgui; - -class WhPerKmText : public virtual espgui::TextInterface { - public: std::string text() const override { +class WhPerKmText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { float avgVoltage = 0; for (auto &controller : controllers) - { avgVoltage += controller.getCalibratedVoltage(); - } avgVoltage = avgVoltage / controllers.size(); auto watt = sumCurrent * avgVoltage; - auto w_per_kmh = watt / avgSpeedKmh; + auto w_per_kmh = watt / std::abs(avgSpeedKmh); return fmt::format("{:.0f} Wh/km", w_per_kmh); } }; -class UptimeText : public virtual espgui::TextInterface { - public: std::string text() const override { - return get_current_uptime_string(); +class UptimeText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + const auto uptime = espchrono::millis_clock::now().time_since_epoch(); + auto converted = date::make_time(uptime); + auto msecs = uptime + - converted.hours() + - converted.minutes() + - converted.seconds(); + return fmt::format("Up: {:02d}:{:02d}:{:02d}&7.{:03d}", + converted.hours().count(), + converted.minutes().count(), + converted.seconds().count(), + msecs.count()); } }; -class CurrentKilometersText : public virtual espgui::TextInterface { - public: std::string text() const override { +class CurrentKilometersText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { return fmt::format("Curr: {:.2f}m", drivingStatistics.meters_driven); } }; -class TotalKilometersText : public virtual espgui::TextInterface { - public: std::string text() const override { - return fmt::format("total: {:.1f}km", drivingStatistics.totalMeters / 1000.f ); +class TotalKilometersText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + return fmt::format("total: {:.1f}km", drivingStatistics.totalMeters / 1000.f); } }; -class TotalMetersText : public virtual espgui::TextInterface { - public: std::string text() const override { - return fmt::format("total: {:.0f}m", drivingStatistics.totalMeters ); +class TotalMetersText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + return fmt::format("total: {:.0f}m", drivingStatistics.totalMeters); } }; -class CurrentDrivingTimeText : public virtual espgui::TextInterface { - public: std::string text() const override { - return get_current_driving_time_string(); +class CurrentDrivingTimeText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { + auto converted = date::make_time(drivingStatistics.currentDrivingTime); + auto msecs = drivingStatistics.currentDrivingTime + - converted.hours() + - converted.minutes() + - converted.seconds(); + return fmt::format("Drive: {:02d}:{:02d}:{:02d}&s&7.{:03d}", + converted.hours().count(), + converted.minutes().count(), + converted.seconds().count(), + msecs.count()); } }; @@ -90,18 +123,22 @@ public: } }; -class SaveKilometersAction : public virtual ActionInterface { +class SaveKilometersAction : public virtual espgui::ActionInterface +{ public: - void triggered() override { + void triggered() override + { drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100; settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written; saveSettings(); } }; -class ClearCurrentStatsAction : public virtual ActionInterface { +class ClearCurrentStatsAction : public virtual espgui::ActionInterface +{ public: - void triggered() override { + void triggered() override + { drivingStatistics.meters_driven = 0.; drivingStatistics.currentDrivingTime = {}; drivingStatistics.wh_used = 0; @@ -109,6 +146,8 @@ public: } }; +using namespace espgui; + StatisticsMenu::StatisticsMenu() { constructMenuItem>(); diff --git a/main/drivingstatistics.cpp b/main/drivingstatistics.cpp index 3104d37..9408aac 100644 --- a/main/drivingstatistics.cpp +++ b/main/drivingstatistics.cpp @@ -106,17 +106,3 @@ void calculateStatistics() } } } - -std::string get_current_driving_time_string() -{ - auto converted = date::make_time(drivingStatistics.currentDrivingTime); - auto msecs = drivingStatistics.currentDrivingTime - - converted.hours() - - converted.minutes() - - converted.seconds(); - return fmt::format("Drive: {:02d}:{:02d}:{:02d}.{:03d}", - converted.hours().count(), - converted.minutes().count(), - converted.seconds().count(), - msecs.count()); -} diff --git a/main/drivingstatistics.h b/main/drivingstatistics.h index 13bb5b0..480a51e 100644 --- a/main/drivingstatistics.h +++ b/main/drivingstatistics.h @@ -20,4 +20,3 @@ void calculateStatistics(); float getAvgWhPerKm(); std::string getEfficiencyClassString(); uint16_t getEfficiencyClassColor(); -std::string get_current_driving_time_string(); diff --git a/main/statustexthelper.h b/main/statustexthelper.h index a499824..02e6c0a 100644 --- a/main/statustexthelper.h +++ b/main/statustexthelper.h @@ -5,18 +5,16 @@ #include "globals.h" #include "utils.h" -namespace { template -class StatusTextHelper : public virtual TextInterface +class StatusTextHelper : public virtual espgui::TextInterface { public: std::string text() const override { using std::to_string; using ::to_string; return Ttext + to_string((Tptr->*Tmethod)()); } }; template -class StaticStatusTextHelper : public virtual TextInterface +class StaticStatusTextHelper : public virtual espgui::TextInterface { public: std::string text() const override { using std::to_string; using ::to_string; return Ttext + to_string(Tmethod()); } }; -} diff --git a/main/time_bobbycar.cpp b/main/time_bobbycar.cpp index e69de29..61f8445 100644 --- a/main/time_bobbycar.cpp +++ b/main/time_bobbycar.cpp @@ -0,0 +1,103 @@ +#include "time_bobbycar.h" + +// esp-idf includes +#include +#ifdef FEATURE_NTP +#include +#include +#endif + +// 3rdparty lib includes +#include +#include + +// local includes +#include "globals.h" + +namespace { +constexpr const char * const TAG = "BOBBYTIME"; +} // namespace + +auto espchrono::local_clock::timezone() noexcept -> time_zone +{ + return time_zone{minutes32{settings.timeSettings.timezoneOffset}, settings.timeSettings.daylightSavingMode}; +} + +#ifdef FEATURE_NTP +void time_sync_notification_cb(struct timeval *tv); + +void initTime() +{ + sntp_setoperatingmode(SNTP_OPMODE_POLL); + static_assert(SNTP_MAX_SERVERS >= 1); + sntp_setservername(0, stringSettings.timeServer.c_str()); + sntp_set_time_sync_notification_cb(time_sync_notification_cb); + sntp_set_sync_mode(settings.timeSettings.timeSyncMode); + sntp_set_sync_interval(espchrono::milliseconds32{settings.timeSettings.timeSyncInterval}.count()); + if (settings.timeSettings.timeServerEnabled) + { + ESP_LOGI("BOBBY", "sntp_init() ..."); + sntp_init(); + if (!sntp_enabled()) + { + ESP_LOGE("BOBBY", "sntp_init() failed"); + } + } +} + +void updateTime() +{ + if (bool(sntp_enabled()) != settings.timeSettings.timeServerEnabled) + { + if (settings.timeSettings.timeServerEnabled) + { + ESP_LOGD("BOBBY", "calling sntp_init()..."); + sntp_init(); + ESP_LOGI("BOBBY", "sntp_init() finished"); + } + else + { + ESP_LOGD("BOBBY", "calling sntp_stop()..."); + sntp_stop(); + ESP_LOGI("BOBBY", "sntp_stop() finished"); + } + } + + if (stringSettings.timeServer != sntp_getservername(0)) + { + ESP_LOGD("BOBBY", "calling sntp_getservername() with %s...", stringSettings.timeServer.c_str()); + sntp_setservername(0, stringSettings.timeServer.c_str()); + ESP_LOGI("BOBBY", "sntp_getservername() finished"); + } + + if (settings.timeSettings.timeSyncMode != sntp_get_sync_mode()) + { + ESP_LOGD("BOBBY", "calling sntp_set_sync_mode() with %s...", espcpputils::toString(settings.timeSettings.timeSyncMode).c_str()); + sntp_set_sync_mode(settings.timeSettings.timeSyncMode); + ESP_LOGI("BOBBY", "sntp_set_sync_mode() finished"); + } + + if (settings.timeSettings.timeSyncInterval != espchrono::milliseconds32{sntp_get_sync_interval()}) + { + ESP_LOGD("BOBBY", "calling sntp_set_sync_interval() with %s...", espchrono::toString(settings.timeSettings.timeSyncInterval).c_str()); + sntp_set_sync_interval(espchrono::milliseconds32{settings.timeSettings.timeSyncInterval}.count()); + ESP_LOGI("BOBBY", "sntp_set_sync_interval() finished"); + } +} + +tl::expected time_requestSync() +{ + ESP_LOGI("BOBBY", "called"); + if (!sntp_restart()) + return tl::make_unexpected("sntp_restart() failed"); + return {}; +} + +void time_sync_notification_cb(struct timeval *tv) +{ + if (tv) + ESP_LOGI("BOBBY", "%ld", tv->tv_sec); + else + ESP_LOGI("BOBBY", "nullptr"); +} +#endif diff --git a/main/time_bobbycar.h b/main/time_bobbycar.h index 78ece0f..641d4be 100644 --- a/main/time_bobbycar.h +++ b/main/time_bobbycar.h @@ -1,101 +1,6 @@ #pragma once -// esp-idf includes -#include #ifdef FEATURE_NTP -#include -#include +void initTime(); +void updateTime(); #endif - -// 3rdparty lib includes -#include -#include - -// local includes -#include "globals.h" - -auto espchrono::local_clock::timezone() noexcept -> time_zone -{ - return time_zone{minutes32{settings.timeSettings.timezoneOffset}, settings.timeSettings.daylightSavingMode}; -} - -namespace { -#ifdef FEATURE_NTP -void time_sync_notification_cb(struct timeval *tv); - -void initTime() -{ - sntp_setoperatingmode(SNTP_OPMODE_POLL); - static_assert(SNTP_MAX_SERVERS >= 1); - sntp_setservername(0, stringSettings.timeServer.c_str()); - sntp_set_time_sync_notification_cb(time_sync_notification_cb); - sntp_set_sync_mode(settings.timeSettings.timeSyncMode); - sntp_set_sync_interval(espchrono::milliseconds32{settings.timeSettings.timeSyncInterval}.count()); - if (settings.timeSettings.timeServerEnabled) - { - ESP_LOGI("BOBBY", "sntp_init() ..."); - sntp_init(); - if (!sntp_enabled()) - { - ESP_LOGE("BOBBY", "sntp_init() failed"); - } - } -} - -void updateTime() -{ - if (bool(sntp_enabled()) != settings.timeSettings.timeServerEnabled) - { - if (settings.timeSettings.timeServerEnabled) - { - ESP_LOGD("BOBBY", "calling sntp_init()..."); - sntp_init(); - ESP_LOGI("BOBBY", "sntp_init() finished"); - } - else - { - ESP_LOGD("BOBBY", "calling sntp_stop()..."); - sntp_stop(); - ESP_LOGI("BOBBY", "sntp_stop() finished"); - } - } - - if (stringSettings.timeServer != sntp_getservername(0)) - { - ESP_LOGD("BOBBY", "calling sntp_getservername() with %s...", stringSettings.timeServer.c_str()); - sntp_setservername(0, stringSettings.timeServer.c_str()); - ESP_LOGI("BOBBY", "sntp_getservername() finished"); - } - - if (settings.timeSettings.timeSyncMode != sntp_get_sync_mode()) - { - ESP_LOGD("BOBBY", "calling sntp_set_sync_mode() with %s...", espcpputils::toString(settings.timeSettings.timeSyncMode).c_str()); - sntp_set_sync_mode(settings.timeSettings.timeSyncMode); - ESP_LOGI("BOBBY", "sntp_set_sync_mode() finished"); - } - - if (settings.timeSettings.timeSyncInterval != espchrono::milliseconds32{sntp_get_sync_interval()}) - { - ESP_LOGD("BOBBY", "calling sntp_set_sync_interval() with %s...", espchrono::toString(settings.timeSettings.timeSyncInterval).c_str()); - sntp_set_sync_interval(espchrono::milliseconds32{settings.timeSettings.timeSyncInterval}.count()); - ESP_LOGI("BOBBY", "sntp_set_sync_interval() finished"); - } -} - -tl::expected time_requestSync() -{ - ESP_LOGI("BOBBY", "called"); - if (!sntp_restart()) - return tl::make_unexpected("sntp_restart() failed"); - return {}; -} - -void time_sync_notification_cb(struct timeval *tv) -{ - if (tv) - ESP_LOGI("BOBBY", "%ld", tv->tv_sec); - else - ESP_LOGI("BOBBY", "nullptr"); -} -#endif -} diff --git a/main/utils.cpp b/main/utils.cpp index 9d610f5..358e768 100644 --- a/main/utils.cpp +++ b/main/utils.cpp @@ -322,34 +322,18 @@ float wattToMotorCurrent(float watt) return wattToAmpere(watt) / 4; } -std::string get_current_uptime_string() -{ - const auto uptime_time_point = espchrono::utc_clock::now(); - const auto dateTimeUptime = espchrono::toDateTime(uptime_time_point); - std::string out = fmt::format("Up: {:02d}:{:02d}:{:02d}", dateTimeUptime.hour, dateTimeUptime.minute, dateTimeUptime.second); - return out; -} - -uint8_t time_to_percent(std::chrono::duration> repeat, std::chrono::duration> riseTime, std::chrono::duration> fullTime, size_t numLeds, bool invert) +uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::milliseconds32 riseTime, espchrono::milliseconds32 fullTime, size_t numLeds, bool invert) { const auto now = espchrono::millis_clock::now().time_since_epoch() % repeat; - int activated = invert ? numLeds : 0; if (now <= riseTime) { if (invert) - { - activated = numLeds - ((now*numLeds) / riseTime); - } + return numLeds - ((now*numLeds) / riseTime); else - { - activated = (now*numLeds) / riseTime; - } + return (now*numLeds) / riseTime; } else if (now < riseTime + fullTime) - { - activated = invert ? 0 : numLeds; - } + return invert ? 0 : numLeds; else - activated = invert ? numLeds : 0; - return activated; + return invert ? numLeds : 0; } diff --git a/main/utils.h b/main/utils.h index 3d59579..1b35324 100644 --- a/main/utils.h +++ b/main/utils.h @@ -58,5 +58,4 @@ void updateAccumulators(); void readPotis(); float wattToAmpere(float watt); float wattToMotorCurrent(float watt); -std::string get_current_uptime_string(); -uint8_t time_to_percent(std::chrono::duration> repeat, std::chrono::duration> riseTime, std::chrono::duration> fullTime, size_t numLeds, bool invert); +uint8_t time_to_percent(espchrono::milliseconds32 repeat, espchrono::milliseconds32 riseTime, espchrono::milliseconds32 fullTime, size_t numLeds, bool invert);