hitl_tester.test_cases.bms.test_thermal_chamber_cell

Test Cell testing
GitHub Issue(s) turnaroundfactor/HITL#97
turnaroundfactor/HITL#308
Description Record the voltage of a cell at different capacities and temperatures
Instructions 1. Completely charge cell at room temperature
2. Completely discharge cell at a set temperature
⠀⠀⦁ Determine the capacity of the cell
3. Completely charge cell at room temperature
4. Step discharge cell at a set temperature
⠀⠀⦁ Discharge one increment (using the capacity from step two)
⠀⠀⦁ Rest for three hours
⠀⠀⦁ Record OCV data
⠀⠀⦁ Repeat until the cell is fully discharged
Pass / Fail Criteria Pass if no exceptions occur. Results will be manually checked
Estimated Duration 3 days

Used in these test plans:

  • thermal_chamber_ada ⠀⠀⠀(bms/thermal_chamber_ada.plan)
  • thermal_chamber_nanograf ⠀⠀⠀(bms/thermal_chamber_nanograf.plan)
  • thermal_chamber_ale_si4000 ⠀⠀⠀(bms/thermal_chamber_ale_si4000.plan)
  • thermal_chamber_amprius ⠀⠀⠀(bms/thermal_chamber_amprius.plan)
  • thermal_chamber_samsung_inr_35e ⠀⠀⠀(bms/thermal_chamber_samsung_inr_35e.plan)
  • thermal_chamber_ale_si4200 ⠀⠀⠀(bms/thermal_chamber_ale_si4200.plan)

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

  • ./hitl_tester.py thermal_chamber_ada -DMINUTE=60 -DHOUR=3600 -DMANUAL_DISCHARGE=0.0 -DMANUAL_DISCHARGE2=0.0 -DTHERMAL_CHAMBER_TEMP=20 -DMAX_THERMAL_CHAMBER_TIME=3600 -DMAX_CHARGE_TIME=28800 -DCHARGE_VOLTAGE=2.7 -DCHARGE_OV_PROTECTION=2.75 -DCHARGE_CURRENT_A=0.7 -DCHARGE_TERMINATION_CURRENT=0.175 -DCHARGE_SAMPLE_INTERVAL=10 -DDISCHARGE_SOAK_TIME=5 -DMAX_DISCHARGE_TIME=28800 -DMAX_DISCHARGE_STEP_TIME=3600 -DDISCHARGE_CURRENT_A=0.7 -DDISCHARGE_VOLTAGE=1.7 -DDISCHARGE_UV_PROTECTION=1.65 -DDISCHARGE_SAMPLE_INTERVAL=10 -DRESTING_TIME=10800 -DRESTING_SAMPLE_INTERVAL=60 -DMIN_READINGS=3 -DCAPACITY=0
  1"""
  2| Test                 | Cell testing                                                          |
  3| :------------------- | :-------------------------------------------------------------------- |
  4| GitHub Issue(s)      | turnaroundfactor/HITL#97                                  </br>\
  5                         turnaroundfactor/HITL#308                                      |
  6| Description          | Record the voltage of a cell at different capacities and temperatures |
  7| Instructions         | 1. Completely charge cell at room temperature                    </br>\
  8                         2. Completely discharge cell at a set temperature                </br>\
  9                          ⠀⠀⦁ Determine the capacity of the cell                          </br>\
 10                         3. Completely charge cell at room temperature                    </br>\
 11                         4. Step discharge cell at a set temperature                      </br>\
 12                          ⠀⠀⦁ Discharge one increment (using the capacity from step two)  </br>\
 13                          ⠀⠀⦁ Rest for three hours                                        </br>\
 14                          ⠀⠀⦁ Record OCV data                                             </br>\
 15                          ⠀⠀⦁ Repeat until the cell is fully discharged                        |
 16| Pass / Fail Criteria | Pass if no exceptions occur. Results will be manually checked         |
 17| Estimated Duration   | 3 days                                                                |
 18"""
 19
 20import pytest
 21
 22from hitl_tester.modules.bms.bms_hw import BMSHardware, UserInterrupt
 23from hitl_tester.modules.bms_types import DischargeType
 24from hitl_tester.modules.logger import logger
 25
 26# Global Variables that can be shared between tests
 27MINUTE = 60
 28HOUR = 60 * MINUTE
 29
 30MANUAL_DISCHARGE = 0.0
 31"""Force a discharge of some amount before step discharge."""
 32
 33MANUAL_DISCHARGE2 = 0.0
 34"""Force a discharge of some amount before step discharge."""
 35
 36THERMAL_CHAMBER_TEMP = 20  # Room temperature: 23 C
 37"""The discharge temperature."""
 38
 39MAX_THERMAL_CHAMBER_TIME = 60 * MINUTE
 40"""Timeout for reaching a set temperature."""
 41
 42MAX_CHARGE_TIME = 8 * HOUR
 43"""Timeout for a full charge."""
 44CHARGE_VOLTAGE = 2.7
 45"""Voltage to charge at."""
 46CHARGE_OV_PROTECTION = 2.75
 47"""Overvoltage limit."""
 48CHARGE_CURRENT_A = 0.7
 49"""Current limit while charging."""
 50CHARGE_TERMINATION_CURRENT = 0.175
 51"""When to stop charging."""
 52CHARGE_SAMPLE_INTERVAL = 10
 53"""Sample time while charging."""
 54
 55DISCHARGE_SOAK_TIME = 5  # Soak longer at extreme temperatures
 56"""How long to soak before a full discharge."""
 57MAX_DISCHARGE_TIME = 8 * HOUR
 58"""Timeout for a full discharge."""
 59MAX_DISCHARGE_STEP_TIME = HOUR
 60"""Timeout for a single step cycle."""
 61DISCHARGE_CURRENT_A = 0.7
 62"""Current to discharge at. The cell sims will only work with 2.5A or less."""
 63DISCHARGE_VOLTAGE = 1.7
 64"""Voltage to discharge at."""
 65DISCHARGE_UV_PROTECTION = 1.65
 66"""Undervoltage limit."""
 67DISCHARGE_SAMPLE_INTERVAL = 10
 68"""Sample time while discharging."""
 69
 70RESTING_TIME = 3 * HOUR
 71"""How long to rest after steps."""
 72RESTING_SAMPLE_INTERVAL = 1 * MINUTE
 73"""Sample time while resting."""
 74
 75MIN_READINGS = 3
 76"""How many readings to take before passing (for erroneous readings)."""
 77CAPACITY = 0
 78"""Cell capacity. Set by the discharge cycle."""
 79
 80
 81bms_hardware = BMSHardware(pytest.flags)  # type: ignore[arg-type]
 82bms_hardware.init()
 83
 84if not -30 < THERMAL_CHAMBER_TEMP < 55:
 85    DISCHARGE_SOAK_TIME = 4 * HOUR
 86
 87
 88def test_thermal_chamber_room_temperature_1():
 89    """Set the thermal chamber to room temperature."""
 90    try:
 91        bms_hardware.thermal_chamber.set_room_temperature()
 92        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
 93    except RuntimeError:
 94        logger.write_debug_to_report("No thermal chamber in config, skipping.")
 95
 96
 97def test_full_charge_cycle_1():
 98    """Completely charge cell."""
 99    bms_hardware.voltage = CHARGE_VOLTAGE
100    assert bms_hardware.voltage == CHARGE_VOLTAGE
101
102    bms_hardware.ov_protection = CHARGE_OV_PROTECTION
103    assert bms_hardware.ov_protection == CHARGE_OV_PROTECTION
104
105    bms_hardware.current = CHARGE_CURRENT_A
106    assert bms_hardware.current == CHARGE_CURRENT_A
107
108    bms_hardware.termination_current = CHARGE_TERMINATION_CURRENT
109    assert bms_hardware.termination_current == CHARGE_TERMINATION_CURRENT
110
111    bms_hardware.max_time = MAX_CHARGE_TIME
112    assert bms_hardware.max_time == MAX_CHARGE_TIME
113
114    bms_hardware.sample_interval = CHARGE_SAMPLE_INTERVAL
115    assert bms_hardware.sample_interval == CHARGE_SAMPLE_INTERVAL
116
117    bms_hardware.minimum_readings = MIN_READINGS
118    assert bms_hardware.minimum_readings == MIN_READINGS
119
120    # Run the Charge cycle and ensure that it was successful
121    bms_hardware.run_li_charge_cycle()
122
123
124def test_thermal_chamber_user_temperature_1():
125    """Set the thermal chamber to a user defined temperature."""
126    UserInterrupt.force_pause()  # Suspend the test
127    try:
128        bms_hardware.thermal_chamber.internal_units = "C"
129        bms_hardware.thermal_chamber.set_point_temperature = THERMAL_CHAMBER_TEMP
130        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
131    except RuntimeError:
132        logger.write_debug_to_report("No thermal chamber in config, skipping.")
133
134
135def test_full_discharge_soak_time_1():
136    """Rest after temperature is set to allow cells temperature to settle."""
137    bms_hardware.max_time = DISCHARGE_SOAK_TIME
138    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
139    bms_hardware.run_resting_cycle()
140
141
142def test_full_discharge_cycle(capsys):
143    """Completely discharge cell. From step 2, you will get capacity (mAh)."""
144    global CAPACITY
145
146    bms_hardware.max_time = MAX_DISCHARGE_TIME  # 5 hours
147    assert bms_hardware.max_time == MAX_DISCHARGE_TIME
148
149    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL  # sample every second
150    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
151
152    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
153    assert bms_hardware.discharge_type == DischargeType.CONSTANT_CURRENT
154
155    bms_hardware.current = DISCHARGE_CURRENT_A
156    assert bms_hardware.current == DISCHARGE_CURRENT_A
157
158    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
159    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
160
161    bms_hardware.voltage = DISCHARGE_VOLTAGE
162    assert bms_hardware.voltage == DISCHARGE_VOLTAGE
163
164    CAPACITY = bms_hardware.run_discharge_cycle()  # * 100 # FOR TESTING!!!
165    with capsys.disabled():  # Output Ah
166        print(f"Ah = {CAPACITY}")
167    assert CAPACITY != 0  # make sure we didn't get an error
168
169
170def test_thermal_chamber_room_temperature_2():
171    """Set the thermal chamber to room temperature."""
172    UserInterrupt.force_pause()  # Suspend the test
173    try:
174        bms_hardware.thermal_chamber.set_room_temperature()
175        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
176    except RuntimeError:
177        logger.write_debug_to_report("No thermal chamber in config, skipping.")
178
179
180def test_full_charge_cycle_2():
181    """Completely charge cell."""
182    bms_hardware.voltage = CHARGE_VOLTAGE
183    assert bms_hardware.voltage == CHARGE_VOLTAGE
184
185    bms_hardware.ov_protection = CHARGE_OV_PROTECTION
186    assert bms_hardware.ov_protection == CHARGE_OV_PROTECTION
187
188    bms_hardware.current = CHARGE_CURRENT_A
189    assert bms_hardware.current == CHARGE_CURRENT_A
190
191    bms_hardware.termination_current = CHARGE_TERMINATION_CURRENT
192    assert bms_hardware.termination_current == CHARGE_TERMINATION_CURRENT
193
194    bms_hardware.max_time = MAX_CHARGE_TIME
195    assert bms_hardware.max_time == MAX_CHARGE_TIME
196
197    bms_hardware.sample_interval = CHARGE_SAMPLE_INTERVAL
198    assert bms_hardware.sample_interval == CHARGE_SAMPLE_INTERVAL
199
200    bms_hardware.max_increment = None
201    assert bms_hardware.max_increment is None
202
203    bms_hardware.minimum_readings = MIN_READINGS
204    assert bms_hardware.minimum_readings == MIN_READINGS
205
206    # Run the Charge cycle and ensure that it was successful
207    bms_hardware.run_li_charge_cycle()
208
209
210def test_thermal_chamber_user_temperature_2():
211    """Set the thermal chamber to a user defined temperature."""
212    UserInterrupt.force_pause()  # Suspend the test
213    try:
214        bms_hardware.thermal_chamber.internal_units = "C"
215        bms_hardware.thermal_chamber.set_point_temperature = THERMAL_CHAMBER_TEMP
216        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
217    except RuntimeError:
218        logger.write_debug_to_report("No thermal chamber in config, skipping.")
219
220
221def test_discharge_soak_time_2():
222    """Rest after temperature is set to allow cells temperature to settle."""
223    bms_hardware.max_time = DISCHARGE_SOAK_TIME
224    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
225    bms_hardware.run_resting_cycle()
226
227
228@pytest.mark.skipif(MANUAL_DISCHARGE == 0.0, reason="Manual discharge not set.")
229def test_discharge_user_amount():
230    """Discharge a user set amount."""
231
232    bms_hardware.max_time = MAX_DISCHARGE_TIME
233    bms_hardware.current = DISCHARGE_CURRENT_A
234    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
235    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
236    bms_hardware.percent_discharge = MANUAL_DISCHARGE / 100
237    bms_hardware.total_ah = CAPACITY
238    bms_hardware.run_discharge_step_cycle()
239
240
241def test_discharge_100():
242    """Record the voltage at 100% charge."""
243    bms_hardware.max_time = RESTING_TIME
244    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
245    bms_hardware.run_resting_cycle()
246
247    # now that we've paused, measure the voltage
248    bms_hardware.csv.ocv.record(CAPACITY)
249
250
251def test_discharge_95():
252    """Discharge at increments. Wait for 3 hours at the stop."""
253
254    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
255    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
256
257    bms_hardware.current = DISCHARGE_CURRENT_A
258    assert bms_hardware.current == DISCHARGE_CURRENT_A
259
260    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
261    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
262
263    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
264    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
265
266    # Discharge 5% (bringing battery down to 95%)
267    bms_hardware.percent_discharge = 0.05
268    assert bms_hardware.percent_discharge == 0.05
269
270    bms_hardware.total_ah = CAPACITY
271    assert bms_hardware.total_ah == CAPACITY
272
273    bms_hardware.run_discharge_step_cycle()
274
275    bms_hardware.max_time = RESTING_TIME
276    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
277    bms_hardware.run_resting_cycle()
278
279    # now that we've paused, measure the voltage
280    bms_hardware.csv.ocv.record(CAPACITY * 0.95)
281
282
283def test_discharge_90():
284    """Discharge at increments. Wait for 3 hours at the stop."""
285
286    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
287    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
288
289    bms_hardware.current = DISCHARGE_CURRENT_A
290    assert bms_hardware.current == DISCHARGE_CURRENT_A
291
292    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
293    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
294
295    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
296    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
297
298    # We're at 95%, so discharge another 5% off
299    bms_hardware.percent_discharge = 0.05
300    assert bms_hardware.percent_discharge == 0.05
301
302    bms_hardware.total_ah = CAPACITY
303    assert bms_hardware.total_ah == CAPACITY
304
305    bms_hardware.run_discharge_step_cycle()
306
307    bms_hardware.max_time = RESTING_TIME
308    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
309    bms_hardware.run_resting_cycle()
310
311    # now that we've paused, measure the voltage
312    bms_hardware.csv.ocv.record(CAPACITY * 0.90)
313
314
315def test_discharge_80():
316    """Discharge at increments. Wait for 3 hours at the stop."""
317
318    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
319    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
320
321    bms_hardware.current = DISCHARGE_CURRENT_A
322    assert bms_hardware.current == DISCHARGE_CURRENT_A
323
324    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
325    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
326
327    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
328    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
329
330    # We're at 90% so discharge another 10% to bring us to 80%
331    bms_hardware.percent_discharge = 0.1
332    assert bms_hardware.percent_discharge == 0.1
333
334    bms_hardware.total_ah = CAPACITY
335    assert bms_hardware.total_ah == CAPACITY
336
337    bms_hardware.run_discharge_step_cycle()
338
339    bms_hardware.max_time = RESTING_TIME
340    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
341    bms_hardware.run_resting_cycle()
342
343    # now that we've paused, measure the voltage
344    bms_hardware.csv.ocv.record(CAPACITY * 0.80)
345
346
347def test_discharge_70():
348    """Discharge at increments. Wait for 3 hours at the stop."""
349
350    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
351    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
352
353    bms_hardware.current = DISCHARGE_CURRENT_A
354    assert bms_hardware.current == DISCHARGE_CURRENT_A
355
356    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
357    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
358
359    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
360    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
361
362    # We're at 80%, discharge 10% to bring us to 70%
363    bms_hardware.percent_discharge = 0.1
364    assert bms_hardware.percent_discharge == 0.1
365
366    bms_hardware.total_ah = CAPACITY
367    assert bms_hardware.total_ah == CAPACITY
368
369    bms_hardware.run_discharge_step_cycle()
370
371    bms_hardware.max_time = RESTING_TIME
372    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
373    bms_hardware.run_resting_cycle()
374
375    # now that we've paused, measure the voltage
376    bms_hardware.csv.ocv.record(CAPACITY * 0.70)
377
378
379def test_discharge_60():
380    """Discharge at increments. Wait for 3 hours at the stop."""
381
382    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
383    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
384
385    bms_hardware.current = DISCHARGE_CURRENT_A
386    assert bms_hardware.current == DISCHARGE_CURRENT_A
387
388    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
389    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
390
391    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
392    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
393
394    # We're at 70%, discharge 10% to bring us to 60%
395    bms_hardware.percent_discharge = 0.1
396    assert bms_hardware.percent_discharge == 0.1
397
398    bms_hardware.total_ah = CAPACITY
399    assert bms_hardware.total_ah == CAPACITY
400
401    bms_hardware.run_discharge_step_cycle()
402
403    bms_hardware.max_time = RESTING_TIME
404    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
405    bms_hardware.run_resting_cycle()
406
407    # now that we've paused, measure the voltage
408    bms_hardware.csv.ocv.record(CAPACITY * 0.60)
409
410
411def test_discharge_50():
412    """Discharge at increments. Wait for 3 hours at the stop."""
413
414    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
415    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
416
417    bms_hardware.current = DISCHARGE_CURRENT_A
418    assert bms_hardware.current == DISCHARGE_CURRENT_A
419
420    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
421    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
422
423    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
424    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
425
426    # We're at 60%, discharge 10% to bring us to 50%
427    bms_hardware.percent_discharge = 0.1
428    assert bms_hardware.percent_discharge == 0.1
429
430    bms_hardware.total_ah = CAPACITY
431    assert bms_hardware.total_ah == CAPACITY
432
433    bms_hardware.run_discharge_step_cycle()
434
435    bms_hardware.max_time = RESTING_TIME
436    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
437    bms_hardware.run_resting_cycle()
438
439    # now that we've paused, measure the voltage
440    bms_hardware.csv.ocv.record(CAPACITY * 0.50)
441
442
443def test_discharge_40():
444    """Discharge at increments. Wait for 3 hours at the stop."""
445
446    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
447    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
448
449    bms_hardware.current = DISCHARGE_CURRENT_A
450    assert bms_hardware.current == DISCHARGE_CURRENT_A
451
452    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
453    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
454
455    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
456    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
457
458    # We're at 50%, discharge 10% to bring us to 40%
459    bms_hardware.percent_discharge = 0.1
460    assert bms_hardware.percent_discharge == 0.1
461
462    bms_hardware.total_ah = CAPACITY
463    assert bms_hardware.total_ah == CAPACITY
464
465    bms_hardware.run_discharge_step_cycle()
466
467    bms_hardware.max_time = RESTING_TIME
468    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
469    bms_hardware.run_resting_cycle()
470
471    # now that we've paused, measure the voltage
472    bms_hardware.csv.ocv.record(CAPACITY * 0.40)
473
474
475def test_discharge_30():
476    """Discharge at increments. Wait for 3 hours at the stop."""
477
478    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
479    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
480
481    bms_hardware.current = DISCHARGE_CURRENT_A
482    assert bms_hardware.current == DISCHARGE_CURRENT_A
483
484    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
485    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
486
487    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
488    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
489
490    # We're at 40%, discharge 10% to bring us to 30%
491    bms_hardware.percent_discharge = 0.1
492    assert bms_hardware.percent_discharge == 0.1
493
494    bms_hardware.total_ah = CAPACITY
495    assert bms_hardware.total_ah == CAPACITY
496
497    bms_hardware.run_discharge_step_cycle()
498
499    bms_hardware.max_time = RESTING_TIME
500    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
501    bms_hardware.run_resting_cycle()
502
503    # now that we've paused, measure the voltage
504    bms_hardware.csv.ocv.record(CAPACITY * 0.30)
505
506
507def test_discharge_20():
508    """Discharge at increments. Wait for 3 hours at the stop."""
509
510    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
511    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
512
513    bms_hardware.current = DISCHARGE_CURRENT_A
514    assert bms_hardware.current == DISCHARGE_CURRENT_A
515
516    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
517    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
518
519    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
520    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
521
522    # We're at 30%, discharge 10% to bring us to 20%
523    bms_hardware.percent_discharge = 0.1
524    assert bms_hardware.percent_discharge == 0.1
525
526    bms_hardware.total_ah = CAPACITY
527    assert bms_hardware.total_ah == CAPACITY
528
529    bms_hardware.run_discharge_step_cycle()
530
531    bms_hardware.max_time = RESTING_TIME
532    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
533    bms_hardware.run_resting_cycle()
534
535    # now that we've paused, measure the voltage
536    bms_hardware.csv.ocv.record(CAPACITY * 0.20)
537
538
539@pytest.mark.skipif(MANUAL_DISCHARGE2 == 0.0, reason="Manual discharge not set.")
540def test_discharge_user_amount_2():
541    """Discharge a user set amount."""
542
543    bms_hardware.max_time = MAX_DISCHARGE_TIME
544    bms_hardware.current = DISCHARGE_CURRENT_A
545    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
546    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
547    bms_hardware.percent_discharge = MANUAL_DISCHARGE2 / 100
548    bms_hardware.total_ah = CAPACITY
549    bms_hardware.run_discharge_step_cycle()
550
551
552def test_discharge_10():
553    """Discharge at increments. Wait for 3 hours at the stop."""
554
555    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
556    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
557
558    bms_hardware.current = DISCHARGE_CURRENT_A
559    assert bms_hardware.current == DISCHARGE_CURRENT_A
560
561    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
562    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
563
564    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
565    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
566
567    # We're at 20%, discharge 10% to bring us to 10%
568    bms_hardware.percent_discharge = 0.1
569    assert bms_hardware.percent_discharge == 0.1
570
571    bms_hardware.total_ah = CAPACITY
572    assert bms_hardware.total_ah == CAPACITY
573
574    bms_hardware.run_discharge_step_cycle()
575
576    bms_hardware.max_time = RESTING_TIME
577    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
578    bms_hardware.run_resting_cycle()
579
580    # now that we've paused, measure the voltage
581    bms_hardware.csv.ocv.record(CAPACITY * 0.10)
582
583
584def test_discharge_7_5():
585    """Discharge at increments. Wait for 3 hours at the stop."""
586
587    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
588    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
589
590    bms_hardware.current = DISCHARGE_CURRENT_A
591    assert bms_hardware.current == DISCHARGE_CURRENT_A
592
593    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
594    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
595
596    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
597    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
598
599    # We're at 10%, discharge 2.5% to bring us to 7.5%
600    bms_hardware.percent_discharge = 0.025
601    assert bms_hardware.percent_discharge == 0.025
602
603    bms_hardware.total_ah = CAPACITY
604    assert bms_hardware.total_ah == CAPACITY
605
606    bms_hardware.run_discharge_step_cycle()
607
608    bms_hardware.max_time = RESTING_TIME
609    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
610    bms_hardware.run_resting_cycle()
611
612    # now that we've paused, measure the voltage
613    bms_hardware.csv.ocv.record(CAPACITY * 0.075)
614
615
616def test_discharge_5():
617    """Discharge at increments. Wait for 3 hours at the stop."""
618
619    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
620    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
621
622    bms_hardware.current = DISCHARGE_CURRENT_A
623    assert bms_hardware.current == DISCHARGE_CURRENT_A
624
625    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
626    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
627
628    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
629    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
630
631    # We're at 7.5%, discharge 2.5% to bring us to 5%
632    bms_hardware.percent_discharge = 0.025
633    assert bms_hardware.percent_discharge == 0.025
634
635    bms_hardware.total_ah = CAPACITY
636    assert bms_hardware.total_ah == CAPACITY
637
638    bms_hardware.run_discharge_step_cycle()
639
640    bms_hardware.max_time = RESTING_TIME
641    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
642    bms_hardware.run_resting_cycle()
643
644    # now that we've paused, measure the voltage
645    bms_hardware.csv.ocv.record(CAPACITY * 0.05)
646
647
648def test_discharge_2_5():
649    """Discharge at increments. Wait for 3 hours at the stop."""
650
651    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
652    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
653
654    bms_hardware.current = DISCHARGE_CURRENT_A
655    assert bms_hardware.current == DISCHARGE_CURRENT_A
656
657    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
658    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
659
660    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
661    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
662
663    # We're at 5%, discharge 2.5% to bring us to 2.5%
664    bms_hardware.percent_discharge = 0.025
665    assert bms_hardware.percent_discharge == 0.025
666
667    bms_hardware.total_ah = CAPACITY
668    assert bms_hardware.total_ah == CAPACITY
669
670    bms_hardware.run_discharge_step_cycle()
671
672    bms_hardware.max_time = RESTING_TIME
673    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
674    bms_hardware.run_resting_cycle()
675
676    # now that we've paused, measure the voltage
677    bms_hardware.csv.ocv.record(CAPACITY * 0.025)
678
679
680def test_discharge_0():
681    """Discharge at increments. Wait for 3 hours at the stop."""
682
683    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
684    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
685
686    bms_hardware.current = DISCHARGE_CURRENT_A
687    assert bms_hardware.current == DISCHARGE_CURRENT_A
688
689    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
690    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
691
692    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
693    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
694
695    # We're at 2.5%, discharge 2.5% to bring us to 0%
696    bms_hardware.percent_discharge = 0.025
697    assert bms_hardware.percent_discharge == 0.025
698
699    bms_hardware.total_ah = CAPACITY
700    assert bms_hardware.total_ah == CAPACITY
701
702    # Continue discharging until an undervoltage is triggered
703    bms_hardware.discharge_until_undervoltage = True
704    assert bms_hardware.discharge_until_undervoltage
705
706    bms_hardware.run_discharge_step_cycle()
707
708    bms_hardware.max_time = RESTING_TIME
709    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
710    bms_hardware.run_resting_cycle()
711
712    # now that we've paused, measure the voltage
713    bms_hardware.csv.ocv.record(CAPACITY * 0.0)
MINUTE = 60
HOUR = 3600
MANUAL_DISCHARGE = 0.0

Force a discharge of some amount before step discharge.

MANUAL_DISCHARGE2 = 0.0

Force a discharge of some amount before step discharge.

THERMAL_CHAMBER_TEMP = 20

The discharge temperature.

MAX_THERMAL_CHAMBER_TIME = 3600

Timeout for reaching a set temperature.

MAX_CHARGE_TIME = 28800

Timeout for a full charge.

CHARGE_VOLTAGE = 2.7

Voltage to charge at.

CHARGE_OV_PROTECTION = 2.75

Overvoltage limit.

CHARGE_CURRENT_A = 0.7

Current limit while charging.

CHARGE_TERMINATION_CURRENT = 0.175

When to stop charging.

CHARGE_SAMPLE_INTERVAL = 10

Sample time while charging.

DISCHARGE_SOAK_TIME = 5

How long to soak before a full discharge.

MAX_DISCHARGE_TIME = 28800

Timeout for a full discharge.

MAX_DISCHARGE_STEP_TIME = 3600

Timeout for a single step cycle.

DISCHARGE_CURRENT_A = 0.7

Current to discharge at. The cell sims will only work with 2.5A or less.

DISCHARGE_VOLTAGE = 1.7

Voltage to discharge at.

DISCHARGE_UV_PROTECTION = 1.65

Undervoltage limit.

DISCHARGE_SAMPLE_INTERVAL = 10

Sample time while discharging.

RESTING_TIME = 10800

How long to rest after steps.

RESTING_SAMPLE_INTERVAL = 60

Sample time while resting.

MIN_READINGS = 3

How many readings to take before passing (for erroneous readings).

CAPACITY = 0

Cell capacity. Set by the discharge cycle.

def test_thermal_chamber_room_temperature_1():
89def test_thermal_chamber_room_temperature_1():
90    """Set the thermal chamber to room temperature."""
91    try:
92        bms_hardware.thermal_chamber.set_room_temperature()
93        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
94    except RuntimeError:
95        logger.write_debug_to_report("No thermal chamber in config, skipping.")

Set the thermal chamber to room temperature.

def test_full_charge_cycle_1():
 98def test_full_charge_cycle_1():
 99    """Completely charge cell."""
100    bms_hardware.voltage = CHARGE_VOLTAGE
101    assert bms_hardware.voltage == CHARGE_VOLTAGE
102
103    bms_hardware.ov_protection = CHARGE_OV_PROTECTION
104    assert bms_hardware.ov_protection == CHARGE_OV_PROTECTION
105
106    bms_hardware.current = CHARGE_CURRENT_A
107    assert bms_hardware.current == CHARGE_CURRENT_A
108
109    bms_hardware.termination_current = CHARGE_TERMINATION_CURRENT
110    assert bms_hardware.termination_current == CHARGE_TERMINATION_CURRENT
111
112    bms_hardware.max_time = MAX_CHARGE_TIME
113    assert bms_hardware.max_time == MAX_CHARGE_TIME
114
115    bms_hardware.sample_interval = CHARGE_SAMPLE_INTERVAL
116    assert bms_hardware.sample_interval == CHARGE_SAMPLE_INTERVAL
117
118    bms_hardware.minimum_readings = MIN_READINGS
119    assert bms_hardware.minimum_readings == MIN_READINGS
120
121    # Run the Charge cycle and ensure that it was successful
122    bms_hardware.run_li_charge_cycle()

Completely charge cell.

def test_thermal_chamber_user_temperature_1():
125def test_thermal_chamber_user_temperature_1():
126    """Set the thermal chamber to a user defined temperature."""
127    UserInterrupt.force_pause()  # Suspend the test
128    try:
129        bms_hardware.thermal_chamber.internal_units = "C"
130        bms_hardware.thermal_chamber.set_point_temperature = THERMAL_CHAMBER_TEMP
131        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
132    except RuntimeError:
133        logger.write_debug_to_report("No thermal chamber in config, skipping.")

Set the thermal chamber to a user defined temperature.

def test_full_discharge_soak_time_1():
136def test_full_discharge_soak_time_1():
137    """Rest after temperature is set to allow cells temperature to settle."""
138    bms_hardware.max_time = DISCHARGE_SOAK_TIME
139    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
140    bms_hardware.run_resting_cycle()

Rest after temperature is set to allow cells temperature to settle.

def test_full_discharge_cycle(capsys):
143def test_full_discharge_cycle(capsys):
144    """Completely discharge cell. From step 2, you will get capacity (mAh)."""
145    global CAPACITY
146
147    bms_hardware.max_time = MAX_DISCHARGE_TIME  # 5 hours
148    assert bms_hardware.max_time == MAX_DISCHARGE_TIME
149
150    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL  # sample every second
151    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
152
153    bms_hardware.discharge_type = DischargeType.CONSTANT_CURRENT
154    assert bms_hardware.discharge_type == DischargeType.CONSTANT_CURRENT
155
156    bms_hardware.current = DISCHARGE_CURRENT_A
157    assert bms_hardware.current == DISCHARGE_CURRENT_A
158
159    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
160    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
161
162    bms_hardware.voltage = DISCHARGE_VOLTAGE
163    assert bms_hardware.voltage == DISCHARGE_VOLTAGE
164
165    CAPACITY = bms_hardware.run_discharge_cycle()  # * 100 # FOR TESTING!!!
166    with capsys.disabled():  # Output Ah
167        print(f"Ah = {CAPACITY}")
168    assert CAPACITY != 0  # make sure we didn't get an error

Completely discharge cell. From step 2, you will get capacity (mAh).

def test_thermal_chamber_room_temperature_2():
171def test_thermal_chamber_room_temperature_2():
172    """Set the thermal chamber to room temperature."""
173    UserInterrupt.force_pause()  # Suspend the test
174    try:
175        bms_hardware.thermal_chamber.set_room_temperature()
176        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
177    except RuntimeError:
178        logger.write_debug_to_report("No thermal chamber in config, skipping.")

Set the thermal chamber to room temperature.

def test_full_charge_cycle_2():
181def test_full_charge_cycle_2():
182    """Completely charge cell."""
183    bms_hardware.voltage = CHARGE_VOLTAGE
184    assert bms_hardware.voltage == CHARGE_VOLTAGE
185
186    bms_hardware.ov_protection = CHARGE_OV_PROTECTION
187    assert bms_hardware.ov_protection == CHARGE_OV_PROTECTION
188
189    bms_hardware.current = CHARGE_CURRENT_A
190    assert bms_hardware.current == CHARGE_CURRENT_A
191
192    bms_hardware.termination_current = CHARGE_TERMINATION_CURRENT
193    assert bms_hardware.termination_current == CHARGE_TERMINATION_CURRENT
194
195    bms_hardware.max_time = MAX_CHARGE_TIME
196    assert bms_hardware.max_time == MAX_CHARGE_TIME
197
198    bms_hardware.sample_interval = CHARGE_SAMPLE_INTERVAL
199    assert bms_hardware.sample_interval == CHARGE_SAMPLE_INTERVAL
200
201    bms_hardware.max_increment = None
202    assert bms_hardware.max_increment is None
203
204    bms_hardware.minimum_readings = MIN_READINGS
205    assert bms_hardware.minimum_readings == MIN_READINGS
206
207    # Run the Charge cycle and ensure that it was successful
208    bms_hardware.run_li_charge_cycle()

Completely charge cell.

def test_thermal_chamber_user_temperature_2():
211def test_thermal_chamber_user_temperature_2():
212    """Set the thermal chamber to a user defined temperature."""
213    UserInterrupt.force_pause()  # Suspend the test
214    try:
215        bms_hardware.thermal_chamber.internal_units = "C"
216        bms_hardware.thermal_chamber.set_point_temperature = THERMAL_CHAMBER_TEMP
217        bms_hardware.thermal_chamber.block_until_set_point_reached(MAX_THERMAL_CHAMBER_TIME)
218    except RuntimeError:
219        logger.write_debug_to_report("No thermal chamber in config, skipping.")

Set the thermal chamber to a user defined temperature.

def test_discharge_soak_time_2():
222def test_discharge_soak_time_2():
223    """Rest after temperature is set to allow cells temperature to settle."""
224    bms_hardware.max_time = DISCHARGE_SOAK_TIME
225    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
226    bms_hardware.run_resting_cycle()

Rest after temperature is set to allow cells temperature to settle.

@pytest.mark.skipif(MANUAL_DISCHARGE == 0.0, reason='Manual discharge not set.')
def test_discharge_user_amount():
229@pytest.mark.skipif(MANUAL_DISCHARGE == 0.0, reason="Manual discharge not set.")
230def test_discharge_user_amount():
231    """Discharge a user set amount."""
232
233    bms_hardware.max_time = MAX_DISCHARGE_TIME
234    bms_hardware.current = DISCHARGE_CURRENT_A
235    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
236    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
237    bms_hardware.percent_discharge = MANUAL_DISCHARGE / 100
238    bms_hardware.total_ah = CAPACITY
239    bms_hardware.run_discharge_step_cycle()

Discharge a user set amount.

def test_discharge_100():
242def test_discharge_100():
243    """Record the voltage at 100% charge."""
244    bms_hardware.max_time = RESTING_TIME
245    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
246    bms_hardware.run_resting_cycle()
247
248    # now that we've paused, measure the voltage
249    bms_hardware.csv.ocv.record(CAPACITY)

Record the voltage at 100% charge.

