hitl_tester.test_cases.bms.test_2590_0v

Modified version of the tests in test_2590_cell_sims.py, for testing 0V cells.

Used in these test plans:

  • 0v_testing ⠀⠀⠀(bms/0v_testing.plan)

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

  • ./hitl_tester.py 0v_testing -DDISCHARGE_CURRENT=0 -DCHARGE_CURRENT=0 -DCELL_VOLTAGE=1.375 -DCHARGE_VOLTAGE=16.8 -DREST_TIME=1800 -DMINIMUM_READINGS=3 -DSAMPLE_INTERVAL=10 -DDEFAULT_TEMPERATURE_C=15
  1"""
  2Modified version of the tests in test_2590_cell_sims.py, for testing 0V cells.
  3"""
  4
  5from __future__ import annotations
  6
  7import time
  8
  9import pytest
 10
 11from hitl_tester.modules.bms.bms_hw import BMSHardware
 12from hitl_tester.modules.bms.event_watcher import SerialWatcher
 13from hitl_tester.modules.bms.plateset import Plateset
 14from hitl_tester.modules.bms_types import DischargeType
 15from hitl_tester.modules.logger import logger
 16
 17DISCHARGE_CURRENT = 0
 18CHARGE_CURRENT = 0
 19CELL_VOLTAGE = 1.375
 20CHARGE_VOLTAGE = 16.8
 21REST_TIME = 30 * 60
 22
 23MINIMUM_READINGS = 3
 24SAMPLE_INTERVAL = 10
 25DEFAULT_TEMPERATURE_C = 15
 26
 27bms_hardware = BMSHardware(pytest.flags)  # type: ignore[arg-type]
 28bms_hardware.init()
 29
 30serial_watcher = SerialWatcher()
 31plateset = Plateset()
 32
 33
 34def test_reset_cell_sims():
 35    """Activate cell sims and set appropriate temperatures."""
 36    logger.write_info_to_report("Powering down cell sims to 0V")
 37    for cell in bms_hardware.cells.values():
 38        cell.disengage_safety_protocols = True
 39        cell.volts = 0.0001
 40    time.sleep(5)
 41    logger.write_info_to_report(f"Powering up cell sims to {CELL_VOLTAGE}V")
 42    for cell in bms_hardware.cells.values():
 43        cell.volts = CELL_VOLTAGE
 44        cell.disengage_safety_protocols = False
 45    logger.write_info_to_report(f"Setting temperature to {DEFAULT_TEMPERATURE_C}°C")
 46    plateset.thermistor1 = DEFAULT_TEMPERATURE_C
 47    plateset.thermistor2 = DEFAULT_TEMPERATURE_C
 48    time.sleep(5)
 49
 50
 51def standard_charge(
 52    charge_current: float = 2,
 53    max_time: int = 3 * 3600,
 54    sample_interval: int = 10,
 55    minimum_readings: int = 3,
 56    charge_voltage: float = 16.8,
 57    termination_current: float = 0.100,
 58):
 59    """
 60    Charge batteries in accordance with 4.3.1 for not greater than three hours.
 61    4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.
 62    """
 63    bms_hardware.voltage = charge_voltage
 64    bms_hardware.ov_protection = bms_hardware.voltage + 0.050  # 50mV above the charging voltage
 65    bms_hardware.current = charge_current
 66    bms_hardware.termination_current = termination_current
 67    bms_hardware.max_time = max_time
 68    bms_hardware.sample_interval = sample_interval
 69    bms_hardware.minimum_readings = minimum_readings
 70
 71    # Run the Charge cycle
 72    bms_hardware.run_li_charge_cycle()
 73
 74
 75def standard_discharge(
 76    discharge_current: float = 2, max_time: int = 8 * 3600, sample_interval: int = 10, discharge_voltage: float = 10
 77):
 78    """Discharge at 2A until 10V."""
 79    bms_hardware.voltage = discharge_voltage
 80    bms_hardware.uv_protection = -0.05  # bms_hardware.voltage - 0.050  # 50mV below voltage cutoff
 81    bms_hardware.current = discharge_current
 82    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
 83    bms_hardware.max_time = max_time
 84    bms_hardware.sample_interval = sample_interval
 85
 86    # Run the discharge cycle, returning the capacity
 87    capacity = bms_hardware.run_discharge_cycle()
 88    logger.write_info_to_report(f"Discharge complete, capacity was {capacity * 1000.0} mAh")
 89    return capacity
 90
 91
 92def test_0v_manual():
 93    """
 94    | Requirement          | Charge from any starting voltage  |
 95    | :------------------- | :-------------------------------- |
 96    | GitHub Issue         | #161 (HITL), #250 (BMS)           |
 97    | Instructions         | Charge, discharge, or rest depending on </br>\
 98                             current |
 99    | Configuration        | ⦁ `CHARGE_VOLTAGE` = In volts </br>\
100                             ⦁ `CHARGE_CURRENT` = In milliamps </br>\
101                             ⦁ `DISCHARGE_CURRENT` = In milliamps </br>\
102                             ⦁ `CELL_VOLTAGE` = Starting voltage of each cell </br>\
103                             ⦁ `REST_TIME` = How long to rest </br>\
104                             ⦁ `SAMPLE_INTERVAL` = How often to output / poll data |
105    """
106    old_cycle_function = bms_hardware.csv.cycle
107    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
108    bms_hardware.csv.cycle.create_file()
109
110    if DISCHARGE_CURRENT:
111        standard_discharge(
112            sample_interval=SAMPLE_INTERVAL, discharge_current=DISCHARGE_CURRENT / 1000, discharge_voltage=-0.05
113        )
114
115    elif CHARGE_CURRENT:
116        plateset.ce_switch = True
117        standard_charge(
118            sample_interval=SAMPLE_INTERVAL,
119            charge_current=CHARGE_CURRENT / 1000,
120            termination_current=-0.05,
121            charge_voltage=CHARGE_VOLTAGE,
122        )
123        plateset.ce_switch = False
124
125    else:
126        bms_hardware.max_time = REST_TIME
127        bms_hardware.sample_interval = SAMPLE_INTERVAL
128        bms_hardware.run_resting_cycle()
129
130    bms_hardware.csv.cycle = old_cycle_function
DISCHARGE_CURRENT = 0
CHARGE_CURRENT = 0
CELL_VOLTAGE = 1.375
CHARGE_VOLTAGE = 16.8
REST_TIME = 1800
MINIMUM_READINGS = 3
SAMPLE_INTERVAL = 10
DEFAULT_TEMPERATURE_C = 15
def test_reset_cell_sims():
35def test_reset_cell_sims():
36    """Activate cell sims and set appropriate temperatures."""
37    logger.write_info_to_report("Powering down cell sims to 0V")
38    for cell in bms_hardware.cells.values():
39        cell.disengage_safety_protocols = True
40        cell.volts = 0.0001
41    time.sleep(5)
42    logger.write_info_to_report(f"Powering up cell sims to {CELL_VOLTAGE}V")
43    for cell in bms_hardware.cells.values():
44        cell.volts = CELL_VOLTAGE
45        cell.disengage_safety_protocols = False
46    logger.write_info_to_report(f"Setting temperature to {DEFAULT_TEMPERATURE_C}°C")
47    plateset.thermistor1 = DEFAULT_TEMPERATURE_C
48    plateset.thermistor2 = DEFAULT_TEMPERATURE_C
49    time.sleep(5)

