Skip to content

Commit

Permalink
add methods to serialize and deserialize battery config
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasBoehm authored and schlimmchen committed Sep 13, 2024
1 parent 7b859bc commit 599b460
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 90 deletions.
41 changes: 23 additions & 18 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,26 @@ enum BatteryVoltageUnit { Volts = 0, DeciVolts = 1, CentiVolts = 2, MilliVolts =

enum BatteryAmperageUnit { Amps = 0, MilliAmps = 1 };

struct BATTERY_CONFIG_T {
bool Enabled;
bool VerboseLogging;
uint8_t Provider;
uint8_t JkBmsInterface;
uint8_t JkBmsPollingInterval;
char MqttSocTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttSocJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
char MqttVoltageTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttVoltageJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryVoltageUnit MqttVoltageUnit;
bool EnableDischargeCurrentLimit;
float DischargeCurrentLimit;
bool UseBatteryReportedDischargeCurrentLimit;
char MqttDischargeCurrentTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttDischargeCurrentJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryAmperageUnit MqttAmperageUnit;
};
using BatteryConfig = struct BATTERY_CONFIG_T;

struct CONFIG_T {
struct {
uint32_t Version;
Expand Down Expand Up @@ -279,24 +299,7 @@ struct CONFIG_T {
float FullSolarPassThroughStopVoltage;
} PowerLimiter;

struct {
bool Enabled;
bool VerboseLogging;
uint8_t Provider;
uint8_t JkBmsInterface;
uint8_t JkBmsPollingInterval;
char MqttSocTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttSocJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
char MqttVoltageTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttVoltageJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryVoltageUnit MqttVoltageUnit;
bool EnableDischargeCurrentLimit;
float DischargeCurrentLimit;
bool UseBatteryReportedDischargeCurrentLimit;
char MqttDischargeCurrentTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttDischargeCurrentJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryAmperageUnit MqttAmperageUnit;
} Battery;
BatteryConfig Battery;

struct {
bool Enabled;
Expand Down Expand Up @@ -335,12 +338,14 @@ class ConfigurationClass {
static void serializePowerMeterSerialSdmConfig(PowerMeterSerialSdmConfig const& source, JsonObject& target);
static void serializePowerMeterHttpJsonConfig(PowerMeterHttpJsonConfig const& source, JsonObject& target);
static void serializePowerMeterHttpSmlConfig(PowerMeterHttpSmlConfig const& source, JsonObject& target);
static void serializeBatteryConfig(BatteryConfig const& source, JsonObject& target);

static void deserializeHttpRequestConfig(JsonObject const& source, HttpRequestConfig& target);
static void deserializePowerMeterMqttConfig(JsonObject const& source, PowerMeterMqttConfig& target);
static void deserializePowerMeterSerialSdmConfig(JsonObject const& source, PowerMeterSerialSdmConfig& target);
static void deserializePowerMeterHttpJsonConfig(JsonObject const& source, PowerMeterHttpJsonConfig& target);
static void deserializePowerMeterHttpSmlConfig(JsonObject const& source, PowerMeterHttpSmlConfig& target);
static void deserializeBatteryConfig(JsonObject const& source, BatteryConfig& target);
};

extern ConfigurationClass Configuration;
75 changes: 42 additions & 33 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ void ConfigurationClass::serializePowerMeterHttpSmlConfig(PowerMeterHttpSmlConfi
serializeHttpRequestConfig(source.HttpRequest, target);
}

void ConfigurationClass::serializeBatteryConfig(BatteryConfig const& source, JsonObject& target)
{
target["enabled"] = config.Battery.Enabled;
target["verbose_logging"] = config.Battery.VerboseLogging;
target["provider"] = config.Battery.Provider;
target["jkbms_interface"] = config.Battery.JkBmsInterface;
target["jkbms_polling_interval"] = config.Battery.JkBmsPollingInterval;
target["mqtt_soc_topic"] = config.Battery.MqttSocTopic;
target["mqtt_soc_json_path"] = config.Battery.MqttSocJsonPath;
target["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
target["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
target["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
target["enable_discharge_current_limit"] = config.Battery.EnableDischargeCurrentLimit;
target["discharge_current_limit"] = config.Battery.DischargeCurrentLimit;
target["use_battery_reported_discharge_current_limit"] = config.Battery.UseBatteryReportedDischargeCurrentLimit;
target["mqtt_discharge_current_topic"] = config.Battery.MqttDischargeCurrentTopic;
target["mqtt_discharge_current_json_path"] = config.Battery.MqttDischargeCurrentJsonPath;
target["mqtt_amperage_unit"] = config.Battery.MqttAmperageUnit;
}

bool ConfigurationClass::write()
{
File f = LittleFS.open(CONFIG_FILENAME, "w");
Expand Down Expand Up @@ -251,22 +271,7 @@ bool ConfigurationClass::write()
powerlimiter["full_solar_passthrough_stop_voltage"] = config.PowerLimiter.FullSolarPassThroughStopVoltage;

JsonObject battery = doc["battery"].to<JsonObject>();
battery["enabled"] = config.Battery.Enabled;
battery["verbose_logging"] = config.Battery.VerboseLogging;
battery["provider"] = config.Battery.Provider;
battery["jkbms_interface"] = config.Battery.JkBmsInterface;
battery["jkbms_polling_interval"] = config.Battery.JkBmsPollingInterval;
battery["mqtt_topic"] = config.Battery.MqttSocTopic;
battery["mqtt_json_path"] = config.Battery.MqttSocJsonPath;
battery["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
battery["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
battery["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
battery["enable_discharge_current_limit"] = config.Battery.EnableDischargeCurrentLimit;
battery["discharge_current_limit"] = config.Battery.DischargeCurrentLimit;
battery["use_battery_reported_discharge_current_limit"] = config.Battery.UseBatteryReportedDischargeCurrentLimit;
battery["mqtt_discharge_current_topic"] = config.Battery.MqttDischargeCurrentTopic;
battery["mqtt_discharge_current_json_path"] = config.Battery.MqttDischargeCurrentJsonPath;
battery["mqtt_amperage_unit"] = config.Battery.MqttAmperageUnit;
serializeBatteryConfig(config.Battery, battery);

JsonObject huawei = doc["huawei"].to<JsonObject>();
huawei["enabled"] = config.Huawei.Enabled;
Expand Down Expand Up @@ -359,6 +364,26 @@ void ConfigurationClass::deserializePowerMeterHttpSmlConfig(JsonObject const& so
deserializeHttpRequestConfig(source, target.HttpRequest);
}

void ConfigurationClass::deserializeBatteryConfig(JsonObject const& source, BatteryConfig& target)
{
target.Enabled = source["enabled"] | BATTERY_ENABLED;
target.VerboseLogging = source["verbose_logging"] | VERBOSE_LOGGING;
target.Provider = source["provider"] | BATTERY_PROVIDER;
target.JkBmsInterface = source["jkbms_interface"] | BATTERY_JKBMS_INTERFACE;
target.JkBmsPollingInterval = source["jkbms_polling_interval"] | BATTERY_JKBMS_POLLING_INTERVAL;
strlcpy(target.MqttSocTopic, source["mqtt_soc_topic"] | source["mqtt_topic"] | "", sizeof(config.Battery.MqttSocTopic)); // mqtt_soc_topic was previously saved as mqtt_topic. Be nice and also try old key.
strlcpy(target.MqttSocJsonPath, source["mqtt_soc_json_path"] | source["mqtt_json_path"] | "", sizeof(config.Battery.MqttSocJsonPath)); // mqtt_soc_json_path was previously saved as mqtt_json_path. Be nice and also try old key.
strlcpy(target.MqttVoltageTopic, source["mqtt_voltage_topic"] | "", sizeof(config.Battery.MqttVoltageTopic));
strlcpy(target.MqttVoltageJsonPath, source["mqtt_voltage_json_path"] | "", sizeof(config.Battery.MqttVoltageJsonPath));
target.MqttVoltageUnit = source["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;
target.EnableDischargeCurrentLimit = source["enable_discharge_current_limit"] | BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT;
target.DischargeCurrentLimit = source["discharge_current_limit"] | BATTERY_DISCHARGE_CURRENT_LIMIT;
target.UseBatteryReportedDischargeCurrentLimit = source["use_battery_reported_discharge_current_limit"] | BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT;
strlcpy(target.MqttDischargeCurrentTopic, source["mqtt_discharge_current_topic"] | "", sizeof(config.Battery.MqttDischargeCurrentTopic));
strlcpy(target.MqttDischargeCurrentJsonPath, source["mqtt_discharge_current_json_path"] | "", sizeof(config.Battery.MqttDischargeCurrentJsonPath));
target.MqttAmperageUnit = source["mqtt_amperage_unit"] | BatteryAmperageUnit::Amps;
}

bool ConfigurationClass::read()
{
File f = LittleFS.open(CONFIG_FILENAME, "r", false);
Expand Down Expand Up @@ -606,23 +631,7 @@ bool ConfigurationClass::read()
config.PowerLimiter.FullSolarPassThroughStartVoltage = powerlimiter["full_solar_passthrough_start_voltage"] | POWERLIMITER_FULL_SOLAR_PASSTHROUGH_START_VOLTAGE;
config.PowerLimiter.FullSolarPassThroughStopVoltage = powerlimiter["full_solar_passthrough_stop_voltage"] | POWERLIMITER_FULL_SOLAR_PASSTHROUGH_STOP_VOLTAGE;

JsonObject battery = doc["battery"];
config.Battery.Enabled = battery["enabled"] | BATTERY_ENABLED;
config.Battery.VerboseLogging = battery["verbose_logging"] | VERBOSE_LOGGING;
config.Battery.Provider = battery["provider"] | BATTERY_PROVIDER;
config.Battery.JkBmsInterface = battery["jkbms_interface"] | BATTERY_JKBMS_INTERFACE;
config.Battery.JkBmsPollingInterval = battery["jkbms_polling_interval"] | BATTERY_JKBMS_POLLING_INTERVAL;
strlcpy(config.Battery.MqttSocTopic, battery["mqtt_topic"] | "", sizeof(config.Battery.MqttSocTopic));
strlcpy(config.Battery.MqttSocJsonPath, battery["mqtt_json_path"] | "", sizeof(config.Battery.MqttSocJsonPath));
strlcpy(config.Battery.MqttVoltageTopic, battery["mqtt_voltage_topic"] | "", sizeof(config.Battery.MqttVoltageTopic));
strlcpy(config.Battery.MqttVoltageJsonPath, battery["mqtt_voltage_json_path"] | "", sizeof(config.Battery.MqttVoltageJsonPath));
config.Battery.MqttVoltageUnit = battery["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;
config.Battery.EnableDischargeCurrentLimit = battery["enable_discharge_current_limit"] | BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT;
config.Battery.DischargeCurrentLimit = battery["discharge_current_limit"] | BATTERY_DISCHARGE_CURRENT_LIMIT;
config.Battery.UseBatteryReportedDischargeCurrentLimit = battery["use_battery_reported_discharge_current_limit"] | BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT;
strlcpy(config.Battery.MqttDischargeCurrentTopic, battery["mqtt_discharge_current_topic"] | "", sizeof(config.Battery.MqttDischargeCurrentTopic));
strlcpy(config.Battery.MqttDischargeCurrentJsonPath, battery["mqtt_discharge_current_json_path"] | "", sizeof(config.Battery.MqttDischargeCurrentJsonPath));
config.Battery.MqttAmperageUnit = battery["mqtt_amperage_unit"] | BatteryAmperageUnit::Amps;
deserializeBatteryConfig(doc["battery"], config.Battery);

JsonObject huawei = doc["huawei"];
config.Huawei.Enabled = huawei["enabled"] | HUAWEI_ENABLED;
Expand Down
47 changes: 8 additions & 39 deletions src/WebApi_battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,12 @@ void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot();
const CONFIG_T& config = Configuration.get();

root["enabled"] = config.Battery.Enabled;
root["verbose_logging"] = config.Battery.VerboseLogging;
root["provider"] = config.Battery.Provider;
root["jkbms_interface"] = config.Battery.JkBmsInterface;
root["jkbms_polling_interval"] = config.Battery.JkBmsPollingInterval;
root["mqtt_soc_topic"] = config.Battery.MqttSocTopic;
root["mqtt_soc_json_path"] = config.Battery.MqttSocJsonPath;
root["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
root["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
root["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
root["enable_discharge_current_limit"] = config.Battery.EnableDischargeCurrentLimit;
root["discharge_current_limit"] = static_cast<int>(config.Battery.DischargeCurrentLimit * 100 +0.5) / 100.0;
root["use_battery_reported_discharge_current_limit"] = config.Battery.UseBatteryReportedDischargeCurrentLimit;
root["mqtt_discharge_current_topic"] = config.Battery.MqttDischargeCurrentTopic;
root["mqtt_discharge_current_json_path"] = config.Battery.MqttDischargeCurrentJsonPath;
root["mqtt_amperage_unit"] = config.Battery.MqttAmperageUnit;

response->setLength();
request->send(response);
auto root = response->getRoot().as<JsonObject>();
auto& config = Configuration.get();

ConfigurationClass::serializeBatteryConfig(config.Battery, root);

WebApi.sendJsonResponse(request, response, __FUNCTION__, __LINE__);
}

void WebApiBatteryClass::onAdminGet(AsyncWebServerRequest* request)
Expand Down Expand Up @@ -86,23 +70,8 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
return;
}

CONFIG_T& config = Configuration.get();
config.Battery.Enabled = root["enabled"].as<bool>();
config.Battery.VerboseLogging = root["verbose_logging"].as<bool>();
config.Battery.Provider = root["provider"].as<uint8_t>();
config.Battery.JkBmsInterface = root["jkbms_interface"].as<uint8_t>();
config.Battery.JkBmsPollingInterval = root["jkbms_polling_interval"].as<uint8_t>();
strlcpy(config.Battery.MqttSocTopic, root["mqtt_soc_topic"].as<String>().c_str(), sizeof(config.Battery.MqttSocTopic));
strlcpy(config.Battery.MqttSocJsonPath, root["mqtt_soc_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttSocJsonPath));
strlcpy(config.Battery.MqttVoltageTopic, root["mqtt_voltage_topic"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageTopic));
strlcpy(config.Battery.MqttVoltageJsonPath, root["mqtt_voltage_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageJsonPath));
config.Battery.MqttVoltageUnit = static_cast<BatteryVoltageUnit>(root["mqtt_voltage_unit"].as<uint8_t>());
config.Battery.EnableDischargeCurrentLimit = root["enable_discharge_current_limit"].as<bool>();
config.Battery.DischargeCurrentLimit = static_cast<int>(root["discharge_currentLimit"].as<float>() * 100) / 100.0;
config.Battery.UseBatteryReportedDischargeCurrentLimit = root["use_battery_reported_discharge_current_limit"].as<bool>();
strlcpy(config.Battery.MqttDischargeCurrentTopic, root["mqtt_discharge_current_topic"].as<String>().c_str(), sizeof(config.Battery.MqttDischargeCurrentTopic));
strlcpy(config.Battery.MqttDischargeCurrentJsonPath, root["mqtt_discharge_current_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttDischargeCurrentJsonPath));
config.Battery.MqttAmperageUnit = static_cast<BatteryAmperageUnit>(root["mqtt_amperage_unit"].as<uint8_t>());
auto& config = Configuration.get();
ConfigurationClass::deserializeBatteryConfig(root.as<JsonObject>(), config.Battery);

WebApi.writeConfig(retMsg);

Expand Down

0 comments on commit 599b460

Please sign in to comment.