hitl_tester.test_cases.bms.test_2590_assembly

Test Confirm assembly mode transition
GitHub Issue #232 (battery-benchtop-rev1)
Description To ensure a successful bringup, the firmware starts with undervoltage, cell imbalance, and temperature faults disabled. This test confirms that's the case and checks that the faults can be enabled and function.

Used in these test plans:

  • 2590_assembly_b ⠀⠀⠀(bms/2590_assembly_b.plan)

Example Command (warning: test plan may run other test cases):

  • ./hitl_tester.py 2590_assembly_b -DCELL_VOLTAGE=3.8
  1"""
  2| Test                 | Confirm assembly mode transition |
  3| :------------------- | :---------------------------------- |
  4| GitHub Issue         | #232 (battery-benchtop-rev1)        |
  5| Description          | To ensure a successful bringup, the firmware starts with \
  6                         undervoltage, cell imbalance, and temperature faults disabled. \
  7                         This test confirms that's the case and checks that the faults \
  8                         can be enabled and function. |
  9"""
 10
 11from __future__ import annotations
 12
 13import time
 14
 15import pytest
 16
 17from hitl_tester.modules.bms.bms_hw import BMSHardware
 18from hitl_tester.modules.bms.event_watcher import SerialWatcher
 19from hitl_tester.modules.bms.plateset import Plateset
 20from hitl_tester.modules.logger import logger
 21
 22CELL_VOLTAGE = 3.8
 23
 24bms_hardware = BMSHardware(pytest.flags)  # type: ignore[arg-type]
 25bms_hardware.init()
 26
 27serial_watcher = SerialWatcher()
 28plateset = Plateset()
 29
 30
 31def reset_cell_sims():
 32    """Activate cell sims and set appropriate temperatures."""
 33    logger.write_info_to_report("Powering down cell sims")
 34    for cell in bms_hardware.cells.values():
 35        cell.disengage_safety_protocols = True
 36        cell.volts = 0.0001
 37    time.sleep(5)
 38    logger.write_info_to_report("Powering up cell sims")
 39    for cell in bms_hardware.cells.values():
 40        cell.volts = CELL_VOLTAGE
 41        cell.disengage_safety_protocols = False
 42    for cell in bms_hardware.cells.values():
 43        cell.exact_volts = CELL_VOLTAGE
 44    logger.write_info_to_report("Setting temperature to 15°C")
 45    plateset.thermistor1 = 15
 46    plateset.thermistor2 = 15
 47
 48
 49def test_no_overtemp_faults():
 50    """
 51    | Requirement          | Confirm overtemp flags are disabled |
 52    | :------------------- | :---------------------------------- |
 53    | GitHub Issue         | #232 (BMS)                          |
 54    | Instructions         | 1. Rest at 60°C and ensure no fault is raised </br>\
 55                             2. Discharge at 100mA, 60°C and ensure no fault is raised </br>\
 56                             3. Charge at 100mA, 46°C and ensure no fault is raised </br>\
 57                             4. Rest at 94°C and ensure no permanentdisable is raised |
 58    | Pass / Fail Criteria | Fail if a fault is raised |
 59    """
 60    logger.write_info_to_report("Testing Overtemp")
 61    reset_cell_sims()
 62    serial_watcher.start()
 63
 64    # Test resting overtemp
 65    logger.write_info_to_report("Resting at 59°C")
 66    plateset.thermistor1 = 60
 67    serial_watcher.assert_false("flags.prefault_overtemp_discharge", True)
 68    serial_watcher.assert_false("flags.fault_overtemp_discharge", True)
 69
 70    # Test discharging overtemp
 71    logger.write_info_to_report("Discharging at -100 mA, 59°C")
 72    bms_hardware.load.mode_cc()
 73    bms_hardware.load.amps = 0.100
 74    bms_hardware.load.enable()
 75    serial_watcher.assert_false("flags.prefault_overtemp_discharge", True)
 76    serial_watcher.assert_false("flags.fault_overtemp_discharge", True)
 77    bms_hardware.load.disable()
 78
 79    # Test charging overtemp
 80    logger.write_info_to_report("Charging at 100 mA, 46°C")
 81    bms_hardware.charger.set_profile(16.8, 0.1)
 82    plateset.ce_switch = True
 83    bms_hardware.charger.enable()
 84    plateset.thermistor1 = 46
 85    serial_watcher.assert_false("flags.prefault_overtemp_charge", True)
 86    serial_watcher.assert_false("flags.fault_overtemp_charge", True)
 87    bms_hardware.charger.disable()
 88    plateset.ce_switch = False
 89
 90    # Test resting permanent disable
 91    plateset.disengage_safety_protocols = True
 92    logger.write_info_to_report("Resting at 94°C")
 93    plateset.thermistor1 = 94
 94    plateset.disengage_safety_protocols = False
 95    serial_watcher.assert_false("flags.permanentdisable_overtemp", True)
 96
 97    serial_watcher.stop()
 98
 99
