Files
multi_energy_complementarity/tests/test_excel_data.py
2025-12-27 19:15:56 +08:00

306 lines
12 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
测试程序 - 验证Excel数据输入和储能容量优化
该程序使用data_template_24.xlsx和data_template_8760.xlsx作为输入
测试储能容量优化系统的功能和错误处理。
作者: iFlow CLI
创建日期: 2025-12-25
"""
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from typing import Dict, Any
from excel_reader import read_excel_data, analyze_excel_data, read_system_parameters, validate_system_parameters
from storage_optimization import optimize_storage_capacity, SystemParameters
from advanced_visualization import create_comprehensive_plot, create_time_series_plot
def test_excel_file(file_path: str, test_name: str) -> Dict[str, Any]:
"""
测试单个Excel文件
Args:
file_path: Excel文件路径
test_name: 测试名称
Returns:
测试结果字典
"""
print(f"\n{'='*60}")
print(f"测试:{test_name}")
print(f"文件:{file_path}")
print(f"{'='*60}")
result = {
'test_name': test_name,
'file_path': file_path,
'success': False,
'error': None,
'data_stats': {},
'optimization_result': {}
}
try:
# 1. 检查文件是否存在
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在:{file_path}")
print("[OK] 文件存在检查通过")
# 2. 读取Excel数据
print("正在读取Excel数据...")
data = read_excel_data(file_path, include_parameters=True)
print(f"[OK] 数据读取成功,类型:{data['data_type']}")
print(f" 原始数据长度:{data['original_length']}")
print(f" 处理后数据长度:{len(data['solar_output'])}")
# 2.1 测试参数读取
if 'system_parameters' in data:
params = data['system_parameters']
print(f"[OK] 系统参数读取成功")
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}")
raise ValueError(f"系统参数验证失败: {validation['errors']}")
if validation['warnings']:
print("[WARNING] 系统参数警告:")
for warning in validation['warnings']:
print(f" - {warning}")
else:
print("[WARNING] 未找到系统参数,使用默认参数")
params = SystemParameters()
# 3. 分析数据统计信息
print("正在分析数据统计信息...")
stats = analyze_excel_data(file_path)
result['data_stats'] = stats
print("[OK] 数据统计分析完成")
# 4. 验证数据完整性
print("正在验证数据完整性...")
solar_output = data['solar_output']
wind_output = data['wind_output']
thermal_output = data['thermal_output']
load_demand = data['load_demand']
# 检查数据长度一致性
if not (len(solar_output) == len(wind_output) == len(thermal_output) == len(load_demand)):
raise ValueError("数据长度不一致")
print("[OK] 数据长度一致性检查通过")
# 检查非负值
for name, values in [
("光伏出力", solar_output), ("风电出力", wind_output),
("火电出力", thermal_output), ("负荷需求", load_demand)
]:
if any(v < 0 for v in values):
raise ValueError(f"{name}包含负值")
print("[OK] 非负值检查通过")
# 5. 储能容量优化测试
print("正在进行储能容量优化计算...")
# 使用Excel中的参数和不同的测试配置
excel_params = params # 从Excel中读取的参数
test_configs = [
{
'name': 'Excel配置',
'params': excel_params
},
{
'name': '基础配置',
'params': SystemParameters(
max_curtailment_wind=0.1,
max_curtailment_solar=0.1,
max_grid_ratio=0.2,
storage_efficiency=0.9,
discharge_rate=1.0,
charge_rate=1.0
)
},
{
'name': '高弃风弃光配置',
'params': SystemParameters(
max_curtailment_wind=0.2,
max_curtailment_solar=0.2,
max_grid_ratio=0.3,
storage_efficiency=0.85,
discharge_rate=1.5,
charge_rate=1.5
)
},
{
'name': '低储能效率配置',
'params': SystemParameters(
max_curtailment_wind=0.05,
max_curtailment_solar=0.05,
max_grid_ratio=0.1,
storage_efficiency=0.75,
discharge_rate=0.8,
charge_rate=0.8
)
}
]
optimization_results = []
for config in test_configs:
print(f" 测试配置:{config['name']}")
opt_result = optimize_storage_capacity(
solar_output, wind_output, thermal_output, load_demand, config['params']
)
print(f" 所需储能容量:{opt_result['required_storage_capacity']:.2f} MWh")
print(f" 弃风率:{opt_result['total_curtailment_wind_ratio']:.3f}")
print(f" 弃光率:{opt_result['total_curtailment_solar_ratio']:.3f}")
print(f" 上网电量比例:{opt_result['total_grid_feed_in_ratio']:.3f}")
print(f" 能量平衡校验:{'通过' if opt_result['energy_balance_check'] else '未通过'}")
optimization_results.append({
'config_name': config['name'],
'result': opt_result
})
result['optimization_result'] = optimization_results
print("[OK] 储能容量优化计算完成")
# 6. 可视化测试仅对24小时数据进行避免8760小时数据生成过大图像
if data['data_type'] == '24':
print("正在生成可视化图表...")
try:
# 使用基础配置的结果生成图表
base_result = optimization_results[0]['result']
base_params = test_configs[0]['params']
# 生成基础图表截取前24小时数据
solar_24 = solar_output[:24] if len(solar_output) > 24 else solar_output
wind_24 = wind_output[:24] if len(wind_output) > 24 else wind_output
thermal_24 = thermal_output[:24] if len(thermal_output) > 24 else thermal_output
load_24 = load_demand[:24] if len(load_demand) > 24 else load_demand
# 截取结果的24小时数据
result_24 = {
'required_storage_capacity': base_result['required_storage_capacity'],
'charge_profile': base_result['charge_profile'][:24] if len(base_result['charge_profile']) > 24 else base_result['charge_profile'],
'discharge_profile': base_result['discharge_profile'][:24] if len(base_result['discharge_profile']) > 24 else base_result['discharge_profile'],
'curtailed_wind': base_result['curtailed_wind'][:24] if len(base_result['curtailed_wind']) > 24 else base_result['curtailed_wind'],
'curtailed_solar': base_result['curtailed_solar'][:24] if len(base_result['curtailed_solar']) > 24 else base_result['curtailed_solar'],
'grid_feed_in': base_result['grid_feed_in'][:24] if len(base_result['grid_feed_in']) > 24 else base_result['grid_feed_in'],
'storage_profile': base_result['storage_profile'][:24] if len(base_result['storage_profile']) > 24 else base_result['storage_profile'],
'total_curtailment_wind_ratio': base_result['total_curtailment_wind_ratio'],
'total_curtailment_solar_ratio': base_result['total_curtailment_solar_ratio'],
'total_grid_feed_in_ratio': base_result['total_grid_feed_in_ratio'],
'energy_balance_check': base_result['energy_balance_check']
}
create_comprehensive_plot(solar_24, wind_24, thermal_24, load_24, result_24, base_params)
create_time_series_plot(solar_24, wind_24, thermal_24, load_24, result_24)
print("[OK] 可视化图表生成完成")
except Exception as e:
print(f"⚠ 可视化图表生成失败:{str(e)}")
print(" 这不是严重错误,可能是字体或显示问题")
# 标记测试成功
result['success'] = True
print(f"\n[OK] 测试 '{test_name}' 成功完成!")
except Exception as e:
result['error'] = str(e)
result['traceback'] = traceback.format_exc()
print(f"\n[ERROR] 测试 '{test_name}' 失败:{str(e)}")
print("详细错误信息:")
traceback.print_exc()
return result
def run_comprehensive_tests():
"""运行综合测试"""
print("开始运行Excel数据输入综合测试...")
print(f"当前工作目录:{os.getcwd()}")
# 测试文件列表
test_files = [
{
'path': 'data_template_24.xlsx',
'name': '24小时数据模板测试'
},
{
'path': 'data_template_8760.xlsx',
'name': '8760小时数据模板测试'
}
]
# 运行所有测试
results = []
for test_file in test_files:
result = test_excel_file(test_file['path'], test_file['name'])
results.append(result)
# 生成测试报告
print(f"\n{'='*80}")
print("测试报告总结")
print(f"{'='*80}")
total_tests = len(results)
successful_tests = sum(1 for r in results if r['success'])
failed_tests = total_tests - successful_tests
print(f"总测试数:{total_tests}")
print(f"成功测试:{successful_tests}")
print(f"失败测试:{failed_tests}")
print(f"成功率:{successful_tests/total_tests*100:.1f}%")
print("\n详细结果:")
for i, result in enumerate(results, 1):
status = "[OK] 成功" if result['success'] else "[ERROR] 失败"
print(f"{i}. {result['test_name']}: {status}")
if not result['success']:
print(f" 错误:{result['error']}")
# 如果有失败的测试,返回非零退出码
if failed_tests > 0:
print(f"\n{failed_tests}个测试失败,请检查上述错误信息")
return False
else:
print("\n所有测试通过!系统运行正常。")
return True
def main():
"""主函数"""
try:
success = run_comprehensive_tests()
sys.exit(0 if success else 1)
except KeyboardInterrupt:
print("\n测试被用户中断")
sys.exit(1)
except Exception as e:
print(f"\n测试过程中发生未预期的错误:{str(e)}")
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()