Wifi settings for common image

This commit is contained in:
Jaakko Haakana 2025-07-11 15:10:16 +03:00
parent 0b73436d3d
commit 5d86058852
9 changed files with 254 additions and 384 deletions

View file

@ -16,6 +16,10 @@
#include "../utils/timer.h"
#include "esp_task_wdt.h"
#include <string>
extern std::string http_username;
extern std::string http_password;
void transmit_can_frame(CAN_frame* tx_frame, int interface);
#ifdef WEBSERVER
@ -26,6 +30,14 @@ const bool webserver_enabled_default = false;
bool webserver_enabled = webserver_enabled_default; // Global flag to enable or disable the webserver
#ifndef COMMON_IMAGE
const bool webserver_auth_default = WEBSERVER_AUTH_REQUIRED;
#else
const bool webserver_auth_default = false;
#endif
bool webserver_auth = webserver_auth_default;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
@ -167,30 +179,31 @@ void canReplayTask(void* param) {
vTaskDelete(NULL);
}
void def_route_with_auth(const char* uri, AsyncWebServer& serv, WebRequestMethodComposite method,
std::function<void(AsyncWebServerRequest*)> handler) {
serv.on(uri, method, [handler](AsyncWebServerRequest* request) {
if (webserver_auth && !request->authenticate(http_username.c_str(), http_password.c_str())) {
return request->requestAuthentication();
}
handler(request);
});
}
void init_webserver() {
server.on("/logout", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(401); });
// Route for firmware info from ota update page
server.on("/GetFirmwareInfo", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/GetFirmwareInfo", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(200, "application/json", get_firmware_info_html, get_firmware_info_processor);
});
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
request->send(200, "text/html", index_html, processor);
});
def_route_with_auth("/", server, HTTP_GET,
[](AsyncWebServerRequest* request) { request->send(200, "text/html", index_html, processor); });
// Route for going to settings web page
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) {
return request->requestAuthentication();
}
def_route_with_auth("/settings", server, HTTP_GET, [](AsyncWebServerRequest* request) {
// Using make_shared to ensure lifetime for the settings object during send() lambda execution
auto settings = std::make_shared<BatteryEmulatorSettingsStore>(true);
@ -199,30 +212,21 @@ void init_webserver() {
});
// Route for going to advanced battery info web page
server.on("/advanced", HTTP_GET, [](AsyncWebServerRequest* request) {
def_route_with_auth("/advanced", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(200, "text/html", index_html, advanced_battery_processor);
});
// Route for going to CAN logging web page
server.on("/canlog", HTTP_GET, [](AsyncWebServerRequest* request) {
AsyncWebServerResponse* response = request->beginResponse(200, "text/html", can_logger_processor());
request->send(response);
def_route_with_auth("/canlog", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(request->beginResponse(200, "text/html", can_logger_processor()));
});
// Route for going to CAN replay web page
server.on("/canreplay", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) {
return request->requestAuthentication();
}
AsyncWebServerResponse* response = request->beginResponse(200, "text/html", can_replay_processor());
request->send(response);
def_route_with_auth("/canreplay", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(request->beginResponse(200, "text/html", can_replay_processor()));
});
server.on("/startReplay", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) {
return request->requestAuthentication();
}
def_route_with_auth("/startReplay", server, HTTP_GET, [](AsyncWebServerRequest* request) {
// Prevent multiple replay tasks from being created
if (isReplayRunning) {
request->send(400, "text/plain", "Replay already running!");
@ -238,18 +242,14 @@ void init_webserver() {
});
// Route for stopping the CAN replay
server.on("/stopReplay", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) {
return request->requestAuthentication();
}
def_route_with_auth("/stopReplay", server, HTTP_GET, [](AsyncWebServerRequest* request) {
datalayer.system.info.loop_playback = false;
request->send(200, "text/plain", "CAN replay stopped!");
});
// Route to handle setting the CAN interface for CAN replay
server.on("/setCANInterface", HTTP_GET, [](AsyncWebServerRequest* request) {
def_route_with_auth("/setCANInterface", server, HTTP_GET, [](AsyncWebServerRequest* request) {
if (request->hasParam("interface")) {
String canInterface = request->getParam("interface")->value();
@ -377,23 +377,17 @@ void init_webserver() {
#endif
// Route for going to cellmonitor web page
server.on("/cellmonitor", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/cellmonitor", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(200, "text/html", index_html, cellmonitor_processor);
});
// Route for going to event log web page
server.on("/events", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/events", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(200, "text/html", index_html, events_processor);
});
// Route for clearing all events
server.on("/clearevents", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/clearevents", server, HTTP_GET, [](AsyncWebServerRequest* request) {
reset_all_events();
// Send back a response that includes an instant redirect to /events
String response = "<html><body>";
@ -402,6 +396,14 @@ void init_webserver() {
request->send(200, "text/html", response);
});
def_route_with_auth("/factoryReset", server, HTTP_POST, [](AsyncWebServerRequest* request) {
// Reset all settings to factory defaults
BatteryEmulatorSettingsStore settings;
settings.clearAll();
request->send(200, "text/html", "OK");
});
#ifdef COMMON_IMAGE
struct BoolSetting {
const char* name;
@ -421,7 +423,7 @@ void init_webserver() {
std::vector<BoolSetting> boolSettings;
for (auto& name : boolSettingNames) {
boolSettings.push_back({name, settings.getBool(name), false});
boolSettings.push_back({name, settings.getBool(name, name == std::string("WIFIAPENABLED")), false});
}
int numParams = request->params();
@ -495,10 +497,7 @@ void init_webserver() {
#endif
// Route for editing SSID
server.on("/updateSSID", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/updateSSID", server, HTTP_GET, [](AsyncWebServerRequest* request) {
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
if (value.length() <= 63) { // Check if SSID is within the allowable length
@ -513,9 +512,7 @@ void init_webserver() {
}
});
// Route for editing Password
server.on("/updatePassword", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/updatePassword", server, HTTP_GET, [](AsyncWebServerRequest* request) {
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
if (value.length() > 8) { // Check if password is within the allowable length
@ -530,118 +527,84 @@ void init_webserver() {
}
});
auto update_string = [](const char* route, std::function<void(String)> setter,
std::function<bool(String)> validator = nullptr) {
def_route_with_auth(route, server, HTTP_GET, [&](AsyncWebServerRequest* request) {
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
if (validator && !validator(value)) {
request->send(400, "text/plain", "Invalid value");
return;
}
setter(value);
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
};
auto update_string_setting = [=](const char* route, std::function<void(String)> setter,
std::function<bool(String)> validator = nullptr) {
update_string(
route,
[setter](String value) {
setter(value);
store_settings();
},
validator);
};
auto update_int_setting = [=](const char* route, std::function<void(int)> setter) {
update_string_setting(route, [setter](String value) { setter(value.toInt()); });
};
// Route for editing Wh
server.on("/updateBatterySize", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.info.total_capacity_Wh = value.toInt();
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/updateBatterySize", [](int value) { datalayer.battery.info.total_capacity_Wh = value; });
// Route for editing USE_SCALED_SOC
server.on("/updateUseScaledSOC", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.soc_scaling_active = value.toInt();
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/updateUseScaledSOC", [](int value) { datalayer.battery.settings.soc_scaling_active = value; });
// Route for editing SOCMax
server.on("/updateSocMax", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.max_percentage = static_cast<uint16_t>(value.toFloat() * 100);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateSocMax", [](String value) {
datalayer.battery.settings.max_percentage = static_cast<uint16_t>(value.toFloat() * 100);
});
// Route for pause/resume Battery emulator
server.on("/pause", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("p")) {
String valueStr = request->getParam("p")->value();
setBatteryPause(valueStr == "true" || valueStr == "1", false);
request->send(200, "text/plain", "Updated successfully");
update_string("/pause", [](String value) { setBatteryPause(value == "true" || value == "1", false); });
// Route for equipment stop/resume
update_string("/equipmentStop", [](String value) {
if (value == "true" || value == "1") {
setBatteryPause(true, false, true); //Pause battery, do not pause CAN, equipment stop on (store to flash)
} else {
request->send(400, "text/plain", "Bad Request");
setBatteryPause(false, false, false);
}
});
// Route for equipment stop/resume
server.on("/equipmentStop", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("stop")) {
String valueStr = request->getParam("stop")->value();
if (valueStr == "true" || valueStr == "1") {
setBatteryPause(true, false, true); //Pause battery, do not pause CAN, equipment stop on (store to flash)
} else {
setBatteryPause(false, false, false);
}
request->send(200, "text/plain", "Updated successfully");
update_string("/equipmentStop", [](String value) {
if (value == "true" || value == "1") {
setBatteryPause(true, false, true); //Pause battery, do not pause CAN, equipment stop on (store to flash)
} else {
request->send(400, "text/plain", "Bad Request");
setBatteryPause(false, false, false);
}
});
// Route for editing SOCMin
server.on("/updateSocMin", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.min_percentage = static_cast<uint16_t>(value.toFloat() * 100);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateSocMin", [](String value) {
datalayer.battery.settings.min_percentage = static_cast<uint16_t>(value.toFloat() * 100);
});
// Route for editing MaxChargeA
server.on("/updateMaxChargeA", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.max_user_set_charge_dA = static_cast<uint16_t>(value.toFloat() * 10);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateMaxChargeA", [](String value) {
datalayer.battery.settings.max_user_set_charge_dA = static_cast<uint16_t>(value.toFloat() * 10);
});
// Route for editing MaxDischargeA
server.on("/updateMaxDischargeA", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.max_user_set_discharge_dA = static_cast<uint16_t>(value.toFloat() * 10);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateMaxDischargeA", [](String value) {
datalayer.battery.settings.max_user_set_discharge_dA = static_cast<uint16_t>(value.toFloat() * 10);
});
for (const auto& cmd : battery_commands) {
@ -649,7 +612,7 @@ void init_webserver() {
server.on(
route.c_str(), HTTP_PUT,
[cmd](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password)) {
if (webserver_auth && !request->authenticate(http_username.c_str(), http_password.c_str())) {
return request->requestAuthentication();
}
},
@ -671,247 +634,88 @@ void init_webserver() {
}
// Route for editing BATTERY_USE_VOLTAGE_LIMITS
server.on("/updateUseVoltageLimit", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.user_set_voltage_limits_active = value.toInt();
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/updateUseVoltageLimit",
[](int value) { datalayer.battery.settings.user_set_voltage_limits_active = value; });
// Route for editing MaxChargeVoltage
server.on("/updateMaxChargeVoltage", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.max_user_set_charge_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateMaxChargeVoltage", [](String value) {
datalayer.battery.settings.max_user_set_charge_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
});
// Route for editing MaxDischargeVoltage
server.on("/updateMaxDischargeVoltage", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.max_user_set_discharge_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/updateMaxDischargeVoltage", [](String value) {
datalayer.battery.settings.max_user_set_discharge_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
});
// Route for editing FakeBatteryVoltage
server.on("/updateFakeBatteryVoltage", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (!request->hasParam("value")) {
request->send(400, "text/plain", "Bad Request");
}
String value = request->getParam("value")->value();
float val = value.toFloat();
battery->set_fake_voltage(val);
request->send(200, "text/plain", "Updated successfully");
});
update_string_setting("/updateFakeBatteryVoltage", [](String value) { battery->set_fake_voltage(value.toFloat()); });
// Route for editing balancing enabled
server.on("/TeslaBalAct", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.user_requests_balancing = value.toInt();
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/TeslaBalAct", [](int value) { datalayer.battery.settings.user_requests_balancing = value; });
// Route for editing balancing max time
server.on("/BalTime", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.balancing_time_ms = static_cast<uint32_t>(value.toFloat() * 60000);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/BalTime", [](String value) {
datalayer.battery.settings.balancing_time_ms = static_cast<uint32_t>(value.toFloat() * 60000);
});
// Route for editing balancing max power
server.on("/BalFloatPower", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.balancing_float_power_W = static_cast<uint16_t>(value.toFloat());
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/BalFloatPower", [](String value) {
datalayer.battery.settings.balancing_float_power_W = static_cast<uint16_t>(value.toFloat());
});
// Route for editing balancing max pack voltage
server.on("/BalMaxPackV", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.balancing_max_pack_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/BalMaxPackV", [](String value) {
datalayer.battery.settings.balancing_max_pack_voltage_dV = static_cast<uint16_t>(value.toFloat() * 10);
});
// Route for editing balancing max cell voltage
server.on("/BalMaxCellV", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.balancing_max_cell_voltage_mV = static_cast<uint16_t>(value.toFloat());
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/BalMaxCellV", [](String value) {
datalayer.battery.settings.balancing_max_cell_voltage_mV = static_cast<uint16_t>(value.toFloat());
});
// Route for editing balancing max cell voltage deviation
server.on("/BalMaxDevCellV", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.battery.settings.balancing_max_deviation_cell_voltage_mV = static_cast<uint16_t>(value.toFloat());
store_settings();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
update_string_setting("/BalMaxDevCellV", [](String value) {
datalayer.battery.settings.balancing_max_deviation_cell_voltage_mV = static_cast<uint16_t>(value.toFloat());
});
if (charger) {
// Route for editing ChargerTargetV
server.on("/updateChargeSetpointV", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (!request->hasParam("value")) {
request->send(400, "text/plain", "Bad Request");
}
String value = request->getParam("value")->value();
float val = value.toFloat();
if (!(val <= CHARGER_MAX_HV && val >= CHARGER_MIN_HV)) {
request->send(400, "text/plain", "Bad Request");
}
if (!(val * datalayer.charger.charger_setpoint_HV_IDC <= CHARGER_MAX_POWER)) {
request->send(400, "text/plain", "Bad Request");
}
datalayer.charger.charger_setpoint_HV_VDC = val;
request->send(200, "text/plain", "Updated successfully");
});
update_string_setting(
"/updateChargeSetpointV", [](String value) { datalayer.charger.charger_setpoint_HV_VDC = value.toFloat(); },
[](String value) {
float val = value.toFloat();
return (val <= CHARGER_MAX_HV && val >= CHARGER_MIN_HV) &&
(val * datalayer.charger.charger_setpoint_HV_IDC <= CHARGER_MAX_POWER);
});
// Route for editing ChargerTargetA
server.on("/updateChargeSetpointA", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (!request->hasParam("value")) {
request->send(400, "text/plain", "Bad Request");
}
String value = request->getParam("value")->value();
float val = value.toFloat();
if (!(val <= datalayer.battery.settings.max_user_set_charge_dA && val <= CHARGER_MAX_A)) {
request->send(400, "text/plain", "Bad Request");
}
if (!(val * datalayer.charger.charger_setpoint_HV_VDC <= CHARGER_MAX_POWER)) {
request->send(400, "text/plain", "Bad Request");
}
datalayer.charger.charger_setpoint_HV_IDC = value.toFloat();
request->send(200, "text/plain", "Updated successfully");
});
update_string_setting(
"/updateChargeSetpointA", [](String value) { datalayer.charger.charger_setpoint_HV_IDC = value.toFloat(); },
[](String value) {
float val = value.toFloat();
return (val <= CHARGER_MAX_A) && (val <= datalayer.battery.settings.max_user_set_charge_dA) &&
(val * datalayer.charger.charger_setpoint_HV_VDC <= CHARGER_MAX_POWER);
});
// Route for editing ChargerEndA
server.on("/updateChargeEndA", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.charger.charger_setpoint_HV_IDC_END = value.toFloat();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_string_setting("/updateChargeEndA",
[](String value) { datalayer.charger.charger_setpoint_HV_IDC_END = value.toFloat(); });
// Route for enabling/disabling HV charger
server.on("/updateChargerHvEnabled", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.charger.charger_HV_enabled = (bool)value.toInt();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/updateChargerHvEnabled",
[](int value) { datalayer.charger.charger_HV_enabled = (bool)value; });
// Route for enabling/disabling aux12v charger
server.on("/updateChargerAux12vEnabled", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
if (request->hasParam("value")) {
String value = request->getParam("value")->value();
datalayer.charger.charger_aux12V_enabled = (bool)value.toInt();
request->send(200, "text/plain", "Updated successfully");
} else {
request->send(400, "text/plain", "Bad Request");
}
});
update_int_setting("/updateChargerAux12vEnabled",
[](int value) { datalayer.charger.charger_aux12V_enabled = (bool)value; });
}
// Send a GET request to <ESP_IP>/update
server.on("/debug", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
request->send(200, "text/plain", "Debug: all OK.");
});
def_route_with_auth("/debug", server, HTTP_GET,
[](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Debug: all OK."); });
// Route to handle reboot command
server.on("/reboot", HTTP_GET, [](AsyncWebServerRequest* request) {
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
return request->requestAuthentication();
def_route_with_auth("/reboot", server, HTTP_GET, [](AsyncWebServerRequest* request) {
request->send(200, "text/plain", "Rebooting server...");
//Equipment STOP without persisting the equipment state before restart
@ -995,7 +799,7 @@ String processor(const String& var) {
content += "</style>";
// Compact header
content += "<h2>" + String(ssidAP) + "</h2>";
content += "<h2>" + String(ssidAP.c_str()) + "</h2>";
// Start content block
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px; border-radius: 50px'>";
@ -1551,7 +1355,7 @@ String processor(const String& var) {
content += "<button onclick='Cellmon()'>Cellmonitor</button> ";
content += "<button onclick='Events()'>Events</button> ";
content += "<button onclick='askReboot()'>Reboot Emulator</button>";
if (WEBSERVER_AUTH_REQUIRED)
if (webserver_auth)
content += "<button onclick='logout()'>Logout</button>";
if (!datalayer.system.settings.equipment_stop_active)
content +=
@ -1577,7 +1381,7 @@ String processor(const String& var) {
content += "function CANreplay() { window.location.href = '/canreplay'; }";
content += "function Log() { window.location.href = '/log'; }";
content += "function Events() { window.location.href = '/events'; }";
if (WEBSERVER_AUTH_REQUIRED) {
if (webserver_auth) {
content += "function logout() {";
content += " var xhr = new XMLHttpRequest();";
content += " xhr.open('GET', '/logout', true);";
@ -1589,7 +1393,7 @@ String processor(const String& var) {
content +=
"var xhr=new "
"XMLHttpRequest();xhr.onload=function() { "
"window.location.reload();};xhr.open('GET','/pause?p='+pause,true);xhr.send();";
"window.location.reload();};xhr.open('GET','/pause?value='+pause,true);xhr.send();";
content += "}";
content += "function estop(stop){";
content +=