100def test_no_undertemp_faults():
101    """
102    | Requirement          | Confirm undertemp flags are disabled |
103    | :------------------- | :---------------------------------- |
104    | GitHub Issue         | #232 (BMS)                          |
105    | Instructions         | 1. Rest at -21°C and ensure no fault is raised </br>\
106                             2. Discharge at 100mA, -21°C and ensure no fault is raised </br>\
107                             3. Charge at 100mA, -5°C and ensure no fault is raised |
108    | Pass / Fail Criteria | Fail if a fault is raised |
109    """
110    logger.write_info_to_report("Testing Undertemp")
111    reset_cell_sims()
112    serial_watcher.start()
113
114    logger.write_info_to_report("Resting at -21°C")
115    plateset.thermistor1 = -21
116    serial_watcher.assert_false("flags.prefault_undertemp_discharge", True)
117    serial_watcher.assert_false("flags.fault_undertemp_discharge", True)
118
119    logger.write_info_to_report("Discharging at -100 mA, -21°C")
120    bms_hardware.load.mode_cc()
121    bms_hardware.load.amps = 0.100
122    bms_hardware.load.enable()
123    plateset.thermistor1 = -21
124    serial_watcher.assert_false("flags.prefault_undertemp_discharge", True)
125    serial_watcher.assert_false("flags.fault_undertemp_discharge", True)
126    bms_hardware.load.disable()
127
128    logger.write_info_to_report("Charging at 100 mA, -5°C")
129    bms_hardware.charger.set_profile(16.8, 0.100)
130    plateset.ce_switch = True
131    bms_hardware.charger.enable()
132    plateset.thermistor1 = -5
133    serial_watcher.assert_false("flags.prefault_undertemp_charge", True)
134    serial_watcher.assert_false("flags.fault_undertemp_charge", True)
135    bms_hardware.charger.disable()
136    plateset.ce_switch = False
137
138    serial_watcher.stop()
139
140
141def test_no_undervoltage_faults():
142    """
143    | Requirement          | Confirm undervoltage flags are disabled |
144    | :------------------- | :---------------------------------- |
145    | GitHub Issue         | #232 (BMS)                          |
146    | Instructions         | 1. Rest at 2.3V and ensure no fault is raised </br>\
147                             2. Charge at 500mA, 2.3V and ensure no fault is raised </br>\
148                             3. Charge at 500mA, 2.2V and ensure no permanentdisable is raised |
149    | Pass / Fail Criteria | Fail if a fault is raised |
150    """
151    logger.write_info_to_report("Testing Undervoltage")
152    reset_cell_sims()
153    test_cell = bms_hardware.cells[1]
154    for cell in bms_hardware.cells.values():
155        cell.disengage_safety_protocols = True
156        test_cell.exact_volts = 3.0  # Must be low enough to not trigger cell imbalance [abs(high - low) > 1.5V]
157    serial_watcher.start()
158
159    logger.write_info_to_report("Resting at 0 mA, 2.3 V")
160    test_cell.exact_volts = 2.3
161    serial_watcher.assert_false("flags.prefault_undervoltage_discharge", True)
162    serial_watcher.assert_false("flags.faultslumber_undervoltage_discharge", True)
163
164    bms_hardware.charger.set_profile(16.8, 0.500)
165    plateset.ce_switch = True
166    bms_hardware.charger.enable()
167
168    logger.write_info_to_report("Charging at 500 mA, 2.3 V")
169    serial_watcher.assert_false("flags.prefault_undervoltage_charge", True)
170    serial_watcher.assert_false("flags.fault_undervoltage_charge", True)
171
172    logger.write_info_to_report("Charging at 500 mA, 2.2 V")
173    test_cell.exact_volts = 2.2
174    serial_watcher.assert_false("flags.permanentdisable_undervoltage", True)
175
176    bms_hardware.charger.disable()
177    plateset.ce_switch = False
178
179    serial_watcher.stop()
180
181
182def test_no_cell_imbalance():
183    """
184    | Requirement          | Confirm cell imbalance flags are disabled |
185    | :------------------- | :---------------------------------- |
186    | GitHub Issue         | #232 (BMS)                          |
187    | Instructions         | Rest with one cell 1.5V+ below the others and ensure no fault is raised |
188    | Pass / Fail Criteria | Fail if a fault is raised |
189    """
190    logger.write_info_to_report("Testing Cell Imbalance")
191    reset_cell_sims()
192    test_cell = bms_hardware.cells[1]
193    serial_watcher.start()
194    test_cell.disengage_safety_protocols = True
195
196    logger.write_info_to_report("Resting at 0 mA, 2.0 V")
197    test_cell.exact_volts = 2.0
198    serial_watcher.assert_false("flags.prefault_cellimbalance", True)
199    serial_watcher.assert_false("flags.permanentdisable_cellimbalance", True)
200
201    serial_watcher.stop()
CELL_VOLTAGE = 3.8
def reset_cell_sims():
32def reset_cell_sims():
33    """Activate cell sims and set appropriate temperatures."""
34    logger.write_info_to_report("Powering down cell sims")
35    for cell in bms_hardware.cells.values():
36        cell.disengage_safety_protocols = True
37        cell.volts = 0.0001
38    time.sleep(5)
39    logger.write_info_to_report("Powering up cell sims")
40    for cell in bms_hardware.cells.values():
41        cell.volts = CELL_VOLTAGE
42        cell.disengage_safety_protocols = False
43    for cell in bms_hardware.cells.values():
44        cell.exact_volts = CELL_VOLTAGE
45    logger.write_info_to_report("Setting temperature to 15°C")
46    plateset.thermistor1 = 15
47    plateset.thermistor2 = 15

