mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Wifi settings for common image
This commit is contained in:
parent
0b73436d3d
commit
5d86058852
9 changed files with 254 additions and 384 deletions
|
@ -21,14 +21,26 @@ volatile CAN_Configuration can_config = {
|
|||
.shunt = CAN_NATIVE // (OPTIONAL) Which CAN is your shunt connected to?
|
||||
};
|
||||
|
||||
#ifdef COMMON_IMAGE
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
std::string passwordAP;
|
||||
#else
|
||||
std::string ssid = WIFI_SSID; // Set in USER_SECRETS.h
|
||||
std::string password = WIFI_PASSWORD; // Set in USER_SECRETS.h
|
||||
const char* ssidAP = "Battery Emulator"; // Maximum of 63 characters, also used for device name on web interface
|
||||
const char* passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h
|
||||
std::string passwordAP = AP_PASSWORD; // Set in USER_SECRETS.h
|
||||
#endif
|
||||
|
||||
const uint8_t wifi_channel = 0; // Set to 0 for automatic channel selection
|
||||
|
||||
const char* http_username = HTTP_USERNAME; // Set in USER_SECRETS.h
|
||||
const char* http_password = HTTP_PASSWORD; // Set in USER_SECRETS.h
|
||||
#ifdef COMMON_IMAGE
|
||||
std::string http_username;
|
||||
std::string http_password;
|
||||
#else
|
||||
std::string http_username = HTTP_USERNAME; // Set in USER_SECRETS.h
|
||||
std::string http_password = HTTP_PASSWORD; // Set in USER_SECRETS.h
|
||||
#endif
|
||||
|
||||
// Set your Static IP address. Only used incase WIFICONFIG is set in USER_SETTINGS.h
|
||||
IPAddress local_IP(192, 168, 10, 150);
|
||||
IPAddress gateway(192, 168, 10, 1);
|
||||
|
|
|
@ -51,6 +51,8 @@ ACAN2517FDSettings* settings2517;
|
|||
|
||||
// Initialization functions
|
||||
|
||||
bool native_can_initialized = false;
|
||||
|
||||
bool init_CAN() {
|
||||
|
||||
auto nativeIt = can_receivers.find(CAN_NATIVE);
|
||||
|
@ -82,6 +84,7 @@ bool init_CAN() {
|
|||
CAN_cfg.rx_queue = xQueueCreate(rx_queue_size, sizeof(CAN_frame_t));
|
||||
// Init CAN Module
|
||||
ESP32Can.CANInit();
|
||||
native_can_initialized = true;
|
||||
}
|
||||
|
||||
auto addonIt = can_receivers.find(CAN_ADDON_MCP2515);
|
||||
|
@ -260,7 +263,9 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
|
|||
|
||||
// Receive functions
|
||||
void receive_can() {
|
||||
if (native_can_initialized) {
|
||||
receive_frame_can_native(); // Receive CAN messages from native CAN port
|
||||
}
|
||||
|
||||
if (can2515) {
|
||||
receive_frame_can_addon(); // Receive CAN messages on add-on MCP2515 chip
|
||||
|
|
|
@ -111,7 +111,9 @@ void init_stored_settings() {
|
|||
remote_bms_reset = settings.getBool("REMBMSRESET", false);
|
||||
use_canfd_as_can = settings.getBool("CANFDASCAN", false);
|
||||
|
||||
wifiap_enabled = settings.getBool("WIFIAPENABLED", false);
|
||||
// WIFI AP is enabled by default unless disabled in the settings
|
||||
wifiap_enabled = settings.getBool("WIFIAPENABLED", true);
|
||||
passwordAP = settings.getString("APPASSWORD", "123456789").c_str();
|
||||
mqtt_enabled = settings.getBool("MQTTENABLED", false);
|
||||
ha_autodiscovery_enabled = settings.getBool("HADISC", false);
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@ class BatteryEmulatorSettingsStore {
|
|||
|
||||
~BatteryEmulatorSettingsStore() { settings.end(); }
|
||||
|
||||
void clearAll() {
|
||||
settings.clear();
|
||||
settingsUpdated = true;
|
||||
}
|
||||
|
||||
uint32_t getUInt(const char* name, uint32_t defaultValue) { return settings.getUInt(name, defaultValue); }
|
||||
|
||||
void saveUInt(const char* name, uint32_t value) {
|
||||
|
@ -56,7 +61,9 @@ class BatteryEmulatorSettingsStore {
|
|||
settingsUpdated = settingsUpdated || value != oldValue;
|
||||
}
|
||||
|
||||
bool getBool(const char* name) { return settings.getBool(name, false); }
|
||||
bool settingExists(const char* name) { return settings.isKey(name); }
|
||||
|
||||
bool getBool(const char* name, bool defaultValue = false) { return settings.getBool(name, defaultValue); }
|
||||
|
||||
void saveBool(const char* name, bool value) {
|
||||
auto oldValue = settings.getBool(name, false);
|
||||
|
|
|
@ -217,7 +217,7 @@ String settings_processor(const String& var, BatteryEmulatorSettingsStore& setti
|
|||
}
|
||||
|
||||
if (var == "WIFIAPENABLED") {
|
||||
return settings.getBool("WIFIAPENABLED") ? "checked" : "";
|
||||
return settings.getBool("WIFIAPENABLED", wifiap_enabled) ? "checked" : "";
|
||||
}
|
||||
|
||||
if (var == "MQTTENABLED") {
|
||||
|
@ -435,6 +435,26 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
#define SETTINGS_HTML_SCRIPTS \
|
||||
R"rawliteral(
|
||||
<script>
|
||||
|
||||
function askFactoryReset() {
|
||||
if (confirm('Are you sure you want to reset the device to factory settings? This will erase all settings and data.')) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function() {
|
||||
if (this.status == 200) {
|
||||
alert('Factory reset successful. The device will now restart.');
|
||||
reboot();
|
||||
} else {
|
||||
alert('Factory reset failed. Please try again.');
|
||||
}
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
alert('An error occurred while trying to reset the device.');
|
||||
};
|
||||
xhr.open('POST', '/factoryReset', true);
|
||||
xhr.send();
|
||||
}
|
||||
}
|
||||
|
||||
function editComplete(){if(this.status==200){window.location.reload();}}
|
||||
|
||||
function editError(){alert('Invalid input');}
|
||||
|
@ -725,6 +745,7 @@ const char* getCANInterfaceName(CAN_Interface interface) {
|
|||
|
||||
</div>
|
||||
|
||||
<button onclick="askFactoryReset()">Factory reset</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -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() {
|
|||
}
|
||||
});
|
||||
|
||||
// Route for editing Wh
|
||||
server.on("/updateBatterySize", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
if (WEBSERVER_AUTH_REQUIRED && !request->authenticate(http_username, http_password))
|
||||
return request->requestAuthentication();
|
||||
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();
|
||||
datalayer.battery.info.total_capacity_Wh = value.toInt();
|
||||
store_settings();
|
||||
|
||||
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
|
||||
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();
|
||||
update_string_setting("/updateSocMax", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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");
|
||||
} else {
|
||||
request->send(400, "text/plain", "Bad Request");
|
||||
}
|
||||
});
|
||||
update_string("/pause", [](String value) { setBatteryPause(value == "true" || value == "1", 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") {
|
||||
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 {
|
||||
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();
|
||||
update_string_setting("/updateSocMin", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/updateMaxChargeA", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/updateMaxDischargeA", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
update_string_setting("/updateMaxChargeVoltage", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/updateMaxDischargeVoltage", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/BalTime", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/BalFloatPower", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/BalMaxPackV", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/BalMaxCellV", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
update_string_setting("/BalMaxDevCellV", [](String 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");
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
update_string_setting(
|
||||
"/updateChargeSetpointV", [](String value) { datalayer.charger.charger_setpoint_HV_VDC = value.toFloat(); },
|
||||
[](String 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");
|
||||
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();
|
||||
update_string_setting(
|
||||
"/updateChargeSetpointA", [](String value) { datalayer.charger.charger_setpoint_HV_IDC = value.toFloat(); },
|
||||
[](String 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");
|
||||
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 +=
|
||||
|
|
|
@ -13,12 +13,6 @@ extern bool webserver_enabled;
|
|||
|
||||
extern const char* version_number; // The current software version, shown on webserver
|
||||
|
||||
#include <string>
|
||||
extern const char* http_username;
|
||||
extern const char* http_password;
|
||||
|
||||
extern const char* ssidAP;
|
||||
|
||||
// Common charger parameters
|
||||
extern float charger_stat_HVcur;
|
||||
extern float charger_stat_HVvol;
|
||||
|
|
|
@ -11,11 +11,15 @@ const bool wifi_enabled_default = false;
|
|||
|
||||
bool wifi_enabled = wifi_enabled_default;
|
||||
|
||||
#ifdef COMMON_IMAGE
|
||||
const bool wifiap_enabled_default = true;
|
||||
#else
|
||||
#ifdef WIFIAP
|
||||
const bool wifiap_enabled_default = true;
|
||||
#else
|
||||
const bool wifiap_enabled_default = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool wifiap_enabled = wifiap_enabled_default;
|
||||
|
||||
|
@ -26,6 +30,8 @@ const bool mdns_enabled_default = false;
|
|||
#endif
|
||||
bool mdns_enabled = mdns_enabled_default;
|
||||
|
||||
std::string ssidAP;
|
||||
|
||||
// Configuration Parameters
|
||||
static const uint16_t WIFI_CHECK_INTERVAL = 2000; // 1 seconds normal check interval when last connected
|
||||
static const uint16_t STEP_WIFI_CHECK_INTERVAL = 2000; // 3 seconds wait step increase in checks for normal reconnects
|
||||
|
@ -51,12 +57,14 @@ static uint16_t current_check_interval = WIFI_CHECK_INTERVAL;
|
|||
static bool connected_once = false;
|
||||
|
||||
void init_WiFi() {
|
||||
DEBUG_PRINTF("init_Wifi enabled=%d, apå=%d, ssid=%s, password=%s\n", wifi_enabled, wifiap_enabled, ssid.c_str(),
|
||||
password.c_str());
|
||||
|
||||
if (!wifiap_enabled) {
|
||||
if (wifiap_enabled) {
|
||||
WiFi.mode(WIFI_AP_STA); // Simultaneous WiFi AP and Router connection
|
||||
init_WiFi_AP();
|
||||
} else {
|
||||
WiFi.mode(WIFI_AP); // Only AP mode
|
||||
} else if (wifi_enabled) {
|
||||
WiFi.mode(WIFI_STA); // Only Router connection
|
||||
}
|
||||
|
||||
// Set WiFi to auto reconnect
|
||||
|
@ -67,17 +75,26 @@ void init_WiFi() {
|
|||
WiFi.config(local_IP, gateway, subnet);
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTF("init_Wifi set event handlers\n");
|
||||
|
||||
// Initialize Wi-Fi event handlers
|
||||
WiFi.onEvent(onWifiConnect, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_CONNECTED);
|
||||
WiFi.onEvent(onWifiDisconnect, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||
WiFi.onEvent(onWifiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP);
|
||||
|
||||
// Start Wi-Fi connection
|
||||
DEBUG_PRINTF("start Wifi\n");
|
||||
connectToWiFi();
|
||||
|
||||
DEBUG_PRINTF("init_Wifi complete\n");
|
||||
}
|
||||
|
||||
// Task to monitor Wi-Fi status and handle reconnections
|
||||
void wifi_monitor() {
|
||||
if (ssid.empty() || password.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long currentMillis = millis();
|
||||
|
||||
// Check if it's time to monitor the Wi-Fi status
|
||||
|
@ -124,6 +141,11 @@ void wifi_monitor() {
|
|||
#ifdef DEBUG_LOG
|
||||
logging.println("No previous OK connection, force a full connection attempt...");
|
||||
#endif
|
||||
|
||||
wifiap_enabled = true;
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
init_WiFi_AP();
|
||||
|
||||
FullReconnectToWiFi();
|
||||
}
|
||||
}
|
||||
|
@ -145,11 +167,18 @@ void FullReconnectToWiFi() {
|
|||
|
||||
// Function to handle Wi-Fi connection
|
||||
void connectToWiFi() {
|
||||
if (ssid.empty() || password.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
lastReconnectAttempt = millis(); // Reset the reconnect attempt timer
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("Connecting to Wi-Fi...");
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTF("Connecting to Wi-Fi SSID: %s, password: %s, Channel: %d\n", ssid.c_str(), password.c_str(),
|
||||
wifi_channel);
|
||||
WiFi.begin(ssid.c_str(), password.c_str(), wifi_channel);
|
||||
} else {
|
||||
#ifdef DEBUG_LOG
|
||||
|
@ -163,12 +192,8 @@ void onWifiConnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||
clear_event(EVENT_WIFI_DISCONNECT);
|
||||
set_event(EVENT_WIFI_CONNECT, 0);
|
||||
connected_once = true;
|
||||
#ifdef DEBUG_LOG
|
||||
logging.print("Wi-Fi connected. RSSI: ");
|
||||
logging.print(-WiFi.RSSI());
|
||||
logging.print(" dBm, IP address: ");
|
||||
logging.println(WiFi.localIP().toString());
|
||||
#endif
|
||||
DEBUG_PRINTF("Wi-Fi connected. RSSI: %d dBm, IP address: %s, SSID: %s\n", -WiFi.RSSI(),
|
||||
WiFi.localIP().toString().c_str(), WiFi.SSID().c_str());
|
||||
hasConnectedBefore = true; // Mark as successfully connected at least once
|
||||
reconnectAttempts = 0; // Reset the attempt counter
|
||||
current_full_reconnect_interval = INIT_WIFI_FULL_RECONNECT_INTERVAL; // Reset the full reconnect interval
|
||||
|
@ -189,8 +214,10 @@ void onWifiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||
|
||||
// Event handler for Wi-Fi disconnection
|
||||
void onWifiDisconnect(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
if (connected_once)
|
||||
|
||||
if (connected_once) {
|
||||
set_event(EVENT_WIFI_DISCONNECT, 0);
|
||||
}
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("Wi-Fi disconnected.");
|
||||
#endif
|
||||
|
@ -218,15 +245,13 @@ void init_mDNS() {
|
|||
}
|
||||
|
||||
void init_WiFi_AP() {
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("Creating Access Point: " + String(ssidAP));
|
||||
logging.println("With password: " + String(passwordAP));
|
||||
#endif
|
||||
WiFi.softAP(ssidAP, passwordAP);
|
||||
ssidAP = std::string("BatteryEmulator") + WiFi.macAddress().c_str();
|
||||
|
||||
DEBUG_PRINTF("Creating Access Point: %s\n", ssidAP.c_str());
|
||||
DEBUG_PRINTF("With password: %s\n", passwordAP.c_str());
|
||||
|
||||
WiFi.softAP(ssidAP.c_str(), passwordAP.c_str());
|
||||
IPAddress IP = WiFi.softAPIP();
|
||||
#ifdef DEBUG_LOG
|
||||
logging.println("Access Point created.");
|
||||
logging.print("IP address: ");
|
||||
logging.println(IP.toString());
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTF("Access Point created.\nIP address: %s\n", IP.toString().c_str());
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
extern std::string ssid;
|
||||
extern std::string password;
|
||||
extern const uint8_t wifi_channel;
|
||||
extern const char* ssidAP;
|
||||
extern const char* passwordAP;
|
||||
extern std::string ssidAP;
|
||||
extern std::string passwordAP;
|
||||
|
||||
void init_WiFi();
|
||||
void wifi_monitor();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue