mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Add Cellmonitor to webserver
This commit is contained in:
parent
4cd5289929
commit
a56ceb50dd
7 changed files with 90 additions and 3 deletions
|
@ -67,6 +67,7 @@ uint8_t bms_status = ACTIVE; // ACTIVE - [0..5]<>[STANDBY,INACTIVE,DA
|
||||||
uint16_t stat_batt_power = 0; // Power going in/out of battery
|
uint16_t stat_batt_power = 0; // Power going in/out of battery
|
||||||
uint16_t cell_max_voltage = 3700; // Stores the highest cell voltage value in the system
|
uint16_t cell_max_voltage = 3700; // Stores the highest cell voltage value in the system
|
||||||
uint16_t cell_min_voltage = 3700; // Stores the minimum cell voltage value in the system
|
uint16_t cell_min_voltage = 3700; // Stores the minimum cell voltage value in the system
|
||||||
|
uint16_t cellvoltages[120]; // Stores all cell voltages
|
||||||
bool LFP_Chemistry = false;
|
bool LFP_Chemistry = false;
|
||||||
|
|
||||||
// Common charger parameters
|
// Common charger parameters
|
||||||
|
|
|
@ -239,6 +239,11 @@ void update_values_leaf_battery() { /* This function maps all the values fetched
|
||||||
max_target_charge_power = 0; //No need to charge further, set max power to 0
|
max_target_charge_power = 0; //No need to charge further, set max power to 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Map all cell voltages to the global array
|
||||||
|
for (int i = 0; i < 97; ++i) {
|
||||||
|
cellvoltages[i] = cell_voltages[i];
|
||||||
|
}
|
||||||
|
|
||||||
/*Extra safety functions below*/
|
/*Extra safety functions below*/
|
||||||
if (LB_GIDS < 10) //800Wh left in battery
|
if (LB_GIDS < 10) //800Wh left in battery
|
||||||
{ //Battery is running abnormally low, some discharge logic might have failed. Zero it all out.
|
{ //Battery is running abnormally low, some discharge logic might have failed. Zero it all out.
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 funct
|
||||||
extern uint16_t cell_max_voltage; //mV, 0-4350
|
extern uint16_t cell_max_voltage; //mV, 0-4350
|
||||||
extern uint16_t cell_min_voltage; //mV, 0-4350
|
extern uint16_t cell_min_voltage; //mV, 0-4350
|
||||||
extern uint8_t LEDcolor; //Enum, 0-10
|
extern uint8_t LEDcolor; //Enum, 0-10
|
||||||
|
extern uint16_t cellvoltages[120]; //mV 0-5000 per cell
|
||||||
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
||||||
|
|
||||||
void update_values_leaf_battery();
|
void update_values_leaf_battery();
|
||||||
|
|
|
@ -33,9 +33,9 @@ void update_values_test_battery() { /* This function puts fake values onto the p
|
||||||
|
|
||||||
remaining_capacity_Wh = 15000; // 15kWh
|
remaining_capacity_Wh = 15000; // 15kWh
|
||||||
|
|
||||||
cell_max_voltage = 3750;
|
cell_max_voltage = 3596;
|
||||||
|
|
||||||
cell_min_voltage = 3730;
|
cell_min_voltage = 3500;
|
||||||
|
|
||||||
stat_batt_power = 0; // 0W
|
stat_batt_power = 0; // 0W
|
||||||
|
|
||||||
|
@ -47,6 +47,10 @@ void update_values_test_battery() { /* This function puts fake values onto the p
|
||||||
|
|
||||||
max_target_charge_power = 5000; // 5kW
|
max_target_charge_power = 5000; // 5kW
|
||||||
|
|
||||||
|
for (int i = 0; i < 97; ++i) {
|
||||||
|
cellvoltages[i] = 3500+i;
|
||||||
|
}
|
||||||
|
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_VIA_USB
|
#ifdef DEBUG_VIA_USB
|
||||||
Serial.println("FAKE Values going to inverter");
|
Serial.println("FAKE Values going to inverter");
|
||||||
|
|
|
@ -25,6 +25,7 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 funct
|
||||||
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
|
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
|
||||||
extern uint16_t cell_max_voltage; //mV, 0-4350
|
extern uint16_t cell_max_voltage; //mV, 0-4350
|
||||||
extern uint16_t cell_min_voltage; //mV, 0-4350
|
extern uint16_t cell_min_voltage; //mV, 0-4350
|
||||||
|
extern uint16_t cellvoltages[120]; //mV 0-5000 per cell
|
||||||
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
||||||
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
|
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
|
||||||
extern uint8_t LEDcolor; //Enum, 0-10
|
extern uint8_t LEDcolor; //Enum, 0-10
|
||||||
|
|
|
@ -60,6 +60,10 @@ void init_webserver() {
|
||||||
server.on("/settings", HTTP_GET,
|
server.on("/settings", HTTP_GET,
|
||||||
[](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, settings_processor); });
|
[](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, settings_processor); });
|
||||||
|
|
||||||
|
// Route for going to cellmonitor web page
|
||||||
|
server.on("/cellmonitor", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest* request) { request->send_P(200, "text/html", index_html, cellmonitor_processor); });
|
||||||
|
|
||||||
// Route for editing Wh
|
// Route for editing Wh
|
||||||
server.on("/updateBatterySize", HTTP_GET, [](AsyncWebServerRequest* request) {
|
server.on("/updateBatterySize", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
if (request->hasParam("value")) {
|
if (request->hasParam("value")) {
|
||||||
|
@ -547,11 +551,14 @@ String processor(const String& var) {
|
||||||
|
|
||||||
content += "<button onclick='goToUpdatePage()'>Perform OTA update</button>";
|
content += "<button onclick='goToUpdatePage()'>Perform OTA update</button>";
|
||||||
content += " ";
|
content += " ";
|
||||||
content += "<button onclick='goToSettingsPage()'>Change Battery Settings</button>";
|
content += "<button onclick='goToSettingsPage()'>Change Settings</button>";
|
||||||
|
content += " ";
|
||||||
|
content += "<button onclick='goToCellmonitorPage()'>Cellmonitor</button>";
|
||||||
content += " ";
|
content += " ";
|
||||||
content += "<button onclick='promptToReboot()'>Reboot Emulator</button>";
|
content += "<button onclick='promptToReboot()'>Reboot Emulator</button>";
|
||||||
content += "<script>";
|
content += "<script>";
|
||||||
content += "function goToUpdatePage() { window.location.href = '/update'; }";
|
content += "function goToUpdatePage() { window.location.href = '/update'; }";
|
||||||
|
content += "function goToCellmonitorPage() { window.location.href = '/cellmonitor'; }";
|
||||||
content += "function goToSettingsPage() { window.location.href = '/settings'; }";
|
content += "function goToSettingsPage() { window.location.href = '/settings'; }";
|
||||||
content +=
|
content +=
|
||||||
"function promptToReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If "
|
"function promptToReboot() { if (window.confirm('Are you sure you want to reboot the emulator? NOTE: If "
|
||||||
|
@ -810,6 +817,64 @@ String settings_processor(const String& var) {
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String cellmonitor_processor(const String& var) {
|
||||||
|
if (var == "PLACEHOLDER") {
|
||||||
|
String content = "";
|
||||||
|
// Page format
|
||||||
|
content += "<style>";
|
||||||
|
content += "body { background-color: black; color: white; }";
|
||||||
|
content += ".container { display: flex; flex-wrap: wrap; justify-content: space-around; }";
|
||||||
|
content += ".cell { width: 48%; margin: 1%; padding: 10px; border: 1px solid white; text-align: center; }";
|
||||||
|
content += ".low-voltage { color: red; }"; // Style for low voltage text
|
||||||
|
content += ".voltage-values { margin-bottom: 10px; }"; // Style for voltage values section
|
||||||
|
content += "</style>";
|
||||||
|
|
||||||
|
// Start a new block with a specific background color
|
||||||
|
content += "<div style='background-color: #303E47; padding: 10px; margin-bottom: 10px; border-radius: 50px'>";
|
||||||
|
|
||||||
|
// Display max, min, and deviation voltage values
|
||||||
|
content += "<div class='voltage-values'>";
|
||||||
|
content += "Max Voltage: " + String(cell_max_voltage) + " mV<br>";
|
||||||
|
content += "Min Voltage: " + String(cell_min_voltage) + " mV<br>";
|
||||||
|
int deviation = cell_max_voltage - cell_min_voltage;
|
||||||
|
content += "Voltage Deviation: " + String(deviation) + " mV";
|
||||||
|
content += "</div>";
|
||||||
|
|
||||||
|
// Visualize the populated cells in forward order using flexbox with conditional text color
|
||||||
|
content += "<div class='container'>";
|
||||||
|
for (int i = 0; i < 120; ++i) {
|
||||||
|
// Skip empty values
|
||||||
|
if (cellvoltages[i] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cellContent = "Cell " + String(i + 1) + "<br>" + String(cellvoltages[i]) + " mV";
|
||||||
|
|
||||||
|
// Check if the cell voltage is below 3000, apply red color
|
||||||
|
if (cellvoltages[i] < 3000) {
|
||||||
|
cellContent = "<span class='low-voltage'>" + cellContent + "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
content += "<div class='cell'>" + cellContent + "</div>";
|
||||||
|
}
|
||||||
|
content += "</div>";
|
||||||
|
|
||||||
|
// Close the block
|
||||||
|
content += "</div>";
|
||||||
|
|
||||||
|
content += "<button onclick='goToMainPage()'>Back to main page</button>";
|
||||||
|
content += "<script>";
|
||||||
|
content += "function goToMainPage() { window.location.href = '/'; }";
|
||||||
|
content += "</script>";
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void onOTAStart() {
|
void onOTAStart() {
|
||||||
// Log when OTA has started
|
// Log when OTA has started
|
||||||
Serial.println("OTA update started!");
|
Serial.println("OTA update started!");
|
||||||
|
|
|
@ -25,6 +25,7 @@ extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 funct
|
||||||
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
|
extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
|
||||||
extern uint16_t cell_max_voltage; //mV, 0-4350
|
extern uint16_t cell_max_voltage; //mV, 0-4350
|
||||||
extern uint16_t cell_min_voltage; //mV, 0-4350
|
extern uint16_t cell_min_voltage; //mV, 0-4350
|
||||||
|
extern uint16_t cellvoltages[120]; //mV 0-5000 per cell
|
||||||
extern uint8_t LEDcolor; //Enum, 0-10
|
extern uint8_t LEDcolor; //Enum, 0-10
|
||||||
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
|
||||||
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
|
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
|
||||||
|
@ -98,6 +99,15 @@ String processor(const String& var);
|
||||||
*/
|
*/
|
||||||
String settings_processor(const String& var);
|
String settings_processor(const String& var);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Replaces placeholder with content section in web page
|
||||||
|
*
|
||||||
|
* @param[in] var
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
String cellmonitor_processor(const String& var);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Executes on OTA start
|
* @brief Executes on OTA start
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue