Added driving statistics
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
#include "displays/garagedisplay.h"
|
||||
#include "displays/menus/otamenu.h"
|
||||
#include "displays/poweroffdisplay.h"
|
||||
#include "displays/menus/statisticsmenu.h"
|
||||
#include "actions/rebootaction.h"
|
||||
#include "displays/menus/debugmenu.h"
|
||||
#include "icons/battery.h"
|
||||
@ -43,16 +44,18 @@
|
||||
#endif
|
||||
#include "icons/poweroff.h"
|
||||
#include "icons/reboot.h"
|
||||
#include "icons/statistics.h"
|
||||
|
||||
using namespace espgui;
|
||||
|
||||
MainMenu::MainMenu()
|
||||
{
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
|
||||
#ifdef FEATURE_LEDSTRIP
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
|
||||
#endif
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATISTICSMENU>, SwitchScreenAction<StatisticsMenu>, StaticMenuItemIcon<&bobbyicons::statistics>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
|
||||
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>>(); }
|
||||
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
|
||||
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
|
||||
|
90
main/displays/menus/statisticsmenu.cpp
Normal file
90
main/displays/menus/statisticsmenu.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "statisticsmenu.h"
|
||||
|
||||
// local includes
|
||||
#include "mainmenu.h"
|
||||
#include "actions/dummyaction.h"
|
||||
#include "actioninterface.h"
|
||||
#include "fmt/core.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace espgui;
|
||||
|
||||
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;
|
||||
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 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: {:.2f}m", drivingStatistics.totalMeters );
|
||||
}
|
||||
};
|
||||
|
||||
class CurrentDrivingTimeText : public virtual espgui::TextInterface {
|
||||
public: std::string text() const override {
|
||||
return get_current_driving_time_string();
|
||||
}
|
||||
};
|
||||
|
||||
class SavedTotalCentimetersText : public virtual espgui::TextInterface {
|
||||
public: std::string text() const override {
|
||||
return fmt::format("saved: {}cm", settings.savedStatistics.totalCentimeters );
|
||||
}
|
||||
};
|
||||
|
||||
class SaveKilometersAction : public virtual ActionInterface {
|
||||
public:
|
||||
void triggered() override {
|
||||
drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100;
|
||||
settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written;
|
||||
saveSettings();
|
||||
}
|
||||
};
|
||||
|
||||
class ClearCurrentStatsAction : public virtual ActionInterface {
|
||||
public:
|
||||
void triggered() override {
|
||||
drivingStatistics.meters_driven = 0.;
|
||||
drivingStatistics.currentDrivingTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
StatisticsMenu::StatisticsMenu()
|
||||
{
|
||||
constructMenuItem<makeComponent<MenuItem, WhPerKmText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, UptimeText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, CurrentKilometersText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, CurrentDrivingTimeText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, TotalKilometersText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, SavedTotalCentimetersText, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATSSAVE>, SaveKilometersAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATSCLEAR>, ClearCurrentStatsAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||
}
|
||||
|
||||
void StatisticsMenu::back()
|
||||
{
|
||||
switchScreen<MainMenu>();
|
||||
}
|
22
main/displays/menus/statisticsmenu.h
Normal file
22
main/displays/menus/statisticsmenu.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <menudisplay.h>
|
||||
#include <menuitem.h>
|
||||
#include <icons/back.h>
|
||||
#include <actions/dummyaction.h>
|
||||
#include <actions/switchscreenaction.h>
|
||||
|
||||
// Local includes
|
||||
#include "utils.h"
|
||||
#include "texts.h"
|
||||
|
||||
class StatisticsMenu :
|
||||
public espgui::MenuDisplay,
|
||||
public espgui::StaticText<TEXT_STATISTICSMENU>
|
||||
{
|
||||
public:
|
||||
StatisticsMenu();
|
||||
|
||||
void back() override;
|
||||
};
|
@ -47,3 +47,5 @@ BluetoothSerial bluetoothSerial;
|
||||
|
||||
ModeInterface *lastMode{};
|
||||
ModeInterface *currentMode{};
|
||||
|
||||
DrivingStatistics drivingStatistics;
|
||||
|
@ -56,6 +56,15 @@ extern std::string dns_lastIpAddress_v6_global;
|
||||
|
||||
extern bool simplified;
|
||||
|
||||
struct DrivingStatistics {
|
||||
float meters_driven;
|
||||
float currentDrivingTime;
|
||||
double totalMeters;
|
||||
uint32_t last_cm_written;
|
||||
};
|
||||
|
||||
extern DrivingStatistics drivingStatistics;
|
||||
|
||||
extern Settings settings;
|
||||
extern StringSettings stringSettings;
|
||||
extern SettingsPersister settingsPersister;
|
||||
|
@ -524,5 +524,33 @@ extern "C" void app_main()
|
||||
dns_lastIpAddress_v6_global = "-";
|
||||
}
|
||||
#endif
|
||||
EVERY_N_MILLIS( 10 ) {
|
||||
|
||||
if ((settings.savedStatistics.totalCentimeters / 100.f) > drivingStatistics.totalMeters)
|
||||
{
|
||||
drivingStatistics.totalMeters = settings.savedStatistics.totalCentimeters / 100.f;
|
||||
drivingStatistics.last_cm_written = settings.savedStatistics.totalCentimeters;
|
||||
}
|
||||
|
||||
static auto last_km_calculation = espchrono::millis_clock::now();
|
||||
const auto duration = espchrono::ago(last_km_calculation).count() / 1000.0f;
|
||||
last_km_calculation = espchrono::millis_clock::now();
|
||||
|
||||
const float meters_driven_now = (abs(avgSpeedKmh) / 3.6) * duration;
|
||||
drivingStatistics.meters_driven += meters_driven_now;
|
||||
drivingStatistics.totalMeters += meters_driven_now;
|
||||
|
||||
if (abs(avgSpeedKmh) > 1)
|
||||
{
|
||||
drivingStatistics.currentDrivingTime += duration;
|
||||
}
|
||||
|
||||
if (drivingStatistics.totalMeters > ((drivingStatistics.last_cm_written / 100.f) + 100))
|
||||
{
|
||||
drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100;
|
||||
settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written;
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +273,10 @@ constexpr Settings::Hybrid defaultHybrid {
|
||||
.deactivationLimit = 950,
|
||||
};
|
||||
|
||||
constexpr Settings::SavedStatistics defaultSavedStatistics {
|
||||
.totalCentimeters = 0,
|
||||
};
|
||||
|
||||
constexpr Settings defaultSettings {
|
||||
#ifdef FEATURE_BMS
|
||||
.autoConnectBms = false,
|
||||
@ -300,7 +304,8 @@ constexpr Settings defaultSettings {
|
||||
#endif
|
||||
.battery = defaultBattery,
|
||||
.hybrid = defaultHybrid,
|
||||
.lockscreen = defaultLockscreen
|
||||
.lockscreen = defaultLockscreen,
|
||||
.savedStatistics = defaultSavedStatistics,
|
||||
};
|
||||
|
||||
StringSettings makeDefaultStringSettings();
|
||||
|
@ -197,6 +197,10 @@ struct Settings
|
||||
std::array<int8_t, 4> pin;
|
||||
} lockscreen;
|
||||
|
||||
struct SavedStatistics {
|
||||
uint32_t totalCentimeters;
|
||||
} savedStatistics;
|
||||
|
||||
template<typename T>
|
||||
void executeForEveryCommonSetting(T &&callable);
|
||||
|
||||
@ -317,6 +321,7 @@ void Settings::executeForEveryCommonSetting(T &&callable)
|
||||
|
||||
callable("lockAlwPresetSw", lockscreen.allowPresetSwitch);
|
||||
callable("lockscreenPin", lockscreen.pin);
|
||||
callable("totalCentimeter", savedStatistics.totalCentimeters);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "utils.h"
|
||||
#include "globals.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@ -317,3 +318,32 @@ float wattToAmpere(float watt) {
|
||||
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;
|
||||
}
|
||||
|
||||
void secondsToHMS( const float seconds, uint16_t &h, uint16_t &m, uint16_t &s )
|
||||
{
|
||||
uint32_t t = seconds;
|
||||
|
||||
s = t % 60;
|
||||
|
||||
t = (t - s)/60;
|
||||
m = t % 60;
|
||||
|
||||
t = (t - m)/60;
|
||||
h = t;
|
||||
}
|
||||
|
||||
std::string get_current_driving_time_string() {
|
||||
uint16_t hour{};
|
||||
uint16_t minute{};
|
||||
uint16_t second{};
|
||||
secondsToHMS(drivingStatistics.currentDrivingTime, hour, minute, second);
|
||||
std::string out = fmt::format("Drive: {:02d}:{:02d}:{:02d}", hour, minute, second);
|
||||
return out;
|
||||
}
|
||||
|
@ -58,3 +58,6 @@ void updateAccumulators();
|
||||
void readPotis();
|
||||
float wattToAmpere(float watt);
|
||||
float wattToMotorCurrent(float watt);
|
||||
std::string get_current_uptime_string();
|
||||
std::string get_current_driving_time_string();
|
||||
void secondsToHMS( const float seconds, uint16_t &h, uint8_t &m, uint8_t &s );
|
||||
|
Reference in New Issue
Block a user