Moved settings.battery

This commit is contained in:
CommanderRedYT
2022-01-03 01:31:48 +01:00
parent 7466a2c3d2
commit eed4f541ec
13 changed files with 70 additions and 83 deletions

View File

@ -210,10 +210,10 @@ struct LedstripOtaAnimationAccessor : public NewSettingsAccessor<OtaAnimationMod
#endif #endif
// Battery // Battery
struct BatterySeriesCellsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.battery.cellsSeries; } }; struct BatterySeriesCellsAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.battery.cellsSeries; } };
struct BatteryParallelCellsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.battery.cellsParallel; } }; struct BatteryParallelCellsAccessor : public NewSettingsAccessor<uint8_t> { ConfigWrapper<uint8_t> &getConfig() const override { return configs.battery.cellsParallel; } };
struct BatteryWHperKMAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } }; struct BatteryWHperKMAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.battery.watthoursPerKilometer; } };
struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.battery.applyCalibration; } }; struct BatteryApplyCalibrationAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.battery.applyCalibration; } };
// Lockscreen // Lockscreen
struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } }; struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } };

View File

@ -7,6 +7,7 @@
// local includes // local includes
#include "drivingstatistics.h" #include "drivingstatistics.h"
#include "globals.h" #include "globals.h"
#include "newsettings.h"
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \ #define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
@ -14,7 +15,7 @@ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
float getBatteryPercentage(float batVoltage, BatteryCellType cellType) float getBatteryPercentage(float batVoltage, BatteryCellType cellType)
{ {
const float cellVoltage = batVoltage / settings.battery.cellsSeries; const float cellVoltage = batVoltage / configs.battery.cellsSeries.value;
switch (cellType) switch (cellType)
{ {
@ -129,23 +130,23 @@ float getRemainingWattHours()
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();
return (target_mah / 1000.f) * 3.7 * settings.battery.cellsParallel * settings.battery.cellsSeries * (getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)) / 100); return (target_mah / 1000.f) * 3.7 * configs.battery.cellsParallel.value * configs.battery.cellsSeries.value * (getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)) / 100);
} }
float getPercentageByWh(float wh) float getPercentageByWh(float wh)
{ {
const float maxWh = (getTarget_mAh() / 1000.f) * 3.7 * settings.battery.cellsParallel * settings.battery.cellsSeries; const float maxWh = (getTarget_mAh() / 1000.f) * 3.7 * configs.battery.cellsParallel.value * configs.battery.cellsSeries.value;
return maxWh / wh; return maxWh / wh;
} }
float getTarget_mAh() float getTarget_mAh()
{ {
float target_mah = 2000; //default float target_mah = 2000; //default
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::_22P) target_mah = 2200; if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::_22P) target_mah = 2200;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::HG2) target_mah = 3000; if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::HG2) target_mah = 3000;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::MH1) target_mah = 3200; if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::MH1) target_mah = 3200;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::VTC5) target_mah = 2600; if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::VTC5) target_mah = 2600;
if(BatteryCellType(settings.battery.cellType) == BatteryCellType::BAK_25R) target_mah = 2500; if(BatteryCellType(configs.battery.cellType.value) == BatteryCellType::BAK_25R) target_mah = 2500;
return target_mah; return target_mah;
} }
@ -158,7 +159,7 @@ std::string getBatteryPercentageString()
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();
std::string output = fmt::format("Battery: {:.1f}%", getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType))); std::string output = fmt::format("Battery: {:.1f}%", getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)));
return output; return output;
} }
@ -175,12 +176,12 @@ std::string getBatteryRemainingWattHoursString()
std::string getBatteryCellTypeString() std::string getBatteryCellTypeString()
{ {
return fmt::format("Cells: {}", toString(BatteryCellType(settings.battery.cellType))); return fmt::format("Cells: {}", toString(BatteryCellType(configs.battery.cellType.value)));
} }
std::string getRemainingRangeString() std::string getRemainingRangeString()
{ {
return fmt::format("{:.1f} km", getRemainingWattHours() / settings.battery.watthoursPerKilometer); return fmt::format("{:.1f} km", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value);
} }
std::string getBatteryDebugString() std::string getBatteryDebugString()

View File

