mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Add initial skeleton for replay
This commit is contained in:
parent
827e7eae70
commit
26baf25c97
4 changed files with 129 additions and 2 deletions
|
@ -41,7 +41,7 @@
|
||||||
//#define TESLA_MODEL_SX_BATTERY
|
//#define TESLA_MODEL_SX_BATTERY
|
||||||
//#define VOLVO_SPA_BATTERY
|
//#define VOLVO_SPA_BATTERY
|
||||||
//#define VOLVO_SPA_HYBRID_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 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)
|
//#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)
|
//#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 */
|
/* Select hardware used for Battery-Emulator */
|
||||||
//#define HW_LILYGO
|
#define HW_LILYGO
|
||||||
//#define HW_STARK
|
//#define HW_STARK
|
||||||
//#define HW_3LB
|
//#define HW_3LB
|
||||||
//#define HW_DEVKIT
|
//#define HW_DEVKIT
|
||||||
|
|
75
Software/src/devboard/webserver/can_replay_html.cpp
Normal file
75
Software/src/devboard/webserver/can_replay_html.cpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
#include "can_replay_html.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#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 += "<style>";
|
||||||
|
content += "body { background-color: black; color: white; font-family: Arial, sans-serif; }";
|
||||||
|
content +=
|
||||||
|
"button { background-color: #505E67; color: white; border: none; padding: 10px 20px; margin-bottom: 20px; "
|
||||||
|
"cursor: pointer; border-radius: 10px; }";
|
||||||
|
content += "button:hover { background-color: #3A4A52; }";
|
||||||
|
content +=
|
||||||
|
".can-message { background-color: #404E57; margin-bottom: 5px; padding: 10px; border-radius: 5px; font-family: "
|
||||||
|
"monospace; }";
|
||||||
|
content += "</style>";
|
||||||
|
content += "<button onclick='importLog()'>Import .txt</button> ";
|
||||||
|
content += "<button onclick='stopPlaybackAndGoToMainPage()'>Stop & Back to main page</button>";
|
||||||
|
|
||||||
|
// Start a new block for the CAN messages
|
||||||
|
content += "<div style='background-color: #303E47; padding: 20px; border-radius: 15px'>";
|
||||||
|
|
||||||
|
// Ask user to select which CAN interface log should be sent to
|
||||||
|
content += "<h4>Select CAN Interface for Playback</h4>";
|
||||||
|
|
||||||
|
// Dropdown with choices
|
||||||
|
content += "<label for='canInterface'>CAN Interface:</label>";
|
||||||
|
content += "<select id='canInterface' name='canInterface'>";
|
||||||
|
content += "<option value='" + String(CAN_NATIVE) + "'>CAN Native</option>";
|
||||||
|
content += "<option value='" + String(CANFD_NATIVE) + "'>CANFD Native</option>";
|
||||||
|
content += "<option value='" + String(CAN_ADDON_MCP2515) + "'>CAN Addon MCP2515</option>";
|
||||||
|
content += "<option value='" + String(CANFD_ADDON_MCP2518) + "'>CANFD Addon MCP2518</option>";
|
||||||
|
content += "</select>";
|
||||||
|
|
||||||
|
// Add a button to submit the selected CAN interface
|
||||||
|
content += "<button onclick='sendCANSelection()'>Apply</button>";
|
||||||
|
|
||||||
|
// Show text that log file is not loaded yet
|
||||||
|
content += "<h4>Log file not loaded yet. Import log before starting replay!</h4>";
|
||||||
|
|
||||||
|
// Add a button to start playing the log
|
||||||
|
content += "<button onclick='startReplay()'>Start</button> ";
|
||||||
|
|
||||||
|
// Add a button to stop playing the log
|
||||||
|
content += "<button onclick='startReplay()'>Stop</button> ";
|
||||||
|
|
||||||
|
// Add a checkbox to loop the log
|
||||||
|
//content += "<input type="checkbox" id="myCheck" onclick="myFunction()">";
|
||||||
|
|
||||||
|
content += "</div>";
|
||||||
|
|
||||||
|
// Add JavaScript for navigation
|
||||||
|
content += "<script>";
|
||||||
|
content += "function sendCANSelection() {";
|
||||||
|
content += " var selectedInterface = document.getElementById('canInterface').value;";
|
||||||
|
content += " var xhr = new XMLHttpRequest();";
|
||||||
|
content += " xhr.open('GET', '/setCANInterface?interface=' + selectedInterface, true);";
|
||||||
|
content += " xhr.send();";
|
||||||
|
content += "}";
|
||||||
|
content += "function importLog() { window.location.href = '/import_can_log'; }";
|
||||||
|
content += "function stopPlaybackAndGoToMainPage() {";
|
||||||
|
content += " fetch('/stop_can_logging').then(() => window.location.href = '/');";
|
||||||
|
content += "}";
|
||||||
|
content += "</script>";
|
||||||
|
content += index_html_footer;
|
||||||
|
return content;
|
||||||
|
}
|
16
Software/src/devboard/webserver/can_replay_html.h
Normal file
16
Software/src/devboard/webserver/can_replay_html.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef CANREPLAY_H
|
||||||
|
#define CANREPLAY_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces placeholder with content section in web page
|
||||||
|
*
|
||||||
|
* @param[in] var
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
String can_replay_processor(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,6 +18,7 @@ unsigned long ota_progress_millis = 0;
|
||||||
|
|
||||||
#include "advanced_battery_html.h"
|
#include "advanced_battery_html.h"
|
||||||
#include "can_logging_html.h"
|
#include "can_logging_html.h"
|
||||||
|
#include "can_replay_html.h"
|
||||||
#include "cellmonitor_html.h"
|
#include "cellmonitor_html.h"
|
||||||
#include "debug_logging_html.h"
|
#include "debug_logging_html.h"
|
||||||
#include "events_html.h"
|
#include "events_html.h"
|
||||||
|
@ -29,6 +30,25 @@ bool ota_active = false;
|
||||||
|
|
||||||
const char get_firmware_info_html[] = R"rawliteral(%X%)rawliteral";
|
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() {
|
void init_webserver() {
|
||||||
|
|
||||||
server.on("/logout", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(401); });
|
server.on("/logout", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(401); });
|
||||||
|
@ -65,6 +85,12 @@ void init_webserver() {
|
||||||
request->send(response);
|
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)
|
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
||||||
// Route for going to debug logging web page
|
// Route for going to debug logging web page
|
||||||
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
@ -79,6 +105,14 @@ void init_webserver() {
|
||||||
request->send(200, "text/plain", "Logging stopped");
|
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
|
#ifndef LOG_CAN_TO_SD
|
||||||
// Define the handler to export can log
|
// Define the handler to export can log
|
||||||
server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/export_can_log", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
@ -1280,6 +1314,7 @@ String processor(const String& var) {
|
||||||
content += "<button onclick='Settings()'>Change Settings</button> ";
|
content += "<button onclick='Settings()'>Change Settings</button> ";
|
||||||
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
content += "<button onclick='Advanced()'>More Battery Info</button> ";
|
||||||
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
content += "<button onclick='CANlog()'>CAN logger</button> ";
|
||||||
|
content += "<button onclick='CANreplay()'>CAN replay</button> ";
|
||||||
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
#if defined(DEBUG_VIA_WEB) || defined(LOG_TO_SD)
|
||||||
content += "<button onclick='Log()'>Log</button> ";
|
content += "<button onclick='Log()'>Log</button> ";
|
||||||
#endif // DEBUG_VIA_WEB
|
#endif // DEBUG_VIA_WEB
|
||||||
|
@ -1308,6 +1343,7 @@ String processor(const String& var) {
|
||||||
content += "function Settings() { window.location.href = '/settings'; }";
|
content += "function Settings() { window.location.href = '/settings'; }";
|
||||||
content += "function Advanced() { window.location.href = '/advanced'; }";
|
content += "function Advanced() { window.location.href = '/advanced'; }";
|
||||||
content += "function CANlog() { window.location.href = '/canlog'; }";
|
content += "function CANlog() { window.location.href = '/canlog'; }";
|
||||||
|
content += "function CANreplay() { window.location.href = '/canreplay'; }";
|
||||||
content += "function Log() { window.location.href = '/log'; }";
|
content += "function Log() { window.location.href = '/log'; }";
|
||||||
content += "function Events() { window.location.href = '/events'; }";
|
content += "function Events() { window.location.href = '/events'; }";
|
||||||
content +=
|
content +=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue