""" 测试优先上网逻辑 该程序创建一个测试场景,验证系统是否优先上网而不是弃风弃光。 作者: iFlow CLI 创建日期: 2025-12-26 """ import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src')) import pandas as pd from excel_reader import create_excel_template from storage_optimization import optimize_storage_capacity, SystemParameters def create_test_excel(): """创建测试用的Excel文件,有明显的发电盈余""" # 创建24小时数据,其中某些小时有大量盈余 hours = 24 # 设计数据:在6-12点有大量光伏出力,超过负荷 solar = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 15.0, 20.0, 20.0, 15.0, 10.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] wind = [2.0] * 24 # 稳定的风电 thermal = [3.0] * 24 # 稳定的火电 load = [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 8.0, 8.0, 9.0, 9.0, 8.0, 8.0, 6.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0] # 验证长度 print(f"数据长度检查: solar={len(solar)}, wind={len(wind)}, thermal={len(thermal)}, load={len(load)}") # 设置严格的上网电量限制(10%),迫使系统在超出限制时弃风弃光 params = SystemParameters( max_curtailment_wind=0.15, # 允许15%弃风 max_curtailment_solar=0.15, # 允许15%弃光 max_grid_ratio=0.1, # 严格限制上网电量比例10% storage_efficiency=0.9, discharge_rate=1.0, charge_rate=1.0, max_storage_capacity=5.0 # 限制储能容量,增加上网压力 ) # 创建DataFrame df = pd.DataFrame({ '小时': range(1, hours + 1), '光伏出力(MW)': solar, '风电出力(MW)': wind, '火电出力(MW)': thermal, '负荷需求(MW)': load }) # 保存到Excel filename = 'test_grid_priority.xlsx' with pd.ExcelWriter(filename, engine='openpyxl') as writer: df.to_excel(writer, sheet_name='数据', index=False) # 添加参数工作表 parameters_df = pd.DataFrame({ '参数名称': [ '最大弃风率', '最大弃光率', '最大上网电量比例', '储能效率', '放电倍率', '充电倍率', '最大储能容量' ], '参数值': [ 0.15, # 最大弃风率 0.15, # 最大弃光率 0.1, # 最大上网电量比例(严格限制) 0.9, # 储能效率 1.0, # 放电倍率 1.0, # 充电倍率 5.0 # 最大储能容量(限制) ], '参数说明': [ '允许的最大弃风率(0.0-1.0)', '允许的最大弃光率(0.0-1.0)', '允许的最大上网电量比例(0.0-∞,只限制上网电量)', '储能充放电效率(0.0-1.0)', '储能放电倍率(C-rate,>0)', '储能充电倍率(C-rate,>0)', '储能容量上限(MWh,空表示无限制)' ], '取值范围': [ '0.0-1.0', '0.0-1.0', '≥0.0', '0.0-1.0', '>0', '>0', '>0或空' ], '默认值': [ '0.1', '0.1', '0.2', '0.9', '1.0', '1.0', '无限制' ] }) parameters_df.to_excel(writer, sheet_name='参数', index=False) # 添加说明工作表 description_df = pd.DataFrame({ '项目': ['数据说明', '数据类型', '时间范围', '单位', '注意事项', '参数说明'], '内容': [ '测试优先上网逻辑的数据', '24小时电力数据', '1-24小时', 'MW (兆瓦)', '所有数值必须为非负数', '设置了严格的上网电量限制(10%)和储能容量限制(5MWh)' ] }) description_df.to_excel(writer, sheet_name='说明', index=False) print(f"测试Excel文件已创建:{filename}") return filename def test_grid_priority(): """测试优先上网逻辑""" print("=== 测试优先上网逻辑 ===\n") # 创建测试文件 test_file = create_test_excel() # 从Excel读取数据 from excel_reader import read_excel_data data = read_excel_data(test_file, include_parameters=True) solar_output = data['solar_output'] wind_output = data['wind_output'] thermal_output = data['thermal_output'] load_demand = data['load_demand'] params = data['system_parameters'] print("测试数据概况:") print(f"光伏出力范围: {min(solar_output):.1f} - {max(solar_output):.1f} MW") print(f"风电出力: {wind_output[0]:.1f} MW (恒定)") print(f"火电出力: {thermal_output[0]:.1f} MW (恒定)") print(f"负荷需求范围: {min(load_demand):.1f} - {max(load_demand):.1f} MW") print(f"\n系统参数:") print(f"最大上网电量比例: {params.max_grid_ratio}") print(f"最大储能容量: {params.max_storage_capacity} MWh") print(f"最大弃风率: {params.max_curtailment_wind}") print(f"最大弃光率: {params.max_curtailment_solar}") # 计算总发电量和负荷 total_generation = sum(solar_output) + sum(wind_output) + sum(thermal_output) total_load = sum(load_demand) total_surplus = total_generation - total_load print(f"\n能量平衡:") print(f"总发电量: {total_generation:.1f} MWh") print(f"总负荷: {total_load:.1f} MWh") print(f"总盈余: {total_surplus:.1f} MWh") # 运行优化 print("\n正在运行储能容量优化...") result = optimize_storage_capacity( solar_output, wind_output, thermal_output, load_demand, params ) # 分析结果 total_grid_feed_in = sum(result['grid_feed_in']) total_curtailed_wind = sum(result['curtailed_wind']) total_curtailed_solar = sum(result['curtailed_solar']) print(f"\n=== 优化结果 ===") print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh") print(f"实际上网电量: {total_grid_feed_in:.2f} MWh") print(f"上网电量比例: {result['total_grid_feed_in_ratio']:.3f}") print(f"弃风量: {total_curtailed_wind:.2f} MWh") print(f"弃光量: {total_curtailed_solar:.2f} MWh") print(f"弃风率: {result['total_curtailment_wind_ratio']:.3f}") print(f"弃光率: {result['total_curtailment_solar_ratio']:.3f}") # 验证优先上网逻辑 max_allowed_grid = total_generation * params.max_grid_ratio print(f"\n=== 验证优先上网逻辑 ===") print(f"最大允许上网电量: {max_allowed_grid:.2f} MWh") print(f"实际上网电量: {total_grid_feed_in:.2f} MWh") if abs(total_grid_feed_in - max_allowed_grid) < 1.0: # 允许1MW误差 print("[OK] 验证通过:系统优先上网,达到上网电量限制上限") else: print("[ERROR] 验证失败:系统未充分利用上网电量限制") if total_curtailed_wind > 0 or total_curtailed_solar > 0: print("[OK] 验证通过:在上网电量限制达到后,系统开始弃风弃光") else: print("[INFO] 注意:没有弃风弃光,可能盈余电力全部被储能或上网消化") # 查看具体小时的弃风弃光情况 print(f"\n=== 详细分析(盈余时段) ===") for hour in range(6, 13): # 6-12点是光伏出力高峰 available = solar_output[hour] + wind_output[hour] + thermal_output[hour] demand = load_demand[hour] surplus = available - demand grid = result['grid_feed_in'][hour] curtailed = result['curtailed_wind'][hour] + result['curtailed_solar'][hour] if surplus > 0: print(f"小时{hour}: 盈余{surplus:.1f}MW -> 上网{grid:.1f}MW + 弃风弃光{curtailed:.1f}MW") print(f"\n测试完成!") if __name__ == "__main__": test_grid_priority()