diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 497852e1..3fe2e253 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -41,7 +41,7 @@ //#define TESLA_MODEL_SX_BATTERY //#define VOLVO_SPA_BATTERY //#define VOLVO_SPA_HYBRID_BATTERY -//#define TEST_FAKE_BATTERY +#define TEST_FAKE_BATTERY //#define DOUBLE_BATTERY //Enable this line if you use two identical batteries at the same time (requires CAN_ADDON setup) //#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery) @@ -67,7 +67,7 @@ //#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter) /* Select hardware used for Battery-Emulator */ -//#define HW_LILYGO +#define HW_LILYGO //#define HW_STARK //#define HW_3LB //#define HW_DEVKIT diff --git a/Software/src/devboard/webserver/can_replay_html.cpp b/Software/src/devboard/webserver/can_replay_html.cpp new file mode 100644 index 00000000..49135179 --- /dev/null +++ b/Software/src/devboard/webserver/can_replay_html.cpp @@ -0,0 +1,75 @@ +#include "can_replay_html.h" +#include +#include "../../datalayer/datalayer.h" +#include "index_html.h" + +String can_replay_processor(void) { + if (!datalayer.system.info.can_logging_active) { + datalayer.system.info.logged_can_messages_offset = 0; + datalayer.system.info.logged_can_messages[0] = '\0'; + } + datalayer.system.info.can_logging_active = + true; // Signal to main loop that we should log messages. Disabled by default for performance reasons + String content = index_html_header; + // Page format + content += ""; + content += " "; + content += ""; + + // Start a new block for the CAN messages + content += "
"; + + // Ask user to select which CAN interface log should be sent to + content += "

Select CAN Interface for Playback

"; + + // Dropdown with choices + content += ""; + content += ""; + + // Add a button to submit the selected CAN interface + content += ""; + + // Show text that log file is not loaded yet + content += "

Log file not loaded yet. Import log before starting replay!

"; + + // Add a button to start playing the log + content += " "; + + // Add a button to stop playing the log + content += " "; + + // Add a checkbox to loop the log + //content += ""; + + content += "
"; + + // Add JavaScript for navigation + content += ""; + content += index_html_footer; + return content; +} diff --git a/Software/src/devboard/webserver/can_replay_html.h b/Software/src/devboard/webserver/can_replay_html.h new file mode 100644 index 00000000..4f4f3cd8 --- /dev/null +++ b/Software/src/devboard/webserver/can_replay_html.h @@ -0,0 +1,16 @@ +#ifndef CANREPLAY_H +#define CANREPLAY_H + +#include +#include + +/** + * @brief Replaces placeholder with content section in web page + * + * @param[in] var + * + * @return String + */ +String can_replay_processor(void); + +#endif diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 64efbdd5..f179141a 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -18,6 +18,7 @@ unsigned long ota_progress_millis = 0; #include "advanced_battery_html.h" #include "can_logging_html.h" +#include "can_replay_html.h" #include "cellmonitor_html.h" #include "debug_logging_html.h" #include "events_html.h" @@ -29,6 +30,25 @@ bool ota_active = false; const char get_firmware_info_html[] = R"rawliteral(%X%)rawliteral"; +String importedLogs = ""; // Store the uploaded file contents in RAM /WARNING THIS MIGHT GO BOOM + +void handleFileUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { + if (!index) { + importedLogs = ""; // Clear previous logs + Serial.printf("Receiving file: %s\n", filename.c_str()); + } + + // Append received data to the string (RAM storage) + importedLogs += String((char*)data).substring(0, len); + + if (final) { + Serial.println("Upload Complete!"); + Serial.println("Imported Log Data:"); + Serial.println(importedLogs); // Display contents for debugging + request->send(200, "text/plain", "File uploaded successfully"); + } +} + void init_webserver() { server.on("/logout", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(401); }); @@ -65,6 +85,12 @@ void init_webserver() { request->send(response); }); + // Route for going to CAN replay web page + server.on("/canreplay", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncWebServerResponse* response = request->beginResponse(200, "text/html", can_replay_processor()); + request->send(response); + }); + #if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD) // Route for going to debug logging web page server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -79,6 +105,14 @@ void init_webserver() { request->send(200, "text/plain", "Logging stopped"); }); + // Define the handler to import can log + server.on("/import_can_log", HTTP_POST,[](AsyncWebServerRequest *request) { + request->send(200, "text/plain", "Ready to receive file."); // Response when request is made + }, + handleFileUpload + ); + + #ifndef LOG_CAN_TO_SD // Define the handler to export can log server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -1280,6 +1314,7 @@ String processor(const String& var) { content += " "; content += " "; content += " "; + content += " "; #if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD) content += " "; #endif // DEBUG_VIA_WEB @@ -1308,6 +1343,7 @@ String processor(const String& var) { content += "function Settings() { window.location.href = '/settings'; }"; content += "function Advanced() { window.location.href = '/advanced'; }"; content += "function CANlog() { window.location.href = '/canlog'; }"; + content += "function CANreplay() { window.location.href = '/canreplay'; }"; content += "function Log() { window.location.href = '/log'; }"; content += "function Events() { window.location.href = '/events'; }"; content +=