Improvement: ECMP contactor closing (#1177)

* Add contactor closing and diagnostic commands
This commit is contained in:
Daniel Öster 2025-06-12 12:55:31 +03:00 committed by GitHub
parent 27ca07c6bb
commit f44091997f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 2051 additions and 43 deletions

View file

@ -26,14 +26,17 @@ class Battery {
virtual bool supports_reset_SOH() { return false; }
virtual bool supports_reset_BECM() { return false; }
virtual bool supports_contactor_close() { return false; }
virtual bool supports_contactor_reset() { return false; }
virtual bool supports_set_fake_voltage() { return false; }
virtual bool supports_manual_balancing() { return false; }
virtual bool supports_real_BMS_status() { return false; }
virtual bool supports_toggle_SOC_method() { return false; }
virtual bool supports_factory_mode_method() { return false; }
virtual void clear_isolation() {}
virtual void reset_BMS() {}
virtual void reset_crash() {}
virtual void reset_contactor() {}
virtual void reset_NVROL() {}
virtual void reset_DTC() {}
virtual void read_DTC() {}
@ -42,6 +45,7 @@ class Battery {
virtual void request_open_contactors() {}
virtual void request_close_contactors() {}
virtual void toggle_SOC_method() {}
virtual void set_factory_mode() {}
virtual void set_fake_voltage(float v) {}
virtual float get_voltage() { return static_cast<float>(datalayer.battery.status.voltage_dV) / 10.0; }

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,18 @@ class EcmpBattery : public CanBattery {
virtual void update_values();
virtual void transmit_can(unsigned long currentMillis);
bool supports_clear_isolation() { return true; }
void clear_isolation() { datalayer_extended.stellantisECMP.UserRequestIsolationReset = true; }
bool supports_factory_mode_method() { return true; }
void set_factory_mode() { datalayer_extended.stellantisECMP.UserRequestDisableIsoMonitoring = true; }
bool supports_reset_crash() { return true; }
void reset_crash() { datalayer_extended.stellantisECMP.UserRequestCollisionReset = true; }
bool supports_contactor_reset() { return true; }
void reset_contactor() { datalayer_extended.stellantisECMP.UserRequestContactorReset = true; }
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
private:
@ -25,9 +37,25 @@ class EcmpBattery : public CanBattery {
static const int MAX_CELL_DEVIATION_MV = 100;
static const int MAX_CELL_VOLTAGE_MV = 4250;
static const int MIN_CELL_VOLTAGE_MV = 2700;
#define NOT_SAMPLED_YET 255
#define COMPLETED_STATE 0
bool battery_RelayOpenRequest = false;
bool battery_InterlockOpen = false;
uint8_t ContactorResetStatemachine = 0;
uint8_t CollisionResetStatemachine = 0;
uint8_t IsolationResetStatemachine = 0;
uint8_t DisableIsoMonitoringStatemachine = 0;
uint8_t timeSpentDisableIsoMonitoring = 0;
uint8_t timeSpentContactorReset = 0;
uint8_t timeSpentCollisionReset = 0;
uint8_t timeSpentIsolationReset = 0;
uint8_t countIsolationReset = 0;
uint8_t counter_10ms = 0;
uint8_t counter_20ms = 0;
uint8_t counter_50ms = 0;
uint8_t counter_100ms = 0;
uint8_t counter_010 = 0;
uint32_t ticks_552 = 0x0BC8CFC6;
uint8_t battery_MainConnectorState = 0;
int16_t battery_current = 0;
uint16_t battery_voltage = 370;
@ -36,27 +64,368 @@ class EcmpBattery : public CanBattery {
uint16_t battery_AllowedMaxChargeCurrent = 0;
uint16_t battery_AllowedMaxDischargeCurrent = 0;
uint16_t battery_insulationResistanceKOhm = 0;
uint8_t battery_insulation_failure_diag = 0;
int16_t battery_highestTemperature = 0;
int16_t battery_lowestTemperature = 0;
uint8_t pid_welding_detection = NOT_SAMPLED_YET;
uint8_t pid_reason_open = NOT_SAMPLED_YET;
uint8_t pid_contactor_status = NOT_SAMPLED_YET;
uint8_t pid_negative_contactor_control = NOT_SAMPLED_YET;
uint8_t pid_negative_contactor_status = NOT_SAMPLED_YET;
uint8_t pid_positive_contactor_control = NOT_SAMPLED_YET;
uint8_t pid_positive_contactor_status = NOT_SAMPLED_YET;
uint8_t pid_contactor_negative = NOT_SAMPLED_YET;
uint8_t pid_contactor_positive = NOT_SAMPLED_YET;
uint8_t pid_precharge_relay_control = NOT_SAMPLED_YET;
uint8_t pid_precharge_relay_status = NOT_SAMPLED_YET;
uint8_t pid_recharge_status = NOT_SAMPLED_YET;
uint8_t pid_delta_temperature = NOT_SAMPLED_YET;
uint8_t pid_coldest_module = NOT_SAMPLED_YET;
uint8_t pid_lowest_temperature = NOT_SAMPLED_YET;
uint8_t pid_average_temperature = NOT_SAMPLED_YET;
uint8_t pid_highest_temperature = NOT_SAMPLED_YET;
uint8_t pid_hottest_module = NOT_SAMPLED_YET;
uint16_t pid_avg_cell_voltage = NOT_SAMPLED_YET;
int32_t pid_current = NOT_SAMPLED_YET;
uint32_t pid_insulation_res_neg = NOT_SAMPLED_YET;
uint32_t pid_insulation_res_pos = NOT_SAMPLED_YET;
uint32_t pid_max_current_10s = NOT_SAMPLED_YET;
uint32_t pid_max_discharge_10s = NOT_SAMPLED_YET;
uint32_t pid_max_discharge_30s = NOT_SAMPLED_YET;
uint32_t pid_max_charge_10s = NOT_SAMPLED_YET;
uint32_t pid_max_charge_30s = NOT_SAMPLED_YET;
uint32_t pid_energy_capacity = NOT_SAMPLED_YET;
uint8_t pid_highest_cell_voltage_num = NOT_SAMPLED_YET;
uint8_t pid_lowest_cell_voltage_num = NOT_SAMPLED_YET;
uint16_t pid_sum_of_cells = NOT_SAMPLED_YET;
uint16_t pid_cell_min_capacity = NOT_SAMPLED_YET;
uint8_t pid_cell_voltage_measurement_status = NOT_SAMPLED_YET;
uint32_t pid_insulation_res = NOT_SAMPLED_YET;
uint16_t pid_pack_voltage = NOT_SAMPLED_YET;
uint16_t pid_high_cell_voltage = NOT_SAMPLED_YET;
uint16_t pid_low_cell_voltage = NOT_SAMPLED_YET;
uint8_t pid_battery_energy = NOT_SAMPLED_YET;
uint32_t pid_crash_counter = NOT_SAMPLED_YET;
uint8_t pid_wire_crash = NOT_SAMPLED_YET;
uint8_t pid_CAN_crash = NOT_SAMPLED_YET;
uint32_t pid_history_data = NOT_SAMPLED_YET;
uint32_t pid_lowsoc_counter = NOT_SAMPLED_YET;
uint32_t pid_last_can_failure_detail = NOT_SAMPLED_YET;
uint32_t pid_hw_version_num = NOT_SAMPLED_YET;
uint32_t pid_sw_version_num = NOT_SAMPLED_YET;
uint32_t pid_factory_mode_control = NOT_SAMPLED_YET;
uint8_t pid_battery_serial[13] = {0};
uint32_t pid_aux_fuse_state = NOT_SAMPLED_YET;
uint32_t pid_battery_state = NOT_SAMPLED_YET;
uint32_t pid_precharge_short_circuit = NOT_SAMPLED_YET;
uint32_t pid_eservice_plug_state = NOT_SAMPLED_YET;
uint32_t pid_mainfuse_state = NOT_SAMPLED_YET;
uint32_t pid_most_critical_fault = NOT_SAMPLED_YET;
uint32_t pid_current_time = NOT_SAMPLED_YET;
uint32_t pid_time_sent_by_car = NOT_SAMPLED_YET;
uint32_t pid_12v = 12345; //Initialized to over 12V to not trigger low 12V event
uint32_t pid_12v_abnormal = NOT_SAMPLED_YET;
uint32_t pid_hvil_in_voltage = NOT_SAMPLED_YET;
uint32_t pid_hvil_out_voltage = NOT_SAMPLED_YET;
uint32_t pid_hvil_state = NOT_SAMPLED_YET;
uint32_t pid_bms_state = NOT_SAMPLED_YET;
uint32_t pid_vehicle_speed = NOT_SAMPLED_YET;
uint32_t pid_time_spent_over_55c = NOT_SAMPLED_YET;
uint32_t pid_contactor_closing_counter = NOT_SAMPLED_YET;
uint32_t pid_date_of_manufacture = NOT_SAMPLED_YET;
unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was sent
unsigned long previousMillis20 = 0; // will store last time a 20ms CAN Message was sent
unsigned long previousMillis50 = 0; // will store last time a 50ms CAN Message was sent
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was sent
unsigned long previousMillis250 = 0; // will store last time a 250ms CAN Message was sent
unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was sent
unsigned long previousMillis1000 = 0; // will store last time a 1000ms CAN Message was sent
unsigned long previousMillis5000 = 0; // will store last time a 1000ms CAN Message was sent
#define PID_WELD_CHECK 0xD814
#define PID_CONT_REASON_OPEN 0xD812
#define PID_CONTACTOR_STATUS 0xD813
#define PID_NEG_CONT_CONTROL 0xD44F
#define PID_NEG_CONT_STATUS 0xD453
#define PID_POS_CONT_CONTROL 0xD44E
#define PID_POS_CONT_STATUS 0xD452
#define PID_CONTACTOR_NEGATIVE 0xD44C
#define PID_CONTACTOR_POSITIVE 0xD44D
#define PID_PRECHARGE_RELAY_CONTROL 0xD44B
#define PID_PRECHARGE_RELAY_STATUS 0xD451
#define PID_RECHARGE_STATUS 0xD864
#define PID_DELTA_TEMPERATURE 0xD878
#define PID_COLDEST_MODULE 0xD446
#define PID_LOWEST_TEMPERATURE 0xD87D
#define PID_AVERAGE_TEMPERATURE 0xD877
#define PID_HIGHEST_TEMPERATURE 0xD817
#define PID_HOTTEST_MODULE 0xD445
#define PID_AVG_CELL_VOLTAGE 0xD43D
#define PID_CURRENT 0xD816
#define PID_INSULATION_NEG 0xD87C
#define PID_INSULATION_POS 0xD87B
#define PID_MAX_CURRENT_10S 0xD876
#define PID_MAX_DISCHARGE_10S 0xD873
#define PID_MAX_DISCHARGE_30S 0xD874
#define PID_MAX_CHARGE_10S 0xD871
#define PID_MAX_CHARGE_30S 0xD872
#define PID_ENERGY_CAPACITY 0xD860
#define PID_HIGH_CELL_NUM 0xD43B
#define PID_LOW_CELL_NUM 0xD43C
#define PID_SUM_OF_CELLS 0xD438
#define PID_CELL_MIN_CAPACITY 0xD413
#define PID_CELL_VOLTAGE_MEAS_STATUS 0xD48A
#define PID_INSULATION_RES 0xD47A
#define PID_PACK_VOLTAGE 0xD815
#define PID_HIGH_CELL_VOLTAGE 0xD870
#define PID_ALL_CELL_VOLTAGES 0xD440 //Multi-frame
#define PID_LOW_CELL_VOLTAGE 0xD86F
#define PID_BATTERY_ENERGY 0xD865
#define PID_BATTERY_ENERGY 0xD865
#define PID_CELLBALANCE_STATUS 0xD46F //Multi-frame?
#define PID_CELLBALANCE_HWERR_MASK 0xD470 //Multi-frame
#define PID_CRASH_COUNTER 0xD42F
#define PID_WIRE_CRASH 0xD87F
#define PID_CAN_CRASH 0xD48D
#define PID_HISTORY_DATA 0xD465
#define PID_LOWSOC_COUNTER 0xD492 //Not supported on all batteris
#define PID_LAST_CAN_FAILURE_DETAIL 0xD89E //Not supported on all batteris
#define PID_HW_VERSION_NUM 0xF193 //Not supported on all batteris
#define PID_SW_VERSION_NUM 0xF195 //Not supported on all batteris
#define PID_FACTORY_MODE_CONTROL 0xD900
#define PID_BATTERY_SERIAL 0xD901
#define PID_ALL_CELL_SOH 0xD4B5 //Very long message reply, too much data for this integration
#define PID_AUX_FUSE_STATE 0xD86C
#define PID_BATTERY_STATE 0xD811
#define PID_PRECHARGE_SHORT_CIRCUIT 0xD4D8
#define PID_ESERVICE_PLUG_STATE 0xD86A
#define PID_MAINFUSE_STATE 0xD86B
#define PID_MOST_CRITICAL_FAULT 0xD481
#define PID_CURRENT_TIME 0xD47F
#define PID_TIME_SENT_BY_CAR 0xD4CA
#define PID_12V 0xD822
#define PID_12V_ABNORMAL 0xD42B
#define PID_HVIL_IN_VOLTAGE 0xD46B
#define PID_HVIL_OUT_VOLTAGE 0xD46A
#define PID_HVIL_STATE 0xD869
#define PID_BMS_STATE 0xD45A
#define PID_VEHICLE_SPEED 0xD802
#define PID_TIME_SPENT_OVER_55C 0xE082
#define PID_CONTACTOR_CLOSING_COUNTER 0xD416
#define PID_DATE_OF_MANUFACTURE 0xF18B
CAN_frame ECMP_382 = {
.FD = false, //BSI_Info (VCU) PSA specific
uint16_t poll_state = PID_WELD_CHECK;
uint16_t incoming_poll = 0;
CAN_frame ECMP_010 = {.FD = false, .ext_ID = false, .DLC = 1, .ID = 0x010, .data = {0xB4}};
CAN_frame ECMP_041 = {.FD = false, .ext_ID = false, .DLC = 1, .ID = 0x041, .data = {0x00}};
CAN_frame ECMP_0A6 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x382,
.data = {0x09, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //09 20 on AC charge. 0A 20 on DC charge
CAN_frame ECMP_0F0 = {.FD = false, //VCU (Common)
.DLC = 2,
.ID = 0x0A6,
.data = {0x02, 0x00}}; //Content changes after 12minutes of runtime (not emulated)
CAN_frame ECMP_0F0 = {.FD = false, //VCU2_0F0 (Common) 20ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false,
.DLC = 8,
.ID = 0x0F0,
.data = {0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}};
uint8_t data_0F0_20[16] = {0xFF, 0x0E, 0x1D, 0x2C, 0x3B, 0x4A, 0x59, 0x68,
0x77, 0x86, 0x95, 0xA4, 0xB3, 0xC2, 0xD1, 0xE0};
uint8_t data_0F0_00[16] = {0xF1, 0x00, 0x1F, 0x2E, 0x3D, 0x4C, 0x5B, 0x6A,
0x79, 0x88, 0x97, 0xA6, 0xB5, 0xC4, 0xD3, 0xE2};
CAN_frame ECMP_0F2 = {.FD = false, //CtrlMCU1_0F2 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x0F2,
.data = {0x7D, 0x00, 0x4E, 0x20, 0x00, 0x00, 0x60, 0x0D}};
CAN_frame ECMP_0AE = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x0AE, .data = {0x04, 0x77, 0x7A, 0x5E, 0xDF}};
CAN_frame ECMP_110 = {.FD = false, //??? 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x110,
.data = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, 0x05}};
CAN_frame ECMP_111 = {.FD = false, //??? 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x111,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_112 = {.FD = false, //MCU1_112 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, only CRC changes at end
.DLC = 8,
.ID = 0x112,
.data = {0x4E, 0x20, 0x00, 0x0F, 0xA0, 0x7D, 0x00, 0x0A}};
CAN_frame ECMP_114 = {.FD = false, //??? 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x114,
.data = {0x00, 0x00, 0x00, 0x7D, 0x07, 0xD0, 0x7D, 0x00}};
CAN_frame ECMP_0C5 = {.FD = false, //DC2_0C5 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x0C5,
.data = {0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_17B = {.FD = false, //VCU_PCANInfo_17B 10ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x17B,
.data = {0x00, 0x00, 0x00, 0x7E, 0x78, 0x00, 0x00, 0x0F}}; // NOTE. Changes on BMS state
CAN_frame ECMP_230 = {.FD = false, //OBC3_230 50ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x230,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_27A = {
.FD = false, //VCU_BSI_Wakeup_27A message 50ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8, //Contains SEV main state, position of the BSI shunt park, ACC status
.ID = 0x27A, // electric network state, powetrain status, Wakeups, diagmux, APC activation
.data = {0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_31E = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x31E,
.data = {0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08}};
CAN_frame ECMP_31D = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x31D,
.data = {0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42}};
CAN_frame ECMP_3D0 = {.FD = false, //Not in logs, but makes speed go to 0km/h in diag tool when we send this
.ext_ID = false, //Only sent in idle state
.DLC = 8,
.ID = 0x3D0,
.data = {0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_345 = {.FD = false, //DC1_345 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x345,
.data = {0x45, 0x57, 0x00, 0x04, 0x00, 0x00, 0x06, 0x31}};
CAN_frame ECMP_351 = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x351,
.data = {0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E}};
CAN_frame ECMP_372 = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x372,
.data = {0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; // NOTE. Changes on BMS state
CAN_frame ECMP_37F = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // Seems to be a bunch of temperature measurements? Static for now
.DLC = 8,
.ID = 0x37F,
.data = {0x45, 0x49, 0x51, 0x45, 0x45, 0x00, 0x45, 0x45}};
CAN_frame ECMP_382 = {
//BSIInfo_382 (VCU) PSA specific 100ms periodic (Perfectly emulated in Battery-Emulator)
.FD = false, //Same content always, fully static
.ext_ID = false,
.DLC = 8,
.ID = 0x382, //Frame1 has rollerbenchmode request, frame2 has generic powertrain cycle sync status
.data = {0x02, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_383 = {.FD = false, //??? 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x383,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_3A2 = {.FD = false, //OBC2_3A2 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x3A2,
.data = {0x03, 0xE8, 0x00, 0x00, 0x81, 0x00, 0x08, 0x02}};
CAN_frame ECMP_3A3 = {.FD = false, //OBC1_3A3 100ms periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x3A3,
.data = {0x4A, 0x4A, 0x40, 0x00, 0x00, 0x08, 0x00, 0x0F}};
CAN_frame ECMP_439 = {.FD = false, //??? 1s periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 8,
.ID = 0x439,
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
CAN_frame ECMP_486 = {.FD = false, //??? 1s periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, // NOTE. Changes on BMS state
.DLC = 8,
.ID = 0x486,
.data = {0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
CAN_frame ECMP_552 = {.FD = false, //VCU_552 1s periodic (Perfectly handled in Battery-Emulator)
.ext_ID = false,
.DLC = 8, //552 seems to be tracking time in byte 0-3
.ID = 0x552, // distance in km in byte 4-6, temporal reset counter in byte 7
.data = {0x00, 0x02, 0x95, 0x6D, 0x00, 0xD7, 0xB5, 0xFE}};
CAN_frame ECMP_55F = {.FD = false, //5s periodic (Perfectly emulated in Battery-Emulator)
.ext_ID = false, //Same content always, fully static
.DLC = 1,
.ID = 0x55F,
.data = {0x82}};
CAN_frame ECMP_591 = {.FD = false, //1s periodic
.ext_ID = false, //Always static in HV mode
.DLC = 8,
.ID = 0x591,
.data = {0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
CAN_frame ECMP_786 = {.FD = false, //1s periodic
.ext_ID = false, //Always static in HV mode
.DLC = 8,
.ID = 0x786,
.data = {0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
CAN_frame ECMP_794 = {.FD = false, //Unsure who sends this. Could it be BMU?
.ext_ID = false,
.DLC = 8,
.ID = 0x794,
.data = {0xB8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; // NOTE. Changes on BMS state
CAN_frame ECMP_POLL = {.FD = false, .ext_ID = false, .DLC = 4, .ID = 0x6B4, .data = {0x03, 0x22, 0xD8, 0x66}};
CAN_frame ECMP_ACK = {.FD = false, //Ack frame
.ext_ID = false,
.DLC = 3,
.ID = 0x6B4,
.data = {0x30, 0x00, 0x00}};
CAN_frame ECMP_DIAG_START = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x6B4, .data = {0x02, 0x10, 0x03}};
//Start diagnostic session (extended diagnostic session, mode 0x10 with sub-mode 0x03)
CAN_frame ECMP_CONTACTOR_RESET_START = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x01, 0xDD, 0x35}};
CAN_frame ECMP_CONTACTOR_RESET_PROGRESS = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x03, 0xDD, 0x35}};
CAN_frame ECMP_COLLISION_RESET_START = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x01, 0xDF, 0x60}};
CAN_frame ECMP_COLLISION_RESET_PROGRESS = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x03, 0xDF, 0x60}};
CAN_frame ECMP_ISOLATION_RESET_START = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x01, 0xDF, 0x46}};
CAN_frame ECMP_ISOLATION_RESET_PROGRESS = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x03, 0xDF, 0x46}};
CAN_frame ECMP_RESET_DONE = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x6B4, .data = {0x02, 0x3E, 0x00}};
CAN_frame ECMP_FACTORY_MODE_ACTIVATION = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x2E, 0xD9, 0x00, 0x01}};
CAN_frame ECMP_FACTORY_MODE_ACTIVATION_NEW = {.FD = false,
.ext_ID = false,
.DLC = 4,
.ID = 0x6B4,
.data = {0x04, 0x2E, 0x19, 0x01}};
CAN_frame ECMP_DISABLE_ISOLATION_REQ = {.FD = false,
.ext_ID = false,
.DLC = 5,
.ID = 0x6B4,
.data = {0x04, 0x31, 0x02, 0xDF, 0xE1}};
uint8_t data_010_CRC[8] = {0xB4, 0x96, 0x78, 0x5A, 0x3C, 0x1E, 0xF0, 0xD2};
uint8_t data_3A2_CRC[16] = {0x0C, 0x1B, 0x2A, 0x39, 0x48, 0x57,
0x66, 0x75, 0x84, 0x93, 0xA2, 0xB1}; // NOTE. Changes on BMS state
uint8_t data_345_content[16] = {0x04, 0xF5, 0xE6, 0xD7, 0xC8, 0xB9, 0xAA, 0x9B, // NOTE. Changes on BMS state
0x8C, 0x7D, 0x6E, 0x5F, 0x40, 0x31, 0x22, 0x13};
};
#endif

View file

@ -1,5 +1,5 @@
#ifndef _ECMP_HTML_H
#define _ECMP_HTML_H
#ifndef _ECMP_BATTERY_HTML_H
#define _ECMP_BATTERT_HTML_H
#include "../datalayer/datalayer.h"
#include "../datalayer/datalayer_extended.h"
@ -9,7 +9,6 @@ class EcmpHtmlRenderer : public BatteryHtmlRenderer {
public:
String get_status_html() {
String content;
content += "<h4>Main Connector State: ";
if (datalayer_extended.stellantisECMP.MainConnectorState == 0) {
content += "Contactors open</h4>";
@ -20,6 +19,363 @@ class EcmpHtmlRenderer : public BatteryHtmlRenderer {
}
content +=
"<h4>Insulation Resistance: " + String(datalayer_extended.stellantisECMP.InsulationResistance) + "kOhm</h4>";
content += "<h4>Interlock: ";
if (datalayer_extended.stellantisECMP.InterlockOpen == true) {
content += "BROKEN!</h4>";
} else {
content += "Seated OK</h4>";
}
content += "<h4>Insulation Diag: ";
if (datalayer_extended.stellantisECMP.InsulationDiag == 0) {
content += "No failure</h4>";
} else if (datalayer_extended.stellantisECMP.InsulationDiag == 1) {
content += "Symmetric failure</h4>";
} else { //4 Invalid, 5-7 illegal, wrap em under one text
content += "N/A</h4>";
}
content += "<h4>Contactor weld check: ";
if (datalayer_extended.stellantisECMP.pid_welding_detection == 0) {
content += "OK</h4>";
} else if (datalayer_extended.stellantisECMP.pid_welding_detection == 255) {
content += "N/A</h4>";
} else { //Problem
content += "WELDED!" + String(datalayer_extended.stellantisECMP.pid_welding_detection) + "</h4>";
}
content += "<h4>Contactor opening reason: ";
if (datalayer_extended.stellantisECMP.pid_reason_open == 7) {
content += "Invalid Status</h4>";
} else if (datalayer_extended.stellantisECMP.pid_reason_open == 255) {
content += "N/A</h4>";
} else { //Problem (Also status 0 might be OK?)
content += "Unknown" + String(datalayer_extended.stellantisECMP.pid_reason_open) + "</h4>";
}
content += "<h4>Status of power switch: " +
(datalayer_extended.stellantisECMP.pid_contactor_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_contactor_status)) +
"</h4>";
content += "<h4>Negative power switch control: " +
(datalayer_extended.stellantisECMP.pid_negative_contactor_control == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_negative_contactor_control)) +
"</h4>";
content += "<h4>Negative power switch status: " +
(datalayer_extended.stellantisECMP.pid_negative_contactor_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_negative_contactor_status)) +
"</h4>";
content += "<h4>Positive power switch control: " +
(datalayer_extended.stellantisECMP.pid_positive_contactor_control == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_positive_contactor_control)) +
"</h4>";
content += "<h4>Positive power switch status: " +
(datalayer_extended.stellantisECMP.pid_positive_contactor_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_positive_contactor_status)) +
"</h4>";
content += "<h4>Contactor negative: " +
(datalayer_extended.stellantisECMP.pid_contactor_negative == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_contactor_negative)) +
"</h4>";
content += "<h4>Contactor positive: " +
(datalayer_extended.stellantisECMP.pid_contactor_positive == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_contactor_positive)) +
"</h4>";
content += "<h4>Precharge control: " +
(datalayer_extended.stellantisECMP.pid_precharge_relay_control == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_precharge_relay_control)) +
"</h4>";
content += "<h4>Precharge status: " +
(datalayer_extended.stellantisECMP.pid_precharge_relay_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_precharge_relay_status)) +
"</h4>";
content += "<h4>Recharge Status: " +
(datalayer_extended.stellantisECMP.pid_recharge_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_recharge_status)) +
"</h4>";
content += "<h4>Delta temperature: " +
(datalayer_extended.stellantisECMP.pid_delta_temperature == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_delta_temperature)) +
"&deg;C</h4>";
content += "<h4>Lowest temperature: " +
(datalayer_extended.stellantisECMP.pid_lowest_temperature == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_lowest_temperature)) +
"&deg;C</h4>";
content += "<h4>Average temperature: " +
(datalayer_extended.stellantisECMP.pid_average_temperature == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_average_temperature)) +
"&deg;C</h4>";
content += "<h4>Highest temperature: " +
(datalayer_extended.stellantisECMP.pid_highest_temperature == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_highest_temperature)) +
"&deg;C</h4>";
content += "<h4>Coldest module: " +
(datalayer_extended.stellantisECMP.pid_coldest_module == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_coldest_module)) +
"</h4>";
content += "<h4>Hottest module: " +
(datalayer_extended.stellantisECMP.pid_hottest_module == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_hottest_module)) +
"</h4>";
content += "<h4>Average cell voltage: " +
(datalayer_extended.stellantisECMP.pid_avg_cell_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_avg_cell_voltage)) +
" mV</h4>";
content +=
"<h4>High precision current: " +
(datalayer_extended.stellantisECMP.pid_current == 255 ? "N/A"
: String(datalayer_extended.stellantisECMP.pid_current)) +
" mA</h4>";
content += "<h4>Insulation resistance neg-gnd: " +
(datalayer_extended.stellantisECMP.pid_insulation_res_neg == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_insulation_res_neg)) +
" kOhm</h4>";
content += "<h4>Insulation resistance pos-gnd: " +
(datalayer_extended.stellantisECMP.pid_insulation_res_pos == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_insulation_res_pos)) +
" kOhm</h4>";
content += "<h4>Max current 10s: " +
(datalayer_extended.stellantisECMP.pid_max_current_10s == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_max_current_10s)) +
"</h4>";
content += "<h4>Max discharge power 10s: " +
(datalayer_extended.stellantisECMP.pid_max_discharge_10s == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_max_discharge_10s)) +
"</h4>";
content += "<h4>Max discharge power 30s: " +
(datalayer_extended.stellantisECMP.pid_max_discharge_30s == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_max_discharge_30s)) +
"</h4>";
content += "<h4>Max charge power 10s: " +
(datalayer_extended.stellantisECMP.pid_max_charge_10s == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_max_charge_10s)) +
"</h4>";
content += "<h4>Max charge power 30s: " +
(datalayer_extended.stellantisECMP.pid_max_charge_30s == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_max_charge_30s)) +
"</h4>";
content += "<h4>Energy capacity: " +
(datalayer_extended.stellantisECMP.pid_energy_capacity == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_energy_capacity)) +
"</h4>";
content += "<h4>Highest cell number: " +
(datalayer_extended.stellantisECMP.pid_highest_cell_voltage_num == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_highest_cell_voltage_num)) +
"</h4>";
content += "<h4>Lowest cell voltage number: " +
(datalayer_extended.stellantisECMP.pid_lowest_cell_voltage_num == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_lowest_cell_voltage_num)) +
"</h4>";
content += "<h4>Sum of all cell voltages: " +
(datalayer_extended.stellantisECMP.pid_sum_of_cells == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_sum_of_cells)) +
" dV</h4>";
content += "<h4>Cell min capacity: " +
(datalayer_extended.stellantisECMP.pid_cell_min_capacity == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_cell_min_capacity)) +
"</h4>";
content += "<h4>Cell voltage measurement status: " +
(datalayer_extended.stellantisECMP.pid_cell_voltage_measurement_status == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_cell_voltage_measurement_status)) +
"</h4>";
content += "<h4>Battery Insulation Resistance: " +
(datalayer_extended.stellantisECMP.pid_insulation_res == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_insulation_res)) +
" kOhm</h4>";
content += "<h4>Pack voltage: " +
(datalayer_extended.stellantisECMP.pid_pack_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_pack_voltage)) +
" dV</h4>";
content += "<h4>Highest cell voltage: " +
(datalayer_extended.stellantisECMP.pid_high_cell_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_high_cell_voltage)) +
" mV</h4>";
content += "<h4>Lowest cell voltage: " +
(datalayer_extended.stellantisECMP.pid_low_cell_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_low_cell_voltage)) +
" mV</h4>";
content += "<h4>Battery Energy: " +
(datalayer_extended.stellantisECMP.pid_battery_energy == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_battery_energy)) +
"</h4>";
content += "<h4>Collision information Counter: " +
(datalayer_extended.stellantisECMP.pid_crash_counter == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_crash_counter)) +
"</h4>";
content += "<h4>Collision Counter recieved by Wire: " +
(datalayer_extended.stellantisECMP.pid_wire_crash == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_wire_crash)) +
"</h4>";
content += "<h4>Collision data sent from car to battery: " +
(datalayer_extended.stellantisECMP.pid_CAN_crash == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_CAN_crash)) +
"</h4>";
content += "<h4>History data: " +
(datalayer_extended.stellantisECMP.pid_history_data == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_history_data)) +
"</h4>";
content += "<h4>Low SOC counter: " +
(datalayer_extended.stellantisECMP.pid_lowsoc_counter == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_lowsoc_counter)) +
"</h4>";
content += "<h4>Last CAN failure detail: " +
(datalayer_extended.stellantisECMP.pid_last_can_failure_detail == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_last_can_failure_detail)) +
"</h4>";
content += "<h4>HW version number: " +
(datalayer_extended.stellantisECMP.pid_hw_version_num == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_hw_version_num)) +
"</h4>";
content += "<h4>SW version number: " +
(datalayer_extended.stellantisECMP.pid_sw_version_num == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_sw_version_num)) +
"</h4>";
content += "<h4>Factory mode: " +
(datalayer_extended.stellantisECMP.pid_factory_mode_control == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_factory_mode_control)) +
"</h4>";
char readableSerialNumber[14]; // One extra space for null terminator
memcpy(readableSerialNumber, datalayer_extended.stellantisECMP.pid_battery_serial,
sizeof(datalayer_extended.stellantisECMP.pid_battery_serial));
readableSerialNumber[13] = '\0'; // Null terminate the string
content += "<h4>Battery serial: " + String(readableSerialNumber) + "</h4>";
uint8_t day = (datalayer_extended.stellantisECMP.pid_date_of_manufacture >> 16) & 0xFF;
uint8_t month = (datalayer_extended.stellantisECMP.pid_date_of_manufacture >> 8) & 0xFF;
uint8_t year = datalayer_extended.stellantisECMP.pid_date_of_manufacture & 0xFF;
content += "<h4>Date of manufacture: " + String(day) + "/" + String(month) + "/" + String(year) + "</h4>";
content += "<h4>Aux fuse state: " +
(datalayer_extended.stellantisECMP.pid_aux_fuse_state == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_aux_fuse_state)) +
"</h4>";
content += "<h4>Battery state: " +
(datalayer_extended.stellantisECMP.pid_battery_state == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_battery_state)) +
"</h4>";
content += "<h4>Precharge short circuit: " +
(datalayer_extended.stellantisECMP.pid_precharge_short_circuit == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_precharge_short_circuit)) +
"</h4>";
content += "<h4>Service plug state: " +
(datalayer_extended.stellantisECMP.pid_eservice_plug_state == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_eservice_plug_state)) +
"</h4>";
content += "<h4>Main fuse state: " +
(datalayer_extended.stellantisECMP.pid_mainfuse_state == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_mainfuse_state)) +
"</h4>";
content += "<h4>Most critical fault: " +
(datalayer_extended.stellantisECMP.pid_most_critical_fault == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_most_critical_fault)) +
"</h4>";
content += "<h4>Current time: " +
(datalayer_extended.stellantisECMP.pid_current_time == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_current_time)) +
" ticks</h4>";
content += "<h4>Time sent by car: " +
(datalayer_extended.stellantisECMP.pid_time_sent_by_car == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_time_sent_by_car)) +
" ticks</h4>";
content +=
"<h4>12V: " +
(datalayer_extended.stellantisECMP.pid_12v == 255 ? "N/A" : String(datalayer_extended.stellantisECMP.pid_12v)) +
"</h4>";
content += "<h4>12V abnormal: ";
if (datalayer_extended.stellantisECMP.pid_12v_abnormal == 255) {
content += "N/A</h4>";
} else if (datalayer_extended.stellantisECMP.pid_12v_abnormal == 0) {
content += "No</h4>";
} else {
content += "Yes</h4>";
}
content += "<h4>HVIL IN Voltage: " +
(datalayer_extended.stellantisECMP.pid_hvil_in_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_hvil_in_voltage)) +
"mV</h4>";
content += "<h4>HVIL Out Voltage: " +
(datalayer_extended.stellantisECMP.pid_hvil_out_voltage == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_hvil_out_voltage)) +
"mV</h4>";
content += "<h4>HVIL State: " +
(datalayer_extended.stellantisECMP.pid_hvil_state == 255
? "N/A"
: (datalayer_extended.stellantisECMP.pid_hvil_state == 0
? "OK"
: String(datalayer_extended.stellantisECMP.pid_hvil_state))) +
"</h4>";
content += "<h4>BMS State: " +
(datalayer_extended.stellantisECMP.pid_bms_state == 255
? "N/A"
: (datalayer_extended.stellantisECMP.pid_bms_state == 0
? "OK"
: String(datalayer_extended.stellantisECMP.pid_bms_state))) +
"</h4>";
content += "<h4>Vehicle speed: " +
(datalayer_extended.stellantisECMP.pid_vehicle_speed == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_vehicle_speed)) +
" km/h</h4>";
content += "<h4>Time spent over 55c: " +
(datalayer_extended.stellantisECMP.pid_time_spent_over_55c == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_time_spent_over_55c)) +
" minutes</h4>";
content += "<h4>Contactor lifetime closing counter: " +
(datalayer_extended.stellantisECMP.pid_contactor_closing_counter == 255
? "N/A"
: String(datalayer_extended.stellantisECMP.pid_contactor_closing_counter)) +
" cycles</h4>";
return content;
}

View file

@ -297,6 +297,78 @@ typedef struct {
typedef struct {
uint8_t MainConnectorState = 0;
uint16_t InsulationResistance = 0;
uint8_t InsulationDiag = 0;
bool InterlockOpen = false;
bool UserRequestContactorReset = false;
bool UserRequestCollisionReset = false;
bool UserRequestIsolationReset = false;
bool UserRequestDisableIsoMonitoring = false;
uint8_t pid_welding_detection = 0;
uint8_t pid_reason_open = 0;
uint8_t pid_contactor_status = 0;
uint8_t pid_negative_contactor_control = 0;
uint8_t pid_negative_contactor_status = 0;
uint8_t pid_positive_contactor_control = 0;
uint8_t pid_positive_contactor_status = 0;
uint8_t pid_contactor_negative = 0;
uint8_t pid_contactor_positive = 0;
uint8_t pid_precharge_relay_control = 0;
uint8_t pid_precharge_relay_status = 0;
uint8_t pid_recharge_status = 0;
uint8_t pid_delta_temperature = 0;
uint8_t pid_coldest_module = 0;
uint8_t pid_lowest_temperature = 0;
uint8_t pid_average_temperature = 0;
uint8_t pid_highest_temperature = 0;
uint8_t pid_hottest_module = 0;
uint16_t pid_avg_cell_voltage = 0;
int32_t pid_current = 0;
uint32_t pid_insulation_res_neg = 0;
uint32_t pid_insulation_res_pos = 0;
uint32_t pid_max_current_10s = 0;
uint32_t pid_max_discharge_10s = 0;
uint32_t pid_max_discharge_30s = 0;
uint32_t pid_max_charge_10s = 0;
uint32_t pid_max_charge_30s = 0;
uint32_t pid_energy_capacity = 0;
uint8_t pid_highest_cell_voltage_num = 0;
uint8_t pid_lowest_cell_voltage_num = 0;
uint16_t pid_sum_of_cells = 0;
uint16_t pid_cell_min_capacity = 0;
uint8_t pid_cell_voltage_measurement_status = 0;
uint32_t pid_insulation_res = 0;
uint16_t pid_pack_voltage = 0;
uint16_t pid_high_cell_voltage = 0;
uint16_t pid_low_cell_voltage = 0;
uint8_t pid_battery_energy = 0;
uint32_t pid_crash_counter = 0;
uint8_t pid_wire_crash = 0;
uint8_t pid_CAN_crash = 0;
uint32_t pid_history_data = 0;
uint32_t pid_lowsoc_counter = 0;
uint32_t pid_last_can_failure_detail = 0;
uint32_t pid_hw_version_num = 0;
uint32_t pid_sw_version_num = 0;
uint32_t pid_factory_mode_control = 0;
uint8_t pid_battery_serial[13] = {0};
uint32_t pid_aux_fuse_state = 0;
uint32_t pid_battery_state = 0;
uint32_t pid_precharge_short_circuit = 0;
uint32_t pid_eservice_plug_state = 0;
uint32_t pid_mainfuse_state = 0;
uint32_t pid_most_critical_fault = 0;
uint32_t pid_current_time = 0;
uint32_t pid_time_sent_by_car = 0;
uint32_t pid_12v = 0;
uint32_t pid_12v_abnormal = 0;
uint32_t pid_hvil_in_voltage = 0;
uint32_t pid_hvil_out_voltage = 0;
uint32_t pid_hvil_state = 0;
uint32_t pid_bms_state = 0;
uint32_t pid_vehicle_speed = 0;
uint32_t pid_time_spent_over_55c = 0;
uint32_t pid_contactor_closing_counter = 0;
uint32_t pid_date_of_manufacture = 0;
} DATALAYER_INFO_ECMP;
typedef struct {

View file

@ -28,6 +28,11 @@ std::vector<BatteryCommand> battery_commands = {
[](Battery* b) {
b->reset_NVROL();
}},
{"resetContactor", "Perform contactor reset", "reset contactors?",
[](Battery* b) { return b && b->supports_contactor_reset(); },
[](Battery* b) {
b->reset_contactor();
}},
{"resetDTC", "Erase DTC", "erase DTCs?", [](Battery* b) { return b && b->supports_reset_DTC(); },
[](Battery* b) {
b->reset_DTC();
@ -56,6 +61,11 @@ std::vector<BatteryCommand> battery_commands = {
[](Battery* b) {
b->reset_SOH();
}},
{"setFactoryMode", "Set Factory Mode", "set factory mode and disable isolation measurement?",
[](Battery* b) { return b && b->supports_factory_mode_method(); },
[](Battery* b) {
b->set_factory_mode();
}},
{"toggleSOC", "Toggle SOC method",
"toggle SOC method? This will toggle between ESTIMATED and MEASURED SOC methods.",
[](Battery* b) { return b && b->supports_toggle_SOC_method(); },

View file

@ -480,7 +480,7 @@ void init_webserver() {
if (request->hasParam("stop")) {
String valueStr = request->getParam("stop")->value();
if (valueStr == "true" || valueStr == "1") {
setBatteryPause(true, false, true);
setBatteryPause(true, false, true); //Pause battery, do not pause CAN, equipment stop on (store to flash)
} else {
setBatteryPause(false, false, false);
}
@ -1444,7 +1444,7 @@ String processor(const String& var) {
content +=
"<br/><br/><button style=\"background:red;color:white;cursor:pointer;\""
" onclick=\""
"if(confirm('This action will open contactors on the battery and stop all CAN communications. Are you "
"if(confirm('This action will attempt to open contactors on the battery. Are you "
"sure?')) { estop(true); }\""
">Open Contactors</button><br/>";
else
@ -1452,7 +1452,8 @@ String processor(const String& var) {
"<br/><br/><button style=\"background:green;color:white;cursor:pointer;\""
"20px;font-size:16px;font-weight:bold;cursor:pointer;border-radius:5px; margin:10px;"
" onclick=\""
"if(confirm('This action will restore the battery state. Are you sure?')) { estop(false); }\""
"if(confirm('This action will attempt to close contactors and enable power transfer. Are you sure?')) { "
"estop(false); }\""
">Close Contactors</button><br/>";
content += "<script>";
content += "function OTA() { window.location.href = '/update'; }";