driving statistics fixes
This commit is contained in:
@ -1,5 +1,13 @@
|
|||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
|
|
||||||
|
// 3rdparty lib includes
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include <cpputils.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "drivingstatistics.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
|
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
|
||||||
if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
|
if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
|
||||||
return 100 * (expected_ah - cpputils::mapValue<float>(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
|
return 100 * (expected_ah - cpputils::mapValue<float>(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// 3rdparty lib includes
|
// system includes
|
||||||
#include <fmt/core.h>
|
#include <cstdint>
|
||||||
#include <cpptypesafeenum.h>
|
|
||||||
#include <cpputils.h>
|
|
||||||
|
|
||||||
// local includes
|
// 3rdparty lib includes
|
||||||
#include "globals.h"
|
#include <cpptypesafeenum.h>
|
||||||
|
|
||||||
#define BatteryCellTypeValues(x) \
|
#define BatteryCellTypeValues(x) \
|
||||||
x(_22P) \
|
x(_22P) \
|
||||||
|
@ -123,6 +123,8 @@ void cloudCollect()
|
|||||||
addController(controllers.front);
|
addController(controllers.front);
|
||||||
addController(controllers.back);
|
addController(controllers.back);
|
||||||
|
|
||||||
|
//cloudBuffer += fmt::format("", );
|
||||||
|
|
||||||
cloudBuffer += "]";
|
cloudBuffer += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class ClearCurrentStatsAction : public virtual ActionInterface {
|
|||||||
public:
|
public:
|
||||||
void triggered() override {
|
void triggered() override {
|
||||||
drivingStatistics.meters_driven = 0.;
|
drivingStatistics.meters_driven = 0.;
|
||||||
drivingStatistics.currentDrivingTime = 0;
|
drivingStatistics.currentDrivingTime = {};
|
||||||
drivingStatistics.wh_used = 0;
|
drivingStatistics.wh_used = 0;
|
||||||
drivingStatistics.batteryWhEstimate = 0;
|
drivingStatistics.batteryWhEstimate = 0;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
#include "drivingstatistics.h"
|
#include "drivingstatistics.h"
|
||||||
|
|
||||||
// 3rd party
|
// 3rdparty lib includes
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
#include "TFT_eSPI.h"
|
#include <TFT_eSPI.h>
|
||||||
|
#include <date/date.h>
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
DrivingStatistics drivingStatistics;
|
||||||
|
|
||||||
float getAvgWhPerKm()
|
float getAvgWhPerKm()
|
||||||
{
|
{
|
||||||
return drivingStatistics.wh_used / (drivingStatistics.meters_driven / 1000.f);
|
return drivingStatistics.wh_used / (drivingStatistics.meters_driven / 1000.f);
|
||||||
@ -17,91 +20,31 @@ float getAvgWhPerKm()
|
|||||||
std::string getEfficiencyClassString()
|
std::string getEfficiencyClassString()
|
||||||
{
|
{
|
||||||
const float avgWhPerKm = getAvgWhPerKm();
|
const float avgWhPerKm = getAvgWhPerKm();
|
||||||
if (avgWhPerKm <= 14)
|
if (avgWhPerKm <= 14) return "A+++";
|
||||||
{
|
else if (avgWhPerKm <= 16) return "A++";
|
||||||
return "A+++";
|
else if (avgWhPerKm <= 18) return "A+";
|
||||||
}
|
else if (avgWhPerKm <= 20) return "A";
|
||||||
else if (avgWhPerKm <= 16)
|
else if (avgWhPerKm <= 24) return "B";
|
||||||
{
|
else if (avgWhPerKm <= 28) return "C";
|
||||||
return "A++";
|
else if (avgWhPerKm <= 32) return "D";
|
||||||
}
|
else if (avgWhPerKm <= 36) return "E";
|
||||||
else if (avgWhPerKm <= 18)
|
else if (avgWhPerKm <= 40) return "F";
|
||||||
{
|
else return "G";
|
||||||
return "A+";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 20)
|
|
||||||
{
|
|
||||||
return "A";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 24)
|
|
||||||
{
|
|
||||||
return "B";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 28)
|
|
||||||
{
|
|
||||||
return "C";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 32)
|
|
||||||
{
|
|
||||||
return "D";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 36)
|
|
||||||
{
|
|
||||||
return "E";
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 40)
|
|
||||||
{
|
|
||||||
return "F";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "G";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getEfficiencyClassColor()
|
uint16_t getEfficiencyClassColor()
|
||||||
{
|
{
|
||||||
const float avgWhPerKm = getAvgWhPerKm();
|
const float avgWhPerKm = getAvgWhPerKm();
|
||||||
if (avgWhPerKm <= 14)
|
if (avgWhPerKm <= 14) return 0x1700;
|
||||||
{
|
else if (avgWhPerKm <= 16) return 0x3640;
|
||||||
return 0x1700;
|
else if (avgWhPerKm <= 18) return 0x5560;
|
||||||
}
|
else if (avgWhPerKm <= 20) return 0x6CA0;
|
||||||
else if (avgWhPerKm <= 16)
|
else if (avgWhPerKm <= 24) return 0x83E0;
|
||||||
{
|
else if (avgWhPerKm <= 28) return 0x9B20;
|
||||||
return 0x3640;
|
else if (avgWhPerKm <= 32) return 0xB240;
|
||||||
}
|
else if (avgWhPerKm <= 36) return 0xC980;
|
||||||
else if (avgWhPerKm <= 18)
|
else if (avgWhPerKm <= 40) return 0xE0C0;
|
||||||
{
|
else return 0xF800;
|
||||||
return 0x5560;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 20)
|
|
||||||
{
|
|
||||||
return 0x6CA0;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 24)
|
|
||||||
{
|
|
||||||
return 0x83E0;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 28)
|
|
||||||
{
|
|
||||||
return 0x9B20;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 32)
|
|
||||||
{
|
|
||||||
return 0xB240;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 36)
|
|
||||||
{
|
|
||||||
return 0xC980;
|
|
||||||
}
|
|
||||||
else if (avgWhPerKm <= 40)
|
|
||||||
{
|
|
||||||
return 0xE0C0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0xF800;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateStatistics()
|
void calculateStatistics()
|
||||||
@ -116,10 +59,10 @@ void calculateStatistics()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static auto last_km_calculation = espchrono::millis_clock::now();
|
static auto last_km_calculation = espchrono::millis_clock::now();
|
||||||
const auto duration = espchrono::ago(last_km_calculation).count() / 1000.0f;
|
const auto duration = espchrono::ago(last_km_calculation);
|
||||||
last_km_calculation = espchrono::millis_clock::now();
|
last_km_calculation = espchrono::millis_clock::now();
|
||||||
|
|
||||||
const float meters_driven_now = (abs(avgSpeedKmh) / 3.6) * duration;
|
const float meters_driven_now = (abs(avgSpeedKmh) / 3.6) * std::chrono::floor<espchrono::seconds32>(duration).count();
|
||||||
drivingStatistics.meters_driven += meters_driven_now;
|
drivingStatistics.meters_driven += meters_driven_now;
|
||||||
drivingStatistics.totalMeters += meters_driven_now; // Udate meters driven
|
drivingStatistics.totalMeters += meters_driven_now; // Udate meters driven
|
||||||
|
|
||||||
@ -139,13 +82,13 @@ void calculateStatistics()
|
|||||||
avgVoltage = avgVoltage / controllers.size();
|
avgVoltage = avgVoltage / controllers.size();
|
||||||
|
|
||||||
auto watt = sumCurrent * avgVoltage;
|
auto watt = sumCurrent * avgVoltage;
|
||||||
const float ws_driven_now = watt * duration;
|
const float ws_driven_now = watt * std::chrono::floor<espchrono::seconds32>(duration).count();
|
||||||
drivingStatistics.wh_used += ws_driven_now / 3600; // Wh
|
drivingStatistics.wh_used += ws_driven_now / 3600; // Wh
|
||||||
drivingStatistics.batteryWhEstimate -= ws_driven_now / 3600;
|
drivingStatistics.batteryWhEstimate -= ws_driven_now / 3600;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
drivingStatistics.wh_used += (13 * duration) / 3600; // Wh
|
drivingStatistics.wh_used += (13 * std::chrono::floor<espchrono::seconds32>(duration).count()) / 3600; // Wh
|
||||||
drivingStatistics.batteryWhEstimate = getRemainingWattHours();
|
drivingStatistics.batteryWhEstimate = getRemainingWattHours();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,3 +104,12 @@ void calculateStatistics()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_current_driving_time_string()
|
||||||
|
{
|
||||||
|
auto converted = date::make_time(drivingStatistics.currentDrivingTime);
|
||||||
|
return fmt::format("Drive: {:02d}:{:02d}:{:02d}",
|
||||||
|
converted.hours().count(),
|
||||||
|
converted.minutes().count(),
|
||||||
|
converted.seconds().count());
|
||||||
|
}
|
||||||
|
@ -1,7 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// system includes
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
struct DrivingStatistics
|
||||||
|
{
|
||||||
|
float meters_driven;
|
||||||
|
std::chrono::milliseconds currentDrivingTime;
|
||||||
|
double totalMeters;
|
||||||
|
uint32_t last_cm_written;
|
||||||
|
float wh_used;
|
||||||
|
float batteryWhEstimate;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DrivingStatistics drivingStatistics;
|
||||||
|
|
||||||
void calculateStatistics();
|
void calculateStatistics();
|
||||||
float getAvgWhPerKm();
|
float getAvgWhPerKm();
|
||||||
std::string getEfficiencyClassString();
|
std::string getEfficiencyClassString();
|
||||||
uint16_t getEfficiencyClassColor();
|
uint16_t getEfficiencyClassColor();
|
||||||
|
std::string get_current_driving_time_string();
|
||||||
|
@ -47,5 +47,3 @@ BluetoothSerial bluetoothSerial;
|
|||||||
|
|
||||||
ModeInterface *lastMode{};
|
ModeInterface *lastMode{};
|
||||||
ModeInterface *currentMode{};
|
ModeInterface *currentMode{};
|
||||||
|
|
||||||
DrivingStatistics drivingStatistics;
|
|
||||||
|
@ -56,17 +56,6 @@ extern std::string dns_lastIpAddress_v6_global;
|
|||||||
|
|
||||||
extern bool simplified;
|
extern bool simplified;
|
||||||
|
|
||||||
struct DrivingStatistics {
|
|
||||||
float meters_driven;
|
|
||||||
float currentDrivingTime;
|
|
||||||
double totalMeters;
|
|
||||||
uint32_t last_cm_written;
|
|
||||||
float wh_used;
|
|
||||||
float batteryWhEstimate;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern DrivingStatistics drivingStatistics;
|
|
||||||
|
|
||||||
extern Settings settings;
|
extern Settings settings;
|
||||||
extern StringSettings stringSettings;
|
extern StringSettings stringSettings;
|
||||||
extern SettingsPersister settingsPersister;
|
extern SettingsPersister settingsPersister;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
// local includes
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
@ -315,40 +317,19 @@ float wattToAmpere(float watt) {
|
|||||||
return watt / voltage;
|
return watt / voltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
float wattToMotorCurrent(float watt) {
|
float wattToMotorCurrent(float watt)
|
||||||
|
{
|
||||||
return wattToAmpere(watt) / 4;
|
return wattToAmpere(watt) / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_current_uptime_string() {
|
std::string get_current_uptime_string()
|
||||||
|
{
|
||||||
const auto uptime_time_point = espchrono::utc_clock::now();
|
const auto uptime_time_point = espchrono::utc_clock::now();
|
||||||
const auto dateTimeUptime = espchrono::toDateTime(uptime_time_point);
|
const auto dateTimeUptime = espchrono::toDateTime(uptime_time_point);
|
||||||
std::string out = fmt::format("Up: {:02d}:{:02d}:{:02d}", dateTimeUptime.hour, dateTimeUptime.minute, dateTimeUptime.second);
|
std::string out = fmt::format("Up: {:02d}:{:02d}:{:02d}", dateTimeUptime.hour, dateTimeUptime.minute, dateTimeUptime.second);
|
||||||
return out;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(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)
|
||||||
{
|
{
|
||||||
const auto now = espchrono::millis_clock::now().time_since_epoch() % repeat;
|
const auto now = espchrono::millis_clock::now().time_since_epoch() % repeat;
|
||||||
|
@ -59,6 +59,4 @@ void readPotis();
|
|||||||
float wattToAmpere(float watt);
|
float wattToAmpere(float watt);
|
||||||
float wattToMotorCurrent(float watt);
|
float wattToMotorCurrent(float watt);
|
||||||
std::string get_current_uptime_string();
|
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 );
|
|
||||||
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(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);
|
||||||
|
Reference in New Issue
Block a user