def test_discharge_95():
252def test_discharge_95():
253    """Discharge at increments. Wait for 3 hours at the stop."""
254
255    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
256    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
257
258    bms_hardware.current = DISCHARGE_CURRENT_A
259    assert bms_hardware.current == DISCHARGE_CURRENT_A
260
261    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
262    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
263
264    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
265    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
266
267    # Discharge 5% (bringing battery down to 95%)
268    bms_hardware.percent_discharge = 0.05
269    assert bms_hardware.percent_discharge == 0.05
270
271    bms_hardware.total_ah = CAPACITY
272    assert bms_hardware.total_ah == CAPACITY
273
274    bms_hardware.run_discharge_step_cycle()
275
276    bms_hardware.max_time = RESTING_TIME
277    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
278    bms_hardware.run_resting_cycle()
279
280    # now that we've paused, measure the voltage
281    bms_hardware.csv.ocv.record(CAPACITY * 0.95)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_90():
284def test_discharge_90():
285    """Discharge at increments. Wait for 3 hours at the stop."""
286
287    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
288    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
289
290    bms_hardware.current = DISCHARGE_CURRENT_A
291    assert bms_hardware.current == DISCHARGE_CURRENT_A
292
293    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
294    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
295
296    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
297    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
298
299    # We're at 95%, so discharge another 5% off
300    bms_hardware.percent_discharge = 0.05
301    assert bms_hardware.percent_discharge == 0.05
302
303    bms_hardware.total_ah = CAPACITY
304    assert bms_hardware.total_ah == CAPACITY
305
306    bms_hardware.run_discharge_step_cycle()
307
308    bms_hardware.max_time = RESTING_TIME
309    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
310    bms_hardware.run_resting_cycle()
311
312    # now that we've paused, measure the voltage
313    bms_hardware.csv.ocv.record(CAPACITY * 0.90)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_80():
316def test_discharge_80():
317    """Discharge at increments. Wait for 3 hours at the stop."""
318
319    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
320    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
321
322    bms_hardware.current = DISCHARGE_CURRENT_A
323    assert bms_hardware.current == DISCHARGE_CURRENT_A
324
325    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
326    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
327
328    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
329    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
330
331    # We're at 90% so discharge another 10% to bring us to 80%
332    bms_hardware.percent_discharge = 0.1
333    assert bms_hardware.percent_discharge == 0.1
334
335    bms_hardware.total_ah = CAPACITY
336    assert bms_hardware.total_ah == CAPACITY
337
338    bms_hardware.run_discharge_step_cycle()
339
340    bms_hardware.max_time = RESTING_TIME
341    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
342    bms_hardware.run_resting_cycle()
343
344    # now that we've paused, measure the voltage
345    bms_hardware.csv.ocv.record(CAPACITY * 0.80)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_70():
348def test_discharge_70():
349    """Discharge at increments. Wait for 3 hours at the stop."""
350
351    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
352    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
353
354    bms_hardware.current = DISCHARGE_CURRENT_A
355    assert bms_hardware.current == DISCHARGE_CURRENT_A
356
357    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
358    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
359
360    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
361    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
362
363    # We're at 80%, discharge 10% to bring us to 70%
364    bms_hardware.percent_discharge = 0.1
365    assert bms_hardware.percent_discharge == 0.1
366
367    bms_hardware.total_ah = CAPACITY
368    assert bms_hardware.total_ah == CAPACITY
369
370    bms_hardware.run_discharge_step_cycle()
371
372    bms_hardware.max_time = RESTING_TIME
373    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
374    bms_hardware.run_resting_cycle()
375
376    # now that we've paused, measure the voltage
377    bms_hardware.csv.ocv.record(CAPACITY * 0.70)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_60():
380def test_discharge_60():
381    """Discharge at increments. Wait for 3 hours at the stop."""
382
383    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
384    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
385
386    bms_hardware.current = DISCHARGE_CURRENT_A
387    assert bms_hardware.current == DISCHARGE_CURRENT_A
388
389    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
390    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
391
392    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
393    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
394
395    # We're at 70%, discharge 10% to bring us to 60%
396    bms_hardware.percent_discharge = 0.1
397    assert bms_hardware.percent_discharge == 0.1
398
399    bms_hardware.total_ah = CAPACITY
400    assert bms_hardware.total_ah == CAPACITY
401
402    bms_hardware.run_discharge_step_cycle()
403
404    bms_hardware.max_time = RESTING_TIME
405    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
406    bms_hardware.run_resting_cycle()
407
408    # now that we've paused, measure the voltage
409    bms_hardware.csv.ocv.record(CAPACITY * 0.60)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_50():
412def test_discharge_50():
413    """Discharge at increments. Wait for 3 hours at the stop."""
414
415    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
416    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
417
418    bms_hardware.current = DISCHARGE_CURRENT_A
419    assert bms_hardware.current == DISCHARGE_CURRENT_A
420
421    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
422    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
423
424    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
425    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
426
427    # We're at 60%, discharge 10% to bring us to 50%
428    bms_hardware.percent_discharge = 0.1
429    assert bms_hardware.percent_discharge == 0.1
430
431    bms_hardware.total_ah = CAPACITY
432    assert bms_hardware.total_ah == CAPACITY
433
434    bms_hardware.run_discharge_step_cycle()
435
436    bms_hardware.max_time = RESTING_TIME
437    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
438    bms_hardware.run_resting_cycle()
439
440    # now that we've paused, measure the voltage
441    bms_hardware.csv.ocv.record(CAPACITY * 0.50)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_40():
444def test_discharge_40():
445    """Discharge at increments. Wait for 3 hours at the stop."""
446
447    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
448    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
449
450    bms_hardware.current = DISCHARGE_CURRENT_A
451    assert bms_hardware.current == DISCHARGE_CURRENT_A
452
453    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
454    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
455
456    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
457    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
458
459    # We're at 50%, discharge 10% to bring us to 40%
460    bms_hardware.percent_discharge = 0.1
461    assert bms_hardware.percent_discharge == 0.1
462
463    bms_hardware.total_ah = CAPACITY
464    assert bms_hardware.total_ah == CAPACITY
465
466    bms_hardware.run_discharge_step_cycle()
467
468    bms_hardware.max_time = RESTING_TIME
469    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
470    bms_hardware.run_resting_cycle()
471
472    # now that we've paused, measure the voltage
473    bms_hardware.csv.ocv.record(CAPACITY * 0.40)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_30():
476def test_discharge_30():
477    """Discharge at increments. Wait for 3 hours at the stop."""
478
479    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
480    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
481
482    bms_hardware.current = DISCHARGE_CURRENT_A
483    assert bms_hardware.current == DISCHARGE_CURRENT_A
484
485    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
486    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
487
488    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
489    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
490
491    # We're at 40%, discharge 10% to bring us to 30%
492    bms_hardware.percent_discharge = 0.1
493    assert bms_hardware.percent_discharge == 0.1
494
495    bms_hardware.total_ah = CAPACITY
496    assert bms_hardware.total_ah == CAPACITY
497
498    bms_hardware.run_discharge_step_cycle()
499
500    bms_hardware.max_time = RESTING_TIME
501    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
502    bms_hardware.run_resting_cycle()
503
504    # now that we've paused, measure the voltage
505    bms_hardware.csv.ocv.record(CAPACITY * 0.30)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_20():
508def test_discharge_20():
509    """Discharge at increments. Wait for 3 hours at the stop."""
510
511    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
512    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
513
514    bms_hardware.current = DISCHARGE_CURRENT_A
515    assert bms_hardware.current == DISCHARGE_CURRENT_A
516
517    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
518    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
519
520    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
521    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
522
523    # We're at 30%, discharge 10% to bring us to 20%
524    bms_hardware.percent_discharge = 0.1
525    assert bms_hardware.percent_discharge == 0.1
526
527    bms_hardware.total_ah = CAPACITY
528    assert bms_hardware.total_ah == CAPACITY
529
530    bms_hardware.run_discharge_step_cycle()
531
532    bms_hardware.max_time = RESTING_TIME
533    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
534    bms_hardware.run_resting_cycle()
535
536    # now that we've paused, measure the voltage
537    bms_hardware.csv.ocv.record(CAPACITY * 0.20)

