from types import SimpleNamespace from performance_reporter import PerformanceReporter class _Pid: kp = 1.0 ki = 0.1 kd = 0.0 def _result(timestamp, flow, pressure_before, pressure_after, target=100.0): return SimpleNamespace( status="OK", timestamp=timestamp, measured_flow_slm=flow, target_flow_slm=target, pressure_before_kpa=pressure_before, pressure_kpa=pressure_after, ) def _reporter(): return PerformanceReporter( _Pid(), window_s=0.2, sample_period_s=0.1, band_pct=1.0, pressure_band_kpa=1.0, flow_range_min_slm=0.0, flow_range_max_slm=300.0, ) def test_steady_uses_pressure_band_instead_of_flow_std(): reporter = _reporter() # 流量标准差很大,但窗口均值为目标值;压力均在各自均值 ±1 kPa 内。 reporter.observe(_result(0.0, 50.0, 200.0, 100.0)) reporter.observe(_result(0.1, 150.0, 201.0, 99.0)) assert reporter.steady_reached assert reporter.steady_mean == 100.0 assert reporter.steady_std == 50.0 def test_pressure_outside_mean_band_prevents_steady_state(): reporter = _reporter() reporter.observe(_result(0.0, 100.0, 200.0, 100.0)) reporter.observe(_result(0.1, 100.0, 203.0, 100.0)) assert not reporter.steady_reached def test_missing_pressure_sample_is_not_used_for_steady_state(): reporter = _reporter() reporter.observe(_result(0.0, 100.0, None, 100.0)) reporter.observe(_result(0.1, 100.0, 200.0, 100.0)) assert not reporter.steady_reached