216 lines
8.2 KiB
Python
216 lines
8.2 KiB
Python
"""
|
||
测试优先上网逻辑
|
||
|
||
该程序创建一个测试场景,验证系统是否优先上网而不是弃风弃光。
|
||
|
||
作者: 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() |