@ -8,7 +8,7 @@ Controller::Controller(
HardwareSerial &serial, HardwareSerial &serial,
#endif #endif
bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight, bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight,
int16_t &voltageCalib30V, int16_t &voltageCalib50V espconfig::ConfigWrapper<int16_t> &voltageCalib30V, espconfig::ConfigWrapper<int16_t> &voltageCalib50V
) : ) :
#ifdef FEATURE_SERIAL #ifdef FEATURE_SERIAL
serial{serial}, serial{serial},
@ -21,9 +21,9 @@ Controller::Controller(
float Controller::getCalibratedVoltage() const float Controller::getCalibratedVoltage() const
{ {
float voltage = feedback.batVoltage; float voltage = feedback.batVoltage;
if (settings.battery.applyCalibration) if (configs.battery.applyCalibration.value)
{ {
voltage = ((voltage - float(voltageCalib30V)) * (20.f / (float(voltageCalib50V) - float(voltageCalib30V))) + 30.f); voltage = ((voltage - float(voltageCalib30V.value)) * (20.f / (float(voltageCalib50V.value) - float(voltageCalib30V.value))) + 30.f);
} }
else else
{ {

View File

@ -10,6 +10,7 @@
// 3rdparty lib includes // 3rdparty lib includes
#include <espchrono.h> #include <espchrono.h>
#include <configwrapper.h>
// local includes // local includes
#include "bobbycar-common.h" #include "bobbycar-common.h"
@ -30,7 +31,7 @@ struct Controller
HardwareSerial &serial, HardwareSerial &serial,
#endif #endif
bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight, bool &enableLeft, bool &enableRight, bool &invertLeft, bool &invertRight,
int16_t &voltageCalib30V, int16_t &voltageCalib50V); espconfig::ConfigWrapper<int16_t> &voltageCalib30V, espconfig::ConfigWrapper<int16_t> &voltageCalib50V);
// Controller(const Controller &) = delete; // Controller(const Controller &) = delete;
// Controller &operator=(const Controller &) = delete; // Controller &operator=(const Controller &) = delete;
@ -38,7 +39,7 @@ struct Controller
std::reference_wrapper<HardwareSerial> serial; std::reference_wrapper<HardwareSerial> serial;
#endif #endif
bool &enableLeft, &enableRight, &invertLeft, &invertRight; bool &enableLeft, &enableRight, &invertLeft, &invertRight;
int16_t &voltageCalib30V, &voltageCalib50V; espconfig::ConfigWrapper<int16_t> &voltageCalib30V, &voltageCalib50V;
bobbycar::protocol::serial::Command command{}; bobbycar::protocol::serial::Command command{};

View File

@ -13,7 +13,7 @@
#include "icons/settings.h" #include "icons/settings.h"
#include "battery.h" #include "battery.h"
#include "menus/batterymenu.h" #include "menus/batterymenu.h"
#include "globals.h" #include "newsettings.h"
#include "displays/menus/batterymenu.h" #include "displays/menus/batterymenu.h"
#include "accessors/settingsaccessors.h" #include "accessors/settingsaccessors.h"
#include "bobbycheckbox.h" #include "bobbycheckbox.h"
@ -35,9 +35,8 @@ class Save30VCalibrationAction : public virtual espgui::ActionInterface
public: public:
void triggered() override void triggered() override
{ {
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage; configs.write_config(configs.battery.front30VoltCalibration, controllers.front.feedback.batVoltage);
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage; configs.write_config(configs.battery.back30VoltCalibration, controllers.back.feedback.batVoltage);
saveSettings();
} }
}; };
@ -46,9 +45,8 @@ class Save50VCalibrationAction : public virtual espgui::ActionInterface
public: public:
void triggered() override void triggered() override
{ {
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage; configs.write_config(configs.battery.front50VoltCalibration, controllers.front.feedback.batVoltage);
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage; configs.write_config(configs.battery.back50VoltCalibration, controllers.back.feedback.batVoltage);
saveSettings();
} }
}; };
@ -57,11 +55,10 @@ class ResetCalibrationAction : public virtual espgui::ActionInterface
public: public:
void triggered() override void triggered() override
{ {
settings.battery.front30VoltCalibration = 3000; configs.reset_config(configs.battery.front30VoltCalibration);
settings.battery.back30VoltCalibration = 3000; configs.reset_config(configs.battery.back30VoltCalibration);
settings.battery.front50VoltCalibration = 5000; configs.reset_config(configs.battery.front50VoltCalibration);
settings.battery.back50VoltCalibration = 5000; configs.reset_config(configs.battery.back50VoltCalibration);
saveSettings();
} }
}; };
@ -75,7 +72,7 @@ class BatteryVoltageCalibrationFront30VText : public virtual espgui::TextInterfa
public: public:
std::string text() const override std::string text() const override
{ {
return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration)); return fmt::format("30V Front: {}", convertToFloat(configs.battery.front30VoltCalibration.value));
} }
}; };
@ -84,7 +81,7 @@ class BatteryVoltageCalibrationBack30VText : public virtual espgui::TextInterfac
public: public:
std::string text() const override std::string text() const override
{ {
return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration)); return fmt::format("30V Back: {}", convertToFloat(configs.battery.back30VoltCalibration.value));
} }
}; };
@ -93,7 +90,7 @@ class BatteryVoltageCalibrationFront50VText : public virtual espgui::TextInterfa
public: public:
std::string text() const override std::string text() const override
{ {
return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration)); return fmt::format("50V Front: {}", convertToFloat(configs.battery.front50VoltCalibration.value));
} }
}; };
@ -102,7 +99,7 @@ class BatteryVoltageCalibrationBack50VText : public virtual espgui::TextInterfac
public: public:
std::string text() const override std::string text() const override
{ {
return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration)); return fmt::format("50V Back: {}", convertToFloat(configs.battery.back50VoltCalibration.value));
} }
}; };
@ -111,7 +108,7 @@ class BatteryVoltageCalibratedText : public virtual espgui::TextInterface
public: public:
std::string text() const override std::string text() const override
{ {
if (settings.battery.applyCalibration) if (configs.battery.applyCalibration.value)
return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(), controllers.back.getCalibratedVoltage()); return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(), controllers.back.getCalibratedVoltage());
else else
return "Not activated"; return "Not activated";

View File

@ -101,7 +101,7 @@ void BatteryMenu::redraw()
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();
const auto batPercent = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)); const auto batPercent = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
m_doubleProgressBarBatPercentage.redraw(batPercent, battery::bootBatPercentage); m_doubleProgressBarBatPercentage.redraw(batPercent, battery::bootBatPercentage);
} }

View File

@ -9,7 +9,7 @@
// local includes // local includes
#include "battery.h" #include "battery.h"
#include "globals.h" #include "newsettings.h"
#include "utils.h" #include "utils.h"
#include "displays/menus/batterymenu.h" #include "displays/menus/batterymenu.h"
#include "batterymenu.h" #include "batterymenu.h"
@ -44,7 +44,7 @@ template<BatteryCellType T>
class BatterySelectTypeAction : public virtual espgui::ActionInterface class BatterySelectTypeAction : public virtual espgui::ActionInterface
{ {
public: public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); } void triggered() override { configs.write_config(configs.battery.cellType, uint8_t(T)); }
}; };
} // namespace } // namespace

View File

@ -23,6 +23,7 @@
#include "display.h" #include "display.h"
#include "modeinterface.h" #include "modeinterface.h"
#include "settings.h" #include "settings.h"
#include "newsettings.h"
#include "settingspersister.h" #include "settingspersister.h"
#include "macros_bobbycar.h" #include "macros_bobbycar.h"
@ -64,14 +65,14 @@ public:
Serial1, Serial1,
#endif #endif
settings.controllerHardware.enableFrontLeft, settings.controllerHardware.enableFrontRight, settings.controllerHardware.invertFrontLeft, settings.controllerHardware.invertFrontRight, settings.controllerHardware.enableFrontLeft, settings.controllerHardware.enableFrontRight, settings.controllerHardware.invertFrontLeft, settings.controllerHardware.invertFrontRight,
settings.battery.front30VoltCalibration, settings.battery.front50VoltCalibration configs.battery.front30VoltCalibration, configs.battery.front50VoltCalibration
}, },
Controller { Controller {
#ifdef FEATURE_SERIAL #ifdef FEATURE_SERIAL
Serial2, Serial2,
#endif #endif
settings.controllerHardware.enableBackLeft, settings.controllerHardware.enableBackRight, settings.controllerHardware.invertBackLeft, settings.controllerHardware.invertBackRight, settings.controllerHardware.enableBackLeft, settings.controllerHardware.enableBackRight, settings.controllerHardware.invertBackLeft, settings.controllerHardware.invertBackRight,
settings.battery.back30VoltCalibration, settings.battery.back50VoltCalibration configs.battery.back30VoltCalibration, configs.battery.back50VoltCalibration
} }
}} }}
{} {}

