hitl_tester.test_cases.bms.power_draw

Test Power Draw
GitHub Issue(s) turnaroundfactor/HITL#321
turnaroundfactor/battery-benchtop-rev1#271
Description Tests power draw conforms to MIL-PRF-32383/5A (16-December-2021)

Used in these test plans:

  • power_draw ⠀⠀⠀(bms/power_draw.plan)

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

  • ./hitl_tester.py power_draw -DRUNTIME=3600
 1"""
 2| Test                 | Power Draw                                                       |
 3| :------------------- | :--------------------------------------------------------------- |
 4| GitHub Issue(s)      | turnaroundfactor/HITL#321                            </br>\
 5                         turnaroundfactor/battery-benchtop-rev1#271                       |
 6| Description          | Tests power draw conforms to MIL-PRF-32383/5A (16-December-2021) |
 7"""
 8
 9from __future__ import annotations
10
11import time
12
13import pytest
14
15from hitl_tester.modules.bms.bms_hw import BMSHardware
16from hitl_tester.modules.bms.event_watcher import SerialWatcher
17from hitl_tester.modules.logger import logger
18from hitl_tester.modules.bms.plateset import Plateset
19
20RUNTIME = 3600
21"""Runtime in seconds. Defaults to 1 hour"""
22
23_serial_watcher = SerialWatcher()
24_bms = BMSHardware(pytest.flags)  # type: ignore[arg-type]
25_bms.init()
26_plateset = Plateset()
27
28# TODO(JA): move to MIL-PRF test plan?
29
30
31def measure_dmm() -> tuple[float, float, float, float, float]:
32    """Sample the DMM, returning the elapsed time and data."""
33
34    start = time.perf_counter()
35    logger.write_info_to_report("Initiating data collection")
36    assert _bms.power_dmm
37    _bms.power_dmm.resource.write("INIT")
38    _bms.power_dmm.resource.write("*OPC")
39    logger.write_info_to_report("Waiting for completion")
40    while int(_bms.power_dmm.resource.query("*ESR?")) & 1 != 1:
41        time.sleep(0.1)
42    logger.write_info_to_report("Complete, fetching data")
43
44    result = _bms.power_dmm.resource.query("FETC?")
45    data_list = list(map(float, result.split(",")))
46
47    result_average = sum(data_list) / len(data_list)
48    result_max = max(data_list)
49    result_min = min(data_list)
50    result_count = len(data_list)
51
52    return time.perf_counter() - start, result_average, result_max, result_min, result_count
53
54
55@pytest.mark.sim_cells
56def test_power_draw():
57    """
58    | Requirement          | Enter deep slumber and measure voltages                                    |
59    | :------------------- | :------------------------------------------------------------------------- |
60    | GitHub Issue(s)      | turnaroundfactor/HITL#321                                      </br>\
61                             turnaroundfactor/battery-benchtop-rev1#271                                 |
62    | Instructions         | 1. Set up the DMM for the fastest sampling mode at 2V                 </br>\
63                             2. Record multiple samples for 20 minutes                                  |
64    | Pass / Fail Criteria | Pass if calculated current is below MIL-PRF requirements                   |
65    """
66
67    # Initialize DMM (2V and 0.006 NPLC)
68    _bms.power_dmm.resource.write("ZERO:AUTO ONCE")
69    _bms.power_dmm.resource.write("CONF:VOLT:DC 2,MAX")
70    _bms.power_dmm.resource.write("TRIG:SOUR IMM")
71    _bms.power_dmm.resource.write("TRIG:COUN 1")
72    _bms.power_dmm.resource.write("TRIG:DEL 0")
73    _bms.power_dmm.resource.write("SAMP:COUN 2000")
74    _bms.power_dmm.resource.write("*ESE 1")
75
76    # Begin measurements
77    start = time.perf_counter()
78    logger.write_info_to_report(f"Logging samples for {RUNTIME} seconds.")
79    index = 0
80    while time.perf_counter() - start < RUNTIME:
81        logger.write_info_to_report(f"Sample {index}...")
82        measurement_time, average_volts, max_volts, min_volts, measurement_count = measure_dmm()
83        logger.write_info_to_report(f"{average_volts=}, {max_volts=}, {min_volts=}, {measurement_count=}")
84        _bms.csv.raw_voltage_average.record(
85            time.perf_counter() - start, measurement_time, average_volts, max_volts, min_volts, measurement_count
86        )
87        index += 1
RUNTIME = 3600

