增加在excel中设置参数的功能。
This commit is contained in:
@@ -109,15 +109,26 @@ def create_comprehensive_plot(solar_output, wind_output, thermal_output, load_de
|
|||||||
total_curtailed = sum(curtailed_wind) + sum(curtailed_solar)
|
total_curtailed = sum(curtailed_wind) + sum(curtailed_solar)
|
||||||
total_grid = sum(result['grid_feed_in'])
|
total_grid = sum(result['grid_feed_in'])
|
||||||
|
|
||||||
# 能量分配
|
# 处理上网电量为负的情况(购电)
|
||||||
|
if total_grid >= 0:
|
||||||
|
# 有上网电量
|
||||||
energy_data = [total_load, total_curtailed, total_grid]
|
energy_data = [total_load, total_curtailed, total_grid]
|
||||||
energy_labels = [f'负荷\n({total_load:.1f} MWh)',
|
energy_labels = [f'负荷\n({total_load:.1f} MWh)',
|
||||||
f'弃风弃光\n({total_curtailed:.1f} MWh)',
|
f'弃风弃光\n({total_curtailed:.1f} MWh)',
|
||||||
f'上网电量\n({total_grid:.1f} MWh)']
|
f'上网电量\n({total_grid:.1f} MWh)']
|
||||||
colors = ['red', 'orange', 'green']
|
colors = ['red', 'orange', 'green']
|
||||||
|
|
||||||
ax5.pie(energy_data, labels=energy_labels, colors=colors, autopct='%1.1f%%', startangle=90)
|
ax5.pie(energy_data, labels=energy_labels, colors=colors, autopct='%1.1f%%', startangle=90)
|
||||||
ax5.set_title('能量分配')
|
ax5.set_title('能量分配')
|
||||||
|
else:
|
||||||
|
# 从电网购电
|
||||||
|
grid_purchase = -total_grid # 转为正值
|
||||||
|
energy_data = [total_load, total_curtailed, grid_purchase]
|
||||||
|
energy_labels = [f'负荷\n({total_load:.1f} MWh)',
|
||||||
|
f'弃风弃光\n({total_curtailed:.1f} MWh)',
|
||||||
|
f'购电量\n({grid_purchase:.1f} MWh)']
|
||||||
|
colors = ['red', 'orange', 'blue'] # 购电用蓝色
|
||||||
|
ax5.pie(energy_data, labels=energy_labels, colors=colors, autopct='%1.1f%%', startangle=90)
|
||||||
|
ax5.set_title('能量分配(含购电)')
|
||||||
|
|
||||||
# === 发电构成饼图 ===
|
# === 发电构成饼图 ===
|
||||||
ax6 = fig.add_subplot(gs[2, 1])
|
ax6 = fig.add_subplot(gs[2, 1])
|
||||||
@@ -146,7 +157,7 @@ def create_comprehensive_plot(solar_output, wind_output, thermal_output, load_de
|
|||||||
弃光率: {result['total_curtailment_solar_ratio']:.1%}
|
弃光率: {result['total_curtailment_solar_ratio']:.1%}
|
||||||
上网电量比例: {result['total_grid_feed_in_ratio']:.1%}
|
上网电量比例: {result['total_grid_feed_in_ratio']:.1%}
|
||||||
|
|
||||||
能量平衡: {'✓' if result['energy_balance_check'] else '✗'}
|
能量平衡: {'通过' if result['energy_balance_check'] else '未通过'}
|
||||||
|
|
||||||
最大储能状态: {max(storage_soc):.1f} MWh
|
最大储能状态: {max(storage_soc):.1f} MWh
|
||||||
最小储能状态: {min(storage_soc):.1f} MWh
|
最小储能状态: {min(storage_soc):.1f} MWh
|
||||||
|
|||||||
232
excel_reader.py
232
excel_reader.py
@@ -9,8 +9,9 @@ Excel数据读取模块
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Optional, Tuple, Any
|
||||||
import os
|
import os
|
||||||
|
from storage_optimization import SystemParameters
|
||||||
|
|
||||||
|
|
||||||
def validate_excel_data(df: pd.DataFrame, data_type: str = "8760") -> bool:
|
def validate_excel_data(df: pd.DataFrame, data_type: str = "8760") -> bool:
|
||||||
@@ -52,13 +53,79 @@ def validate_excel_data(df: pd.DataFrame, data_type: str = "8760") -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def read_excel_data(file_path: str, sheet_name: str = 0) -> Dict[str, List[float]]:
|
def read_system_parameters(file_path: str) -> SystemParameters:
|
||||||
|
"""
|
||||||
|
从Excel文件读取系统参数
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path: Excel文件路径
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
SystemParameters对象
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
FileNotFoundError: 文件不存在
|
||||||
|
ValueError: 参数格式错误
|
||||||
|
"""
|
||||||
|
# 检查文件是否存在
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
raise FileNotFoundError(f"文件不存在:{file_path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 读取参数工作表
|
||||||
|
df_params = pd.read_excel(file_path, sheet_name='参数')
|
||||||
|
|
||||||
|
# 验证参数工作表格式
|
||||||
|
required_columns = ['参数名称', '参数值', '参数说明']
|
||||||
|
missing_columns = [col for col in required_columns if col not in df_params.columns]
|
||||||
|
|
||||||
|
if missing_columns:
|
||||||
|
raise ValueError(f"参数工作表缺少必需的列:{missing_columns}")
|
||||||
|
|
||||||
|
# 提取参数值
|
||||||
|
params_dict = {}
|
||||||
|
for _, row in df_params.iterrows():
|
||||||
|
param_name = row['参数名称']
|
||||||
|
param_value = row['参数值']
|
||||||
|
|
||||||
|
# 跳过空行
|
||||||
|
if pd.isna(param_name) or pd.isna(param_value):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 转换参数值
|
||||||
|
try:
|
||||||
|
if isinstance(param_value, str):
|
||||||
|
# 尝试转换为浮点数
|
||||||
|
param_value = float(param_value)
|
||||||
|
params_dict[param_name] = param_value
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
raise ValueError(f"参数 '{param_name}' 的值 '{param_value}' 不是有效的数值")
|
||||||
|
|
||||||
|
# 创建SystemParameters对象
|
||||||
|
return SystemParameters(
|
||||||
|
max_curtailment_wind=params_dict.get('最大弃风率', 0.1),
|
||||||
|
max_curtailment_solar=params_dict.get('最大弃光率', 0.1),
|
||||||
|
max_grid_ratio=params_dict.get('最大上网电量比例', 0.2),
|
||||||
|
storage_efficiency=params_dict.get('储能效率', 0.9),
|
||||||
|
discharge_rate=params_dict.get('放电倍率', 1.0),
|
||||||
|
charge_rate=params_dict.get('充电倍率', 1.0),
|
||||||
|
max_storage_capacity=params_dict.get('最大储能容量', None)
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"读取参数工作表失败,使用默认参数:{str(e)}")
|
||||||
|
# 如果参数工作表不存在或读取失败,返回默认参数
|
||||||
|
return SystemParameters()
|
||||||
|
|
||||||
|
|
||||||
|
def read_excel_data(file_path: str, sheet_name: str = 0, include_parameters: bool = True) -> Dict[str, List[float]]:
|
||||||
"""
|
"""
|
||||||
从Excel文件读取8760小时数据
|
从Excel文件读取8760小时数据
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_path: Excel文件路径
|
file_path: Excel文件路径
|
||||||
sheet_name: 工作表名称或索引,默认为第一个工作表
|
sheet_name: 工作表名称或索引,默认为第一个工作表
|
||||||
|
include_parameters: 是否同时读取系统参数
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
包含所有数据的字典
|
包含所有数据的字典
|
||||||
@@ -96,7 +163,8 @@ def read_excel_data(file_path: str, sheet_name: str = 0) -> Dict[str, List[float
|
|||||||
thermal_output = thermal_output * 365
|
thermal_output = thermal_output * 365
|
||||||
load_demand = load_demand * 365
|
load_demand = load_demand * 365
|
||||||
|
|
||||||
return {
|
# 构建返回结果
|
||||||
|
result = {
|
||||||
'solar_output': solar_output,
|
'solar_output': solar_output,
|
||||||
'wind_output': wind_output,
|
'wind_output': wind_output,
|
||||||
'thermal_output': thermal_output,
|
'thermal_output': thermal_output,
|
||||||
@@ -105,6 +173,17 @@ def read_excel_data(file_path: str, sheet_name: str = 0) -> Dict[str, List[float
|
|||||||
'original_length': len(df)
|
'original_length': len(df)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 如果需要读取参数
|
||||||
|
if include_parameters:
|
||||||
|
try:
|
||||||
|
result['system_parameters'] = read_system_parameters(file_path)
|
||||||
|
print("成功读取系统参数")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"读取系统参数失败,使用默认参数:{str(e)}")
|
||||||
|
result['system_parameters'] = SystemParameters()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(f"读取Excel文件失败:{str(e)}")
|
raise ValueError(f"读取Excel文件失败:{str(e)}")
|
||||||
|
|
||||||
@@ -173,15 +252,66 @@ def create_excel_template(file_path: str, data_type: str = "8760"):
|
|||||||
with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
|
with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
|
||||||
df.to_excel(writer, sheet_name='数据', index=False)
|
df.to_excel(writer, sheet_name='数据', index=False)
|
||||||
|
|
||||||
|
# 添加参数工作表
|
||||||
|
parameters_df = pd.DataFrame({
|
||||||
|
'参数名称': [
|
||||||
|
'最大弃风率',
|
||||||
|
'最大弃光率',
|
||||||
|
'最大上网电量比例',
|
||||||
|
'储能效率',
|
||||||
|
'放电倍率',
|
||||||
|
'充电倍率',
|
||||||
|
'最大储能容量'
|
||||||
|
],
|
||||||
|
'参数值': [
|
||||||
|
0.1, # 最大弃风率
|
||||||
|
0.1, # 最大弃光率
|
||||||
|
0.2, # 最大上网电量比例
|
||||||
|
0.9, # 储能效率
|
||||||
|
1.0, # 放电倍率
|
||||||
|
1.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({
|
description_df = pd.DataFrame({
|
||||||
'项目': ['数据说明', '数据类型', '时间范围', '单位', '注意事项'],
|
'项目': ['数据说明', '数据类型', '时间范围', '单位', '注意事项', '参数说明'],
|
||||||
'内容': [
|
'内容': [
|
||||||
description,
|
description,
|
||||||
f'{data_type}小时电力数据',
|
f'{data_type}小时电力数据',
|
||||||
f'1-{hours}小时',
|
f'1-{hours}小时',
|
||||||
'MW (兆瓦)',
|
'MW (兆瓦)',
|
||||||
'所有数值必须为非负数'
|
'所有数值必须为非负数',
|
||||||
|
'系统参数请在"参数"工作表中修改'
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
description_df.to_excel(writer, sheet_name='说明', index=False)
|
description_df.to_excel(writer, sheet_name='说明', index=False)
|
||||||
@@ -228,6 +358,70 @@ def analyze_excel_data(file_path: str) -> Dict[str, float]:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_system_parameters(params: SystemParameters) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
验证系统参数的有效性
|
||||||
|
|
||||||
|
Args:
|
||||||
|
params: SystemParameters对象
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
验证结果字典
|
||||||
|
"""
|
||||||
|
validation_result = {
|
||||||
|
'valid': True,
|
||||||
|
'errors': [],
|
||||||
|
'warnings': []
|
||||||
|
}
|
||||||
|
|
||||||
|
# 检查弃风率
|
||||||
|
if not (0.0 <= params.max_curtailment_wind <= 1.0):
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"弃风率必须在0.0-1.0之间,当前值:{params.max_curtailment_wind}")
|
||||||
|
|
||||||
|
# 检查弃光率
|
||||||
|
if not (0.0 <= params.max_curtailment_solar <= 1.0):
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"弃光率必须在0.0-1.0之间,当前值:{params.max_curtailment_solar}")
|
||||||
|
|
||||||
|
# 检查上网电量比例
|
||||||
|
if not (0.0 <= params.max_grid_ratio):
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"上网电量比例必须为非负值,当前值:{params.max_grid_ratio}")
|
||||||
|
|
||||||
|
# 检查储能效率
|
||||||
|
if not (0.0 < params.storage_efficiency <= 1.0):
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"储能效率必须在0.0-1.0之间,当前值:{params.storage_efficiency}")
|
||||||
|
|
||||||
|
# 检查放电倍率
|
||||||
|
if params.discharge_rate <= 0:
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"放电倍率必须大于0,当前值:{params.discharge_rate}")
|
||||||
|
|
||||||
|
# 检查充电倍率
|
||||||
|
if params.charge_rate <= 0:
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"充电倍率必须大于0,当前值:{params.charge_rate}")
|
||||||
|
|
||||||
|
# 检查储能容量上限
|
||||||
|
if params.max_storage_capacity is not None and params.max_storage_capacity <= 0:
|
||||||
|
validation_result['valid'] = False
|
||||||
|
validation_result['errors'].append(f"储能容量上限必须大于0,当前值:{params.max_storage_capacity}")
|
||||||
|
|
||||||
|
# 添加警告信息
|
||||||
|
if params.storage_efficiency < 0.8:
|
||||||
|
validation_result['warnings'].append("储能效率较低,可能影响系统性能")
|
||||||
|
|
||||||
|
if params.max_curtailment_wind > 0.3 or params.max_curtailment_solar > 0.3:
|
||||||
|
validation_result['warnings'].append("弃风弃光率较高,可能造成能源浪费")
|
||||||
|
|
||||||
|
if params.max_grid_ratio > 0.5:
|
||||||
|
validation_result['warnings'].append("上网电量比例较高,可能影响电网稳定性")
|
||||||
|
|
||||||
|
return validation_result
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""主函数,演示Excel数据读取功能"""
|
"""主函数,演示Excel数据读取功能"""
|
||||||
print("=== Excel数据读取模块演示 ===")
|
print("=== Excel数据读取模块演示 ===")
|
||||||
@@ -255,11 +449,39 @@ def main():
|
|||||||
print(f"光伏出力前10小时:{data['solar_output'][:10]}")
|
print(f"光伏出力前10小时:{data['solar_output'][:10]}")
|
||||||
print(f"风电出力前10小时:{data['wind_output'][:10]}")
|
print(f"风电出力前10小时:{data['wind_output'][:10]}")
|
||||||
print(f"负荷需求前10小时:{data['load_demand'][:10]}")
|
print(f"负荷需求前10小时:{data['load_demand'][:10]}")
|
||||||
|
|
||||||
|
# 演示参数读取
|
||||||
|
if 'system_parameters' in data:
|
||||||
|
params = data['system_parameters']
|
||||||
|
print(f"\n系统参数:")
|
||||||
|
print(f" 最大弃风率: {params.max_curtailment_wind}")
|
||||||
|
print(f" 最大弃光率: {params.max_curtailment_solar}")
|
||||||
|
print(f" 最大上网电量比例: {params.max_grid_ratio}")
|
||||||
|
print(f" 储能效率: {params.storage_efficiency}")
|
||||||
|
print(f" 放电倍率: {params.discharge_rate}")
|
||||||
|
print(f" 充电倍率: {params.charge_rate}")
|
||||||
|
print(f" 最大储能容量: {params.max_storage_capacity}")
|
||||||
|
|
||||||
|
# 验证参数
|
||||||
|
validation = validate_system_parameters(params)
|
||||||
|
if validation['valid']:
|
||||||
|
print("[OK] 参数验证通过")
|
||||||
|
else:
|
||||||
|
print("[ERROR] 参数验证失败:")
|
||||||
|
for error in validation['errors']:
|
||||||
|
print(f" - {error}")
|
||||||
|
|
||||||
|
if validation['warnings']:
|
||||||
|
print("[WARNING] 参数警告:")
|
||||||
|
for warning in validation['warnings']:
|
||||||
|
print(f" - {warning}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"读取失败:{str(e)}")
|
print(f"读取失败:{str(e)}")
|
||||||
|
|
||||||
print("\n=== 演示完成 ===")
|
print("\n=== 演示完成 ===")
|
||||||
print("模板文件已创建,您可以根据实际数据修改Excel文件。")
|
print("模板文件已创建,您可以根据实际数据修改Excel文件。")
|
||||||
|
print("系统参数可以在Excel的'参数'工作表中直接修改。")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user