View File

@ -127,7 +127,7 @@ extern "C" void app_main()
} }
avgVoltage = avgVoltage / controllers.size(); avgVoltage = avgVoltage / controllers.size();
if (avgVoltage > 30) if (avgVoltage > 30)
battery::bootBatPercentage = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)); battery::bootBatPercentage = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
} }
} }
} }

View File

@ -236,6 +236,18 @@ public:
ConfigWrapper<OtaAnimationModes> otaMode {OtaAnimationModes::GreenProgressBar, DoReset, {}, "ledOtaAnim" }; ConfigWrapper<OtaAnimationModes> otaMode {OtaAnimationModes::GreenProgressBar, DoReset, {}, "ledOtaAnim" };
ConfigWrapper<uint32_t> maxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" }; ConfigWrapper<uint32_t> maxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" };
} ledstrip; } ledstrip;
struct {
ConfigWrapper<uint8_t> cellsSeries {12, DoReset, {}, "batteryCS" };
ConfigWrapper<uint8_t> cellsParallel {10, DoReset, {}, "batteryCP" };
ConfigWrapper<uint8_t> cellType {0, DoReset, {}, "batteryType" };
ConfigWrapper<uint16_t> watthoursPerKilometer{25, DoReset, {}, "whkm" };
ConfigWrapper<int16_t> front30VoltCalibration{3000, DoReset, {}, "batF30VCal" };
ConfigWrapper<int16_t> back30VoltCalibration {3000, DoReset, {}, "batB30VCal" };
ConfigWrapper<int16_t> front50VoltCalibration{5000, DoReset, {}, "batF50VCal" };
ConfigWrapper<int16_t> back50VoltCalibration {5000, DoReset, {}, "batB50VCal" };
ConfigWrapper<bool> applyCalibration {true, DoReset, {}, "applyBatCal" };
} battery;
// end old settings // end old settings
struct { struct {
@ -474,7 +486,17 @@ public:
x(ledstrip.brightness) \ x(ledstrip.brightness) \
x(ledstrip.enableAnimBlink) \ x(ledstrip.enableAnimBlink) \
x(ledstrip.otaMode) \ x(ledstrip.otaMode) \
x(ledstrip.maxMilliamps) x(ledstrip.maxMilliamps) \
\
x(battery.cellsSeries) \
x(battery.cellsParallel) \
x(battery.cellType) \
x(battery.watthoursPerKilometer) \
x(battery.front30VoltCalibration) \
x(battery.back30VoltCalibration) \
x(battery.front50VoltCalibration) \
x(battery.back50VoltCalibration) \
x(battery.applyCalibration)
//x(bleSettings.bleEnabled) //x(bleSettings.bleEnabled)
template<typename T> template<typename T>

View File

@ -137,18 +137,6 @@ constexpr Settings::LockscreenSettings defaultLockscreen {
.pin = { 1, 2, 3, 4 } .pin = { 1, 2, 3, 4 }
}; };
constexpr Settings::Battery defaultBattery {
.cellsSeries = 12,
.cellsParallel = 4,
.cellType = 0,
.watthoursPerKilometer = 20,
.front30VoltCalibration = 3000,
.back30VoltCalibration = 3000,
.front50VoltCalibration = 5000,
.back50VoltCalibration = 5000,
.applyCalibration = true
};
constexpr Settings::Hybrid defaultHybrid { constexpr Settings::Hybrid defaultHybrid {
.hybridMode = UnifiedModelMode::FocTorque, .hybridMode = UnifiedModelMode::FocTorque,
.enable = false, .enable = false,
@ -180,7 +168,6 @@ constexpr Settings defaultSettings {
.tempomatMode = defaultTempomatMode, .tempomatMode = defaultTempomatMode,
.larsmMode = defaultLarsmMode, .larsmMode = defaultLarsmMode,
.motortestMode = defaultMotortestMode, .motortestMode = defaultMotortestMode,
.battery = defaultBattery,
.hybrid = defaultHybrid, .hybrid = defaultHybrid,
.lockscreen = defaultLockscreen, .lockscreen = defaultLockscreen,
.savedStatistics = defaultSavedStatistics, .savedStatistics = defaultSavedStatistics,

View File

@ -71,18 +71,6 @@ struct Settings
uint16_t maxPwm; // profileSetting uint16_t maxPwm; // profileSetting
} motortestMode; } motortestMode;
struct Battery {
uint8_t cellsSeries;
uint8_t cellsParallel;
uint8_t cellType;
uint16_t watthoursPerKilometer;
int16_t front30VoltCalibration;
int16_t back30VoltCalibration;
int16_t front50VoltCalibration;
int16_t back50VoltCalibration;
bool applyCalibration;
} battery;
struct Hybrid { struct Hybrid {
UnifiedModelMode hybridMode; UnifiedModelMode hybridMode;
bool enable; bool enable;
@ -126,16 +114,6 @@ struct Settings
template<typename T> template<typename T>
void Settings::executeForEveryCommonSetting(T &&callable) void Settings::executeForEveryCommonSetting(T &&callable)
{ {
callable("batteryCS", battery.cellsSeries);
callable("batteryCP", battery.cellsParallel);
callable("batteryType", battery.cellType);
callable("whkm", battery.watthoursPerKilometer);
callable("batF30VCal", battery.front30VoltCalibration);
callable("batB30VCal", battery.back30VoltCalibration);
callable("batF50VCal", battery.front50VoltCalibration);
callable("batB50VCal", battery.back50VoltCalibration);
callable("applyBatCal", battery.applyCalibration);
callable("hybridMode", hybrid.hybridMode); callable("hybridMode", hybrid.hybridMode);
callable("hybridEn", hybrid.enable); callable("hybridEn", hybrid.enable);
callable("hybridAcL", hybrid.activationLimit); callable("hybridAcL", hybrid.activationLimit);

View File

@ -142,7 +142,7 @@ std::string buildUdpCloudJson()
} }
// Statistics // Statistics
doc["bP"] = getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType)); doc["bP"] = getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value));
doc["bV"] = avgVoltage; doc["bV"] = avgVoltage;
doc["l"] = isLocked; doc["l"] = isLocked;
doc["mN"] = drivingStatistics.meters_driven; doc["mN"] = drivingStatistics.meters_driven;
@ -151,7 +151,7 @@ std::string buildUdpCloudJson()
doc["cW"] = watt; doc["cW"] = watt;
doc["wN"] = drivingStatistics.wh_used; doc["wN"] = drivingStatistics.wh_used;
doc["wL"] = getRemainingWattHours(); doc["wL"] = getRemainingWattHours();
doc["kmL"] = getRemainingWattHours() / settings.battery.watthoursPerKilometer; doc["kmL"] = getRemainingWattHours() / configs.battery.watthoursPerKilometer.value;
doc["ver"] = version_string.substr(0, 6); doc["ver"] = version_string.substr(0, 6);
serializeJson(doc, buf); serializeJson(doc, buf);
@ -290,7 +290,7 @@ std::string buildUdpCloudString()
} }
// Statistics // Statistics
buf += fmt::format("\"bP\":{},", getBatteryPercentage(avgVoltage, BatteryCellType(settings.battery.cellType))); buf += fmt::format("\"bP\":{},", getBatteryPercentage(avgVoltage, BatteryCellType(configs.battery.cellType.value)));
buf += fmt::format("\"bV\":{},", avgVoltage); buf += fmt::format("\"bV\":{},", avgVoltage);
buf += fmt::format("\"l\":{},", isLocked); buf += fmt::format("\"l\":{},", isLocked);
buf += fmt::format("\"mN\":{},", drivingStatistics.meters_driven); buf += fmt::format("\"mN\":{},", drivingStatistics.meters_driven);
@ -299,7 +299,7 @@ std::string buildUdpCloudString()
buf += fmt::format("\"cW\":{},", watt); buf += fmt::format("\"cW\":{},", watt);
buf += fmt::format("\"wN\":{},", drivingStatistics.wh_used); buf += fmt::format("\"wN\":{},", drivingStatistics.wh_used);
buf += fmt::format("\"wL\":{},", getRemainingWattHours()); buf += fmt::format("\"wL\":{},", getRemainingWattHours());
buf += fmt::format("\"kmL\":{},", getRemainingWattHours() / settings.battery.watthoursPerKilometer); buf += fmt::format("\"kmL\":{},", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value);
buf += fmt::format("\"ver\":{}", version_string.substr(0, 6)); buf += fmt::format("\"ver\":{}", version_string.substr(0, 6));
buf += "}"; buf += "}";