Runtime in seconds. Defaults to 1 hour

def measure_dmm() -> tuple[float, float, float, float, float]:
32def measure_dmm() -> tuple[float, float, float, float, float]:
33    """Sample the DMM, returning the elapsed time and data."""
34
35    start = time.perf_counter()
36    logger.write_info_to_report("Initiating data collection")
37    assert _bms.power_dmm
38    _bms.power_dmm.resource.write("INIT")
39    _bms.power_dmm.resource.write("*OPC")
40    logger.write_info_to_report("Waiting for completion")
41    while int(_bms.power_dmm.resource.query("*ESR?")) & 1 != 1:
42        time.sleep(0.1)
43    logger.write_info_to_report("Complete, fetching data")
44
45    result = _bms.power_dmm.resource.query("FETC?")
46    data_list = list(map(float, result.split(",")))
47
48    result_average = sum(data_list) / len(data_list)
49    result_max = max(data_list)
50    result_min = min(data_list)
51    result_count = len(data_list)
52
53    return time.perf_counter() - start, result_average, result_max, result_min, result_count

Sample the DMM, returning the elapsed time and data.

@pytest.mark.sim_cells
def test_power_draw():
56@pytest.mark.sim_cells
57def test_power_draw():
58    """
59    | Requirement          | Enter deep slumber and measure voltages                                    |
60    | :------------------- | :------------------------------------------------------------------------- |
61    | GitHub Issue(s)      | turnaroundfactor/HITL#321                                      </br>\
62                             turnaroundfactor/battery-benchtop-rev1#271                                 |
63    | Instructions         | 1. Set up the DMM for the fastest sampling mode at 2V                 </br>\
64                             2. Record multiple samples for 20 minutes                                  |
65    | Pass / Fail Criteria | Pass if calculated current is below MIL-PRF requirements                   |
66    """
67
68    # Initialize DMM (2V and 0.006 NPLC)
69    _bms.power_dmm.resource.write("ZERO:AUTO ONCE")
70    _bms.power_dmm.resource.write("CONF:VOLT:DC 2,MAX")
71    _bms.power_dmm.resource.write("TRIG:SOUR IMM")
72    _bms.power_dmm.resource.write("TRIG:COUN 1")
73    _bms.power_dmm.resource.write("TRIG:DEL 0")
74    _bms.power_dmm.resource.write("SAMP:COUN 2000")
75    _bms.power_dmm.resource.write("*ESE 1")
76
77    # Begin measurements
78    start = time.perf_counter()
79    logger.write_info_to_report(f"Logging samples for {RUNTIME} seconds.")
80    index = 0
81    while time.perf_counter() - start < RUNTIME:
82        logger.write_info_to_report(f"Sample {index}...")
83        measurement_time, average_volts, max_volts, min_volts, measurement_count = measure_dmm()
84        logger.write_info_to_report(f"{average_volts=}, {max_volts=}, {min_volts=}, {measurement_count=}")
85        _bms.csv.raw_voltage_average.record(
86            time.perf_counter() - start, measurement_time, average_volts, max_volts, min_volts, measurement_count
87        )
88        index += 1
Requirement Enter deep slumber and measure voltages
GitHub Issue(s) turnaroundfactor/HITL#321
turnaroundfactor/battery-benchtop-rev1#271
Instructions 1. Set up the DMM for the fastest sampling mode at 2V
2. Record multiple samples for 20 minutes
Pass / Fail Criteria Pass if calculated current is below MIL-PRF requirements