driving statics menu improvements
This commit is contained in:
@ -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<makeComponent<MenuItem, WhPerKmText, DummyAction>>();
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -20,4 +20,3 @@ void calculateStatistics();
|
||||
float getAvgWhPerKm();
|
||||
std::string getEfficiencyClassString();
|
||||
uint16_t getEfficiencyClassColor();
|
||||
std::string get_current_driving_time_string();
|
||||
|
@ -5,18 +5,16 @@
|
||||
#include "globals.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
template<const char *Ttext, typename Ttype, Ttype *Tptr, typename TreturnType, TreturnType (Ttype::*Tmethod)()>
|
||||
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<const char *Ttext, typename TreturnType, TreturnType (*Tmethod)()>
|
||||
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()); }
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
#include "time_bobbycar.h"
|
||||
|
||||
// esp-idf includes
|
||||
#include <esp_log.h>
|
||||
#ifdef FEATURE_NTP
|
||||
#include <lwip/apps/snmp.h>
|
||||
#include <esp_sntp.h>
|
||||
#endif
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <espchrono.h>
|
||||
#include <espstrutils.h>
|
||||
|
||||
// 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<void, std::string> 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
|
||||
|
@ -1,101 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
// esp-idf includes
|
||||
#include <esp_log.h>
|
||||
#ifdef FEATURE_NTP
|
||||
#include <lwip/apps/snmp.h>
|
||||
#include <esp_sntp.h>
|
||||
void initTime();
|
||||
void updateTime();
|
||||
#endif
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <espchrono.h>
|
||||
#include <espstrutils.h>
|
||||
|
||||
// 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<void, std::string> 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
|
||||
}
|
||||
|
@ -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<long, std::ratio<1,1000>> repeat, std::chrono::duration<long, std::ratio<1,1000>> riseTime, std::chrono::duration<long, std::ratio<1,1000>> 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;
|
||||
}
|
||||
|
@ -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<long, std::ratio<1,1000>> repeat, std::chrono::duration<long, std::ratio<1,1000>> riseTime, std::chrono::duration<long, std::ratio<1,1000>> 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);
|
||||
|
Reference in New Issue
Block a user