mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-05 02:39:57 +02:00
MEB: Improve MEB status output. (#983)
* Add 4 missing status outputs from battery to MEB more battery page. BMS_fault_performance BMS_fault_emergency_shutdown_crash BMS_error_shutdown_request BMS_error_shutdown * Adds SOH calculation. * Fixes: (hopefully) the capacity calculation from Ah to kWh. * Only update capacity and soh if number of cells is set. Remove incorrect scaling on Wh_max. Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
f4613ae2d4
commit
e6a6ce9925
4 changed files with 50 additions and 13 deletions
|
@ -540,14 +540,27 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
datalayer.battery.status.real_soc = battery_SOC * 5; //*0.05*100
|
datalayer.battery.status.real_soc = battery_SOC * 5; //*0.05*100
|
||||||
|
|
||||||
datalayer.battery.status.soh_pptt;
|
|
||||||
|
|
||||||
datalayer.battery.status.voltage_dV = BMS_voltage * 2.5; // *0.25*10
|
datalayer.battery.status.voltage_dV = BMS_voltage * 2.5; // *0.25*10
|
||||||
|
|
||||||
datalayer.battery.status.current_dA = (BMS_current - 16300); // 0.1 * 10
|
datalayer.battery.status.current_dA = (BMS_current - 16300); // 0.1 * 10
|
||||||
|
|
||||||
|
if (nof_cells_determined) {
|
||||||
datalayer.battery.info.total_capacity_Wh =
|
datalayer.battery.info.total_capacity_Wh =
|
||||||
((float)datalayer.battery.info.number_of_cells) * 3.6458 * ((float)BMS_capacity_ah) * 0.2 * 1.13;
|
((float)datalayer.battery.info.number_of_cells) * 3.67 * ((float)BMS_capacity_ah) * 0.2 * 1.02564;
|
||||||
|
// The factor 1.02564 = 1/0.975 is to correct for bottom 2.5% which is reported by the remaining_capacity_Wh,
|
||||||
|
// but which is not actually usable, but if we do not include it, the remaining_capacity_Wh can be larger than
|
||||||
|
// the total_capacity_Wh.
|
||||||
|
// 0.935 and 0.9025 are the different conversions for different battery sizes to go from design capacity to
|
||||||
|
// total_capacity_Wh calculated above.
|
||||||
|
|
||||||
|
int Wh_max = 61832 * 0.935; // 108 cells
|
||||||
|
if (datalayer.battery.info.number_of_cells <= 84)
|
||||||
|
Wh_max = 48091 * 0.9025;
|
||||||
|
else if (datalayer.battery.info.number_of_cells <= 96)
|
||||||
|
Wh_max = 82442 * 0.9025;
|
||||||
|
if (BMS_capacity_ah > 0)
|
||||||
|
datalayer.battery.status.soh_pptt = 10000 * datalayer.battery.info.total_capacity_Wh / Wh_max;
|
||||||
|
}
|
||||||
|
|
||||||
datalayer.battery.status.remaining_capacity_Wh = usable_energy_amount_Wh * 5;
|
datalayer.battery.status.remaining_capacity_Wh = usable_energy_amount_Wh * 5;
|
||||||
|
|
||||||
|
@ -589,6 +602,11 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
datalayer_extended.meb.BMS_mode = BMS_mode;
|
datalayer_extended.meb.BMS_mode = BMS_mode;
|
||||||
datalayer_extended.meb.battery_diagnostic = battery_diagnostic;
|
datalayer_extended.meb.battery_diagnostic = battery_diagnostic;
|
||||||
datalayer_extended.meb.status_HV_line = status_HV_line;
|
datalayer_extended.meb.status_HV_line = status_HV_line;
|
||||||
|
datalayer_extended.meb.BMS_fault_performance = BMS_fault_performance;
|
||||||
|
datalayer_extended.meb.BMS_fault_emergency_shutdown_crash = BMS_fault_emergency_shutdown_crash;
|
||||||
|
datalayer_extended.meb.BMS_error_shutdown_request = BMS_error_shutdown_request;
|
||||||
|
datalayer_extended.meb.BMS_error_shutdown = BMS_error_shutdown;
|
||||||
|
|
||||||
datalayer_extended.meb.warning_support = warning_support;
|
datalayer_extended.meb.warning_support = warning_support;
|
||||||
datalayer_extended.meb.BMS_status_voltage_free = BMS_status_voltage_free;
|
datalayer_extended.meb.BMS_status_voltage_free = BMS_status_voltage_free;
|
||||||
datalayer_extended.meb.BMS_OBD_MIL = BMS_OBD_MIL;
|
datalayer_extended.meb.BMS_OBD_MIL = BMS_OBD_MIL;
|
||||||
|
|
|
@ -585,6 +585,14 @@ typedef struct {
|
||||||
uint8_t status_HV_line = 0;
|
uint8_t status_HV_line = 0;
|
||||||
/** uint8_t */
|
/** uint8_t */
|
||||||
/** 0 = OK, 1 = Not OK, 0x06 = init, 0x07 = fault */
|
/** 0 = OK, 1 = Not OK, 0x06 = init, 0x07 = fault */
|
||||||
|
bool BMS_fault_performance = false; //Error: Battery performance is limited (e.g. due to sensor or fan failure)
|
||||||
|
bool BMS_fault_emergency_shutdown_crash =
|
||||||
|
false; //Error: Safety-critical error (crash detection) Battery contactors are already opened / will be opened immediately Signal is read directly by the EMS and initiates an AKS of the PWR and an active discharge of the DC link
|
||||||
|
|
||||||
|
bool BMS_error_shutdown_request =
|
||||||
|
false; // Fault: Fault condition, requires battery contactors to be opened internal battery error; Advance notification of an impending opening of the battery contactors by the BMS
|
||||||
|
bool BMS_error_shutdown =
|
||||||
|
false; // Fault: Fault condition, requires battery contactors to be opened Internal battery error, battery contactors opened without notice by the BMS
|
||||||
uint8_t warning_support = 0;
|
uint8_t warning_support = 0;
|
||||||
/** uint32_t */
|
/** uint32_t */
|
||||||
/** Isolation resistance in kOhm */
|
/** Isolation resistance in kOhm */
|
||||||
|
|
|
@ -1062,7 +1062,18 @@ String advanced_battery_processor(const String& var) {
|
||||||
default:
|
default:
|
||||||
content += String("? ") + String(datalayer_extended.meb.status_HV_line);
|
content += String("? ") + String(datalayer_extended.meb.status_HV_line);
|
||||||
}
|
}
|
||||||
content += "</h4><h4>Warning support: ";
|
content += "</h4>";
|
||||||
|
content += datalayer_extended.meb.BMS_fault_performance ? "<h4>BMS fault performance: Active!</h4>"
|
||||||
|
: "<h4>BMS fault performance: Off</h4>";
|
||||||
|
content += datalayer_extended.meb.BMS_fault_emergency_shutdown_crash
|
||||||
|
? "<h4>BMS fault emergency shutdown crash: Active!</h4>"
|
||||||
|
: "<h4>BMS fault emergency shutdown crash: Off</h4>";
|
||||||
|
content += datalayer_extended.meb.BMS_error_shutdown_request ? "<h4>BMS error shutdown request: Active!</h4>"
|
||||||
|
: "<h4>BMS error shutdown request: Inactive</h4>";
|
||||||
|
content += datalayer_extended.meb.BMS_error_shutdown ? "<h4>BMS error shutdown: Active!</h4>"
|
||||||
|
: "<h4>BMS error shutdown: Off</h4>";
|
||||||
|
|
||||||
|
content += "<h4>Warning support: ";
|
||||||
switch (datalayer_extended.meb.warning_support) {
|
switch (datalayer_extended.meb.warning_support) {
|
||||||
case 0:
|
case 0:
|
||||||
content += String("OK");
|
content += String("OK");
|
||||||
|
|
|
@ -1054,13 +1054,13 @@ String processor(const String& var) {
|
||||||
uint16_t cell_delta_mv =
|
uint16_t cell_delta_mv =
|
||||||
datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV;
|
datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV;
|
||||||
|
|
||||||
content += "<h4 style='color: white;'>Real SOC: " + String(socRealFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>Real SOC: " + String(socRealFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>Scaled SOC: " + String(socScaledFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>Scaled SOC: " + String(socScaledFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>SOH: " + String(sohFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>SOH: " + String(sohFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>Voltage: " + String(voltageFloat, 1) + " V</h4>";
|
content += "<h4 style='color: white;'>Voltage: " + String(voltageFloat, 1) + " V</h4>";
|
||||||
content += "<h4 style='color: white;'>Current: " + String(currentFloat, 1) + " A</h4>";
|
content += "<h4 style='color: white;'>Current: " + String(currentFloat, 1) + " A</h4>";
|
||||||
content += formatPowerValue("Power", powerFloat, "", 1);
|
content += formatPowerValue("Power", powerFloat, "", 1);
|
||||||
content += formatPowerValue("Total capacity", datalayer.battery.info.total_capacity_Wh, "h", 0);
|
content += formatPowerValue("Total capacity", datalayer.battery.info.total_capacity_Wh, "h", 1);
|
||||||
content += formatPowerValue("Real Remaining capacity", datalayer.battery.status.remaining_capacity_Wh, "h", 1);
|
content += formatPowerValue("Real Remaining capacity", datalayer.battery.status.remaining_capacity_Wh, "h", 1);
|
||||||
content +=
|
content +=
|
||||||
formatPowerValue("Scaled Remaining capacity", datalayer.battery.status.reported_remaining_capacity_Wh, "h", 1);
|
formatPowerValue("Scaled Remaining capacity", datalayer.battery.status.reported_remaining_capacity_Wh, "h", 1);
|
||||||
|
@ -1261,13 +1261,13 @@ String processor(const String& var) {
|
||||||
tempMinFloat = static_cast<float>(datalayer.battery2.status.temperature_min_dC) / 10.0; // Convert to float
|
tempMinFloat = static_cast<float>(datalayer.battery2.status.temperature_min_dC) / 10.0; // Convert to float
|
||||||
cell_delta_mv = datalayer.battery2.status.cell_max_voltage_mV - datalayer.battery2.status.cell_min_voltage_mV;
|
cell_delta_mv = datalayer.battery2.status.cell_max_voltage_mV - datalayer.battery2.status.cell_min_voltage_mV;
|
||||||
|
|
||||||
content += "<h4 style='color: white;'>Real SOC: " + String(socRealFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>Real SOC: " + String(socRealFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>Scaled SOC: " + String(socScaledFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>Scaled SOC: " + String(socScaledFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>SOH: " + String(sohFloat, 2) + "</h4>";
|
content += "<h4 style='color: white;'>SOH: " + String(sohFloat, 2) + "%</h4>";
|
||||||
content += "<h4 style='color: white;'>Voltage: " + String(voltageFloat, 1) + " V</h4>";
|
content += "<h4 style='color: white;'>Voltage: " + String(voltageFloat, 1) + " V</h4>";
|
||||||
content += "<h4 style='color: white;'>Current: " + String(currentFloat, 1) + " A</h4>";
|
content += "<h4 style='color: white;'>Current: " + String(currentFloat, 1) + " A</h4>";
|
||||||
content += formatPowerValue("Power", powerFloat, "", 1);
|
content += formatPowerValue("Power", powerFloat, "", 1);
|
||||||
content += formatPowerValue("Total capacity", datalayer.battery2.info.total_capacity_Wh, "h", 0);
|
content += formatPowerValue("Total capacity", datalayer.battery2.info.total_capacity_Wh, "h", 1);
|
||||||
content += formatPowerValue("Real Remaining capacity", datalayer.battery2.status.remaining_capacity_Wh, "h", 1);
|
content += formatPowerValue("Real Remaining capacity", datalayer.battery2.status.remaining_capacity_Wh, "h", 1);
|
||||||
content +=
|
content +=
|
||||||
formatPowerValue("Scaled Remaining capacity", datalayer.battery2.status.reported_remaining_capacity_Wh, "h", 1);
|
formatPowerValue("Scaled Remaining capacity", datalayer.battery2.status.reported_remaining_capacity_Wh, "h", 1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue