From 32378df03e9884ada287e00d3759b82daecd088c Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:11:02 +0100 Subject: [PATCH 01/19] Some cleanup before more surgery --- Software/Software.ino | 2 +- Software/src/devboard/utils/CMakeLists.txt | 1 - Software/src/devboard/utils/events.cpp | 11 ++++++++--- Software/src/devboard/utils/events.h | 2 +- test/utils/events_test.cpp | 14 +++++++------- 5 files changed, 17 insertions(+), 13 deletions(-) delete mode 100644 Software/src/devboard/utils/CMakeLists.txt diff --git a/Software/Software.ino b/Software/Software.ino index eb65591a..779b6aed 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -194,7 +194,7 @@ void loop() { #ifdef DUAL_CAN send_can2(); #endif - update_event_timestamps(); + run_event_handling(); } // Initialization functions diff --git a/Software/src/devboard/utils/CMakeLists.txt b/Software/src/devboard/utils/CMakeLists.txt deleted file mode 100644 index bded7cb0..00000000 --- a/Software/src/devboard/utils/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -# add_library(utils_library events.cpp) diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 06963830..bbdf51ea 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -17,10 +17,15 @@ static uint8_t total_led_color = GREEN; static char event_message[256]; /* Local function prototypes */ +static void update_event_time(void); static void set_event_message(EVENTS_ENUM_TYPE event); static void update_led_color(EVENTS_ENUM_TYPE event); /* Exported functions */ +void run_event_handling(void) { + update_event_time(); +} + void init_events(void) { for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) { entries[i].timestamp = 0; @@ -49,7 +54,8 @@ void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { #endif } -void update_event_timestamps(void) { +/* Local functions */ +static void update_event_time(void) { unsigned long new_millis = millis(); if (new_millis - previous_millis >= 1000) { time_seconds++; @@ -57,7 +63,6 @@ void update_event_timestamps(void) { } } -/* Local functions */ static void update_led_color(EVENTS_ENUM_TYPE event) { total_led_color = (total_led_color == RED) ? RED : entries[event].led_color; } @@ -81,7 +86,7 @@ static void set_event_message(EVENTS_ENUM_TYPE event) { "12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); break; case EVENT_SOC_PLAUSIBILITY_ERROR: - snprintf(event_message, sizeof(event_message), "ERROR: SOC% reported by battery not plausible. Restart battery!"); + snprintf(event_message, sizeof(event_message), "ERROR: SOC reported by battery not plausible. Restart battery!"); break; case EVENT_KWH_PLAUSIBILITY_ERROR: snprintf(event_message, sizeof(event_message), diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 58abb58e..1b2daf5f 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -30,6 +30,6 @@ typedef enum { void init_events(void); void set_event(EVENTS_ENUM_TYPE event, uint8_t data); -void update_event_timestamps(void); +void run_event_handling(void); #endif // __MYTIMER_H__ diff --git a/test/utils/events_test.cpp b/test/utils/events_test.cpp index 1d6c0748..1afae2ed 100644 --- a/test/utils/events_test.cpp +++ b/test/utils/events_test.cpp @@ -1,5 +1,5 @@ // The test library must be included first! -#include "test_lib.h" +#include "../test_lib.h" #include "events.cpp" @@ -16,35 +16,35 @@ TEST(init_events_test) { } } -TEST(update_event_timestamps_test) { +TEST(update_event_time_test) { // Reset init_events(); time_seconds = 0; // No delta, so time shouldn't increase testlib_millis = 0; - update_event_timestamps(); + update_event_time(); ASSERT_EQ(time_seconds, 0); // Almost time to bump the seconds testlib_millis = 999; - update_event_timestamps(); + update_event_time(); ASSERT_EQ(time_seconds, 0); ASSERT_EQ(previous_millis, 0); // millis == 1000, so we should add a second testlib_millis = 1000; - update_event_timestamps(); + update_event_time(); ASSERT_EQ(time_seconds, 1); ASSERT_EQ(previous_millis, 1000); // We shouldn't add more seconds until 2000 now testlib_millis = 1999; - update_event_timestamps(); + update_event_time(); ASSERT_EQ(time_seconds, 1); ASSERT_EQ(previous_millis, 1000); testlib_millis = 2000; - update_event_timestamps(); + update_event_time(); ASSERT_EQ(time_seconds, 2); ASSERT_EQ(previous_millis, 2000); } From 0650c3f0efa73f909cd8497cdcc92d90d009d4db Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Wed, 7 Feb 2024 07:26:29 +0100 Subject: [PATCH 02/19] Update unit-tests.yml Update to checkout@v4 --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index ba59c71c..37095df8 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Configure and build with CMake run: | From b528c8917f0c12accb07f0587ef747b06f47a931 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Wed, 7 Feb 2024 08:36:28 +0100 Subject: [PATCH 03/19] Event cleanup --- Software/Software.ino | 8 +--- Software/src/battery/BMW-I3-BATTERY.cpp | 2 - Software/src/battery/CHADEMO-BATTERY.cpp | 2 - .../src/battery/IMIEV-CZERO-ION-BATTERY.cpp | 2 - .../src/battery/IMIEV-CZERO-ION-BATTERY.h | 1 - .../src/battery/KIA-HYUNDAI-64-BATTERY.cpp | 12 ----- Software/src/battery/KIA-HYUNDAI-64-BATTERY.h | 2 - Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 48 ------------------- Software/src/battery/NISSAN-LEAF-BATTERY.h | 2 - .../src/battery/RENAULT-KANGOO-BATTERY.cpp | 8 ---- Software/src/battery/RENAULT-KANGOO-BATTERY.h | 2 - Software/src/battery/RENAULT-ZOE-BATTERY.cpp | 8 ---- Software/src/battery/RENAULT-ZOE-BATTERY.h | 2 - .../src/battery/SANTA-FE-PHEV-BATTERY.cpp | 2 - .../src/battery/TESLA-MODEL-3-BATTERY.cpp | 20 -------- Software/src/battery/TESLA-MODEL-3-BATTERY.h | 2 - Software/src/devboard/config.h | 6 +-- Software/src/devboard/utils/events.cpp | 21 +++++++- Software/src/devboard/utils/events.h | 4 ++ Software/src/devboard/webserver/webserver.cpp | 9 +--- test/CMakeLists.txt | 2 +- test/microtest.h | 2 +- test/test_lib.cpp | 5 ++ test/test_lib.h | 8 +++- test/utils/events_test.cpp | 3 +- 25 files changed, 45 insertions(+), 138 deletions(-) diff --git a/Software/Software.ino b/Software/Software.ino index 779b6aed..409c1f76 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -555,7 +555,7 @@ void handle_LED_state() { } else if (!rampUp && brightness == 0) { rampUp = true; } - switch (LEDcolor) { + switch (get_event_ledcolor()) { case GREEN: pixels.setPixelColor(0, pixels.Color(0, brightness, 0)); // Green pulsing LED break; @@ -575,12 +575,6 @@ void handle_LED_state() { break; } - // BMS in fault state overrides everything - if (bms_status == FAULT) { - LEDcolor = RED; - pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red LED full brightness - } - pixels.show(); // This sends the updated pixel color to the hardware. } diff --git a/Software/src/battery/BMW-I3-BATTERY.cpp b/Software/src/battery/BMW-I3-BATTERY.cpp index 40acb0e2..3e0ffc95 100644 --- a/Software/src/battery/BMW-I3-BATTERY.cpp +++ b/Software/src/battery/BMW-I3-BATTERY.cpp @@ -102,8 +102,6 @@ void update_values_i3_battery() { //This function maps all the values fetched v /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; diff --git a/Software/src/battery/CHADEMO-BATTERY.cpp b/Software/src/battery/CHADEMO-BATTERY.cpp index 84a3634d..225dc404 100644 --- a/Software/src/battery/CHADEMO-BATTERY.cpp +++ b/Software/src/battery/CHADEMO-BATTERY.cpp @@ -105,9 +105,7 @@ void update_values_chademo_battery() { //This function maps all the values fetc /* Check if the Vehicle is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; errorCode = 7; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp index 51ebdba9..585354c5 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp @@ -108,8 +108,6 @@ void update_values_imiev_battery() { //This function maps all the values fetche /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; diff --git a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h index 0a2af171..39d367d9 100644 --- a/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h +++ b/Software/src/battery/IMIEV-CZERO-ION-BATTERY.h @@ -28,7 +28,6 @@ extern uint16_t cell_max_voltage; extern uint16_t cell_min_voltage; extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false -extern uint8_t LEDcolor; void update_values_imiev_battery(); void receive_can_imiev_battery(CAN_frame_t rx_frame); diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp index e1b27df7..0685131b 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp @@ -199,22 +199,16 @@ void update_values_kiaHyundai_64_battery() { //This function maps all the value /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; } if (waterleakageSensor == 0) { - Serial.println("Water leakage inside battery detected. Operation halted. Inspect battery!"); - bms_status = FAULT; set_event(EVENT_WATER_INGRESS, 0); } if (leadAcidBatteryVoltage < 110) { - Serial.println("12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); - LEDcolor = YELLOW; set_event(EVENT_12V_LOW, leadAcidBatteryVoltage); } @@ -222,18 +216,12 @@ void update_values_kiaHyundai_64_battery() { //This function maps all the value cell_deviation_mV = (cell_max_voltage - cell_min_voltage); if (cell_max_voltage >= MAX_CELL_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (cell_min_voltage <= MIN_CELL_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } if (cell_deviation_mV > MAX_CELL_DEVIATION) { - LEDcolor = YELLOW; - Serial.println("ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); set_event(EVENT_CELL_DEVIATION_HIGH, 0); } diff --git a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h index 47d5e2ba..0a55d888 100644 --- a/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h +++ b/Software/src/battery/KIA-HYUNDAI-64-BATTERY.h @@ -20,14 +20,12 @@ extern uint16_t capacity_Wh; //Wh, 0-60000 extern uint16_t remaining_capacity_Wh; //Wh, 0-60000 extern uint16_t max_target_discharge_power; //W, 0-60000 extern uint16_t max_target_charge_power; //W, 0-60000 -extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) extern uint16_t temperature_min; //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_min_voltage; //mV, 0-4350 -extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index 835487ee..dadbc5b4 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -259,10 +259,6 @@ void update_values_leaf_battery() { /* This function maps all the values fetched if (battery_voltage > (ABSOLUTE_MAX_VOLTAGE - 100)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT if (LB_SOC < 650) { - bms_status = FAULT; -#ifdef DEBUG_VIA_USB - Serial.println("ERROR: SOC% reported by battery not plausible. Restart battery!"); -#endif set_event(EVENT_SOC_PLAUSIBILITY_ERROR, LB_SOC / 10); } } @@ -308,30 +304,17 @@ void update_values_leaf_battery() { /* This function maps all the values fetched break; case (5): //Caution Lamp Request & Normal Stop Request - bms_status = FAULT; errorCode = 2; -#ifdef DEBUG_VIA_USB - Serial.println("ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!"); -#endif set_event(EVENT_BATTERY_DISCHG_STOP_REQ, 0); break; case (6): //Caution Lamp Request & Charging Mode Stop Request - bms_status = FAULT; errorCode = 3; -#ifdef DEBUG_VIA_USB - Serial.println("ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"); -#endif set_event(EVENT_BATTERY_CHG_STOP_REQ, 0); break; case (7): //Caution Lamp Request & Charging Mode Stop Request & Normal Stop Request - bms_status = FAULT; errorCode = 4; -#ifdef DEBUG_VIA_USB - Serial.println( - "ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!"); -#endif set_event(EVENT_BATTERY_CHG_DISCHG_STOP_REQ, 0); break; default: @@ -341,11 +324,6 @@ void update_values_leaf_battery() { /* This function maps all the values fetched if (LB_StateOfHealth < 25) { //Battery is extremely degraded, not fit for secondlifestorage. Zero it all out. if (LB_StateOfHealth != 0) { //Extra check to see that we actually have a SOH Value available -#ifdef DEBUG_VIA_USB - Serial.println( - "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery."); -#endif - bms_status = FAULT; errorCode = 5; set_event(EVENT_LOW_SOH, LB_StateOfHealth); max_target_discharge_power = 0; @@ -355,12 +333,6 @@ void update_values_leaf_battery() { /* This function maps all the values fetched #ifdef INTERLOCK_REQUIRED if (!LB_Interlock) { -#ifdef DEBUG_VIA_USB - Serial.println( - "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be " - "disabled!"); -#endif - bms_status = FAULT; set_event(EVENT_HVIL_FAILURE, 0); errorCode = 6; SOC = 0; @@ -371,11 +343,7 @@ void update_values_leaf_battery() { /* This function maps all the values fetched /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; errorCode = 7; -#ifdef DEBUG_VIA_USB - Serial.println("ERROR: No CAN communication detected for 60s. Shutting down battery control."); -#endif set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; @@ -384,10 +352,6 @@ void update_values_leaf_battery() { /* This function maps all the values fetched MAX_CAN_FAILURES) //Also check if we have recieved too many malformed CAN messages. If so, signal via LED { errorCode = 10; - LEDcolor = YELLOW; -#ifdef DEBUG_VIA_USB - Serial.println("ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"); -#endif set_event(EVENT_CAN_WARNING, 0); } @@ -620,27 +584,15 @@ void receive_can_leaf_battery(CAN_frame_t rx_frame) { cell_min_voltage = min_max_voltage[0]; if (cell_deviation_mV > MAX_CELL_DEVIATION) { - LEDcolor = YELLOW; -#ifdef DEBUG_VIA_USB - Serial.println("HIGH CELL DEVIATION!!! Inspect battery!"); -#endif set_event(EVENT_CELL_DEVIATION_HIGH, 0); } if (min_max_voltage[1] >= MAX_CELL_VOLTAGE) { - bms_status = FAULT; errorCode = 8; -#ifdef DEBUG_VIA_USB - Serial.println("CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); -#endif set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (min_max_voltage[0] <= MIN_CELL_VOLTAGE) { - bms_status = FAULT; errorCode = 9; -#ifdef DEBUG_VIA_USB - Serial.println("CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); -#endif set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } break; diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.h b/Software/src/battery/NISSAN-LEAF-BATTERY.h index fa88a959..34fdf23d 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.h +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.h @@ -18,14 +18,12 @@ extern uint16_t capacity_Wh; //Wh, 0-60000 extern uint16_t remaining_capacity_Wh; //Wh, 0-60000 extern uint16_t max_target_discharge_power; //W, 0-60000 extern uint16_t max_target_charge_power; //W, 0-60000 -extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) extern uint16_t temperature_min; //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_min_voltage; //mV, 0-4350 -extern uint8_t LEDcolor; //Enum, 0-10 extern uint16_t cellvoltages[120]; //mV 0-4350 per cell extern uint8_t nof_cellvoltages; // Total number of cell voltages, set by each battery. extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp index 47ab1f64..1657e73f 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.cpp @@ -125,26 +125,18 @@ void update_values_kangoo_battery() { //This function maps all the values fetch /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; } if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (LB_Cell_Min_Voltage <= ABSOLUTE_CELL_MIN_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) { - LEDcolor = YELLOW; - Serial.println("ERROR: HIGH CELL mV DEVIATION!!! Inspect battery!"); set_event(EVENT_CELL_DEVIATION_HIGH, 0); } diff --git a/Software/src/battery/RENAULT-KANGOO-BATTERY.h b/Software/src/battery/RENAULT-KANGOO-BATTERY.h index 973c3df8..105f60a9 100644 --- a/Software/src/battery/RENAULT-KANGOO-BATTERY.h +++ b/Software/src/battery/RENAULT-KANGOO-BATTERY.h @@ -23,7 +23,6 @@ extern uint16_t capacity_Wh; //Wh, 0-60000 extern uint16_t remaining_capacity_Wh; //Wh, 0-60000 extern uint16_t max_target_discharge_power; //W, 0-60000 extern uint16_t max_target_charge_power; //W, 0-60000 -extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) @@ -31,7 +30,6 @@ extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 funct extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint16_t CANerror; -extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false diff --git a/Software/src/battery/RENAULT-ZOE-BATTERY.cpp b/Software/src/battery/RENAULT-ZOE-BATTERY.cpp index d40f09cf..b69ebbf4 100644 --- a/Software/src/battery/RENAULT-ZOE-BATTERY.cpp +++ b/Software/src/battery/RENAULT-ZOE-BATTERY.cpp @@ -86,26 +86,18 @@ void update_values_zoe_battery() { //This function maps all the values fetched /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; } if (LB_Cell_Max_Voltage >= ABSOLUTE_CELL_MAX_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (LB_Cell_Min_Voltage <= ABSOLUTE_CELL_MIN_VOLTAGE) { - bms_status = FAULT; - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } if (cell_deviation_mV > MAX_CELL_DEVIATION_MV) { - LEDcolor = YELLOW; - Serial.println("ERROR: HIGH CELL mV DEVIATION!!! Inspect battery!"); set_event(EVENT_CELL_DEVIATION_HIGH, 0); } diff --git a/Software/src/battery/RENAULT-ZOE-BATTERY.h b/Software/src/battery/RENAULT-ZOE-BATTERY.h index aa45054f..7a2e46c4 100644 --- a/Software/src/battery/RENAULT-ZOE-BATTERY.h +++ b/Software/src/battery/RENAULT-ZOE-BATTERY.h @@ -23,7 +23,6 @@ extern uint16_t capacity_Wh; //Wh, 0-60000 extern uint16_t remaining_capacity_Wh; //Wh, 0-60000 extern uint16_t max_target_discharge_power; //W, 0-60000 extern uint16_t max_target_charge_power; //W, 0-60000 -extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) @@ -31,7 +30,6 @@ extern uint16_t temperature_max; //C+1, Goes thru convert2unsignedint16 funct extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint16_t CANerror; -extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false diff --git a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp index e2aaa66f..ba1417c3 100644 --- a/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp +++ b/Software/src/battery/SANTA-FE-PHEV-BATTERY.cpp @@ -83,8 +83,6 @@ void update_values_santafe_phev_battery() { //This function maps all the values /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!CANstillAlive) { - bms_status = FAULT; - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { CANstillAlive--; diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp index fb05806a..0c03307e 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.cpp @@ -230,16 +230,12 @@ void update_values_tesla_model_3_battery() { //This function maps all the value /* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/ if (!stillAliveCAN) { - bms_status = FAULT; - Serial.println("ERROR: No CAN communication detected for 60s. Shutting down battery control."); set_event(EVENT_CAN_FAILURE, 0); } else { stillAliveCAN--; } if (hvil_status == 3) { //INTERNAL_OPEN_FAULT - Someone disconnected a high voltage cable while battery was in use - bms_status = FAULT; - Serial.println("ERROR: High voltage cable removed while battery running. Opening contactors!"); set_event(EVENT_INTERNAL_OPEN_FAULT, 0); } @@ -259,49 +255,33 @@ void update_values_tesla_model_3_battery() { //This function maps all the value if (battery_voltage > (ABSOLUTE_MAX_VOLTAGE - 100)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT if (SOC < 6500) { //When SOC is less than 65.00% when approaching max voltage - bms_status = FAULT; - Serial.println("ERROR: SOC% reported by battery not plausible. Restart battery!"); set_event(EVENT_SOC_PLAUSIBILITY_ERROR, SOC / 100); } } //Check if BMS is in need of recalibration if (nominal_full_pack_energy < REASONABLE_ENERGYAMOUNT) { - Serial.println("Warning: kWh remaining reported by battery not plausible. Battery needs cycling."); set_event(EVENT_KWH_PLAUSIBILITY_ERROR, nominal_full_pack_energy); - LEDcolor = YELLOW; } if (LFP_Chemistry) { //LFP limits used for voltage safeties if (cell_max_v >= MAX_CELL_VOLTAGE_LFP) { - bms_status = FAULT; - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (cell_min_v <= MIN_CELL_VOLTAGE_LFP) { - bms_status = FAULT; - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } if (cell_deviation_mV > MAX_CELL_DEVIATION_LFP) { - LEDcolor = YELLOW; - Serial.println("ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); set_event(EVENT_CELL_DEVIATION_HIGH, 0); } } else { //NCA/NCM limits used if (cell_max_v >= MAX_CELL_VOLTAGE_NCA_NCM) { - bms_status = FAULT; - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_OVER_VOLTAGE, 0); } if (cell_min_v <= MIN_CELL_VOLTAGE_NCA_NCM) { - bms_status = FAULT; - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); set_event(EVENT_CELL_UNDER_VOLTAGE, 0); } if (cell_deviation_mV > MAX_CELL_DEVIATION_NCA_NCM) { - LEDcolor = YELLOW; - Serial.println("ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); set_event(EVENT_CELL_DEVIATION_HIGH, 0); } } diff --git a/Software/src/battery/TESLA-MODEL-3-BATTERY.h b/Software/src/battery/TESLA-MODEL-3-BATTERY.h index a10d6cc7..ed2ba9c1 100644 --- a/Software/src/battery/TESLA-MODEL-3-BATTERY.h +++ b/Software/src/battery/TESLA-MODEL-3-BATTERY.h @@ -21,7 +21,6 @@ extern uint16_t capacity_Wh; //Wh, 0-60000 extern uint16_t remaining_capacity_Wh; //Wh, 0-60000 extern uint16_t max_target_discharge_power; //W, 0-60000 extern uint16_t max_target_charge_power; //W, 0-60000 -extern uint8_t bms_status; //Enum, 0-5 extern uint8_t bms_char_dis_status; //Enum, 0-2 extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530) extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385) @@ -30,7 +29,6 @@ extern uint16_t cell_max_voltage; //mV, 0-4350 extern uint16_t cell_min_voltage; //mV, 0-4350 extern uint16_t cellvoltages[120]; //mV 0-4350 per cell extern uint8_t nof_cellvoltages; // Total number of cell voltages, set by each battery. -extern uint8_t LEDcolor; //Enum, 0-10 extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false extern bool LFP_Chemistry; diff --git a/Software/src/devboard/config.h b/Software/src/devboard/config.h index 04f12822..ff4b2f7b 100644 --- a/Software/src/devboard/config.h +++ b/Software/src/devboard/config.h @@ -32,11 +32,11 @@ #define SD_CS_PIN 13 #define WS2812_PIN 4 -// LED definitions for the board +// LED definitions for the board, in order of "priority", DONT CHANGE! #define GREEN 0 #define YELLOW 1 -#define RED 2 -#define BLUE 3 +#define BLUE 2 +#define RED 3 #define TEST_ALL_COLORS 10 // Inverter definitions diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index bbdf51ea..48f3ef96 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -39,6 +39,9 @@ void init_events(void) { entries[EVENT_CAN_WARNING].led_color = YELLOW; entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW; entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW; + + // BLUE... + entries[EVENT_OTA_UPDATE].led_color = BLUE; } void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { @@ -48,12 +51,25 @@ void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { entries[event].timestamp = time_seconds; entries[event].data = data; entries[event].occurences++; + + update_led_color(event); + + if (total_led_color == RED) { + bms_status = FAULT; + } else if (total_led_color) { + bms_status = UPDATING; + } + set_event_message(event); #ifdef DEBUG_VIA_USB Serial.println(event_message); #endif } +uint8_t get_event_ledcolor(void) { + return total_led_color; +} + /* Local functions */ static void update_event_time(void) { unsigned long new_millis = millis(); @@ -64,7 +80,7 @@ static void update_event_time(void) { } static void update_led_color(EVENTS_ENUM_TYPE event) { - total_led_color = (total_led_color == RED) ? RED : entries[event].led_color; + total_led_color = max(total_led_color, entries[event].led_color); } static void set_event_message(EVENTS_ENUM_TYPE event) { @@ -132,6 +148,9 @@ static void set_event_message(EVENTS_ENUM_TYPE event) { case EVENT_UNKNOWN_EVENT_SET: snprintf(event_message, sizeof(event_message), "An unknown event was set! Review your code!"); break; + case EVENT_OTA_UPDATE: + snprintf(event_message, sizeof(event_message), "OTA update started!"); + break; case EVENT_DUMMY: snprintf(event_message, sizeof(event_message), "The dummy event was set!"); // Don't change this event message! break; diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 1b2daf5f..8c1345da 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -24,6 +24,7 @@ typedef enum { EVENT_CELL_OVER_VOLTAGE, EVENT_CELL_DEVIATION_HIGH, EVENT_UNKNOWN_EVENT_SET, + EVENT_OTA_UPDATE, EVENT_DUMMY, EVENT_NOF_EVENTS } EVENTS_ENUM_TYPE; @@ -31,5 +32,8 @@ typedef enum { void init_events(void); void set_event(EVENTS_ENUM_TYPE event, uint8_t data); void run_event_handling(void); +uint8_t get_event_ledcolor(void); + +extern uint8_t bms_status; //Enum, 0-5 #endif // __MYTIMER_H__ diff --git a/Software/src/devboard/webserver/webserver.cpp b/Software/src/devboard/webserver/webserver.cpp index 039257a6..73324752 100644 --- a/Software/src/devboard/webserver/webserver.cpp +++ b/Software/src/devboard/webserver/webserver.cpp @@ -1,5 +1,6 @@ #include "webserver.h" #include +#include "../utils/events.h" Preferences preferences3; @@ -927,15 +928,11 @@ String cellmonitor_processor(const String& var) { void onOTAStart() { // Log when OTA has started - Serial.println("OTA update started!"); ESP32Can.CANStop(); - bms_status = UPDATING; //Inform inverter that we are updating - LEDcolor = BLUE; + set_event(EVENT_OTA_UPDATE, 0); } void onOTAProgress(size_t current, size_t final) { - bms_status = UPDATING; //Inform inverter that we are updating - LEDcolor = BLUE; // Log every 1 second if (millis() - ota_progress_millis > 1000) { ota_progress_millis = millis(); @@ -950,8 +947,6 @@ void onOTAEnd(bool success) { } else { Serial.println("There was an error during OTA update!"); } - bms_status = UPDATING; //Inform inverter that we are updating - LEDcolor = BLUE; } template // This function makes power values appear as W when under 1000, and kW when over diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6d63e2e3..76cde93f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ # Include the directory with your source files -include_directories(${CMAKE_SOURCE_DIR}/Software/src/devboard/utils .) +include_directories(${CMAKE_SOURCE_DIR}/Software/src/devboard ${CMAKE_SOURCE_DIR}/Software/src/devboard/utils . ) # Create a variable to store the list of test files file(GLOB TEST_SOURCES utils/*.cpp) diff --git a/test/microtest.h b/test/microtest.h index 36c73aa1..8814cd18 100644 --- a/test/microtest.h +++ b/test/microtest.h @@ -201,7 +201,7 @@ class Runtime { return 0; \ } else { \ double percentage = 100.0 * num_failed / mt::TestsManager::tests().size(); \ - fprintf(stderr, "%s{ summary} %lu tests failed (%.2f%%)%s\n", mt::red(), num_failed, percentage, mt::def()); \ + fprintf(stderr, "%s{ summary} %zu tests failed (%.2f%%)%s\n", mt::red(), num_failed, percentage, mt::def()); \ return -1; \ } \ } diff --git a/test/test_lib.cpp b/test/test_lib.cpp index 8ed9c2f5..0d28b92e 100644 --- a/test/test_lib.cpp +++ b/test/test_lib.cpp @@ -1,6 +1,11 @@ #include "test_lib.h" + #include +#include "config.h" + MySerial Serial; unsigned long testlib_millis = 0; + +uint8_t bms_status = ACTIVE; diff --git a/test/test_lib.h b/test/test_lib.h index ccca3ca4..b2819503 100644 --- a/test/test_lib.h +++ b/test/test_lib.h @@ -2,14 +2,20 @@ #define __TEST_LIB_H__ #include +#include #include #include +#include "config.h" #include "microtest.h" +using namespace std; + class MySerial; extern unsigned long testlib_millis; +extern MySerial Serial; +extern uint8_t bms_status; /* Mock millis() */ static inline unsigned long millis(void) { @@ -38,6 +44,4 @@ class MySerial { } }; -extern MySerial Serial; - #endif diff --git a/test/utils/events_test.cpp b/test/utils/events_test.cpp index 1afae2ed..bf1413ee 100644 --- a/test/utils/events_test.cpp +++ b/test/utils/events_test.cpp @@ -58,13 +58,14 @@ TEST(set_event_test) { ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 0); ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 0); ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 0); - // Set current time and overvoltage event for cell 23 + // Set current time and overvoltage event for cell 23 (RED color, bms_status == FAULT) time_seconds = 345; set_event(EVENT_CELL_OVER_VOLTAGE, 123); // Ensure proper event data ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 123); ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 1); ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345); + ASSERT_EQ(bms_status, FAULT); } TEST(event_message_test) { From 0a7e6e9fb22843f181e6f59638c6a277cb433c70 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Fri, 9 Feb 2024 08:20:29 +0100 Subject: [PATCH 04/19] Update unit-tests.yml trigger commit --- .github/workflows/unit-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 37095df8..62c2f2a9 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,5 +1,6 @@ name: Run Unit Tests + on: [push, pull_request] jobs: From c839646e5824ba781d17032ab32113b5f8423d07 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Fri, 9 Feb 2024 22:27:13 +0100 Subject: [PATCH 05/19] Various additions, still WIP --- Software/src/battery/NISSAN-LEAF-BATTERY.cpp | 4 +- Software/src/devboard/utils/events.cpp | 213 ++++++++++++++----- Software/src/devboard/utils/events.h | 43 ++-- Software/src/devboard/utils/timer.h | 5 +- test/test_lib.cpp | 4 +- test/test_lib.h | 1 + test/utils/events_test.cpp | 52 +++-- 7 files changed, 219 insertions(+), 103 deletions(-) diff --git a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp index dadbc5b4..b3df8531 100644 --- a/Software/src/battery/NISSAN-LEAF-BATTERY.cpp +++ b/Software/src/battery/NISSAN-LEAF-BATTERY.cpp @@ -259,7 +259,9 @@ void update_values_leaf_battery() { /* This function maps all the values fetched if (battery_voltage > (ABSOLUTE_MAX_VOLTAGE - 100)) { // When pack voltage is close to max, and SOC% is still low, raise FAULT if (LB_SOC < 650) { - set_event(EVENT_SOC_PLAUSIBILITY_ERROR, LB_SOC / 10); + set_event(EVENT_SOC_PLAUSIBILITY_ERROR, LB_SOC / 10); // Set event with the SOC as data + } else { + clear_event(EVENT_SOC_PLAUSIBILITY_ERROR); } } diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 48f3ef96..b4929cb1 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -2,157 +2,254 @@ #include "../../../USER_SETTINGS.h" #include "../config.h" +#include "timer.h" + +typedef enum { + EVENT_STATE_INIT = 0, + EVENT_STATE_INACTIVE, + EVENT_STATE_ACTIVE, + EVENT_STATE_ACTIVE_LATCHED +} EVENT_STATE_TYPE; typedef struct { - uint32_t timestamp; // Time in seconds since startup when the event occurred - uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage - uint8_t occurences; // Number of occurrences since startup - uint8_t led_color; // Weirdly indented comment + uint32_t timestamp; // Time in seconds since startup when the event occurred + uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage + uint8_t occurences; // Number of occurrences since startup + uint8_t led_color; // LED indication + EVENT_STATE_TYPE state; // Event state } EVENTS_STRUCT_TYPE; -static EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS]; -static unsigned long previous_millis = 0; -static uint32_t time_seconds = 0; -static uint8_t total_led_color = GREEN; -static char event_message[256]; +typedef struct { + EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS]; + uint32_t time_seconds; + char message[256]; + MyTimer second_timer; + uint8_t nof_yellow_events; + uint8_t nof_blue_events; + uint8_t nof_red_events; +} EVENT_TYPE; + +/* Local variables */ +static EVENT_TYPE events; /* Local function prototypes */ static void update_event_time(void); -static void set_event_message(EVENTS_ENUM_TYPE event); -static void update_led_color(EVENTS_ENUM_TYPE event); +static void set_message(EVENTS_ENUM_TYPE event); +static void update_led_color(void); +static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched); +static void update_event_numbers(void); +static void update_bms_status(void); /* Exported functions */ + +/* Main execution function, should handle various continuous functionality */ void run_event_handling(void) { update_event_time(); } +/* Initialization function */ void init_events(void) { for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) { - entries[i].timestamp = 0; - entries[i].data = 0; - entries[i].occurences = 0; - entries[i].led_color = RED; // Most events are RED + events.entries[i].timestamp = 0; + events.entries[i].data = 0; + events.entries[i].occurences = 0; + events.entries[i].led_color = RED; // Most events are RED + events.entries[i].state = EVENT_STATE_INACTIVE; } // YELLOW events below - entries[EVENT_12V_LOW].led_color = YELLOW; - entries[EVENT_CAN_WARNING].led_color = YELLOW; - entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW; - entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW; + events.entries[EVENT_12V_LOW].led_color = YELLOW; + events.entries[EVENT_CAN_WARNING].led_color = YELLOW; + events.entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW; + events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW; // BLUE... - entries[EVENT_OTA_UPDATE].led_color = BLUE; + events.entries[EVENT_OTA_UPDATE].led_color = BLUE; + + events.second_timer.interval = 1000; + + events.nof_blue_events = 0; + events.nof_red_events = 0; + events.nof_yellow_events = 0; } void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { + set_event(event, data, false); +} + +void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data) { + set_event(event, data, true); +} + +void clear_event(EVENTS_ENUM_TYPE event) { + if (events.entries[event].state == EVENT_STATE_ACTIVE) { + events.entries[event].state = EVENT_STATE_INACTIVE; + update_event_numbers(); + update_led_color(); + update_bms_status(); + } +} + +/* Local functions */ + +static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { + // Just some defensive stuff if someone sets an unknown event if (event >= EVENT_NOF_EVENTS) { event = EVENT_UNKNOWN_EVENT_SET; } - entries[event].timestamp = time_seconds; - entries[event].data = data; - entries[event].occurences++; - update_led_color(event); - - if (total_led_color == RED) { - bms_status = FAULT; - } else if (total_led_color) { - bms_status = UPDATING; + // If the event is already set, no reason to continue + if ((events.entries[event].state == EVENT_STATE_ACTIVE) || + (events.entries[event].state == EVENT_STATE_ACTIVE_LATCHED)) { + return; } - set_event_message(event); + // We should set the event, update event info + events.entries[event].timestamp = events.time_seconds; + events.entries[event].data = data; + events.entries[event].occurences++; + // Check if the event is latching + events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE; + + update_event_numbers(); + update_led_color(); + update_bms_status(); + + // Set the associated event message, even if debug is disabled + set_message(event); #ifdef DEBUG_VIA_USB - Serial.println(event_message); + Serial.println(events.message); #endif } -uint8_t get_event_ledcolor(void) { - return total_led_color; +static void update_bms_status(void) { + if (events.nof_red_events > 0) { + bms_status = FAULT; + } else if (events.nof_blue_events > 0) { + bms_status = UPDATING; + } else if (events.nof_yellow_events > 0) { + // No bms_status update + } +} + +static void update_event_numbers(void) { + events.nof_red_events = 0; + events.nof_blue_events = 0; + events.nof_yellow_events = 0; + for (uint8_t i = 0u; i < EVENT_NOF_EVENTS; i++) { + if ((events.entries[i].state == EVENT_STATE_ACTIVE) || (events.entries[i].state == EVENT_STATE_ACTIVE_LATCHED)) { + switch (events.entries[i].led_color) { + case GREEN: + // Just informative + break; + case YELLOW: + events.nof_yellow_events++; + break; + case BLUE: + events.nof_blue_events++; + break; + case RED: + events.nof_red_events++; + break; + default: + break; + } + } + } } -/* Local functions */ static void update_event_time(void) { unsigned long new_millis = millis(); - if (new_millis - previous_millis >= 1000) { - time_seconds++; - previous_millis = new_millis; + if (events.second_timer.elapsed() == true) { + events.time_seconds++; } } -static void update_led_color(EVENTS_ENUM_TYPE event) { - total_led_color = max(total_led_color, entries[event].led_color); +static void update_led_color(void) { + if (events.nof_red_events > 0) { + LEDcolor = RED; + } else if (events.nof_blue_events > 0) { + LEDcolor = BLUE; + } else if (events.nof_yellow_events > 0) { + LEDcolor = YELLOW; + } else { + LEDcolor = GREEN; + } + + // events.total_led_color = max(events.total_led_color, events.entries[event].led_color); } -static void set_event_message(EVENTS_ENUM_TYPE event) { +static void set_message(EVENTS_ENUM_TYPE event) { switch (event) { case EVENT_CAN_FAILURE: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "No CAN communication detected for 60s. Shutting down battery control."); break; case EVENT_CAN_WARNING: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"); break; case EVENT_WATER_INGRESS: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "Water leakage inside battery detected. Operation halted. Inspect battery!"); break; case EVENT_12V_LOW: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); break; case EVENT_SOC_PLAUSIBILITY_ERROR: - snprintf(event_message, sizeof(event_message), "ERROR: SOC reported by battery not plausible. Restart battery!"); + snprintf(events.message, sizeof(events.message), + "ERROR: SOC reported by battery not plausible. Restart battery!"); break; case EVENT_KWH_PLAUSIBILITY_ERROR: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "Warning: kWh remaining reported by battery not plausible. Battery needs cycling."); break; case EVENT_BATTERY_CHG_STOP_REQ: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"); break; case EVENT_BATTERY_DISCHG_STOP_REQ: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!"); break; case EVENT_BATTERY_CHG_DISCHG_STOP_REQ: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!"); break; case EVENT_LOW_SOH: snprintf( - event_message, sizeof(event_message), + events.message, sizeof(events.message), "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery."); break; case EVENT_HVIL_FAILURE: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be " "disabled!"); break; case EVENT_INTERNAL_OPEN_FAULT: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: High voltage cable removed while battery running. Opening contactors!"); break; case EVENT_CELL_UNDER_VOLTAGE: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); break; case EVENT_CELL_OVER_VOLTAGE: - snprintf(event_message, sizeof(event_message), + snprintf(events.message, sizeof(events.message), "ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); break; case EVENT_CELL_DEVIATION_HIGH: - snprintf(event_message, sizeof(event_message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); + snprintf(events.message, sizeof(events.message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); break; case EVENT_UNKNOWN_EVENT_SET: - snprintf(event_message, sizeof(event_message), "An unknown event was set! Review your code!"); + snprintf(events.message, sizeof(events.message), "An unknown event was set! Review your code!"); break; case EVENT_OTA_UPDATE: - snprintf(event_message, sizeof(event_message), "OTA update started!"); + snprintf(events.message, sizeof(events.message), "OTA update started!"); break; case EVENT_DUMMY: - snprintf(event_message, sizeof(event_message), "The dummy event was set!"); // Don't change this event message! + snprintf(events.message, sizeof(events.message), "The dummy event was set!"); // Don't change this event message! break; default: break; diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 8c1345da..d8052496 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -8,32 +8,35 @@ #include typedef enum { - EVENT_CAN_FAILURE = 0u, - EVENT_CAN_WARNING, - EVENT_WATER_INGRESS, - EVENT_12V_LOW, - EVENT_SOC_PLAUSIBILITY_ERROR, - EVENT_KWH_PLAUSIBILITY_ERROR, - EVENT_BATTERY_CHG_STOP_REQ, - EVENT_BATTERY_DISCHG_STOP_REQ, - EVENT_BATTERY_CHG_DISCHG_STOP_REQ, - EVENT_LOW_SOH, - EVENT_HVIL_FAILURE, - EVENT_INTERNAL_OPEN_FAULT, - EVENT_CELL_UNDER_VOLTAGE, - EVENT_CELL_OVER_VOLTAGE, - EVENT_CELL_DEVIATION_HIGH, - EVENT_UNKNOWN_EVENT_SET, - EVENT_OTA_UPDATE, - EVENT_DUMMY, - EVENT_NOF_EVENTS + EVENT_CAN_FAILURE = 0u, // RED event + EVENT_CAN_WARNING, // YELLOW event + EVENT_WATER_INGRESS, // RED event + EVENT_12V_LOW, // YELLOW event + EVENT_SOC_PLAUSIBILITY_ERROR, // RED event + EVENT_KWH_PLAUSIBILITY_ERROR, // YELLOW event + EVENT_BATTERY_CHG_STOP_REQ, // RED event + EVENT_BATTERY_DISCHG_STOP_REQ, // RED event + EVENT_BATTERY_CHG_DISCHG_STOP_REQ, // RED event + EVENT_LOW_SOH, // RED event + EVENT_HVIL_FAILURE, // RED event + EVENT_INTERNAL_OPEN_FAULT, // RED event + EVENT_CELL_UNDER_VOLTAGE, // RED event + EVENT_CELL_OVER_VOLTAGE, // RED event + EVENT_CELL_DEVIATION_HIGH, // YELLOW event + EVENT_UNKNOWN_EVENT_SET, // RED event + EVENT_OTA_UPDATE, // BLUE event + EVENT_DUMMY, // RED event + EVENT_NOF_EVENTS // RED event } EVENTS_ENUM_TYPE; void init_events(void); +void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data); void set_event(EVENTS_ENUM_TYPE event, uint8_t data); +void clear_event(EVENTS_ENUM_TYPE event); + void run_event_handling(void); -uint8_t get_event_ledcolor(void); extern uint8_t bms_status; //Enum, 0-5 +extern uint8_t LEDcolor; #endif // __MYTIMER_H__ diff --git a/Software/src/devboard/utils/timer.h b/Software/src/devboard/utils/timer.h index e330eb2f..c180bc09 100644 --- a/Software/src/devboard/utils/timer.h +++ b/Software/src/devboard/utils/timer.h @@ -7,13 +7,16 @@ class MyTimer { public: + /** Default constructor */ + MyTimer() : interval(0), previous_millis(0) {} + /** interval in ms */ MyTimer(unsigned long interval); /** Returns true and resets the timer if it has elapsed */ bool elapsed(); + unsigned long interval; private: - unsigned long interval; unsigned long previous_millis; }; diff --git a/test/test_lib.cpp b/test/test_lib.cpp index 0d28b92e..3c89db7d 100644 --- a/test/test_lib.cpp +++ b/test/test_lib.cpp @@ -2,10 +2,12 @@ #include -#include "config.h" +#include "../Software/src/devboard/config.h" MySerial Serial; unsigned long testlib_millis = 0; uint8_t bms_status = ACTIVE; + +uint8_t LEDcolor = GREEN; diff --git a/test/test_lib.h b/test/test_lib.h index b2819503..7bde85d7 100644 --- a/test/test_lib.h +++ b/test/test_lib.h @@ -16,6 +16,7 @@ class MySerial; extern unsigned long testlib_millis; extern MySerial Serial; extern uint8_t bms_status; +extern uint8_t LEDcolor; /* Mock millis() */ static inline unsigned long millis(void) { diff --git a/test/utils/events_test.cpp b/test/utils/events_test.cpp index bf1413ee..d2ff4231 100644 --- a/test/utils/events_test.cpp +++ b/test/utils/events_test.cpp @@ -1,79 +1,87 @@ // The test library must be included first! #include "../test_lib.h" +#include "../../Software/src/devboard/config.h" #include "events.cpp" +#include "timer.cpp" + +/* Local rest variables */ +bool elapsed = false; /* Helper functions */ +// bool MyTimer::elapsed(void) { return true; } + static void reset_event_msg(void) { - snprintf(event_message, sizeof(event_message), ""); + snprintf(events.message, sizeof(events.message), "."); } TEST(init_events_test) { init_events(); for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) { - ASSERT_EQ(entries[i].occurences, 0); + ASSERT_EQ(events.entries[i].occurences, 0); } } TEST(update_event_time_test) { // Reset init_events(); - time_seconds = 0; + events.time_seconds = 0; // No delta, so time shouldn't increase testlib_millis = 0; update_event_time(); - ASSERT_EQ(time_seconds, 0); + ASSERT_EQ(events.time_seconds, 0); // Almost time to bump the seconds testlib_millis = 999; update_event_time(); - ASSERT_EQ(time_seconds, 0); - ASSERT_EQ(previous_millis, 0); + ASSERT_EQ(events.time_seconds, 0); // millis == 1000, so we should add a second testlib_millis = 1000; update_event_time(); - ASSERT_EQ(time_seconds, 1); - ASSERT_EQ(previous_millis, 1000); + ASSERT_EQ(events.time_seconds, 1); // We shouldn't add more seconds until 2000 now testlib_millis = 1999; update_event_time(); - ASSERT_EQ(time_seconds, 1); - ASSERT_EQ(previous_millis, 1000); + ASSERT_EQ(events.time_seconds, 1); testlib_millis = 2000; update_event_time(); - ASSERT_EQ(time_seconds, 2); - ASSERT_EQ(previous_millis, 2000); + ASSERT_EQ(events.time_seconds, 2); } TEST(set_event_test) { // Reset init_events(); - time_seconds = 0; + events.time_seconds = 0; // Initially, the event should not have any data or occurences - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 0); - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 0); - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 0); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].data, 0); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].occurences, 0); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 0); // Set current time and overvoltage event for cell 23 (RED color, bms_status == FAULT) - time_seconds = 345; + events.time_seconds = 345; set_event(EVENT_CELL_OVER_VOLTAGE, 123); // Ensure proper event data - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].data, 123); - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].occurences, 1); - ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].data, 123); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].occurences, 1); + ASSERT_EQ(events.entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345); ASSERT_EQ(bms_status, FAULT); } -TEST(event_message_test) { +TEST(events_message_test) { reset_event_msg(); set_event(EVENT_DUMMY, 0); // Set dummy event with no data - ASSERT_STREQ("The dummy event was set!", event_message); + ASSERT_STREQ("The dummy event was set!", events.message); +} + +TEST(event_priority_test) { + ASSERT_TRUE(RED > BLUE); + ASSERT_TRUE(BLUE > YELLOW); } TEST_MAIN(); From fb33bee99182efa02d8fd19333ca04528772061b Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Fri, 9 Feb 2024 23:23:16 +0100 Subject: [PATCH 06/19] Explicit event initialization, local unit test execution --- CMakeLists.txt | 4 +++ Software/Software.ino | 2 +- Software/src/devboard/utils/events.cpp | 50 +++++++++++++++++++------- cmake_clean.bat | 15 ++++++++ test/utils/events_test.cpp | 6 ++-- 5 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 cmake_clean.bat diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f0c4af6..7c9a3578 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.10) +# Set the C++ standard to C++20 +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + project(BatteryEmulator) # add_subdirectory(Software/src/devboard/utils) diff --git a/Software/Software.ino b/Software/Software.ino index 409c1f76..5de914c1 100644 --- a/Software/Software.ino +++ b/Software/Software.ino @@ -555,7 +555,7 @@ void handle_LED_state() { } else if (!rampUp && brightness == 0) { rampUp = true; } - switch (get_event_ledcolor()) { + switch (LEDcolor) { case GREEN: pixels.setPixelColor(0, pixels.Color(0, brightness, 0)); // Green pulsing LED break; diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index b4929cb1..42293dc7 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -49,19 +49,45 @@ void run_event_handling(void) { /* Initialization function */ void init_events(void) { - for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) { - events.entries[i].timestamp = 0; - events.entries[i].data = 0; - events.entries[i].occurences = 0; - events.entries[i].led_color = RED; // Most events are RED - events.entries[i].state = EVENT_STATE_INACTIVE; - } - // YELLOW events below - events.entries[EVENT_12V_LOW].led_color = YELLOW; - events.entries[EVENT_CAN_WARNING].led_color = YELLOW; - events.entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW; - events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW; + events.entries[EVENT_CAN_FAILURE] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_CAN_WARNING] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_WATER_INGRESS] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_12V_LOW] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_SOC_PLAUSIBILITY_ERROR] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_KWH_PLAUSIBILITY_ERROR] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_BATTERY_CHG_STOP_REQ] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_BATTERY_DISCHG_STOP_REQ] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_LOW_SOH] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_HVIL_FAILURE] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_INTERNAL_OPEN_FAULT] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_CELL_UNDER_VOLTAGE] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_CELL_OVER_VOLTAGE] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_CELL_DEVIATION_HIGH] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_UNKNOWN_EVENT_SET] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_OTA_UPDATE] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = BLUE, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_DUMMY] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; + events.entries[EVENT_NOF_EVENTS] = { + .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; // BLUE... events.entries[EVENT_OTA_UPDATE].led_color = BLUE; diff --git a/cmake_clean.bat b/cmake_clean.bat new file mode 100644 index 00000000..db5215ae --- /dev/null +++ b/cmake_clean.bat @@ -0,0 +1,15 @@ +@echo off +echo Cleaning up +rmdir /Q/S build +echo Creating new CMake build folder +mkdir build +cd build +echo Building CMake project +call cmake .. +call cmake --build . +echo Executing tests +for %%i in ("test\Debug\*.exe") do ( + echo Running %%i + %%i +) +cd.. diff --git a/test/utils/events_test.cpp b/test/utils/events_test.cpp index d2ff4231..3b73ceeb 100644 --- a/test/utils/events_test.cpp +++ b/test/utils/events_test.cpp @@ -2,8 +2,8 @@ #include "../test_lib.h" #include "../../Software/src/devboard/config.h" -#include "events.cpp" -#include "timer.cpp" +#include "../../Software/src/devboard/utils/events.cpp" +#include "../../Software/src/devboard/utils/timer.cpp" /* Local rest variables */ bool elapsed = false; @@ -20,6 +20,8 @@ TEST(init_events_test) { for (uint8_t i = 0; i < EVENT_NOF_EVENTS; i++) { ASSERT_EQ(events.entries[i].occurences, 0); + ASSERT_EQ(events.entries[i].data, 0); + ASSERT_EQ(events.entries[i].timestamp, 0); } } From d9f3dbc3d0b1ca5b3f4bbeac29def72294d94310 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Sun, 11 Feb 2024 11:25:35 +0100 Subject: [PATCH 07/19] More ignore --- .gitignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 448c8864..295b8fe6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # Ignore any .vscode folder *.vscode/ -# Ignore any files in the build folder -Software/build/ \ No newline at end of file +# Ignore any files in any build folder +*build/ + +# Ignore .exe (unit tests) +*.exe \ No newline at end of file From 5e0893d3ca3c0a0a26135f36e31cd90f9fd690a3 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Sun, 11 Feb 2024 13:13:47 +0100 Subject: [PATCH 08/19] Halfway to the finish line --- Software/USER_SETTINGS.h | 6 +- Software/src/devboard/utils/events.cpp | 117 ++----------------------- Software/src/devboard/utils/events.h | 58 ++++++------ 3 files changed, 40 insertions(+), 141 deletions(-) diff --git a/Software/USER_SETTINGS.h b/Software/USER_SETTINGS.h index 4b69ef06..77f6ba33 100644 --- a/Software/USER_SETTINGS.h +++ b/Software/USER_SETTINGS.h @@ -12,7 +12,7 @@ //#define CHADEMO_BATTERY //#define IMIEV_CZERO_ION_BATTERY //#define KIA_HYUNDAI_64_BATTERY -//#define NISSAN_LEAF_BATTERY +#define NISSAN_LEAF_BATTERY //#define RENAULT_KANGOO_BATTERY //#define RENAULT_ZOE_BATTERY //#define SANTA_FE_PHEV_BATTERY @@ -21,7 +21,7 @@ /* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */ //#define BYD_CAN //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus -//#define BYD_MODBUS //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU +#define BYD_MODBUS //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU //#define LUNA2000_MODBUS //Enable this line to emulate a "Luna2000 battery" over Modbus RTU //#define PYLON_CAN //Enable this line to emulate a "Pylontech battery" over CAN bus //#define SMA_CAN //Enable this line to emulate a "BYD Battery-Box H 8.9kWh, 7 mod" over CAN bus @@ -40,7 +40,7 @@ //#define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot /* MQTT options */ -//#define MQTT // Enable this line to enable MQTT +#define MQTT // Enable this line to enable MQTT #define MQTT_SUBSCRIPTIONS \ { "my/topic/abc", "my/other/topic" } #define MQTT_SERVER "192.168.xxx.yyy" diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index ae7f6c7d..2ed795bc 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -4,25 +4,9 @@ #include "../config.h" #include "timer.h" -typedef enum { - EVENT_STATE_INIT = 0, - EVENT_STATE_INACTIVE, - EVENT_STATE_ACTIVE, - EVENT_STATE_ACTIVE_LATCHED -} EVENT_STATE_TYPE; - -typedef struct { - uint32_t timestamp; // Time in seconds since startup when the event occurred - uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage - uint8_t occurences; // Number of occurrences since startup - uint8_t led_color; // LED indication - EVENT_STATE_TYPE state; // Event state -} EVENTS_STRUCT_TYPE; - typedef struct { EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS]; uint32_t time_seconds; - char message[256]; MyTimer second_timer; uint8_t nof_yellow_events; uint8_t nof_blue_events; @@ -31,6 +15,8 @@ typedef struct { /* Local variables */ static EVENT_TYPE events; +static const char* EVENTS_ENUM_TYPE_STRING[] = {EVENTS_ENUM_TYPE(GENERATE_STRING)}; +static const char* EVENTS_LEVEL_TYPE_STRING[] = {EVENTS_LEVEL_TYPE(GENERATE_STRING)}; /* Local function prototypes */ static void update_event_time(void); @@ -125,15 +111,14 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { } // If the event is already set, no reason to continue - if ((events.entries[event].state == EVENT_STATE_ACTIVE) || - (events.entries[event].state == EVENT_STATE_ACTIVE_LATCHED)) { - return; + if ((events.entries[event].state != EVENT_STATE_ACTIVE) && + (events.entries[event].state != EVENT_STATE_ACTIVE_LATCHED)) { + events.entries[event].occurences++; } // We should set the event, update event info events.entries[event].timestamp = events.time_seconds; events.entries[event].data = data; - events.entries[event].occurences++; // Check if the event is latching events.entries[event].state = latched ? EVENT_STATE_ACTIVE_LATCHED : EVENT_STATE_ACTIVE; @@ -141,10 +126,8 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { update_led_color(); update_bms_status(); - // Set the associated event message, even if debug is disabled - set_message(event); #ifdef DEBUG_VIA_USB - Serial.println(events.message); + Serial.println(get_event_message(event)); #endif } @@ -205,83 +188,6 @@ static void update_led_color(void) { // events.total_led_color = max(events.total_led_color, events.entries[event].led_color); } -static void set_message(EVENTS_ENUM_TYPE event) { - switch (event) { - case EVENT_CAN_FAILURE: - snprintf(events.message, sizeof(events.message), - "No CAN communication detected for 60s. Shutting down battery control."); - break; - case EVENT_CAN_WARNING: - snprintf(events.message, sizeof(events.message), - "ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"); - break; - case EVENT_WATER_INGRESS: - snprintf(events.message, sizeof(events.message), - "Water leakage inside battery detected. Operation halted. Inspect battery!"); - break; - case EVENT_12V_LOW: - snprintf(events.message, sizeof(events.message), - "12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); - break; - case EVENT_SOC_PLAUSIBILITY_ERROR: - snprintf(events.message, sizeof(events.message), - "ERROR: SOC reported by battery not plausible. Restart battery!"); - break; - case EVENT_KWH_PLAUSIBILITY_ERROR: - snprintf(events.message, sizeof(events.message), - "Warning: kWh remaining reported by battery not plausible. Battery needs cycling."); - break; - case EVENT_BATTERY_CHG_STOP_REQ: - snprintf(events.message, sizeof(events.message), - "ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"); - break; - case EVENT_BATTERY_DISCHG_STOP_REQ: - snprintf(events.message, sizeof(events.message), - "ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!"); - break; - case EVENT_BATTERY_CHG_DISCHG_STOP_REQ: - snprintf(events.message, sizeof(events.message), - "ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!"); - break; - case EVENT_LOW_SOH: - snprintf( - events.message, sizeof(events.message), - "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery."); - break; - case EVENT_HVIL_FAILURE: - snprintf(events.message, sizeof(events.message), - "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be " - "disabled!"); - break; - case EVENT_INTERNAL_OPEN_FAULT: - snprintf(events.message, sizeof(events.message), - "ERROR: High voltage cable removed while battery running. Opening contactors!"); - break; - case EVENT_CELL_UNDER_VOLTAGE: - snprintf(events.message, sizeof(events.message), - "ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); - break; - case EVENT_CELL_OVER_VOLTAGE: - snprintf(events.message, sizeof(events.message), - "ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); - break; - case EVENT_CELL_DEVIATION_HIGH: - snprintf(events.message, sizeof(events.message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); - break; - case EVENT_UNKNOWN_EVENT_SET: - snprintf(events.message, sizeof(events.message), "An unknown event was set! Review your code!"); - break; - case EVENT_OTA_UPDATE: - snprintf(events.message, sizeof(events.message), "OTA update started!"); - break; - case EVENT_DUMMY: - snprintf(events.message, sizeof(events.message), "The dummy event was set!"); // Don't change this event message! - break; - default: - return "UNKNOWN"; - } -} - const char* get_event_message(EVENTS_ENUM_TYPE event) { switch (event) { case EVENT_CAN_FAILURE: @@ -326,14 +232,7 @@ const char* get_event_message(EVENTS_ENUM_TYPE event) { } const char* get_event_enum_string(EVENTS_ENUM_TYPE event) { - const char* fullString = EVENTS_ENUM_TYPE_STRING[event]; - if (strncmp(fullString, "EVENT_", 6) == 0) { - return fullString + 6; // Skip the first 6 characters - } - return fullString; + return EVENTS_ENUM_TYPE_STRING[event] + 6; // Return the event name but skip "EVENT_" that should always be first } -static void set_event_message(EVENTS_ENUM_TYPE event) { - const char* message = get_event_message(event); - snprintf(event_message, sizeof(event_message), "%s", message); -} +const char* get_event_type(EVENTS_ENUM_TYPE event) {} diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index c82b20ec..b63f5976 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -4,10 +4,27 @@ #ifndef UNIT_TEST #include -extern unsigned long previous_millis; -extern uint32_t time_seconds; #endif +typedef enum { + EVENT_STATE_INIT = 0, + EVENT_STATE_INACTIVE, + EVENT_STATE_ACTIVE, + EVENT_STATE_ACTIVE_LATCHED +} EVENTS_STATE_TYPE; + +typedef struct { + uint32_t timestamp; // Time in seconds since startup when the event occurred + uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage + uint8_t occurences; // Number of occurrences since startup + uint8_t led_color; // LED indication + EVENTS_STATE_TYPE state; // Event state +} EVENTS_STRUCT_TYPE; + +#define GENERATE_ENUM(ENUM) ENUM, +#define GENERATE_STRING(STRING) #STRING, + +/* Event enumeration */ #define EVENTS_ENUM_TYPE(XX) \ XX(EVENT_CAN_FAILURE) \ XX(EVENT_CAN_WARNING) \ @@ -25,42 +42,25 @@ extern uint32_t time_seconds; XX(EVENT_CELL_OVER_VOLTAGE) \ XX(EVENT_CELL_DEVIATION_HIGH) \ XX(EVENT_UNKNOWN_EVENT_SET) \ + XX(EVENT_OTA_UPDATE) \ XX(EVENT_DUMMY) \ XX(EVENT_NOF_EVENTS) -typedef enum { - EVENT_CAN_FAILURE = 0u, // RED event - EVENT_CAN_WARNING, // YELLOW event - EVENT_WATER_INGRESS, // RED event - EVENT_12V_LOW, // YELLOW event - EVENT_SOC_PLAUSIBILITY_ERROR, // RED event - EVENT_KWH_PLAUSIBILITY_ERROR, // YELLOW event - EVENT_BATTERY_CHG_STOP_REQ, // RED event - EVENT_BATTERY_DISCHG_STOP_REQ, // RED event - EVENT_BATTERY_CHG_DISCHG_STOP_REQ, // RED event - EVENT_LOW_SOH, // RED event - EVENT_HVIL_FAILURE, // RED event - EVENT_INTERNAL_OPEN_FAULT, // RED event - EVENT_CELL_UNDER_VOLTAGE, // RED event - EVENT_CELL_OVER_VOLTAGE, // RED event - EVENT_CELL_DEVIATION_HIGH, // YELLOW event - EVENT_UNKNOWN_EVENT_SET, // RED event - EVENT_OTA_UPDATE, // BLUE event - EVENT_DUMMY, // RED event - EVENT_NOF_EVENTS // RED event -} EVENTS_ENUM_TYPE; -#define GENERATE_ENUM(ENUM) ENUM, -#define GENERATE_STRING(STRING) #STRING, - typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE; -static const char* EVENTS_ENUM_TYPE_STRING[] = {EVENTS_ENUM_TYPE(GENERATE_STRING)}; +/* Event type enumeration */ +#define EVENTS_LEVEL_TYPE(XX) \ + XX(EVENT_LEVEL_ERROR) \ + XX(EVENT_LEVEL_WARNING) \ + XX(EVENT_LEVEL_INFO) \ + XX(EVENT_LEVEL_DEBUG) -const char* get_event_enum_string(EVENTS_ENUM_TYPE event); +typedef enum { EVENTS_LEVEL_TYPE(GENERATE_ENUM) } EVENTS_LEVEL_TYPE; +const char* get_event_enum_string(EVENTS_ENUM_TYPE event); const char* get_event_message(EVENTS_ENUM_TYPE event); - const char* get_led_color_display_text(u_int8_t led_color); +const char* get_event_type(EVENTS_ENUM_TYPE event); void init_events(void); void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data); From e2faaecfd4be9d897625c41465c78bca17ab6201 Mon Sep 17 00:00:00 2001 From: Cabooman <81711263+Cabooman@users.noreply.github.com> Date: Sun, 11 Feb 2024 14:39:53 +0100 Subject: [PATCH 09/19] Merging merged mergers --- Software/src/devboard/utils/events.cpp | 134 +++++++----------- Software/src/devboard/utils/events.h | 37 ++--- .../src/devboard/webserver/events_html.cpp | 26 ++-- Software/src/devboard/webserver/events_html.h | 4 +- 4 files changed, 91 insertions(+), 110 deletions(-) diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 6fff10d8..2c2b83df 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -8,9 +8,9 @@ typedef struct { EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS]; uint32_t time_seconds; MyTimer second_timer; - uint8_t nof_yellow_events; - uint8_t nof_blue_events; - uint8_t nof_red_events; + uint8_t nof_warning_events; + uint8_t nof_debug_events; + uint8_t nof_error_events; } EVENT_TYPE; /* Local variables */ @@ -36,53 +36,38 @@ void run_event_handling(void) { /* Initialization function */ void init_events(void) { - events.entries[EVENT_CAN_FAILURE] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_CAN_WARNING] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_WATER_INGRESS] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_12V_LOW] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_SOC_PLAUSIBILITY_ERROR] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_KWH_PLAUSIBILITY_ERROR] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_BATTERY_CHG_STOP_REQ] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_BATTERY_DISCHG_STOP_REQ] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_LOW_SOH] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_HVIL_FAILURE] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_INTERNAL_OPEN_FAULT] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_CELL_UNDER_VOLTAGE] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_CELL_OVER_VOLTAGE] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_CELL_DEVIATION_HIGH] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = YELLOW, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_UNKNOWN_EVENT_SET] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_OTA_UPDATE] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = BLUE, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_DUMMY] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - events.entries[EVENT_NOF_EVENTS] = { - .timestamp = 0, .data = 0, .occurences = 0, .led_color = RED, .state = EVENT_STATE_INACTIVE}; - - // BLUE... + for (uint16_t i = 0; i < EVENT_NOF_EVENTS; i++) { + events.entries[EVENT_CAN_FAILURE].data = 0; + events.entries[EVENT_CAN_FAILURE].timestamp = 0; + events.entries[EVENT_CAN_FAILURE].occurences = 0; + events.entries[EVENT_CAN_FAILURE].state = EVENT_STATE_INACTIVE; + } + + events.entries[EVENT_CAN_FAILURE].led_color = RED; + events.entries[EVENT_CAN_WARNING].led_color = YELLOW; + events.entries[EVENT_WATER_INGRESS].led_color = RED; + events.entries[EVENT_12V_LOW].led_color = YELLOW; + events.entries[EVENT_SOC_PLAUSIBILITY_ERROR].led_color = RED; + events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].led_color = YELLOW; + events.entries[EVENT_BATTERY_CHG_STOP_REQ].led_color = RED; + events.entries[EVENT_BATTERY_DISCHG_STOP_REQ].led_color = RED; + events.entries[EVENT_BATTERY_CHG_DISCHG_STOP_REQ].led_color = RED; + events.entries[EVENT_LOW_SOH].led_color = RED; + events.entries[EVENT_HVIL_FAILURE].led_color = RED; + events.entries[EVENT_INTERNAL_OPEN_FAULT].led_color = RED; + events.entries[EVENT_CELL_UNDER_VOLTAGE].led_color = RED; + events.entries[EVENT_CELL_OVER_VOLTAGE].led_color = RED; + events.entries[EVENT_CELL_DEVIATION_HIGH].led_color = YELLOW; + events.entries[EVENT_UNKNOWN_EVENT_SET].led_color = RED; events.entries[EVENT_OTA_UPDATE].led_color = BLUE; + events.entries[EVENT_DUMMY].led_color = RED; + events.entries[EVENT_NOF_EVENTS].led_color = RED; events.second_timer.interval = 1000; - events.nof_blue_events = 0; - events.nof_red_events = 0; - events.nof_yellow_events = 0; + events.nof_debug_events = 0; + events.nof_error_events = 0; + events.nof_warning_events = 0; } void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { @@ -127,39 +112,24 @@ static void set_event(EVENTS_ENUM_TYPE event, uint8_t data, bool latched) { update_bms_status(); #ifdef DEBUG_VIA_USB - Serial.println(get_event_message(event)); + Serial.println(get_event_message_string(event)); #endif } static void update_bms_status(void) { - if (events.nof_red_events > 0) { + if (events.nof_error_events > 0) { bms_status = FAULT; - } else if (events.nof_blue_events > 0) { + } else if (events.nof_debug_events > 0) { bms_status = UPDATING; - } else if (events.nof_yellow_events > 0) { + } else if (events.nof_warning_events > 0) { // No bms_status update } } -const char* get_led_color_display_text(u_int8_t led_color) { - switch (led_color) { - case RED: - return "Error"; - case YELLOW: - return "Warning"; - case GREEN: - return "Info"; - case BLUE: - return "Debug"; - default: - return "UNKNOWN"; - } -} - static void update_event_numbers(void) { - events.nof_red_events = 0; - events.nof_blue_events = 0; - events.nof_yellow_events = 0; + events.nof_error_events = 0; + events.nof_debug_events = 0; + events.nof_warning_events = 0; for (uint8_t i = 0u; i < EVENT_NOF_EVENTS; i++) { if ((events.entries[i].state == EVENT_STATE_ACTIVE) || (events.entries[i].state == EVENT_STATE_ACTIVE_LATCHED)) { switch (events.entries[i].led_color) { @@ -167,13 +137,13 @@ static void update_event_numbers(void) { // Just informative break; case YELLOW: - events.nof_yellow_events++; + events.nof_warning_events++; break; case BLUE: - events.nof_blue_events++; + events.nof_debug_events++; break; case RED: - events.nof_red_events++; + events.nof_error_events++; break; default: break; @@ -190,20 +160,18 @@ static void update_event_time(void) { } static void update_led_color(void) { - if (events.nof_red_events > 0) { + if (events.nof_error_events > 0) { LEDcolor = RED; - } else if (events.nof_blue_events > 0) { + } else if (events.nof_debug_events > 0) { LEDcolor = BLUE; - } else if (events.nof_yellow_events > 0) { + } else if (events.nof_warning_events > 0) { LEDcolor = YELLOW; } else { LEDcolor = GREEN; } - - // events.total_led_color = max(events.total_led_color, events.entries[event].led_color); } -const char* get_event_message(EVENTS_ENUM_TYPE event) { +const char* get_event_message_string(EVENTS_ENUM_TYPE event) { switch (event) { case EVENT_CAN_FAILURE: return "No CAN communication detected for 60s. Shutting down battery control."; @@ -247,7 +215,15 @@ const char* get_event_message(EVENTS_ENUM_TYPE event) { } const char* get_event_enum_string(EVENTS_ENUM_TYPE event) { - return EVENTS_ENUM_TYPE_STRING[event] + 6; // Return the event name but skip "EVENT_" that should always be first + // Return the event name but skip "EVENT_" that should always be first + return EVENTS_ENUM_TYPE_STRING[event] + 6; } -const char* get_event_type(EVENTS_ENUM_TYPE event) {} +const char* get_event_level_string(EVENTS_ENUM_TYPE event) { + // Return the event level but skip "EVENT_LEVEL_" that should always be first + return EVENTS_LEVEL_TYPE_STRING[event] + 12; +} + +const EVENTS_STRUCT_TYPE* get_event_pointer(EVENTS_ENUM_TYPE event) { + return &events.entries[event]; +} diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index b63f5976..a3db6334 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -6,21 +6,6 @@ #include #endif -typedef enum { - EVENT_STATE_INIT = 0, - EVENT_STATE_INACTIVE, - EVENT_STATE_ACTIVE, - EVENT_STATE_ACTIVE_LATCHED -} EVENTS_STATE_TYPE; - -typedef struct { - uint32_t timestamp; // Time in seconds since startup when the event occurred - uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage - uint8_t occurences; // Number of occurrences since startup - uint8_t led_color; // LED indication - EVENTS_STATE_TYPE state; // Event state -} EVENTS_STRUCT_TYPE; - #define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_STRING(STRING) #STRING, @@ -57,9 +42,25 @@ typedef enum { EVENTS_ENUM_TYPE(GENERATE_ENUM) } EVENTS_ENUM_TYPE; typedef enum { EVENTS_LEVEL_TYPE(GENERATE_ENUM) } EVENTS_LEVEL_TYPE; +typedef enum { + EVENT_STATE_INIT = 0, + EVENT_STATE_INACTIVE, + EVENT_STATE_ACTIVE, + EVENT_STATE_ACTIVE_LATCHED +} EVENTS_STATE_TYPE; + +typedef struct { + uint32_t timestamp; // Time in seconds since startup when the event occurred + uint8_t data; // Custom data passed when setting the event, for example cell number for under voltage + uint8_t occurences; // Number of occurrences since startup + uint8_t led_color; // LED indication + EVENTS_LEVEL_TYPE level; // Event level, i.e. ERROR/WARNING... + EVENTS_STATE_TYPE state; // Event state, i.e. ACTIVE/INACTIVE... +} EVENTS_STRUCT_TYPE; + const char* get_event_enum_string(EVENTS_ENUM_TYPE event); -const char* get_event_message(EVENTS_ENUM_TYPE event); -const char* get_led_color_display_text(u_int8_t led_color); +const char* get_event_message_string(EVENTS_ENUM_TYPE event); +const char* get_event_level_string(EVENTS_ENUM_TYPE event); const char* get_event_type(EVENTS_ENUM_TYPE event); void init_events(void); @@ -67,6 +68,8 @@ void set_event_latched(EVENTS_ENUM_TYPE event, uint8_t data); void set_event(EVENTS_ENUM_TYPE event, uint8_t data); void clear_event(EVENTS_ENUM_TYPE event); +const EVENTS_STRUCT_TYPE* get_event_pointer(EVENTS_ENUM_TYPE event); + void run_event_handling(void); extern uint8_t bms_status; //Enum, 0-5 diff --git a/Software/src/devboard/webserver/events_html.cpp b/Software/src/devboard/webserver/events_html.cpp index 597245e0..fad80b81 100644 --- a/Software/src/devboard/webserver/events_html.cpp +++ b/Software/src/devboard/webserver/events_html.cpp @@ -1,5 +1,6 @@ #include "events_html.h" #include +#include "../utils/events.h" const char EVENTS_HTML_START[] = R"=====(