Activate cell sims and set appropriate temperatures.

def standard_charge( charge_current: float = 2, max_time: int = 10800, sample_interval: int = 10, minimum_readings: int = 3, charge_voltage: float = 16.8, termination_current: float = 0.1):
52def standard_charge(
53    charge_current: float = 2,
54    max_time: int = 3 * 3600,
55    sample_interval: int = 10,
56    minimum_readings: int = 3,
57    charge_voltage: float = 16.8,
58    termination_current: float = 0.100,
59):
60    """
61    Charge batteries in accordance with 4.3.1 for not greater than three hours.
62    4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.
63    """
64    bms_hardware.voltage = charge_voltage
65    bms_hardware.ov_protection = bms_hardware.voltage + 0.050  # 50mV above the charging voltage
66    bms_hardware.current = charge_current
67    bms_hardware.termination_current = termination_current
68    bms_hardware.max_time = max_time
69    bms_hardware.sample_interval = sample_interval
70    bms_hardware.minimum_readings = minimum_readings
71
72    # Run the Charge cycle
73    bms_hardware.run_li_charge_cycle()

Charge batteries in accordance with 4.3.1 for not greater than three hours. 4.3.1 = 23 ± 5°C (73.4°F) ambient pressure/relative humidity, with 2+ hours between charge and discharge.

