|
|
@@ -0,0 +1,103 @@
|
|
|
+import pytest
|
|
|
+from datetime import datetime, timedelta
|
|
|
+from battery_measure_ctrl.src.models.cell import Cell, CellLimits, MeasureValues
|
|
|
+
|
|
|
+@pytest.fixture
|
|
|
+def cell_limits():
|
|
|
+ return CellLimits(min_volt=3000, max_volt=4200, max_curr=1000)
|
|
|
+
|
|
|
+@pytest.fixture
|
|
|
+def test_cell(cell_limits):
|
|
|
+ return Cell(id=1, cell_limits=cell_limits, nom_capacity=2000.0) # 2000mAh capacity
|
|
|
+
|
|
|
+def generate_measurement_sequence(current_pattern: list[int],
|
|
|
+ interval_seconds: float = 1.0,
|
|
|
+ voltage: int = 3700,
|
|
|
+ temperature: int = 25):
|
|
|
+ """Helper to generate a sequence of measurements with specified timing"""
|
|
|
+ measurements = []
|
|
|
+ start_time = datetime.now()
|
|
|
+ last_time = start_time
|
|
|
+
|
|
|
+ for current in current_pattern:
|
|
|
+ measurement = MeasureValues(voltage=voltage,
|
|
|
+ current=current,
|
|
|
+ temperature=temperature)
|
|
|
+
|
|
|
+ # Set up timing for this measurement
|
|
|
+ current_time = last_time + timedelta(seconds=interval_seconds)
|
|
|
+ duration = (current_time - last_time).total_seconds()
|
|
|
+
|
|
|
+ measurements.append((measurement, duration))
|
|
|
+ last_time = current_time
|
|
|
+
|
|
|
+ return measurements
|
|
|
+
|
|
|
+def test_normal_cycles(test_cell:Cell):
|
|
|
+ """Test capacity estimation with normal charge/discharge cycles"""
|
|
|
+ # Create pattern for 2 complete cycles at 0.25C (500mA)
|
|
|
+ # Each charge should take ~4 hours = 14400 seconds
|
|
|
+ current_pattern = (
|
|
|
+ [500] * 14400 + # 4h charge at 0.25C
|
|
|
+ [-500] * 14400 + # 4h discharge
|
|
|
+ [500] * 14400 + # 4h charge
|
|
|
+ [-500] * 14400 # 4h discharge
|
|
|
+ )
|
|
|
+
|
|
|
+ # Add measurements
|
|
|
+ for measurement, duration in generate_measurement_sequence(current_pattern):
|
|
|
+ test_cell.measurements_duration.append(duration)
|
|
|
+ test_cell.measurements.append(measurement)
|
|
|
+
|
|
|
+ capacity = test_cell.estimate_capacity()
|
|
|
+ assert 95.0 <= capacity <= 100.0, "Expected near 100% capacity for normal cycles"
|
|
|
+
|
|
|
+def test_degraded_capacity(test_cell:Cell):
|
|
|
+ """Test capacity estimation with shorter charging cycles (degraded cell)"""
|
|
|
+ # Create pattern for 2 cycles at 0.25C but with shorter duration (~75% capacity)
|
|
|
+ current_pattern = (
|
|
|
+ [500] * 10800 + # 3h charge at 0.25C
|
|
|
+ [-500] * 10800 + # 3h discharge
|
|
|
+ [500] * 10800 + # 3h charge
|
|
|
+ [-500] * 10800 # 3h discharge
|
|
|
+ )
|
|
|
+
|
|
|
+ for measurement, duration in generate_measurement_sequence(current_pattern):
|
|
|
+ test_cell.measurements_duration.append(duration)
|
|
|
+ test_cell.measurements.append(measurement)
|
|
|
+
|
|
|
+ capacity = test_cell.estimate_capacity()
|
|
|
+ assert 70.0 <= capacity <= 80.0, "Expected ~75% capacity for degraded cell"
|
|
|
+
|
|
|
+def test_empty_measurements(test_cell:Cell):
|
|
|
+ """Test capacity estimation with no measurements"""
|
|
|
+ capacity = test_cell.estimate_capacity()
|
|
|
+ assert capacity == -1.0, "Expected -1.0 for no measurements"
|
|
|
+
|
|
|
+def test_no_charge_cycles(test_cell:Cell):
|
|
|
+ """Test capacity estimation with no charging cycles"""
|
|
|
+ # Only discharge cycles
|
|
|
+ current_pattern = [-500] * 1000
|
|
|
+
|
|
|
+ for measurement, duration in generate_measurement_sequence(current_pattern):
|
|
|
+ test_cell.measurements_duration.append(duration)
|
|
|
+ test_cell.measurements.append(measurement)
|
|
|
+
|
|
|
+ capacity = test_cell.estimate_capacity()
|
|
|
+ assert capacity == -1.0, "Expected -1.0 for no charge cycles"
|
|
|
+
|
|
|
+def test_incomplete_cycle(test_cell:Cell):
|
|
|
+ """Test capacity estimation with incomplete cycle"""
|
|
|
+ # One complete cycle and one incomplete
|
|
|
+ current_pattern = (
|
|
|
+ [500] * 14400 + # 4h charge
|
|
|
+ [-500] * 14400 + # 4h discharge
|
|
|
+ [500] * 7200 # 2h partial charge
|
|
|
+ )
|
|
|
+
|
|
|
+ for measurement, duration in generate_measurement_sequence(current_pattern):
|
|
|
+ test_cell.measurements_duration.append(duration)
|
|
|
+ test_cell.measurements.append(measurement)
|
|
|
+
|
|
|
+ capacity = test_cell.estimate_capacity()
|
|
|
+ assert 70.0 <= capacity <= 80.0, "Expected capacity calculation from incomplete cycle"
|