Discharge at increments. Wait for 3 hours at the stop.

@pytest.mark.skipif(MANUAL_DISCHARGE2 == 0.0, reason='Manual discharge not set.')
def test_discharge_user_amount_2():
540@pytest.mark.skipif(MANUAL_DISCHARGE2 == 0.0, reason="Manual discharge not set.")
541def test_discharge_user_amount_2():
542    """Discharge a user set amount."""
543
544    bms_hardware.max_time = MAX_DISCHARGE_TIME
545    bms_hardware.current = DISCHARGE_CURRENT_A
546    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
547    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
548    bms_hardware.percent_discharge = MANUAL_DISCHARGE2 / 100
549    bms_hardware.total_ah = CAPACITY
550    bms_hardware.run_discharge_step_cycle()

Discharge a user set amount.

def test_discharge_10():
553def test_discharge_10():
554    """Discharge at increments. Wait for 3 hours at the stop."""
555
556    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
557    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
558
559    bms_hardware.current = DISCHARGE_CURRENT_A
560    assert bms_hardware.current == DISCHARGE_CURRENT_A
561
562    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
563    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
564
565    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
566    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
567
568    # We're at 20%, discharge 10% to bring us to 10%
569    bms_hardware.percent_discharge = 0.1
570    assert bms_hardware.percent_discharge == 0.1
571
572    bms_hardware.total_ah = CAPACITY
573    assert bms_hardware.total_ah == CAPACITY
574
575    bms_hardware.run_discharge_step_cycle()
576
577    bms_hardware.max_time = RESTING_TIME
578    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
579    bms_hardware.run_resting_cycle()
580
581    # now that we've paused, measure the voltage
582    bms_hardware.csv.ocv.record(CAPACITY * 0.10)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_7_5():
585def test_discharge_7_5():
586    """Discharge at increments. Wait for 3 hours at the stop."""
587
588    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
589    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
590
591    bms_hardware.current = DISCHARGE_CURRENT_A
592    assert bms_hardware.current == DISCHARGE_CURRENT_A
593
594    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
595    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
596
597    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
598    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
599
600    # We're at 10%, discharge 2.5% to bring us to 7.5%
601    bms_hardware.percent_discharge = 0.025
602    assert bms_hardware.percent_discharge == 0.025
603
604    bms_hardware.total_ah = CAPACITY
605    assert bms_hardware.total_ah == CAPACITY
606
607    bms_hardware.run_discharge_step_cycle()
608
609    bms_hardware.max_time = RESTING_TIME
610    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
611    bms_hardware.run_resting_cycle()
612
613    # now that we've paused, measure the voltage
614    bms_hardware.csv.ocv.record(CAPACITY * 0.075)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_5():
617def test_discharge_5():
618    """Discharge at increments. Wait for 3 hours at the stop."""
619
620    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
621    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
622
623    bms_hardware.current = DISCHARGE_CURRENT_A
624    assert bms_hardware.current == DISCHARGE_CURRENT_A
625
626    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
627    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
628
629    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
630    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
631
632    # We're at 7.5%, discharge 2.5% to bring us to 5%
633    bms_hardware.percent_discharge = 0.025
634    assert bms_hardware.percent_discharge == 0.025
635
636    bms_hardware.total_ah = CAPACITY
637    assert bms_hardware.total_ah == CAPACITY
638
639    bms_hardware.run_discharge_step_cycle()
640
641    bms_hardware.max_time = RESTING_TIME
642    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
643    bms_hardware.run_resting_cycle()
644
645    # now that we've paused, measure the voltage
646    bms_hardware.csv.ocv.record(CAPACITY * 0.05)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_2_5():
649def test_discharge_2_5():
650    """Discharge at increments. Wait for 3 hours at the stop."""
651
652    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
653    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
654
655    bms_hardware.current = DISCHARGE_CURRENT_A
656    assert bms_hardware.current == DISCHARGE_CURRENT_A
657
658    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
659    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
660
661    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
662    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
663
664    # We're at 5%, discharge 2.5% to bring us to 2.5%
665    bms_hardware.percent_discharge = 0.025
666    assert bms_hardware.percent_discharge == 0.025
667
668    bms_hardware.total_ah = CAPACITY
669    assert bms_hardware.total_ah == CAPACITY
670
671    bms_hardware.run_discharge_step_cycle()
672
673    bms_hardware.max_time = RESTING_TIME
674    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
675    bms_hardware.run_resting_cycle()
676
677    # now that we've paused, measure the voltage
678    bms_hardware.csv.ocv.record(CAPACITY * 0.025)

Discharge at increments. Wait for 3 hours at the stop.

def test_discharge_0():
681def test_discharge_0():
682    """Discharge at increments. Wait for 3 hours at the stop."""
683
684    bms_hardware.max_time = MAX_DISCHARGE_STEP_TIME
685    assert bms_hardware.max_time == MAX_DISCHARGE_STEP_TIME
686
687    bms_hardware.current = DISCHARGE_CURRENT_A
688    assert bms_hardware.current == DISCHARGE_CURRENT_A
689
690    bms_hardware.sample_interval = DISCHARGE_SAMPLE_INTERVAL
691    assert bms_hardware.sample_interval == DISCHARGE_SAMPLE_INTERVAL
692
693    bms_hardware.uv_protection = DISCHARGE_UV_PROTECTION
694    assert bms_hardware.uv_protection == DISCHARGE_UV_PROTECTION
695
696    # We're at 2.5%, discharge 2.5% to bring us to 0%
697    bms_hardware.percent_discharge = 0.025
698    assert bms_hardware.percent_discharge == 0.025
699
700    bms_hardware.total_ah = CAPACITY
701    assert bms_hardware.total_ah == CAPACITY
702
703    # Continue discharging until an undervoltage is triggered
704    bms_hardware.discharge_until_undervoltage = True
705    assert bms_hardware.discharge_until_undervoltage
706
707    bms_hardware.run_discharge_step_cycle()
708
709    bms_hardware.max_time = RESTING_TIME
710    bms_hardware.sample_interval = RESTING_SAMPLE_INTERVAL
711    bms_hardware.run_resting_cycle()
712
713    # now that we've paused, measure the voltage
714    bms_hardware.csv.ocv.record(CAPACITY * 0.0)

Discharge at increments. Wait for 3 hours at the stop.