def standard_discharge( discharge_current: float = 2, max_time: int = 28800, sample_interval: int = 10, discharge_voltage: float = 10):
76def standard_discharge(
77    discharge_current: float = 2, max_time: int = 8 * 3600, sample_interval: int = 10, discharge_voltage: float = 10
78):
79    """Discharge at 2A until 10V."""
80    bms_hardware.voltage = discharge_voltage
81    bms_hardware.uv_protection = -0.05  # bms_hardware.voltage - 0.050  # 50mV below voltage cutoff
82    bms_hardware.current = discharge_current
83    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
84    bms_hardware.max_time = max_time
85    bms_hardware.sample_interval = sample_interval
86
87    # Run the discharge cycle, returning the capacity
88    capacity = bms_hardware.run_discharge_cycle()
89    logger.write_info_to_report(f"Discharge complete, capacity was {capacity * 1000.0} mAh")
90    return capacity

Discharge at 2A until 10V.

def test_0v_manual():
 93def test_0v_manual():
 94    """
 95    | Requirement          | Charge from any starting voltage  |
 96    | :------------------- | :-------------------------------- |
 97    | GitHub Issue         | #161 (HITL), #250 (BMS)           |
 98    | Instructions         | Charge, discharge, or rest depending on </br>\
 99                             current |
100    | Configuration        | ⦁ `CHARGE_VOLTAGE` = In volts </br>\
101                             ⦁ `CHARGE_CURRENT` = In milliamps </br>\
102                             ⦁ `DISCHARGE_CURRENT` = In milliamps </br>\
103                             ⦁ `CELL_VOLTAGE` = Starting voltage of each cell </br>\
104                             ⦁ `REST_TIME` = How long to rest </br>\
105                             ⦁ `SAMPLE_INTERVAL` = How often to output / poll data |
106    """
107    old_cycle_function = bms_hardware.csv.cycle
108    bms_hardware.csv.cycle = bms_hardware.csv.cycle_smbus
109    bms_hardware.csv.cycle.create_file()
110
111    if DISCHARGE_CURRENT:
112        standard_discharge(
113            sample_interval=SAMPLE_INTERVAL, discharge_current=DISCHARGE_CURRENT / 1000, discharge_voltage=-0.05
114        )
115
116    elif CHARGE_CURRENT:
117        plateset.ce_switch = True
118        standard_charge(
119            sample_interval=SAMPLE_INTERVAL,
120            charge_current=CHARGE_CURRENT / 1000,
121            termination_current=-0.05,
122            charge_voltage=CHARGE_VOLTAGE,
123        )
124        plateset.ce_switch = False
125
126    else:
127        bms_hardware.max_time = REST_TIME
128        bms_hardware.sample_interval = SAMPLE_INTERVAL
129        bms_hardware.run_resting_cycle()
130
131    bms_hardware.csv.cycle = old_cycle_function
Requirement Charge from any starting voltage
GitHub Issue #161 (HITL), #250 (BMS)
Instructions Charge, discharge, or rest depending on
current
Configuration CHARGE_VOLTAGE = In volts
CHARGE_CURRENT = In milliamps
DISCHARGE_CURRENT = In milliamps
CELL_VOLTAGE = Starting voltage of each cell
REST_TIME = How long to rest
SAMPLE_INTERVAL = How often to output / poll data