| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- 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"
|