Activate cell sims and set appropriate temperatures.

def test_no_overtemp_faults():
50def test_no_overtemp_faults():
51    """
52    | Requirement          | Confirm overtemp flags are disabled |
53    | :------------------- | :---------------------------------- |
54    | GitHub Issue         | #232 (BMS)                          |
55    | Instructions         | 1. Rest at 60°C and ensure no fault is raised </br>\
56                             2. Discharge at 100mA, 60°C and ensure no fault is raised </br>\
57                             3. Charge at 100mA, 46°C and ensure no fault is raised </br>\
58                             4. Rest at 94°C and ensure no permanentdisable is raised |
59    | Pass / Fail Criteria | Fail if a fault is raised |
60    """
61    logger.write_info_to_report("Testing Overtemp")
62    reset_cell_sims()
63    serial_watcher.start()
64
65    # Test resting overtemp
66    logger.write_info_to_report("Resting at 59°C")
67    plateset.thermistor1 = 60
68    serial_watcher.assert_false("flags.prefault_overtemp_discharge", True)
69    serial_watcher.assert_false("flags.fault_overtemp_discharge", True)
70
71    # Test discharging overtemp
72    logger.write_info_to_report("Discharging at -100 mA, 59°C")
73    bms_hardware.load.mode_cc()
74    bms_hardware.load.amps = 0.100
75    bms_hardware.load.enable()
76    serial_watcher.assert_false("flags.prefault_overtemp_discharge", True)
77    serial_watcher.assert_false("flags.fault_overtemp_discharge", True)
78    bms_hardware.load.disable()
79
80    # Test charging overtemp
81    logger.write_info_to_report("Charging at 100 mA, 46°C")
82    bms_hardware.charger.set_profile(16.8, 0.1)
83    plateset.ce_switch = True
84    bms_hardware.charger.enable()
85    plateset.thermistor1 = 46
86    serial_watcher.assert_false("flags.prefault_overtemp_charge", True)
87    serial_watcher.assert_false("flags.fault_overtemp_charge", True)
88    bms_hardware.charger.disable()
89    plateset.ce_switch = False
90
91    # Test resting permanent disable
92    plateset.disengage_safety_protocols = True
93    logger.write_info_to_report("Resting at 94°C")
94    plateset.thermistor1 = 94
95    plateset.disengage_safety_protocols = False
96    serial_watcher.assert_false("flags.permanentdisable_overtemp", True)
97
98    serial_watcher.stop()
Requirement Confirm overtemp flags are disabled
GitHub Issue #232 (BMS)
Instructions 1. Rest at 60°C and ensure no fault is raised
2. Discharge at 100mA, 60°C and ensure no fault is raised
3. Charge at 100mA, 46°C and ensure no fault is raised
4. Rest at 94°C and ensure no permanentdisable is raised
Pass / Fail Criteria Fail if a fault is raised
def test_no_undertemp_faults():
101def test_no_undertemp_faults():
102    """
103    | Requirement          | Confirm undertemp flags are disabled |
104    | :------------------- | :---------------------------------- |
105    | GitHub Issue         | #232 (BMS)                          |
106    | Instructions         | 1. Rest at -21°C and ensure no fault is raised </br>\
107                             2. Discharge at 100mA, -21°C and ensure no fault is raised </br>\
108                             3. Charge at 100mA, -5°C and ensure no fault is raised |
109    | Pass / Fail Criteria | Fail if a fault is raised |
110    """
111    logger.write_info_to_report("Testing Undertemp")
112    reset_cell_sims()
113    serial_watcher.start()
114
115    logger.write_info_to_report("Resting at -21°C")
116    plateset.thermistor1 = -21
117    serial_watcher.assert_false("flags.prefault_undertemp_discharge", True)
118    serial_watcher.assert_false("flags.fault_undertemp_discharge", True)
119
120    logger.write_info_to_report("Discharging at -100 mA, -21°C")
121    bms_hardware.load.mode_cc()
122    bms_hardware.load.amps = 0.100
123    bms_hardware.load.enable()
124    plateset.thermistor1 = -21
125    serial_watcher.assert_false("flags.prefault_undertemp_discharge", True)
126    serial_watcher.assert_false("flags.fault_undertemp_discharge", True)
127    bms_hardware.load.disable()
128
129    logger.write_info_to_report("Charging at 100 mA, -5°C")
130    bms_hardware.charger.set_profile(16.8, 0.100)
131    plateset.ce_switch = True
132    bms_hardware.charger.enable()
133    plateset.thermistor1 = -5
134    serial_watcher.assert_false("flags.prefault_undertemp_charge", True)
135    serial_watcher.assert_false("flags.fault_undertemp_charge", True)
136    bms_hardware.charger.disable()
137    plateset.ce_switch = False
138
139    serial_watcher.stop()
Requirement Confirm undertemp flags are disabled
GitHub Issue #232 (BMS)
Instructions 1. Rest at -21°C and ensure no fault is raised
2. Discharge at 100mA, -21°C and ensure no fault is raised
3. Charge at 100mA, -5°C and ensure no fault is raised
Pass / Fail Criteria Fail if a fault is raised
def test_no_undervoltage_faults():
142def test_no_undervoltage_faults():
143    """
144    | Requirement          | Confirm undervoltage flags are disabled |
145    | :------------------- | :---------------------------------- |
146    | GitHub Issue         | #232 (BMS)                          |
147    | Instructions         | 1. Rest at 2.3V and ensure no fault is raised </br>\
148                             2. Charge at 500mA, 2.3V and ensure no fault is raised </br>\
149                             3. Charge at 500mA, 2.2V and ensure no permanentdisable is raised |
150    | Pass / Fail Criteria | Fail if a fault is raised |
151    """
152    logger.write_info_to_report("Testing Undervoltage")
153    reset_cell_sims()
154    test_cell = bms_hardware.cells[1]
155    for cell in bms_hardware.cells.values():
156        cell.disengage_safety_protocols = True
157        test_cell.exact_volts = 3.0  # Must be low enough to not trigger cell imbalance [abs(high - low) > 1.5V]
158    serial_watcher.start()
159
160    logger.write_info_to_report("Resting at 0 mA, 2.3 V")
161    test_cell.exact_volts = 2.3
162    serial_watcher.assert_false("flags.prefault_undervoltage_discharge", True)
163    serial_watcher.assert_false("flags.faultslumber_undervoltage_discharge", True)
164
165    bms_hardware.charger.set_profile(16.8, 0.500)
166    plateset.ce_switch = True
167    bms_hardware.charger.enable()
168
169    logger.write_info_to_report("Charging at 500 mA, 2.3 V")
170    serial_watcher.assert_false("flags.prefault_undervoltage_charge", True)
171    serial_watcher.assert_false("flags.fault_undervoltage_charge", True)
172
173    logger.write_info_to_report("Charging at 500 mA, 2.2 V")
174    test_cell.exact_volts = 2.2
175    serial_watcher.assert_false("flags.permanentdisable_undervoltage", True)
176
177    bms_hardware.charger.disable()
178    plateset.ce_switch = False
179
180    serial_watcher.stop()
Requirement Confirm undervoltage flags are disabled
GitHub Issue #232 (BMS)
Instructions 1. Rest at 2.3V and ensure no fault is raised
2. Charge at 500mA, 2.3V and ensure no fault is raised
3. Charge at 500mA, 2.2V and ensure no permanentdisable is raised
Pass / Fail Criteria Fail if a fault is raised
def test_no_cell_imbalance():
183def test_no_cell_imbalance():
184    """
185    | Requirement          | Confirm cell imbalance flags are disabled |
186    | :------------------- | :---------------------------------- |
187    | GitHub Issue         | #232 (BMS)                          |
188    | Instructions         | Rest with one cell 1.5V+ below the others and ensure no fault is raised |
189    | Pass / Fail Criteria | Fail if a fault is raised |
190    """
191    logger.write_info_to_report("Testing Cell Imbalance")
192    reset_cell_sims()
193    test_cell = bms_hardware.cells[1]
194    serial_watcher.start()
195    test_cell.disengage_safety_protocols = True
196
197    logger.write_info_to_report("Resting at 0 mA, 2.0 V")
198    test_cell.exact_volts = 2.0
199    serial_watcher.assert_false("flags.prefault_cellimbalance", True)
200    serial_watcher.assert_false("flags.permanentdisable_cellimbalance", True)
201
202    serial_watcher.stop()
Requirement Confirm cell imbalance flags are disabled
GitHub Issue #232 (BMS)
Instructions Rest with one cell 1.5V+ below the others and ensure no fault is raised
Pass / Fail Criteria Fail if a fault is raised