Feature: Volkswagen MEB platform support (#405)

* Add MEB Support

Co-authored-by: mvgalen <marijnvangalen@gmail.com>
This commit is contained in:
Daniel Öster 2024-12-02 18:39:57 +02:00 committed by GitHub
parent 4e66ffcd38
commit 0750c6ab5b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 2551 additions and 16 deletions

View file

@ -43,6 +43,7 @@ jobs:
- KIA_HYUNDAI_64_BATTERY - KIA_HYUNDAI_64_BATTERY
- KIA_E_GMP_BATTERY - KIA_E_GMP_BATTERY
- KIA_HYUNDAI_HYBRID_BATTERY - KIA_HYUNDAI_HYBRID_BATTERY
- MEB_BATTERY
- MG_5_BATTERY - MG_5_BATTERY
- NISSAN_LEAF_BATTERY - NISSAN_LEAF_BATTERY
- PYLON_BATTERY - PYLON_BATTERY

View file

@ -625,19 +625,20 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir);
void print_can_frame(CAN_frame frame, frameDirection msgDir) { void print_can_frame(CAN_frame frame, frameDirection msgDir) {
#ifdef DEBUG_CAN_DATA // If enabled in user settings, print out the CAN messages via USB #ifdef DEBUG_CAN_DATA // If enabled in user settings, print out the CAN messages via USB
uint8_t i = 0; uint8_t i = 0;
Serial.print(millis()); Serial.print("(");
Serial.print(" "); Serial.print(millis() / 1000.0);
(msgDir == 0) ? Serial.print("RX ") : Serial.print("TX "); (msgDir == MSG_RX) ? Serial.print(") RX0 ") : Serial.print(") TX1 ");
Serial.print(frame.ID, HEX); Serial.print(frame.ID, HEX);
Serial.print(" "); Serial.print(" [");
Serial.print(frame.DLC); Serial.print(frame.DLC);
Serial.print(" "); Serial.print("] ");
for (i = 0; i < frame.DLC; i++) { for (i = 0; i < frame.DLC; i++) {
Serial.print(frame.data.u8[i] < 16 ? "0" : ""); Serial.print(frame.data.u8[i] < 16 ? "0" : "");
Serial.print(frame.data.u8[i], HEX); Serial.print(frame.data.u8[i], HEX);
Serial.print(" "); if (i < frame.DLC - 1)
Serial.print(" ");
} }
Serial.println(" "); Serial.println("");
#endif //#DEBUG_CAN_DATA #endif //#DEBUG_CAN_DATA
if (datalayer.system.info.can_logging_active) { // If user clicked on CAN Logging page in webserver, start recording if (datalayer.system.info.can_logging_active) { // If user clicked on CAN Logging page in webserver, start recording
@ -686,16 +687,15 @@ void print_can_frame(CAN_frame frame, frameDirection msgDir) {
// Functions // Functions
void receive_canfd() { // This section checks if we have a complete CAN-FD message incoming void receive_canfd() { // This section checks if we have a complete CAN-FD message incoming
CANFDMessage frame; CANFDMessage frame;
if (canfd.available()) { int count = 0;
while (canfd.available() && count++ < 16) {
canfd.receive(frame); canfd.receive(frame);
CAN_frame rx_frame; CAN_frame rx_frame;
rx_frame.ID = frame.id; rx_frame.ID = frame.id;
rx_frame.ext_ID = frame.ext; rx_frame.ext_ID = frame.ext;
rx_frame.DLC = frame.len; rx_frame.DLC = frame.len;
for (uint8_t i = 0; i < rx_frame.DLC && i < 64; i++) { memcpy(rx_frame.data.u8, frame.data, MIN(rx_frame.DLC, 64));
rx_frame.data.u8[i] = frame.data[i];
}
//message incoming, pass it on to the handler //message incoming, pass it on to the handler
receive_can(&rx_frame, CAN_ADDON_FD_MCP2518); receive_can(&rx_frame, CAN_ADDON_FD_MCP2518);
receive_can(&rx_frame, CANFD_NATIVE); receive_can(&rx_frame, CANFD_NATIVE);
@ -1180,6 +1180,11 @@ void transmit_can(CAN_frame* tx_frame, int interface) {
case CAN_ADDON_FD_MCP2518: { case CAN_ADDON_FD_MCP2518: {
#ifdef CAN_FD #ifdef CAN_FD
CANFDMessage MCP2518Frame; CANFDMessage MCP2518Frame;
if (tx_frame->FD) {
MCP2518Frame.type = CANFDMessage::CANFD_WITH_BIT_RATE_SWITCH;
} else { //Classic CAN message
MCP2518Frame.type = CANFDMessage::CAN_DATA;
}
MCP2518Frame.id = tx_frame->ID; MCP2518Frame.id = tx_frame->ID;
MCP2518Frame.ext = tx_frame->ext_ID ? CAN_frame_ext : CAN_frame_std; MCP2518Frame.ext = tx_frame->ext_ID ? CAN_frame_ext : CAN_frame_std;
MCP2518Frame.len = tx_frame->DLC; MCP2518Frame.len = tx_frame->DLC;

View file

@ -19,6 +19,7 @@
//#define KIA_HYUNDAI_64_BATTERY //#define KIA_HYUNDAI_64_BATTERY
//#define KIA_E_GMP_BATTERY //#define KIA_E_GMP_BATTERY
//#define KIA_HYUNDAI_HYBRID_BATTERY //#define KIA_HYUNDAI_HYBRID_BATTERY
//#define MEB_BATTERY
//#define MG_5_BATTERY //#define MG_5_BATTERY
//#define NISSAN_LEAF_BATTERY //#define NISSAN_LEAF_BATTERY
//#define PYLON_BATTERY //#define PYLON_BATTERY

View file

@ -43,6 +43,10 @@
#include "KIA-HYUNDAI-HYBRID-BATTERY.h" #include "KIA-HYUNDAI-HYBRID-BATTERY.h"
#endif #endif
#ifdef MEB_BATTERY
#include "MEB-BATTERY.h"
#endif
#ifdef MG_5_BATTERY #ifdef MG_5_BATTERY
#include "MG-5-BATTERY.h" #include "MG-5-BATTERY.h"
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,138 @@
#ifndef MEB_BATTERY_H
#define MEB_BATTERY_H
#include <Arduino.h>
#include "../include.h"
#define BATTERY_SELECTED
#define MAX_PACK_VOLTAGE_84S_DV 3528 //5000 = 500.0V
#define MIN_PACK_VOLTAGE_84S_DV 2520
#define MAX_PACK_VOLTAGE_96S_DV 4032
#define MIN_PACK_VOLTAGE_96S_DV 2880
#define MAX_PACK_VOLTAGE_108S_DV 4536
#define MIN_PACK_VOLTAGE_108S_DV 3240
#define MAX_CELL_DEVIATION_MV 150
#define MAX_CELL_VOLTAGE_MV 4250 //Battery is put into emergency stop if one cell goes over this value
#define MIN_CELL_VOLTAGE_MV 2700 //Battery is put into emergency stop if one cell goes below this value
#define PID_SOC 0x028C
#define PID_VOLTAGE 0x1E3B
#define PID_CURRENT 0x1E3D
#define PID_MAX_TEMP 0x1E0E
#define PID_MIN_TEMP 0x1E0F
#define PID_MAX_CHARGE_VOLTAGE 0x5171
#define PID_MIN_DISCHARGE_VOLTAGE 0x5170
#define PID_ALLOWED_CHARGE_POWER 0x1E1B
#define PID_ALLOWED_DISCHARGE_POWER 0x1E1C
#define PID_CELLVOLTAGE_CELL_1 0x1E40
#define PID_CELLVOLTAGE_CELL_2 0x1E41
#define PID_CELLVOLTAGE_CELL_3 0x1E42
#define PID_CELLVOLTAGE_CELL_4 0x1E43
#define PID_CELLVOLTAGE_CELL_5 0x1E44
#define PID_CELLVOLTAGE_CELL_6 0x1E45
#define PID_CELLVOLTAGE_CELL_7 0x1E46
#define PID_CELLVOLTAGE_CELL_8 0x1E47
#define PID_CELLVOLTAGE_CELL_9 0x1E48
#define PID_CELLVOLTAGE_CELL_10 0x1E49
#define PID_CELLVOLTAGE_CELL_11 0x1E4A
#define PID_CELLVOLTAGE_CELL_12 0x1E4B
#define PID_CELLVOLTAGE_CELL_13 0x1E4C
#define PID_CELLVOLTAGE_CELL_14 0x1E4D
#define PID_CELLVOLTAGE_CELL_15 0x1E4E
#define PID_CELLVOLTAGE_CELL_16 0x1E4F
#define PID_CELLVOLTAGE_CELL_17 0x1E50
#define PID_CELLVOLTAGE_CELL_18 0x1E51
#define PID_CELLVOLTAGE_CELL_19 0x1E52
#define PID_CELLVOLTAGE_CELL_20 0x1E53
#define PID_CELLVOLTAGE_CELL_21 0x1E54
#define PID_CELLVOLTAGE_CELL_22 0x1E55
#define PID_CELLVOLTAGE_CELL_23 0x1E56
#define PID_CELLVOLTAGE_CELL_24 0x1E57
#define PID_CELLVOLTAGE_CELL_25 0x1E58
#define PID_CELLVOLTAGE_CELL_26 0x1E59
#define PID_CELLVOLTAGE_CELL_27 0x1E5A
#define PID_CELLVOLTAGE_CELL_28 0x1E5B
#define PID_CELLVOLTAGE_CELL_29 0x1E5C
#define PID_CELLVOLTAGE_CELL_30 0x1E5D
#define PID_CELLVOLTAGE_CELL_31 0x1E5E
#define PID_CELLVOLTAGE_CELL_32 0x1E5F
#define PID_CELLVOLTAGE_CELL_33 0x1E60
#define PID_CELLVOLTAGE_CELL_34 0x1E61
#define PID_CELLVOLTAGE_CELL_35 0x1E62
#define PID_CELLVOLTAGE_CELL_36 0x1E63
#define PID_CELLVOLTAGE_CELL_37 0x1E64
#define PID_CELLVOLTAGE_CELL_38 0x1E65
#define PID_CELLVOLTAGE_CELL_39 0x1E66
#define PID_CELLVOLTAGE_CELL_40 0x1E67
#define PID_CELLVOLTAGE_CELL_41 0x1E68
#define PID_CELLVOLTAGE_CELL_42 0x1E69
#define PID_CELLVOLTAGE_CELL_43 0x1E6A
#define PID_CELLVOLTAGE_CELL_44 0x1E6B
#define PID_CELLVOLTAGE_CELL_45 0x1E6C
#define PID_CELLVOLTAGE_CELL_46 0x1E6D
#define PID_CELLVOLTAGE_CELL_47 0x1E6E
#define PID_CELLVOLTAGE_CELL_48 0x1E6F
#define PID_CELLVOLTAGE_CELL_49 0x1E70
#define PID_CELLVOLTAGE_CELL_50 0x1E71
#define PID_CELLVOLTAGE_CELL_51 0x1E72
#define PID_CELLVOLTAGE_CELL_52 0x1E73
#define PID_CELLVOLTAGE_CELL_53 0x1E74
#define PID_CELLVOLTAGE_CELL_54 0x1E75
#define PID_CELLVOLTAGE_CELL_55 0x1E76
#define PID_CELLVOLTAGE_CELL_56 0x1E77
#define PID_CELLVOLTAGE_CELL_57 0x1E78
#define PID_CELLVOLTAGE_CELL_58 0x1E79
#define PID_CELLVOLTAGE_CELL_59 0x1E7A
#define PID_CELLVOLTAGE_CELL_60 0x1E7B
#define PID_CELLVOLTAGE_CELL_61 0x1E7C
#define PID_CELLVOLTAGE_CELL_62 0x1E7D
#define PID_CELLVOLTAGE_CELL_63 0x1E7E
#define PID_CELLVOLTAGE_CELL_64 0x1E7F
#define PID_CELLVOLTAGE_CELL_65 0x1E80
#define PID_CELLVOLTAGE_CELL_66 0x1E81
#define PID_CELLVOLTAGE_CELL_67 0x1E82
#define PID_CELLVOLTAGE_CELL_68 0x1E83
#define PID_CELLVOLTAGE_CELL_69 0x1E84
#define PID_CELLVOLTAGE_CELL_70 0x1E85
#define PID_CELLVOLTAGE_CELL_71 0x1E86
#define PID_CELLVOLTAGE_CELL_72 0x1E87
#define PID_CELLVOLTAGE_CELL_73 0x1E88
#define PID_CELLVOLTAGE_CELL_74 0x1E89
#define PID_CELLVOLTAGE_CELL_75 0x1E8A
#define PID_CELLVOLTAGE_CELL_76 0x1E8B
#define PID_CELLVOLTAGE_CELL_77 0x1E8C
#define PID_CELLVOLTAGE_CELL_78 0x1E8D
#define PID_CELLVOLTAGE_CELL_79 0x1E8E
#define PID_CELLVOLTAGE_CELL_80 0x1E8F
#define PID_CELLVOLTAGE_CELL_81 0x1E90
#define PID_CELLVOLTAGE_CELL_82 0x1E91
#define PID_CELLVOLTAGE_CELL_83 0x1E92
#define PID_CELLVOLTAGE_CELL_84 0x1E93
#define PID_CELLVOLTAGE_CELL_85 0x1E94
#define PID_CELLVOLTAGE_CELL_86 0x1E95
#define PID_CELLVOLTAGE_CELL_87 0x1E96
#define PID_CELLVOLTAGE_CELL_88 0x1E97
#define PID_CELLVOLTAGE_CELL_89 0x1E98
#define PID_CELLVOLTAGE_CELL_90 0x1E99
#define PID_CELLVOLTAGE_CELL_91 0x1E9A
#define PID_CELLVOLTAGE_CELL_92 0x1E9B
#define PID_CELLVOLTAGE_CELL_93 0x1E9C
#define PID_CELLVOLTAGE_CELL_94 0x1E9D
#define PID_CELLVOLTAGE_CELL_95 0x1E9E
#define PID_CELLVOLTAGE_CELL_96 0x1E9F
#define PID_CELLVOLTAGE_CELL_97 0x1EA0
#define PID_CELLVOLTAGE_CELL_98 0x1EA1
#define PID_CELLVOLTAGE_CELL_99 0x1EA2
#define PID_CELLVOLTAGE_CELL_100 0x1EA3
#define PID_CELLVOLTAGE_CELL_101 0x1EA4
#define PID_CELLVOLTAGE_CELL_102 0x1EA5
#define PID_CELLVOLTAGE_CELL_103 0x1EA6
#define PID_CELLVOLTAGE_CELL_104 0x1EA7
#define PID_CELLVOLTAGE_CELL_105 0x1EA8
#define PID_CELLVOLTAGE_CELL_106 0x1EA9
#define PID_CELLVOLTAGE_CELL_107 0x1EAA
#define PID_CELLVOLTAGE_CELL_108 0x1EAB
void setup_battery(void);
void transmit_can(CAN_frame* tx_frame, int interface);
#endif

View file

@ -278,6 +278,78 @@ typedef struct {
} DATALAYER_INFO_NISSAN_LEAF; } DATALAYER_INFO_NISSAN_LEAF;
typedef struct {
/** uint8_t */
/** Service disconnect switch status */
bool SDSW = 0;
/** uint8_t */
/** Pilotline status */
bool pilotline = 0;
/** uint8_t */
/** Transportation mode status */
bool transportmode = 0;
/** uint8_t */
/** Componentprotection mode status */
bool componentprotection = 0;
/** uint8_t */
/** Shutdown status */
bool shutdown_active = 0;
/** uint8_t */
/** Battery heating status */
bool battery_heating = 0;
/** uint8_t */
/** All realtime_ warnings have same enumeration, 0 = no fault, 1 = error level 1, 2 error level 2, 3 error level 3 */
uint8_t rt_overcurrent = 0;
uint8_t rt_CAN_fault = 0;
uint8_t rt_overcharge = 0;
uint8_t rt_SOC_high = 0;
uint8_t rt_SOC_low = 0;
uint8_t rt_SOC_jumping = 0;
uint8_t rt_temp_difference = 0;
uint8_t rt_cell_overtemp = 0;
uint8_t rt_cell_undertemp = 0;
uint8_t rt_battery_overvolt = 0;
uint8_t rt_battery_undervol = 0;
uint8_t rt_cell_overvolt = 0;
uint8_t rt_cell_undervol = 0;
uint8_t rt_cell_imbalance = 0;
uint8_t rt_battery_unathorized = 0;
/** uint8_t */
/** HVIL status, 0 = Init, 1 = Closed, 2 = Open!, 3 = Fault */
uint8_t HVIL = 0;
/** uint8_t */
/** 0 = HV inactive, 1 = HV active, 2 = Balancing, 3 = Extern charging, 4 = AC charging, 5 = Battery error, 6 = DC charging, 7 = init */
uint8_t BMS_mode = 0;
/** uint8_t */
/** 1 = Battery display, 4 = Battery display OK, 4 = Display battery charging, 6 = Display battery check, 7 = Fault */
uint8_t battery_diagnostic = 0;
/** uint8_t */
/** 0 = init, 1 = no open HV line detected, 2 = open HV line , 3 = fault */
uint8_t status_HV_line = 0;
/** uint8_t */
/** 0 = OK, 1 = Not OK, 0x06 = init, 0x07 = fault */
uint8_t warning_support = 0;
/** uint32_t */
/** Isolation resistance in kOhm */
uint32_t isolation_resistance = 0;
/** uint8_t */
/** 0=Init, 1=BMS intermediate circuit voltage-free (U_Zwkr < 20V), 2=BMS intermediate circuit not voltage-free (U_Zwkr >/= 25V, hysteresis), 3=Error */
uint8_t BMS_status_voltage_free = 0;
/** uint8_t */
/** 0 Component_IO, 1 Restricted_CompFkt_Isoerror_I, 2 Restricted_CompFkt_Isoerror_II, 3 Restricted_CompFkt_Interlock, 4 Restricted_CompFkt_SD, 5 Restricted_CompFkt_Performance red, 6 = No component function, 7 = Init */
uint8_t BMS_error_status = 0;
/** uint8_t */
/** 0 init, 1 closed, 2 open, 3 fault */
uint8_t BMS_Kl30c_Status = 0;
/** bool */
/** true if BMS requests error/warning light */
bool BMS_OBD_MIL = 0;
bool BMS_error_lamp_req = 0;
bool BMS_warning_lamp_req = 0;
int32_t BMS_voltage_intermediate_dV = 0;
int32_t BMS_voltage_dV = 0;
} DATALAYER_INFO_MEB;
typedef struct { typedef struct {
/** uint16_t */ /** uint16_t */
/** Values WIP*/ /** Values WIP*/
@ -332,6 +404,7 @@ class DataLayerExtended {
DATALAYER_INFO_CELLPOWER cellpower; DATALAYER_INFO_CELLPOWER cellpower;
DATALAYER_INFO_TESLA tesla; DATALAYER_INFO_TESLA tesla;
DATALAYER_INFO_NISSAN_LEAF nissanleaf; DATALAYER_INFO_NISSAN_LEAF nissanleaf;
DATALAYER_INFO_MEB meb;
DATALAYER_INFO_ZOE_PH2 zoePH2; DATALAYER_INFO_ZOE_PH2 zoePH2;
}; };

View file

@ -97,7 +97,7 @@ void update_machineryprotection() {
clear_event(EVENT_SOH_LOW); clear_event(EVENT_SOH_LOW);
} }
#if !defined(PYLON_BATTERY) && !defined(RENAULT_TWIZY_BATTERY) #ifdef NISSAN_LEAF_BATTERY
// Check if SOC% is plausible // Check if SOC% is plausible
if (datalayer.battery.status.voltage_dV > if (datalayer.battery.status.voltage_dV >
(datalayer.battery.info.max_design_voltage_dV - (datalayer.battery.info.max_design_voltage_dV -
@ -108,7 +108,7 @@ void update_machineryprotection() {
clear_event(EVENT_SOC_PLAUSIBILITY_ERROR); clear_event(EVENT_SOC_PLAUSIBILITY_ERROR);
} }
} }
#endif #endif //NISSAN_LEAF_BATTERY
// Check diff between highest and lowest cell // Check diff between highest and lowest cell
cell_deviation_mV = (datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV); cell_deviation_mV = (datalayer.battery.status.cell_max_voltage_mV - datalayer.battery.status.cell_min_voltage_mV);

View file

@ -144,6 +144,7 @@ void init_events(void) {
events.entries[EVENT_CANMCP_INIT_FAILURE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CANMCP_INIT_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CANFD_BUFFER_FULL].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CANFD_BUFFER_FULL].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO; events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO;
events.entries[EVENT_CANFD_RX_OVERRUN].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_RX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CAN_RX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CAN2_RX_FAILURE].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN2_RX_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CANFD_RX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CANFD_RX_FAILURE].level = EVENT_LEVEL_ERROR;
@ -270,6 +271,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "CAN-FD buffer overflowed. Some CAN messages were not sent. Contact developers."; return "CAN-FD buffer overflowed. Some CAN messages were not sent. Contact developers.";
case EVENT_CAN_OVERRUN: case EVENT_CAN_OVERRUN:
return "CAN message failed to send within defined time. Contact developers, CPU load might be too high."; return "CAN message failed to send within defined time. Contact developers, CPU load might be too high.";
case EVENT_CANFD_RX_OVERRUN:
return "CAN-FD failed to receive all messages from CAN bus. Contact developers, CPU load might be too high.";
case EVENT_CAN_RX_FAILURE: case EVENT_CAN_RX_FAILURE:
return "No CAN communication detected for 60s. Shutting down battery control."; return "No CAN communication detected for 60s. Shutting down battery control.";
case EVENT_CAN2_RX_FAILURE: case EVENT_CAN2_RX_FAILURE:

View file

@ -30,6 +30,7 @@
XX(EVENT_CANMCP_INIT_FAILURE) \ XX(EVENT_CANMCP_INIT_FAILURE) \
XX(EVENT_CANFD_BUFFER_FULL) \ XX(EVENT_CANFD_BUFFER_FULL) \
XX(EVENT_CAN_OVERRUN) \ XX(EVENT_CAN_OVERRUN) \
XX(EVENT_CANFD_RX_OVERRUN) \
XX(EVENT_CAN_RX_FAILURE) \ XX(EVENT_CAN_RX_FAILURE) \
XX(EVENT_CAN2_RX_FAILURE) \ XX(EVENT_CAN2_RX_FAILURE) \
XX(EVENT_CANFD_RX_FAILURE) \ XX(EVENT_CANFD_RX_FAILURE) \

View file

@ -13,7 +13,9 @@ enum led_color { GREEN, YELLOW, RED, BLUE, RGB };
#define INTERVAL_10_MS 10 #define INTERVAL_10_MS 10
#define INTERVAL_20_MS 20 #define INTERVAL_20_MS 20
#define INTERVAL_30_MS 30 #define INTERVAL_30_MS 30
#define INTERVAL_40_MS 40
#define INTERVAL_50_MS 50 #define INTERVAL_50_MS 50
#define INTERVAL_70_MS 70
#define INTERVAL_100_MS 100 #define INTERVAL_100_MS 100
#define INTERVAL_200_MS 200 #define INTERVAL_200_MS 200
#define INTERVAL_250_MS 250 #define INTERVAL_250_MS 250

View file

@ -420,6 +420,205 @@ String advanced_battery_processor(const String& var) {
content += "<h4>Challenge failed: " + String(datalayer_extended.nissanleaf.challengeFailed) + "</h4>"; content += "<h4>Challenge failed: " + String(datalayer_extended.nissanleaf.challengeFailed) + "</h4>";
#endif #endif
#ifdef MEB_BATTERY
content += datalayer_extended.meb.SDSW ? "<h4>Service disconnect switch: Missing!</h4>"
: "<h4>Service disconnect switch: OK</h4>";
content += datalayer_extended.meb.pilotline ? "<h4>Pilotline: Open!</h4>" : "<h4>Pilotline: OK</h4>";
content += datalayer_extended.meb.transportmode ? "<h4>Transportmode: Locked!</h4>" : "<h4>Transportmode: OK</h4>";
content += datalayer_extended.meb.shutdown_active ? "<h4>Shutdown: Active!</h4>" : "<h4>Shutdown: No</h4>";
content += datalayer_extended.meb.componentprotection ? "<h4>Component protection: Active!</h4>"
: "<h4>Component protection: No</h4>";
content += "<h4>HVIL status: ";
switch (datalayer_extended.meb.HVIL) {
case 0:
content += String("Init");
break;
case 1:
content += String("Closed");
break;
case 2:
content += String("Open!");
break;
case 3:
content += String("Fault");
break;
default:
content += String("?");
}
content += "</h4><h4>KL30C status: ";
switch (datalayer_extended.meb.BMS_Kl30c_Status) {
case 0:
content += String("Init");
break;
case 1:
content += String("Closed");
break;
case 2:
content += String("Open!");
break;
case 3:
content += String("Fault");
break;
default:
content += String("?");
}
content += "</h4><h4>BMS mode: ";
switch (datalayer_extended.meb.BMS_mode) {
case 0:
content += String("HV inactive");
break;
case 1:
content += String("HV active");
break;
case 2:
content += String("Balancing");
break;
case 3:
content += String("Extern charging");
break;
case 4:
content += String("AC charging");
break;
case 5:
content += String("Battery error");
break;
case 6:
content += String("DC charging");
break;
case 7:
content += String("Init");
break;
default:
content += String("?");
}
content += "</h4><h4>Diagnostic: ";
switch (datalayer_extended.meb.battery_diagnostic) {
case 0:
content += String("Init");
break;
case 1:
content += String("Battery display");
break;
case 4:
content += String("Battery display OK");
break;
case 6:
content += String("Battery display check");
break;
case 7:
content += String("Fault");
break;
default:
content += String("?");
}
content += "</h4><h4>HV line status: ";
switch (datalayer_extended.meb.status_HV_line) {
case 0:
content += String("Init");
break;
case 1:
content += String("No open HV line detected");
break;
case 2:
content += String("Open HV line");
break;
case 3:
content += String("Fault");
break;
default:
content += String("? ") + String(datalayer_extended.meb.status_HV_line);
}
content += "</h4><h4>Warning support: ";
switch (datalayer_extended.meb.warning_support) {
case 0:
content += String("OK");
break;
case 1:
content += String("Not OK");
break;
case 6:
content += String("Init");
break;
case 7:
content += String("Fault");
break;
default:
content += String("?");
}
content += "</h4><h4>Interm. Voltage (" + String(datalayer_extended.meb.BMS_voltage_intermediate_dV / 10.0, 1) +
"V) status: ";
switch (datalayer_extended.meb.BMS_status_voltage_free) {
case 0:
content += String("Init");
break;
case 1:
content += String("BMS interm circuit voltage free (U<20V)");
break;
case 2:
content += String("BMS interm circuit not voltage free (U >= 25V)");
break;
case 3:
content += String("Error");
break;
default:
content += String("?");
}
content += "</h4><h4>BMS error status: ";
switch (datalayer_extended.meb.BMS_error_status) {
case 0:
content += String("Component IO");
break;
case 1:
content += String("Iso Error 1");
break;
case 2:
content += String("Iso Error 2");
break;
case 3:
content += String("Interlock");
break;
case 4:
content += String("SD");
break;
case 5:
content += String("Performance red");
break;
case 6:
content += String("No component function");
break;
case 7:
content += String("Init");
break;
default:
content += String("?");
}
content += "</h4><h4>BMS voltage: " + String(datalayer_extended.meb.BMS_voltage_dV / 10.0, 1) + "</h4>";
content += datalayer_extended.meb.BMS_OBD_MIL ? "<h4>OBD MIL: ON!</h4>" : "<h4>OBD MIL: Off</h4>";
content +=
datalayer_extended.meb.BMS_error_lamp_req ? "<h4>Red error lamp: ON!</h4>" : "<h4>Red error lamp: Off</h4>";
content += datalayer_extended.meb.BMS_warning_lamp_req ? "<h4>Yellow warning lamp: ON!</h4>"
: "<h4>Yellow warning lamp: Off</h4>";
content += "<h4>Isolation resistance: " + String(datalayer_extended.meb.isolation_resistance) + " kOhm</h4>";
content +=
datalayer_extended.meb.battery_heating ? "<h4>Battery heating: Active!</h4>" : "<h4>Battery heating: Off</h4>";
const char* rt_enum[] = {"No", "Error level 1", "Error level 2", "Error level 3"};
content += "<h4>Overcurrent: " + String(rt_enum[datalayer_extended.meb.rt_overcurrent]) + "</h4>";
content += "<h4>CAN fault: " + String(rt_enum[datalayer_extended.meb.rt_CAN_fault]) + "</h4>";
content += "<h4>Overcharged: " + String(rt_enum[datalayer_extended.meb.rt_overcharge]) + "</h4>";
content += "<h4>SOC too high: " + String(rt_enum[datalayer_extended.meb.rt_SOC_high]) + "</h4>";
content += "<h4>SOC too low: " + String(rt_enum[datalayer_extended.meb.rt_SOC_low]) + "</h4>";
content += "<h4>SOC jumping: " + String(rt_enum[datalayer_extended.meb.rt_SOC_jumping]) + "</h4>";
content += "<h4>Temp difference: " + String(rt_enum[datalayer_extended.meb.rt_temp_difference]) + "</h4>";
content += "<h4>Cell overtemp: " + String(rt_enum[datalayer_extended.meb.rt_cell_overtemp]) + "</h4>";
content += "<h4>Cell undertemp: " + String(rt_enum[datalayer_extended.meb.rt_cell_undertemp]) + "</h4>";
content += "<h4>Battery overvoltage: " + String(rt_enum[datalayer_extended.meb.rt_battery_overvolt]) + "</h4>";
content += "<h4>Battery undervoltage: " + String(rt_enum[datalayer_extended.meb.rt_battery_undervol]) + "</h4>";
content += "<h4>Cell overvoltage: " + String(rt_enum[datalayer_extended.meb.rt_cell_overvolt]) + "</h4>";
content += "<h4>Cell undervoltage: " + String(rt_enum[datalayer_extended.meb.rt_cell_undervol]) + "</h4>";
content += "<h4>Cell imbalance: " + String(rt_enum[datalayer_extended.meb.rt_cell_imbalance]) + "</h4>";
content += "<h4>Battery unathorized: " + String(rt_enum[datalayer_extended.meb.rt_battery_unathorized]) + "</h4>";
#endif //MEB_BATTERY
#ifdef RENAULT_ZOE_GEN2_BATTERY #ifdef RENAULT_ZOE_GEN2_BATTERY
content += "<h4>soc: " + String(datalayer_extended.zoePH2.battery_soc) + "</h4>"; content += "<h4>soc: " + String(datalayer_extended.zoePH2.battery_soc) + "</h4>";
content += "<h4>usable soc: " + String(datalayer_extended.zoePH2.battery_usable_soc) + "</h4>"; content += "<h4>usable soc: " + String(datalayer_extended.zoePH2.battery_usable_soc) + "</h4>";
@ -467,8 +666,9 @@ String advanced_battery_processor(const String& var) {
content += "<h4>soc max: " + String(datalayer_extended.zoePH2.battery_soc_max) + "</h4>"; content += "<h4>soc max: " + String(datalayer_extended.zoePH2.battery_soc_max) + "</h4>";
#endif //RENAULT_ZOE_GEN2_BATTERY #endif //RENAULT_ZOE_GEN2_BATTERY
#if !defined(TESLA_BATTERY) && !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && \ #if !defined(TESLA_BATTERY) && !defined(NISSAN_LEAF_BATTERY) && !defined(BMW_I3_BATTERY) && \
!defined(BYD_ATTO_3_BATTERY) && !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) !defined(BYD_ATTO_3_BATTERY) && !defined(RENAULT_ZOE_GEN2_BATTERY) && !defined(CELLPOWER_BMS) && \
!defined(MEB_BATTERY) //Only the listed types have extra info
content += "No extra information available for this battery type"; content += "No extra information available for this battery type";
#endif #endif

View file

@ -60,8 +60,8 @@ String events_processor(const String& var) {
order_events.clear(); order_events.clear();
content.concat(FPSTR(EVENTS_HTML_END)); content.concat(FPSTR(EVENTS_HTML_END));
return content; return content;
return String();
} }
return String();
} }
/* Script for displaying event log before it gets minified /* Script for displaying event log before it gets minified