Remove F macro from onBattery extensions

This commit is contained in:
helgeerbe 2024-01-05 23:02:26 +01:00
parent bfcce16bc9
commit d5155a07be
12 changed files with 234 additions and 234 deletions

View File

@ -216,7 +216,7 @@ bool Controller::init(bool verboseLogging)
pin.battery_rx, pin.battery_rxen, pin.battery_tx, pin.battery_txen); pin.battery_rx, pin.battery_rxen, pin.battery_tx, pin.battery_txen);
if (pin.battery_rx < 0 || pin.battery_tx < 0) { if (pin.battery_rx < 0 || pin.battery_tx < 0) {
MessageOutput.println(F("[JK BMS] Invalid RX/TX pin config")); MessageOutput.println("[JK BMS] Invalid RX/TX pin config");
return false; return false;
} }
@ -229,7 +229,7 @@ bool Controller::init(bool verboseLogging)
_txEnablePin = pin.battery_txen; _txEnablePin = pin.battery_txen;
if (_rxEnablePin < 0 || _txEnablePin < 0) { if (_rxEnablePin < 0 || _txEnablePin < 0) {
MessageOutput.println(F("[JK BMS] Invalid transceiver pin config")); MessageOutput.println("[JK BMS] Invalid transceiver pin config");
return false; return false;
} }

View File

@ -109,29 +109,29 @@ void MqttHandleVedirectHassClass::publishSensor(const char* caption, const char*
statTopic.concat(subTopic); statTopic.concat(subTopic);
DynamicJsonDocument root(1024); DynamicJsonDocument root(1024);
root[F("name")] = caption; root["name"] = caption;
root[F("stat_t")] = statTopic; root["stat_t"] = statTopic;
root[F("uniq_id")] = serial + "_" + sensorId; root["uniq_id"] = serial + "_" + sensorId;
if (icon != NULL) { if (icon != NULL) {
root[F("icon")] = icon; root["icon"] = icon;
} }
if (unitOfMeasurement != NULL) { if (unitOfMeasurement != NULL) {
root[F("unit_of_meas")] = unitOfMeasurement; root["unit_of_meas"] = unitOfMeasurement;
} }
JsonObject deviceObj = root.createNestedObject("dev"); JsonObject deviceObj = root.createNestedObject("dev");
createDeviceInfo(deviceObj); createDeviceInfo(deviceObj);
if (Configuration.get().Mqtt.Hass.Expire) { if (Configuration.get().Mqtt.Hass.Expire) {
root[F("exp_aft")] = Configuration.get().Mqtt.PublishInterval * 3; root["exp_aft"] = Configuration.get().Mqtt.PublishInterval * 3;
} }
if (deviceClass != NULL) { if (deviceClass != NULL) {
root[F("dev_cla")] = deviceClass; root["dev_cla"] = deviceClass;
} }
if (stateClass != NULL) { if (stateClass != NULL) {
root[F("stat_cla")] = stateClass; root["stat_cla"] = stateClass;
} }
char buffer[512]; char buffer[512];
@ -160,14 +160,14 @@ void MqttHandleVedirectHassClass::publishBinarySensor(const char* caption, const
statTopic.concat(subTopic); statTopic.concat(subTopic);
DynamicJsonDocument root(1024); DynamicJsonDocument root(1024);
root[F("name")] = caption; root["name"] = caption;
root[F("uniq_id")] = serial + "_" + sensorId; root["uniq_id"] = serial + "_" + sensorId;
root[F("stat_t")] = statTopic; root["stat_t"] = statTopic;
root[F("pl_on")] = payload_on; root["pl_on"] = payload_on;
root[F("pl_off")] = payload_off; root["pl_off"] = payload_off;
if (icon != NULL) { if (icon != NULL) {
root[F("icon")] = icon; root["icon"] = icon;
} }
JsonObject deviceObj = root.createNestedObject("dev"); JsonObject deviceObj = root.createNestedObject("dev");
@ -182,12 +182,12 @@ void MqttHandleVedirectHassClass::createDeviceInfo(JsonObject& object)
{ {
auto spMpptData = VictronMppt.getData(); auto spMpptData = VictronMppt.getData();
String serial = spMpptData->SER; String serial = spMpptData->SER;
object[F("name")] = "Victron(" + serial + ")"; object["name"] = "Victron(" + serial + ")";
object[F("ids")] = serial; object["ids"] = serial;
object[F("cu")] = String(F("http://")) + NetworkSettings.localIP().toString(); object["cu"] = String("http://") + NetworkSettings.localIP().toString();
object[F("mf")] = F("OpenDTU"); object["mf"] = "OpenDTU";
object[F("mdl")] = spMpptData->getPidAsString(); object["mdl"] = spMpptData->getPidAsString();
object[F("sw")] = AUTO_GIT_HASH; object["sw"] = AUTO_GIT_HASH;
} }
void MqttHandleVedirectHassClass::publish(const String& subtopic, const String& payload) void MqttHandleVedirectHassClass::publish(const String& subtopic, const String& payload)

View File

@ -586,7 +586,7 @@ float PowerLimiterClass::getLoadCorrectedVoltage()
{ {
if (!_inverter) { if (!_inverter) {
// there should be no need to call this method if no target inverter is known // there should be no need to call this method if no target inverter is known
MessageOutput.println(F("DPL getLoadCorrectedVoltage: no inverter (programmer error)")); MessageOutput.println("DPL getLoadCorrectedVoltage: no inverter (programmer error)");
return 0.0; return 0.0;
} }

View File

@ -12,14 +12,14 @@ bool PylontechCanReceiver::init(bool verboseLogging)
{ {
_verboseLogging = verboseLogging; _verboseLogging = verboseLogging;
MessageOutput.println(F("[Pylontech] Initialize interface...")); MessageOutput.println("[Pylontech] Initialize interface...");
const PinMapping_t& pin = PinMapping.get(); const PinMapping_t& pin = PinMapping.get();
MessageOutput.printf("[Pylontech] Interface rx = %d, tx = %d\r\n", MessageOutput.printf("[Pylontech] Interface rx = %d, tx = %d\r\n",
pin.battery_rx, pin.battery_tx); pin.battery_rx, pin.battery_tx);
if (pin.battery_rx < 0 || pin.battery_tx < 0) { if (pin.battery_rx < 0 || pin.battery_tx < 0) {
MessageOutput.println(F("[Pylontech] Invalid pin config")); MessageOutput.println("[Pylontech] Invalid pin config");
return false; return false;
} }
@ -35,18 +35,18 @@ bool PylontechCanReceiver::init(bool verboseLogging)
esp_err_t twaiLastResult = twai_driver_install(&g_config, &t_config, &f_config); esp_err_t twaiLastResult = twai_driver_install(&g_config, &t_config, &f_config);
switch (twaiLastResult) { switch (twaiLastResult) {
case ESP_OK: case ESP_OK:
MessageOutput.println(F("[Pylontech] Twai driver installed")); MessageOutput.println("[Pylontech] Twai driver installed");
break; break;
case ESP_ERR_INVALID_ARG: case ESP_ERR_INVALID_ARG:
MessageOutput.println(F("[Pylontech] Twai driver install - invalid arg")); MessageOutput.println("[Pylontech] Twai driver install - invalid arg");
return false; return false;
break; break;
case ESP_ERR_NO_MEM: case ESP_ERR_NO_MEM:
MessageOutput.println(F("[Pylontech] Twai driver install - no memory")); MessageOutput.println("[Pylontech] Twai driver install - no memory");
return false; return false;
break; break;
case ESP_ERR_INVALID_STATE: case ESP_ERR_INVALID_STATE:
MessageOutput.println(F("[Pylontech] Twai driver install - invalid state")); MessageOutput.println("[Pylontech] Twai driver install - invalid state");
return false; return false;
break; break;
} }
@ -55,10 +55,10 @@ bool PylontechCanReceiver::init(bool verboseLogging)
twaiLastResult = twai_start(); twaiLastResult = twai_start();
switch (twaiLastResult) { switch (twaiLastResult) {
case ESP_OK: case ESP_OK:
MessageOutput.println(F("[Pylontech] Twai driver started")); MessageOutput.println("[Pylontech] Twai driver started");
break; break;
case ESP_ERR_INVALID_STATE: case ESP_ERR_INVALID_STATE:
MessageOutput.println(F("[Pylontech] Twai driver start - invalid state")); MessageOutput.println("[Pylontech] Twai driver start - invalid state");
return false; return false;
break; break;
} }
@ -72,10 +72,10 @@ void PylontechCanReceiver::deinit()
esp_err_t twaiLastResult = twai_stop(); esp_err_t twaiLastResult = twai_stop();
switch (twaiLastResult) { switch (twaiLastResult) {
case ESP_OK: case ESP_OK:
MessageOutput.println(F("[Pylontech] Twai driver stopped")); MessageOutput.println("[Pylontech] Twai driver stopped");
break; break;
case ESP_ERR_INVALID_STATE: case ESP_ERR_INVALID_STATE:
MessageOutput.println(F("[Pylontech] Twai driver stop - invalid state")); MessageOutput.println("[Pylontech] Twai driver stop - invalid state");
break; break;
} }
@ -83,10 +83,10 @@ void PylontechCanReceiver::deinit()
twaiLastResult = twai_driver_uninstall(); twaiLastResult = twai_driver_uninstall();
switch (twaiLastResult) { switch (twaiLastResult) {
case ESP_OK: case ESP_OK:
MessageOutput.println(F("[Pylontech] Twai driver uninstalled")); MessageOutput.println("[Pylontech] Twai driver uninstalled");
break; break;
case ESP_ERR_INVALID_STATE: case ESP_ERR_INVALID_STATE:
MessageOutput.println(F("[Pylontech] Twai driver uninstall - invalid state")); MessageOutput.println("[Pylontech] Twai driver uninstall - invalid state");
break; break;
} }
} }
@ -103,10 +103,10 @@ void PylontechCanReceiver::loop()
if (twaiLastResult != ESP_OK) { if (twaiLastResult != ESP_OK) {
switch (twaiLastResult) { switch (twaiLastResult) {
case ESP_ERR_INVALID_ARG: case ESP_ERR_INVALID_ARG:
MessageOutput.println(F("[Pylontech] Twai driver get status - invalid arg")); MessageOutput.println("[Pylontech] Twai driver get status - invalid arg");
break; break;
case ESP_ERR_INVALID_STATE: case ESP_ERR_INVALID_STATE:
MessageOutput.println(F("[Pylontech] Twai driver get status - invalid state")); MessageOutput.println("[Pylontech] Twai driver get status - invalid state");
break; break;
} }
return; return;
@ -118,7 +118,7 @@ void PylontechCanReceiver::loop()
// Wait for message to be received, function is blocking // Wait for message to be received, function is blocking
twai_message_t rx_message; twai_message_t rx_message;
if (twai_receive(&rx_message, pdMS_TO_TICKS(100)) != ESP_OK) { if (twai_receive(&rx_message, pdMS_TO_TICKS(100)) != ESP_OK) {
MessageOutput.println(F("[Pylontech] Failed to receive message")); MessageOutput.println("[Pylontech] Failed to receive message");
return; return;
} }

View File

@ -32,7 +32,7 @@ void VictronMpptClass::updateSettings()
MessageOutput.printf("[VictronMppt] rx = %d, tx = %d\r\n", rx, tx); MessageOutput.printf("[VictronMppt] rx = %d, tx = %d\r\n", rx, tx);
if (rx < 0) { if (rx < 0) {
MessageOutput.println(F("[VictronMppt] invalid pin config")); MessageOutput.println("[VictronMppt] invalid pin config");
return; return;
} }

View File

@ -7,14 +7,14 @@
bool VictronSmartShunt::init(bool verboseLogging) bool VictronSmartShunt::init(bool verboseLogging)
{ {
MessageOutput.println(F("[VictronSmartShunt] Initialize interface...")); MessageOutput.println("[VictronSmartShunt] Initialize interface...");
const PinMapping_t& pin = PinMapping.get(); const PinMapping_t& pin = PinMapping.get();
MessageOutput.printf("[VictronSmartShunt] Interface rx = %d, tx = %d\r\n", MessageOutput.printf("[VictronSmartShunt] Interface rx = %d, tx = %d\r\n",
pin.battery_rx, pin.battery_tx); pin.battery_rx, pin.battery_tx);
if (pin.battery_rx < 0) { if (pin.battery_rx < 0) {
MessageOutput.println(F("[VictronSmartShunt] Invalid pin config")); MessageOutput.println("[VictronSmartShunt] Invalid pin config");
return false; return false;
} }

View File

@ -38,12 +38,12 @@ void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
root[F("enabled")] = config.Battery.Enabled; root["enabled"] = config.Battery.Enabled;
root[F("verbose_logging")] = config.Battery.VerboseLogging; root["verbose_logging"] = config.Battery.VerboseLogging;
root[F("provider")] = config.Battery.Provider; root["provider"] = config.Battery.Provider;
root[F("jkbms_interface")] = config.Battery.JkBmsInterface; root["jkbms_interface"] = config.Battery.JkBmsInterface;
root[F("jkbms_polling_interval")] = config.Battery.JkBmsPollingInterval; root["jkbms_polling_interval"] = config.Battery.JkBmsPollingInterval;
root[F("mqtt_topic")] = config.Battery.MqttTopic; root["mqtt_topic"] = config.Battery.MqttTopic;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -62,11 +62,11 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject retMsg = response->getRoot(); JsonObject retMsg = response->getRoot();
retMsg[F("type")] = F("warning"); retMsg["type"] = "warning";
if (!request->hasParam("data", true)) { if (!request->hasParam("data", true)) {
retMsg[F("message")] = F("No values found!"); retMsg["message"] = "No values found!";
retMsg[F("code")] = WebApiError::GenericNoValueFound; retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -75,8 +75,8 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
String json = request->getParam("data", true)->value(); String json = request->getParam("data", true)->value();
if (json.length() > 1024) { if (json.length() > 1024) {
retMsg[F("message")] = F("Data too large!"); retMsg["message"] = "Data too large!";
retMsg[F("code")] = WebApiError::GenericDataTooLarge; retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -86,33 +86,33 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
DeserializationError error = deserializeJson(root, json); DeserializationError error = deserializeJson(root, json);
if (error) { if (error) {
retMsg[F("message")] = F("Failed to parse data!"); retMsg["message"] = "Failed to parse data!";
retMsg[F("code")] = WebApiError::GenericParseError; retMsg["code"] = WebApiError::GenericParseError;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if (!root.containsKey(F("enabled")) || !root.containsKey(F("provider"))) { if (!root.containsKey("enabled") || !root.containsKey("provider")) {
retMsg[F("message")] = F("Values are missing!"); retMsg["message"] = "Values are missing!";
retMsg[F("code")] = WebApiError::GenericValueMissing; retMsg["code"] = WebApiError::GenericValueMissing;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
CONFIG_T& config = Configuration.get(); CONFIG_T& config = Configuration.get();
config.Battery.Enabled = root[F("enabled")].as<bool>(); config.Battery.Enabled = root["enabled"].as<bool>();
config.Battery.VerboseLogging = root[F("verbose_logging")].as<bool>(); config.Battery.VerboseLogging = root["verbose_logging"].as<bool>();
config.Battery.Provider = root[F("provider")].as<uint8_t>(); config.Battery.Provider = root["provider"].as<uint8_t>();
config.Battery.JkBmsInterface = root[F("jkbms_interface")].as<uint8_t>(); config.Battery.JkBmsInterface = root["jkbms_interface"].as<uint8_t>();
config.Battery.JkBmsPollingInterval = root[F("jkbms_polling_interval")].as<uint8_t>(); config.Battery.JkBmsPollingInterval = root["jkbms_polling_interval"].as<uint8_t>();
strlcpy(config.Battery.MqttTopic, root[F("mqtt_topic")].as<String>().c_str(), sizeof(config.Battery.MqttTopic)); strlcpy(config.Battery.MqttTopic, root["mqtt_topic"].as<String>().c_str(), sizeof(config.Battery.MqttTopic));
Configuration.write(); Configuration.write();
retMsg[F("type")] = F("success"); retMsg["type"] = "success";
retMsg[F("message")] = F("Settings saved!"); retMsg["message"] = "Settings saved!";
retMsg[F("code")] = WebApiError::GenericSuccess; retMsg["code"] = WebApiError::GenericSuccess;
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@ -37,27 +37,27 @@ void WebApiPowerLimiterClass::onStatus(AsyncWebServerRequest* request)
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
root[F("enabled")] = config.PowerLimiter.Enabled; root["enabled"] = config.PowerLimiter.Enabled;
root[F("verbose_logging")] = config.PowerLimiter.VerboseLogging; root["verbose_logging"] = config.PowerLimiter.VerboseLogging;
root[F("solar_passthrough_enabled")] = config.PowerLimiter.SolarPassThroughEnabled; root["solar_passthrough_enabled"] = config.PowerLimiter.SolarPassThroughEnabled;
root[F("solar_passthrough_losses")] = config.PowerLimiter.SolarPassThroughLosses; root["solar_passthrough_losses"] = config.PowerLimiter.SolarPassThroughLosses;
root[F("battery_drain_strategy")] = config.PowerLimiter.BatteryDrainStategy; root["battery_drain_strategy"] = config.PowerLimiter.BatteryDrainStategy;
root[F("is_inverter_behind_powermeter")] = config.PowerLimiter.IsInverterBehindPowerMeter; root["is_inverter_behind_powermeter"] = config.PowerLimiter.IsInverterBehindPowerMeter;
root[F("inverter_id")] = config.PowerLimiter.InverterId; root["inverter_id"] = config.PowerLimiter.InverterId;
root[F("inverter_channel_id")] = config.PowerLimiter.InverterChannelId; root["inverter_channel_id"] = config.PowerLimiter.InverterChannelId;
root[F("target_power_consumption")] = config.PowerLimiter.TargetPowerConsumption; root["target_power_consumption"] = config.PowerLimiter.TargetPowerConsumption;
root[F("target_power_consumption_hysteresis")] = config.PowerLimiter.TargetPowerConsumptionHysteresis; root["target_power_consumption_hysteresis"] = config.PowerLimiter.TargetPowerConsumptionHysteresis;
root[F("lower_power_limit")] = config.PowerLimiter.LowerPowerLimit; root["lower_power_limit"] = config.PowerLimiter.LowerPowerLimit;
root[F("upper_power_limit")] = config.PowerLimiter.UpperPowerLimit; root["upper_power_limit"] = config.PowerLimiter.UpperPowerLimit;
root[F("battery_soc_start_threshold")] = config.PowerLimiter.BatterySocStartThreshold; root["battery_soc_start_threshold"] = config.PowerLimiter.BatterySocStartThreshold;
root[F("battery_soc_stop_threshold")] = config.PowerLimiter.BatterySocStopThreshold; root["battery_soc_stop_threshold"] = config.PowerLimiter.BatterySocStopThreshold;
root[F("voltage_start_threshold")] = static_cast<int>(config.PowerLimiter.VoltageStartThreshold * 100 +0.5) / 100.0; root["voltage_start_threshold"] = static_cast<int>(config.PowerLimiter.VoltageStartThreshold * 100 +0.5) / 100.0;
root[F("voltage_stop_threshold")] = static_cast<int>(config.PowerLimiter.VoltageStopThreshold * 100 +0.5) / 100.0;; root["voltage_stop_threshold"] = static_cast<int>(config.PowerLimiter.VoltageStopThreshold * 100 +0.5) / 100.0;;
root[F("voltage_load_correction_factor")] = config.PowerLimiter.VoltageLoadCorrectionFactor; root["voltage_load_correction_factor"] = config.PowerLimiter.VoltageLoadCorrectionFactor;
root[F("inverter_restart_hour")] = config.PowerLimiter.RestartHour; root["inverter_restart_hour"] = config.PowerLimiter.RestartHour;
root[F("full_solar_passthrough_soc")] = config.PowerLimiter.FullSolarPassThroughSoc; root["full_solar_passthrough_soc"] = config.PowerLimiter.FullSolarPassThroughSoc;
root[F("full_solar_passthrough_start_voltage")] = static_cast<int>(config.PowerLimiter.FullSolarPassThroughStartVoltage * 100 + 0.5) / 100.0; root["full_solar_passthrough_start_voltage"] = static_cast<int>(config.PowerLimiter.FullSolarPassThroughStartVoltage * 100 + 0.5) / 100.0;
root[F("full_solar_passthrough_stop_voltage")] = static_cast<int>(config.PowerLimiter.FullSolarPassThroughStopVoltage * 100 + 0.5) / 100.0; root["full_solar_passthrough_stop_voltage"] = static_cast<int>(config.PowerLimiter.FullSolarPassThroughStopVoltage * 100 + 0.5) / 100.0;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -80,10 +80,10 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject retMsg = response->getRoot(); JsonObject retMsg = response->getRoot();
retMsg[F("type")] = F("warning"); retMsg["type"] = "warning";
if (!request->hasParam("data", true)) { if (!request->hasParam("data", true)) {
retMsg[F("message")] = F("No values found!"); retMsg["message"] = "No values found!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -92,7 +92,7 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
String json = request->getParam("data", true)->value(); String json = request->getParam("data", true)->value();
if (json.length() > 1024) { if (json.length() > 1024) {
retMsg[F("message")] = F("Data too large!"); retMsg["message"] = "Data too large!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -102,7 +102,7 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
DeserializationError error = deserializeJson(root, json); DeserializationError error = deserializeJson(root, json);
if (error) { if (error) {
retMsg[F("message")] = F("Failed to parse data!"); retMsg["message"] = "Failed to parse data!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -115,8 +115,8 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
&& root.containsKey("target_power_consumption") && root.containsKey("target_power_consumption")
&& root.containsKey("target_power_consumption_hysteresis") && root.containsKey("target_power_consumption_hysteresis")
)) { )) {
retMsg[F("message")] = F("Values are missing!"); retMsg["message"] = "Values are missing!";
retMsg[F("code")] = WebApiError::GenericValueMissing; retMsg["code"] = WebApiError::GenericValueMissing;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -124,30 +124,30 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
CONFIG_T& config = Configuration.get(); CONFIG_T& config = Configuration.get();
config.PowerLimiter.Enabled = root[F("enabled")].as<bool>(); config.PowerLimiter.Enabled = root["enabled"].as<bool>();
PowerLimiter.setMode(PowerLimiterClass::Mode::Normal); // User input sets PL to normal operation PowerLimiter.setMode(PowerLimiterClass::Mode::Normal); // User input sets PL to normal operation
config.PowerLimiter.VerboseLogging = root[F("verbose_logging")].as<bool>(); config.PowerLimiter.VerboseLogging = root["verbose_logging"].as<bool>();
config.PowerLimiter.SolarPassThroughEnabled = root[F("solar_passthrough_enabled")].as<bool>(); config.PowerLimiter.SolarPassThroughEnabled = root["solar_passthrough_enabled"].as<bool>();
config.PowerLimiter.SolarPassThroughLosses = root[F("solar_passthrough_losses")].as<uint8_t>(); config.PowerLimiter.SolarPassThroughLosses = root["solar_passthrough_losses"].as<uint8_t>();
config.PowerLimiter.BatteryDrainStategy= root[F("battery_drain_strategy")].as<uint8_t>(); config.PowerLimiter.BatteryDrainStategy= root["battery_drain_strategy"].as<uint8_t>();
config.PowerLimiter.IsInverterBehindPowerMeter = root[F("is_inverter_behind_powermeter")].as<bool>(); config.PowerLimiter.IsInverterBehindPowerMeter = root["is_inverter_behind_powermeter"].as<bool>();
config.PowerLimiter.InverterId = root[F("inverter_id")].as<uint8_t>(); config.PowerLimiter.InverterId = root["inverter_id"].as<uint8_t>();
config.PowerLimiter.InverterChannelId = root[F("inverter_channel_id")].as<uint8_t>(); config.PowerLimiter.InverterChannelId = root["inverter_channel_id"].as<uint8_t>();
config.PowerLimiter.TargetPowerConsumption = root[F("target_power_consumption")].as<int32_t>(); config.PowerLimiter.TargetPowerConsumption = root["target_power_consumption"].as<int32_t>();
config.PowerLimiter.TargetPowerConsumptionHysteresis = root[F("target_power_consumption_hysteresis")].as<int32_t>(); config.PowerLimiter.TargetPowerConsumptionHysteresis = root["target_power_consumption_hysteresis"].as<int32_t>();
config.PowerLimiter.LowerPowerLimit = root[F("lower_power_limit")].as<int32_t>(); config.PowerLimiter.LowerPowerLimit = root["lower_power_limit"].as<int32_t>();
config.PowerLimiter.UpperPowerLimit = root[F("upper_power_limit")].as<int32_t>(); config.PowerLimiter.UpperPowerLimit = root["upper_power_limit"].as<int32_t>();
config.PowerLimiter.BatterySocStartThreshold = root[F("battery_soc_start_threshold")].as<uint32_t>(); config.PowerLimiter.BatterySocStartThreshold = root["battery_soc_start_threshold"].as<uint32_t>();
config.PowerLimiter.BatterySocStopThreshold = root[F("battery_soc_stop_threshold")].as<uint32_t>(); config.PowerLimiter.BatterySocStopThreshold = root["battery_soc_stop_threshold"].as<uint32_t>();
config.PowerLimiter.VoltageStartThreshold = root[F("voltage_start_threshold")].as<float>(); config.PowerLimiter.VoltageStartThreshold = root["voltage_start_threshold"].as<float>();
config.PowerLimiter.VoltageStartThreshold = static_cast<int>(config.PowerLimiter.VoltageStartThreshold * 100) / 100.0; config.PowerLimiter.VoltageStartThreshold = static_cast<int>(config.PowerLimiter.VoltageStartThreshold * 100) / 100.0;
config.PowerLimiter.VoltageStopThreshold = root[F("voltage_stop_threshold")].as<float>(); config.PowerLimiter.VoltageStopThreshold = root["voltage_stop_threshold"].as<float>();
config.PowerLimiter.VoltageStopThreshold = static_cast<int>(config.PowerLimiter.VoltageStopThreshold * 100) / 100.0; config.PowerLimiter.VoltageStopThreshold = static_cast<int>(config.PowerLimiter.VoltageStopThreshold * 100) / 100.0;
config.PowerLimiter.VoltageLoadCorrectionFactor = root[F("voltage_load_correction_factor")].as<float>(); config.PowerLimiter.VoltageLoadCorrectionFactor = root["voltage_load_correction_factor"].as<float>();
config.PowerLimiter.RestartHour = root[F("inverter_restart_hour")].as<int8_t>(); config.PowerLimiter.RestartHour = root["inverter_restart_hour"].as<int8_t>();
config.PowerLimiter.FullSolarPassThroughSoc = root[F("full_solar_passthrough_soc")].as<uint32_t>(); config.PowerLimiter.FullSolarPassThroughSoc = root["full_solar_passthrough_soc"].as<uint32_t>();
config.PowerLimiter.FullSolarPassThroughStartVoltage = static_cast<int>(root[F("full_solar_passthrough_start_voltage")].as<float>() * 100) / 100.0; config.PowerLimiter.FullSolarPassThroughStartVoltage = static_cast<int>(root["full_solar_passthrough_start_voltage"].as<float>() * 100) / 100.0;
config.PowerLimiter.FullSolarPassThroughStopVoltage = static_cast<int>(root[F("full_solar_passthrough_stop_voltage")].as<float>() * 100) / 100.0; config.PowerLimiter.FullSolarPassThroughStopVoltage = static_cast<int>(root["full_solar_passthrough_stop_voltage"].as<float>() * 100) / 100.0;
@ -155,8 +155,8 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request)
PowerLimiter.calcNextInverterRestart(); PowerLimiter.calcNextInverterRestart();
retMsg[F("type")] = F("success"); retMsg["type"] = "success";
retMsg[F("message")] = F("Settings saved!"); retMsg["message"] = "Settings saved!";
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@ -38,32 +38,32 @@ void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
root[F("enabled")] = config.PowerMeter.Enabled; root["enabled"] = config.PowerMeter.Enabled;
root[F("verbose_logging")] = config.PowerMeter.VerboseLogging; root["verbose_logging"] = config.PowerMeter.VerboseLogging;
root[F("source")] = config.PowerMeter.Source; root["source"] = config.PowerMeter.Source;
root[F("interval")] = config.PowerMeter.Interval; root["interval"] = config.PowerMeter.Interval;
root[F("mqtt_topic_powermeter_1")] = config.PowerMeter.MqttTopicPowerMeter1; root["mqtt_topic_powermeter_1"] = config.PowerMeter.MqttTopicPowerMeter1;
root[F("mqtt_topic_powermeter_2")] = config.PowerMeter.MqttTopicPowerMeter2; root["mqtt_topic_powermeter_2"] = config.PowerMeter.MqttTopicPowerMeter2;
root[F("mqtt_topic_powermeter_3")] = config.PowerMeter.MqttTopicPowerMeter3; root["mqtt_topic_powermeter_3"] = config.PowerMeter.MqttTopicPowerMeter3;
root[F("sdmbaudrate")] = config.PowerMeter.SdmBaudrate; root["sdmbaudrate"] = config.PowerMeter.SdmBaudrate;
root[F("sdmaddress")] = config.PowerMeter.SdmAddress; root["sdmaddress"] = config.PowerMeter.SdmAddress;
root[F("http_individual_requests")] = config.PowerMeter.HttpIndividualRequests; root["http_individual_requests"] = config.PowerMeter.HttpIndividualRequests;
JsonArray httpPhases = root.createNestedArray(F("http_phases")); JsonArray httpPhases = root.createNestedArray("http_phases");
for (uint8_t i = 0; i < POWERMETER_MAX_PHASES; i++) { for (uint8_t i = 0; i < POWERMETER_MAX_PHASES; i++) {
JsonObject phaseObject = httpPhases.createNestedObject(); JsonObject phaseObject = httpPhases.createNestedObject();
phaseObject[F("index")] = i + 1; phaseObject["index"] = i + 1;
phaseObject[F("enabled")] = config.PowerMeter.Http_Phase[i].Enabled; phaseObject["enabled"] = config.PowerMeter.Http_Phase[i].Enabled;
phaseObject[F("url")] = String(config.PowerMeter.Http_Phase[i].Url); phaseObject["url"] = String(config.PowerMeter.Http_Phase[i].Url);
phaseObject[F("auth_type")]= config.PowerMeter.Http_Phase[i].AuthType; phaseObject["auth_type"]= config.PowerMeter.Http_Phase[i].AuthType;
phaseObject[F("username")] = String(config.PowerMeter.Http_Phase[i].Username); phaseObject["username"] = String(config.PowerMeter.Http_Phase[i].Username);
phaseObject[F("password")] = String(config.PowerMeter.Http_Phase[i].Password); phaseObject["password"] = String(config.PowerMeter.Http_Phase[i].Password);
phaseObject[F("header_key")] = String(config.PowerMeter.Http_Phase[i].HeaderKey); phaseObject["header_key"] = String(config.PowerMeter.Http_Phase[i].HeaderKey);
phaseObject[F("header_value")] = String(config.PowerMeter.Http_Phase[i].HeaderValue); phaseObject["header_value"] = String(config.PowerMeter.Http_Phase[i].HeaderValue);
phaseObject[F("json_path")] = String(config.PowerMeter.Http_Phase[i].JsonPath); phaseObject["json_path"] = String(config.PowerMeter.Http_Phase[i].JsonPath);
phaseObject[F("timeout")] = config.PowerMeter.Http_Phase[i].Timeout; phaseObject["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
} }
response->setLength(); response->setLength();
@ -87,10 +87,10 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject retMsg = response->getRoot(); JsonObject retMsg = response->getRoot();
retMsg[F("type")] = F("warning"); retMsg["type"] = "warning";
if (!request->hasParam("data", true)) { if (!request->hasParam("data", true)) {
retMsg[F("message")] = F("No values found!"); retMsg["message"] = "No values found!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -99,7 +99,7 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
String json = request->getParam("data", true)->value(); String json = request->getParam("data", true)->value();
if (json.length() > 4096) { if (json.length() > 4096) {
retMsg[F("message")] = F("Data too large!"); retMsg["message"] = "Data too large!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -109,49 +109,49 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
DeserializationError error = deserializeJson(root, json); DeserializationError error = deserializeJson(root, json);
if (error) { if (error) {
retMsg[F("message")] = F("Failed to parse data!"); retMsg["message"] = "Failed to parse data!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if (!(root.containsKey("enabled") && root.containsKey("source"))) { if (!(root.containsKey("enabled") && root.containsKey("source"))) {
retMsg[F("message")] = F("Values are missing!"); retMsg["message"] = "Values are missing!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if (root[F("source")].as<uint8_t>() == PowerMeter.SOURCE_HTTP) { if (root["source"].as<uint8_t>() == PowerMeter.SOURCE_HTTP) {
JsonArray http_phases = root[F("http_phases")]; JsonArray http_phases = root["http_phases"];
for (uint8_t i = 0; i < http_phases.size(); i++) { for (uint8_t i = 0; i < http_phases.size(); i++) {
JsonObject phase = http_phases[i].as<JsonObject>(); JsonObject phase = http_phases[i].as<JsonObject>();
if (i > 0 && !phase[F("enabled")].as<bool>()) { if (i > 0 && !phase["enabled"].as<bool>()) {
continue; continue;
} }
if (i == 0 || phase[F("http_individual_requests")].as<bool>()) { if (i == 0 || phase["http_individual_requests"].as<bool>()) {
if (!phase.containsKey("url") if (!phase.containsKey("url")
|| (!phase[F("url")].as<String>().startsWith("http://") || (!phase["url"].as<String>().startsWith("http://")
&& !phase[F("url")].as<String>().startsWith("https://"))) { && !phase["url"].as<String>().startsWith("https://"))) {
retMsg[F("message")] = F("URL must either start with http:// or https://!"); retMsg["message"] = "URL must either start with http:// or https://!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if ((phase[F("auth_type")].as<Auth>() != Auth::none) if ((phase["auth_type"].as<Auth>() != Auth::none)
&& ( phase[F("username")].as<String>().length() == 0 || phase[F("password")].as<String>().length() == 0)) { && ( phase["username"].as<String>().length() == 0 || phase["password"].as<String>().length() == 0)) {
retMsg[F("message")] = F("Username or password must not be empty!"); retMsg["message"] = "Username or password must not be empty!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
if (!phase.containsKey("timeout") if (!phase.containsKey("timeout")
|| phase[F("timeout")].as<uint16_t>() <= 0) { || phase["timeout"].as<uint16_t>() <= 0) {
retMsg[F("message")] = F("Timeout must be greater than 0 ms!"); retMsg["message"] = "Timeout must be greater than 0 ms!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -159,8 +159,8 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
} }
if (!phase.containsKey("json_path") if (!phase.containsKey("json_path")
|| phase[F("json_path")].as<String>().length() == 0) { || phase["json_path"].as<String>().length() == 0) {
retMsg[F("message")] = F("Json path must not be empty!"); retMsg["message"] = "Json path must not be empty!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -169,36 +169,36 @@ void WebApiPowerMeterClass::onAdminPost(AsyncWebServerRequest* request)
} }
CONFIG_T& config = Configuration.get(); CONFIG_T& config = Configuration.get();
config.PowerMeter.Enabled = root[F("enabled")].as<bool>(); config.PowerMeter.Enabled = root["enabled"].as<bool>();
config.PowerMeter.VerboseLogging = root[F("verbose_logging")].as<bool>(); config.PowerMeter.VerboseLogging = root["verbose_logging"].as<bool>();
config.PowerMeter.Source = root[F("source")].as<uint8_t>(); config.PowerMeter.Source = root["source"].as<uint8_t>();
config.PowerMeter.Interval = root[F("interval")].as<uint32_t>(); config.PowerMeter.Interval = root["interval"].as<uint32_t>();
strlcpy(config.PowerMeter.MqttTopicPowerMeter1, root[F("mqtt_topic_powermeter_1")].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter1)); strlcpy(config.PowerMeter.MqttTopicPowerMeter1, root["mqtt_topic_powermeter_1"].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter1));
strlcpy(config.PowerMeter.MqttTopicPowerMeter2, root[F("mqtt_topic_powermeter_2")].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter2)); strlcpy(config.PowerMeter.MqttTopicPowerMeter2, root["mqtt_topic_powermeter_2"].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter2));
strlcpy(config.PowerMeter.MqttTopicPowerMeter3, root[F("mqtt_topic_powermeter_3")].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter3)); strlcpy(config.PowerMeter.MqttTopicPowerMeter3, root["mqtt_topic_powermeter_3"].as<String>().c_str(), sizeof(config.PowerMeter.MqttTopicPowerMeter3));
config.PowerMeter.SdmBaudrate = root[F("sdmbaudrate")].as<uint32_t>(); config.PowerMeter.SdmBaudrate = root["sdmbaudrate"].as<uint32_t>();
config.PowerMeter.SdmAddress = root[F("sdmaddress")].as<uint8_t>(); config.PowerMeter.SdmAddress = root["sdmaddress"].as<uint8_t>();
config.PowerMeter.HttpIndividualRequests = root[F("http_individual_requests")].as<bool>(); config.PowerMeter.HttpIndividualRequests = root["http_individual_requests"].as<bool>();
JsonArray http_phases = root[F("http_phases")]; JsonArray http_phases = root["http_phases"];
for (uint8_t i = 0; i < http_phases.size(); i++) { for (uint8_t i = 0; i < http_phases.size(); i++) {
JsonObject phase = http_phases[i].as<JsonObject>(); JsonObject phase = http_phases[i].as<JsonObject>();
config.PowerMeter.Http_Phase[i].Enabled = (i == 0 ? true : phase[F("enabled")].as<bool>()); config.PowerMeter.Http_Phase[i].Enabled = (i == 0 ? true : phase["enabled"].as<bool>());
strlcpy(config.PowerMeter.Http_Phase[i].Url, phase[F("url")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Url)); strlcpy(config.PowerMeter.Http_Phase[i].Url, phase["url"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Url));
config.PowerMeter.Http_Phase[i].AuthType = phase[F("auth_type")].as<Auth>(); config.PowerMeter.Http_Phase[i].AuthType = phase["auth_type"].as<Auth>();
strlcpy(config.PowerMeter.Http_Phase[i].Username, phase[F("username")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Username)); strlcpy(config.PowerMeter.Http_Phase[i].Username, phase["username"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Username));
strlcpy(config.PowerMeter.Http_Phase[i].Password, phase[F("password")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Password)); strlcpy(config.PowerMeter.Http_Phase[i].Password, phase["password"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].Password));
strlcpy(config.PowerMeter.Http_Phase[i].HeaderKey, phase[F("header_key")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].HeaderKey)); strlcpy(config.PowerMeter.Http_Phase[i].HeaderKey, phase["header_key"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].HeaderKey));
strlcpy(config.PowerMeter.Http_Phase[i].HeaderValue, phase[F("header_value")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].HeaderValue)); strlcpy(config.PowerMeter.Http_Phase[i].HeaderValue, phase["header_value"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].HeaderValue));
config.PowerMeter.Http_Phase[i].Timeout = phase[F("timeout")].as<uint16_t>(); config.PowerMeter.Http_Phase[i].Timeout = phase["timeout"].as<uint16_t>();
strlcpy(config.PowerMeter.Http_Phase[i].JsonPath, phase[F("json_path")].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].JsonPath)); strlcpy(config.PowerMeter.Http_Phase[i].JsonPath, phase["json_path"].as<String>().c_str(), sizeof(config.PowerMeter.Http_Phase[i].JsonPath));
} }
Configuration.write(); Configuration.write();
retMsg[F("type")] = F("success"); retMsg["type"] = "success";
retMsg[F("message")] = F("Settings saved!"); retMsg["message"] = "Settings saved!";
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -217,10 +217,10 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
AsyncJsonResponse* asyncJsonResponse = new AsyncJsonResponse(); AsyncJsonResponse* asyncJsonResponse = new AsyncJsonResponse();
JsonObject retMsg = asyncJsonResponse->getRoot(); JsonObject retMsg = asyncJsonResponse->getRoot();
retMsg[F("type")] = F("warning"); retMsg["type"] = "warning";
if (!request->hasParam("data", true)) { if (!request->hasParam("data", true)) {
retMsg[F("message")] = F("No values found!"); retMsg["message"] = "No values found!";
asyncJsonResponse->setLength(); asyncJsonResponse->setLength();
request->send(asyncJsonResponse); request->send(asyncJsonResponse);
return; return;
@ -229,7 +229,7 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
String json = request->getParam("data", true)->value(); String json = request->getParam("data", true)->value();
if (json.length() > 2048) { if (json.length() > 2048) {
retMsg[F("message")] = F("Data too large!"); retMsg["message"] = "Data too large!";
asyncJsonResponse->setLength(); asyncJsonResponse->setLength();
request->send(asyncJsonResponse); request->send(asyncJsonResponse);
return; return;
@ -239,7 +239,7 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
DeserializationError error = deserializeJson(root, json); DeserializationError error = deserializeJson(root, json);
if (error) { if (error) {
retMsg[F("message")] = F("Failed to parse data!"); retMsg["message"] = "Failed to parse data!";
asyncJsonResponse->setLength(); asyncJsonResponse->setLength();
request->send(asyncJsonResponse); request->send(asyncJsonResponse);
return; return;
@ -248,7 +248,7 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
if (!root.containsKey("url") || !root.containsKey("auth_type") || !root.containsKey("username") || !root.containsKey("password") if (!root.containsKey("url") || !root.containsKey("auth_type") || !root.containsKey("username") || !root.containsKey("password")
|| !root.containsKey("header_key") || !root.containsKey("header_value") || !root.containsKey("header_key") || !root.containsKey("header_value")
|| !root.containsKey("timeout") || !root.containsKey("json_path")) { || !root.containsKey("timeout") || !root.containsKey("json_path")) {
retMsg[F("message")] = F("Missing fields!"); retMsg["message"] = "Missing fields!";
asyncJsonResponse->setLength(); asyncJsonResponse->setLength();
request->send(asyncJsonResponse); request->send(asyncJsonResponse);
return; return;
@ -258,15 +258,15 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
errorMessage[256]; errorMessage[256];
char response[200]; char response[200];
if (HttpPowerMeter.httpRequest(root[F("url")].as<String>().c_str(), if (HttpPowerMeter.httpRequest(root["url"].as<String>().c_str(),
root[F("auth_type")].as<Auth>(), root[F("username")].as<String>().c_str(), root[F("password")].as<String>().c_str(), root["auth_type"].as<Auth>(), root["username"].as<String>().c_str(), root["password"].as<String>().c_str(),
root[F("header_key")].as<String>().c_str(), root[F("header_value")].as<String>().c_str(), root[F("timeout")].as<uint16_t>(), root["header_key"].as<String>().c_str(), root["header_value"].as<String>().c_str(), root["timeout"].as<uint16_t>(),
powerMeterResponse, sizeof(powerMeterResponse), errorMessage, sizeof(errorMessage))) { powerMeterResponse, sizeof(powerMeterResponse), errorMessage, sizeof(errorMessage))) {
float power; float power;
if (HttpPowerMeter.getFloatValueByJsonPath(powerMeterResponse, if (HttpPowerMeter.getFloatValueByJsonPath(powerMeterResponse,
root[F("json_path")].as<String>().c_str(), power)) { root["json_path"].as<String>().c_str(), power)) {
retMsg[F("type")] = F("success"); retMsg["type"] = "success";
snprintf_P(response, sizeof(response), "Success! Power: %5.2fW", power); snprintf_P(response, sizeof(response), "Success! Power: %5.2fW", power);
} else { } else {
snprintf_P(response, sizeof(response), "Error: Could not find value for JSON path!"); snprintf_P(response, sizeof(response), "Error: Could not find value for JSON path!");
@ -275,7 +275,7 @@ void WebApiPowerMeterClass::onTestHttpRequest(AsyncWebServerRequest* request)
snprintf_P(response, sizeof(response), errorMessage); snprintf_P(response, sizeof(response), errorMessage);
} }
retMsg[F("message")] = F(response); retMsg["message"] = response;
asyncJsonResponse->setLength(); asyncJsonResponse->setLength();
request->send(asyncJsonResponse); request->send(asyncJsonResponse);
} }

View File

@ -36,9 +36,9 @@ void WebApiVedirectClass::onVedirectStatus(AsyncWebServerRequest* request)
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
root[F("vedirect_enabled")] = config.Vedirect.Enabled; root["vedirect_enabled"] = config.Vedirect.Enabled;
root[F("verbose_logging")] = config.Vedirect.VerboseLogging; root["verbose_logging"] = config.Vedirect.VerboseLogging;
root[F("vedirect_updatesonly")] = config.Vedirect.UpdatesOnly; root["vedirect_updatesonly"] = config.Vedirect.UpdatesOnly;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -54,9 +54,9 @@ void WebApiVedirectClass::onVedirectAdminGet(AsyncWebServerRequest* request)
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
root[F("vedirect_enabled")] = config.Vedirect.Enabled; root["vedirect_enabled"] = config.Vedirect.Enabled;
root[F("verbose_logging")] = config.Vedirect.VerboseLogging; root["verbose_logging"] = config.Vedirect.VerboseLogging;
root[F("vedirect_updatesonly")] = config.Vedirect.UpdatesOnly; root["vedirect_updatesonly"] = config.Vedirect.UpdatesOnly;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -70,11 +70,11 @@ void WebApiVedirectClass::onVedirectAdminPost(AsyncWebServerRequest* request)
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
JsonObject retMsg = response->getRoot(); JsonObject retMsg = response->getRoot();
retMsg[F("type")] = F("warning"); retMsg["type"] = "warning";
if (!request->hasParam("data", true)) { if (!request->hasParam("data", true)) {
retMsg[F("message")] = F("No values found!"); retMsg["message"] = "No values found!";
retMsg[F("code")] = WebApiError::GenericNoValueFound; retMsg["code"] = WebApiError::GenericNoValueFound;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -83,8 +83,8 @@ void WebApiVedirectClass::onVedirectAdminPost(AsyncWebServerRequest* request)
String json = request->getParam("data", true)->value(); String json = request->getParam("data", true)->value();
if (json.length() > 1024) { if (json.length() > 1024) {
retMsg[F("message")] = F("Data too large!"); retMsg["message"] = "Data too large!";
retMsg[F("code")] = WebApiError::GenericDataTooLarge; retMsg["code"] = WebApiError::GenericDataTooLarge;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -94,8 +94,8 @@ void WebApiVedirectClass::onVedirectAdminPost(AsyncWebServerRequest* request)
DeserializationError error = deserializeJson(root, json); DeserializationError error = deserializeJson(root, json);
if (error) { if (error) {
retMsg[F("message")] = F("Failed to parse data!"); retMsg["message"] = "Failed to parse data!";
retMsg[F("code")] = WebApiError::GenericParseError; retMsg["code"] = WebApiError::GenericParseError;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
@ -104,24 +104,24 @@ void WebApiVedirectClass::onVedirectAdminPost(AsyncWebServerRequest* request)
if (!root.containsKey("vedirect_enabled") || if (!root.containsKey("vedirect_enabled") ||
!root.containsKey("verbose_logging") || !root.containsKey("verbose_logging") ||
!root.containsKey("vedirect_updatesonly") ) { !root.containsKey("vedirect_updatesonly") ) {
retMsg[F("message")] = F("Values are missing!"); retMsg["message"] = "Values are missing!";
retMsg[F("code")] = WebApiError::GenericValueMissing; retMsg["code"] = WebApiError::GenericValueMissing;
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
CONFIG_T& config = Configuration.get(); CONFIG_T& config = Configuration.get();
config.Vedirect.Enabled = root[F("vedirect_enabled")].as<bool>(); config.Vedirect.Enabled = root["vedirect_enabled"].as<bool>();
config.Vedirect.VerboseLogging = root[F("verbose_logging")].as<bool>(); config.Vedirect.VerboseLogging = root["verbose_logging"].as<bool>();
config.Vedirect.UpdatesOnly = root[F("vedirect_updatesonly")].as<bool>(); config.Vedirect.UpdatesOnly = root["vedirect_updatesonly"].as<bool>();
Configuration.write(); Configuration.write();
VictronMppt.updateSettings(); VictronMppt.updateSettings();
retMsg[F("type")] = F("success"); retMsg["type"] = "success";
retMsg[F("message")] = F("Settings saved!"); retMsg["message"] = "Settings saved!";
retMsg[F("code")] = WebApiError::GenericSuccess; retMsg["code"] = WebApiError::GenericSuccess;
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@ -78,26 +78,26 @@ void WebApiWsHuaweiLiveClass::generateJsonResponse(JsonVariant& root)
const RectifierParameters_t * rp = HuaweiCan.get(); const RectifierParameters_t * rp = HuaweiCan.get();
root["data_age"] = (millis() - HuaweiCan.getLastUpdate()) / 1000; root["data_age"] = (millis() - HuaweiCan.getLastUpdate()) / 1000;
root[F("input_voltage")]["v"] = rp->input_voltage; root["input_voltage"]["v"] = rp->input_voltage;
root[F("input_voltage")]["u"] = "V"; root["input_voltage"]["u"] = "V";
root[F("input_current")]["v"] = rp->input_current; root["input_current"]["v"] = rp->input_current;
root[F("input_current")]["u"] = "A"; root["input_current"]["u"] = "A";
root[F("input_power")]["v"] = rp->input_power; root["input_power"]["v"] = rp->input_power;
root[F("input_power")]["u"] = "W"; root["input_power"]["u"] = "W";
root[F("output_voltage")]["v"] = rp->output_voltage; root["output_voltage"]["v"] = rp->output_voltage;
root[F("output_voltage")]["u"] = "V"; root["output_voltage"]["u"] = "V";
root[F("output_current")]["v"] = rp->output_current; root["output_current"]["v"] = rp->output_current;
root[F("output_current")]["u"] = "A"; root["output_current"]["u"] = "A";
root[F("max_output_current")]["v"] = rp->max_output_current; root["max_output_current"]["v"] = rp->max_output_current;
root[F("max_output_current")]["u"] = "A"; root["max_output_current"]["u"] = "A";
root[F("output_power")]["v"] = rp->output_power; root["output_power"]["v"] = rp->output_power;
root[F("output_power")]["u"] = "W"; root["output_power"]["u"] = "W";
root[F("input_temp")]["v"] = rp->input_temp; root["input_temp"]["v"] = rp->input_temp;
root[F("input_temp")]["u"] = "°C"; root["input_temp"]["u"] = "°C";
root[F("output_temp")]["v"] = rp->output_temp; root["output_temp"]["v"] = rp->output_temp;
root[F("output_temp")]["u"] = "°C"; root["output_temp"]["u"] = "°C";
root[F("efficiency")]["v"] = rp->efficiency * 100; root["efficiency"]["v"] = rp->efficiency * 100;
root[F("efficiency")]["u"] = "%"; root["efficiency"]["u"] = "%";
} }

View File

@ -184,7 +184,7 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
} }
JsonObject vedirectObj = root.createNestedObject("vedirect"); JsonObject vedirectObj = root.createNestedObject("vedirect");
vedirectObj[F("enabled")] = Configuration.get().Vedirect.Enabled; vedirectObj["enabled"] = Configuration.get().Vedirect.Enabled;
JsonObject totalVeObj = vedirectObj.createNestedObject("total"); JsonObject totalVeObj = vedirectObj.createNestedObject("total");
addTotalField(totalVeObj, "Power", VictronMppt.getPanelPowerWatts(), "W", 1); addTotalField(totalVeObj, "Power", VictronMppt.getPanelPowerWatts(), "W", 1);
@ -192,16 +192,16 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
addTotalField(totalVeObj, "YieldTotal", VictronMppt.getYieldTotal(), "kWh", 2); addTotalField(totalVeObj, "YieldTotal", VictronMppt.getYieldTotal(), "kWh", 2);
JsonObject huaweiObj = root.createNestedObject("huawei"); JsonObject huaweiObj = root.createNestedObject("huawei");
huaweiObj[F("enabled")] = Configuration.get().Huawei.Enabled; huaweiObj["enabled"] = Configuration.get().Huawei.Enabled;
const RectifierParameters_t * rp = HuaweiCan.get(); const RectifierParameters_t * rp = HuaweiCan.get();
addTotalField(huaweiObj, "Power", rp->output_power, "W", 2); addTotalField(huaweiObj, "Power", rp->output_power, "W", 2);
JsonObject batteryObj = root.createNestedObject("battery"); JsonObject batteryObj = root.createNestedObject("battery");
batteryObj[F("enabled")] = Configuration.get().Battery.Enabled; batteryObj["enabled"] = Configuration.get().Battery.Enabled;
addTotalField(batteryObj, "soc", Battery.getStats()->getSoC(), "%", 0); addTotalField(batteryObj, "soc", Battery.getStats()->getSoC(), "%", 0);
JsonObject powerMeterObj = root.createNestedObject("power_meter"); JsonObject powerMeterObj = root.createNestedObject("power_meter");
powerMeterObj[F("enabled")] = Configuration.get().PowerMeter.Enabled; powerMeterObj["enabled"] = Configuration.get().PowerMeter.Enabled;
addTotalField(powerMeterObj, "Power", PowerMeter.getPowerTotal(false), "W", 1); addTotalField(powerMeterObj, "Power", PowerMeter.getPowerTotal(false), "W", 1);
} }