
说实话做新能源调度这些年我一直有个体会风光配储这五个字写起来轻松跑起来要命。风电光伏完全看天吃饭白天太阳强但风可能停夜里风大电网负荷反而低想靠单一电源撑起稳定出力根本不现实必须靠储能兜底。这就是风光储互补调度要解决的核心问题什么时候发、什么时候存、什么时候放让整个系统既经济又稳。这次分享的项目是一套基于Python实现的风电、光伏与储能互补调度运行研究框架。储能部分做了横向对比设计不只用了常规的电池储能也加入了废弃矿井改造的小型抽水蓄能。整套代码完整覆盖了数据准备、出力建模、调度策略和结果可视化适合新能源方向的研究生、做智慧能源的工程师、以及所有想快速跑通多能互补仿真思路的朋友。代码逻辑不复杂重点在于让你从数据到曲线半天内把整套原理跑通还能直接替换自己的数据做扩展实验。1. 项目整体设计与思路拆解1.1 为什么风电光伏必须依赖储能参与调度风电出力最大的特点是随风而动你可能预测了小时级出力半小时后风速掉一半实际出力跟着对半砍光伏更极端白天有光照才有出力傍晚直接归零。两个间歇性电源单独并网必然带来两个麻烦一是出力波动大对电网频率和电压的冲击很明显二是中午光伏大发、深夜风电大发而负荷低迷的时候电源出力远超负荷需求产生大比例弃电。储能就是中间缓冲带负荷高时放电顶上去负荷低时充电吃下来。但仅仅配了储能不是终点调度策略才是灵魂。同样是电池加抽蓄各20MW的配置一个粗糙的“满了就放、亏了就充”策略可能让弃电率依然居高不下而一套合理的日前计划加实时修正策略能把弃电率从15%压到5%以内。这就是互补调度研究的核心价值也是程序实现中最值得花时间打磨的地方。1.2 电池与废弃矿井抽蓄的组合逻辑说到储能第一反应大多是锂电池但电池有几个硬伤容量规模做不大、循环寿命有限、度电成本高、退役回收还有环保压力。大型抽水蓄能是好但选址条件苛刻天然水库资源就那么点。于是这几年有个新思路废弃矿井空间巨大竖井和巷道天然形成了上下高差改造成小型抽水蓄能电站既把废弃资源盘活了又能在水头不高的情况下实现数十到上百MWh的储能容量。我在这套研究里把电池和矿井抽蓄同时放进调度模型原因很简单电池响应快、效率高适合做短时高频调节抽蓄容量大、寿命长但响应偏慢适合做长周期的能量搬移。电池负责分钟级的波动平抑抽蓄负责小时级的削峰填谷两种储能特性互补整个系统的调节手段才算完整。1.3 技术路线与工具选型背后的考量技术路线选择Python是因为这套研究的数据处理和仿真迭代非常依赖生态工具历史气象数据和负荷数据用Pandas清洗数值计算用NumPy结果可视化用Matplotlib优化求解可以直接调用SciPy如果后续升级到更严格的优化模型还可以衔接Pyomo或商业求解器。这意味着整套代码的研究周期可以很长硕士学位论文里的场景都能覆盖。整体分四步走构建风电、光伏的出力时序模型生成仿真场景数据建立电池与矿井抽蓄的动态状态模型明确各自的运行边界设定调度目标与约束条件编写互补调度策略用典型日数据跑仿真输出调度计划与弃电率、购电成本等关键指标这样设计的核心原因是模块化。每个环节独立想替换风电模型就只动风电模块想对比不同储能策略就只改策略函数其他部分不用动。很多初学者喜欢把出力模型、储能约束和调度逻辑全部写在一个大循环里后面改参数必须从头跑排错极其痛苦。我建议你也采用模块化结构这是后续扩展和复现的基础。2. 核心系统建模与参数处理2.1 风电出力模型从风速曲线到功率曲线风电出力的物理链条是风速带动风轮旋转风轮捕获机械功率发电机把它转成电功率。工程上为了方便调度仿真一般用分段功率曲线来近似这个链条而不是直接做空气动力学计算。典型的功率曲线包含三个关键节点切入风速一般取3m/s左右低于这个值风机不出力额定风速一般取12m/s左右达到这个值出力到额定功率切出风速一般取25m/s高于这个值为了保护风机必须停机分段表达式我习惯写成下面这样v 3m/s 或 v 25m/s时P_wind 03m/s ≤ v 12m/s时P_wind P_r × (v - 3)^3 / (12 - 3)^312m/s ≤ v ≤ 25m/s时P_wind P_r其中P_r是风机的额定功率。做了这个模型之后只要手里有一份风速时序数据就能生成风电出力的时间序列不需要深入风机内部的控制逻辑调度层面完全够用。如果要做不确定性研究可以在风速序列上叠加随机扰动比如用威布尔分布随机数扰动后做多次蒙特卡洛仿真观察系统在不同风速随机场景下的表现。这个扩展对于论文里的鲁棒性分析非常实用。2.2 光伏出力模型辐照度与温度修正光伏出力主要受辐照度影响理论上是线性关系但组件表面温度升高会让效率下降所以模型中要加上温度修正系数。标准测试条件STC下辐照度是1000W/m²实际辐照度G(t)从气象数据里取组件温度T_c(t)不能直接拿环境温度替代但工程简化处理时可以用环境温度加辐照度来估算。简化表达式为P_pv(t) P_stc × G(t) / 1000 × [1 k × (T_c(t) - 25)]其中P_stc是标准条件下的额定功率k是功率温度系数多晶硅组件一般取-0.004左右也就是每升高1℃出力下降0.4%。组件温度T_c(t)如果不想引入复杂的传热模型可以近似取环境温度加上0.03乘以辐照度。如果研究目标是调度策略而不是光伏板本身的电热特性还有一个更省事的做法直接构造归一化的出力曲线横轴是时间纵轴是0到1的标幺值再乘以光伏装机容量和一个反映天气状况的降额系数。这个方法适合做典型日分析做场景对比时的差异主要靠降额系数体现。2.3 电池储能的状态递推与运行边界电池储能的核心状态量是SOC也就是荷电状态。它表示当前剩余电量占额定容量的比例。调度每个时间步都要更新这个值递推关系是SOC(tΔt) SOC(t) (η_c × P_ch(t) - P_dis(t) / η_d) × Δt / E_rated其中η_c是充电效率、η_d是放电效率、P_ch和P_dis分别是充放电功率、E_rated是额定容量。效率和功率单位必须统一否则递推几步就出问题。运行边界方面要注意几点充放电功率不能超过额定功率这是设备硬约束SOC要留安全裕量我一般设0.1到0.9不允许到0和1同一时刻只能充电或者放电不能同时进行这个约束在调度逻辑里最容易漏参数设计上这套研究里我用了电池额定容量80MWh、额定功率20MW、充放电效率95%SOC初值取0.5。20MW功率对应80MWh容量等效0.25C倍率既能做分钟级调节又不至于损耗过快。研究场景里如果想模拟快充快放可以把容量降到40MWh但此时要更注意SOC边界约束否则容易在连续几个时段内触顶或触底。2.4 废弃矿井小型抽水蓄能的模型化处理废弃矿井抽蓄的原理和常规抽蓄电站没有本质区别光伏大发或风电盈余时把水从低位巷道抽到高位巷道或地面蓄水池负荷高峰时放水通过水轮机发电。区别在于矿井巷道断面窄、水头低一般只有50到150m所以单机功率不大但可利用空间大储能容量能做到上百MWh。模型参数方面我定义它的状态量为等效蓄能量E(t)单位MWh递推关系和电池类似E(tΔt) E(t) η_pump × P_pump(t) × Δt - P_gen(t) × Δt / η_gen这里需要注意抽水蓄能综合效率是抽水效率乘以发电效率整体一般在0.7到0.8之间远低于电池的充放电综合效率。这意味着同样输入1MWh电力电池大约能放出0.9MWh而抽蓄只能放出0.75MWh左右。所以从能量效率上看电池优先于抽蓄但从容量和寿命角度抽蓄在大规模能量搬移场景下无可替代。设计参数我取蓄能量等效100MWh、抽水和发电功率都为20MW、综合效率0.75、蓄水量上下限取20%到90%。另外抽蓄机组不能频繁启停实际电站对连续运行时间有要求我在调度策略里加了最小连续运行2小时的约束避免模型出现每分钟都在切换抽水/发电状态的假象。2.5 调度优化目标与约束条件设计互补调度的目标函数学术界常见三类运行成本最小化、弃风弃光率最小化、出力波动平抑。我的这套代码推荐用组合目标min Σ( C_grid × P_buy(t) λ_wind × P_wind_curtail(t) λ_pv × P_pv_curtail(t) )其中C_grid是电网购电电价P_buy是购电功率P_wind_curtail和P_pv_curtail分别是弃风和弃光功率λ_wind和λ_pv是惩罚系数。把弃电惩罚系数调大系统就会优先动用储能去吃下新能源的富裕出力反过来如果想看“最小购电成本”方案就要平衡购电价和储能损耗成本。约束条件中最核心的是每个时段的功率平衡P_wind P_pv P_battery_dis P_pump_gen P_buy P_load P_battery_ch P_pump_pump左边是电源侧和放电侧右边是负荷侧和充电侧。再加上设备出力上下限、SOC和蓄水量边界以及抽蓄最小连续运行时间约束整个优化问题就完整了。研究初期如果不想引入求解器可以像我这样用启发式调度规则逐时段求解后续升级可以换成混合整数线性规划目标函数和约束不变只需要把决策变量和求解器接上。3. Python实现流程与核心代码详解3.1 数据准备与典型场景构造仿真需要四类基础数据风电预测出力曲线、光伏预测出力曲线、负荷预测曲线、分时电价曲线。实际工程里这些数据来自SCADA系统或者气象预报平台研究阶段我通常自己构造两类典型场景夏季晴天和冬季大风天分别验证“光伏主导的午充晚放”和“风电主导的夜间蓄能”两种调度逻辑。数据预处理有三个坑必须避开时间戳对齐所有数据统一到同一时间分辨率我用的15分钟一个点一天96个点缺值处理用相邻时段线性插值不要直接填0功率单位统一为MW避免kW和MW混用导致结果量级失控以一个具体算例为基准风电额定容量100MW、光伏额定容量50MW、负荷峰值约120MW、电池20MW/80MWh、矿井抽蓄20MW/100MWh。这套配置下新能源装机和负荷峰值的比例约1.25:1比较贴近实际高比例新能源场景储能总容量能覆盖约1.5小时峰值负荷属于常见配置。3.2 调度策略设计与核心逻辑我这套代码采用的调度策略是“净负荷优先级死区”核心思路是先用总负荷减去风光出力得到净负荷然后按照响应速度快慢安排储能动作。具体优先级顺序净负荷大于0表示缺电先电池放电电池SOC低于30%后启动抽蓄发电还不够就从电网购电净负荷小于0表示电力盈余先给电池充电电池SOC高于80%后启动抽蓄抽水实在吃不下才弃电净负荷在正负5MW的“死区”内时储能保持当前状态防止频繁启停核心调度函数的简化写法如下def dispatch_step(net_load, battery, pumped, t): 单时段调度决策 net_load 0 缺电; net_load 0 盈余 if net_load 0: # 电池优先放电 p_bat min(battery[power_mw], net_load, max(0, (battery[soc] - battery[soc_min]) * battery[capacity_mwh] * 4)) remaining net_load - p_bat # 电池不够时抽蓄补上 p_pump_gen 0 if remaining 0 and pumped[level] 0.3: p_pump_gen min(pumped[power_mw], remaining) # 还不够只能买电 p_buy remaining - p_pump_gen return {bat: -p_bat, pump_gen: p_pump_gen, buy: p_buy, curtail: 0} else: # 盈余功率取绝对值 surplus -net_load # 电池优先充电 p_bat min(battery[power_mw], surplus, max(0, (battery[soc_max] - battery[soc]) * battery[capacity_mwh] * 4)) remaining surplus - p_bat # 电池吃不下时抽蓄抽水 p_pump 0 if remaining 0 and pumped[level] 0.9: p_pump min(pumped[power_mw], remaining) # 仍然吃不下只能弃电 p_curtail remaining - p_pump return {bat: p_bat, pump_pump: p_pump, buy: 0, curtail: p_curtail}这段代码里有个隐藏细节计算电池最大充放电功率时我额外乘了一个4原因是“SOC边界限制的剩余可充/放电量折合成15分钟功率”例如SOC距上限还有40MWh空间15分钟内最大能吃下160MW但还要受额定功率20MW约束min函数会取较小值。实际在写论文代码时建议把15分钟的功率换算做成独立函数逻辑会更清晰。3.3 结果指标计算与可视化实现仿真结束后重点统计四个指标弃风率、弃光率、储能利用率、电网购电成本。弃风率的定义是弃风电量除以理论可发电量弃光率同理。储能利用率则是电池和抽蓄放电电量总和除以理论储能容量这个指标能看出储能被调用得充不充分。可视化的核心图我画三张第一张是功率平衡曲线横轴时间纵轴功率画负荷、风光总出力、储能净出力、电网购电四条线一眼能看出供需平衡关系第二张是储能状态曲线用两个子图分别画电池SOC和抽蓄蓄水量便于定位“储能是否用满”第三张是弃电累计曲线横轴时间纵轴累计弃电量如果曲线在某个时段突然变陡说明那个时段出现了弃电绘图代码里要提前处理中文字体问题在Linux环境尤其明显不设置字体的话图里全是方框import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, WenQuanYi Micro Hei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False4. 典型案例结果分析与对比4.1 夏季晴天光伏主导下的“午充晚放”夏季晴天场景里光伏出力在10点到15点达到高峰额定50MW的光伏可以出力到45MW左右此时负荷偏低大约80MW风电大约20MW。风光合计约65MW负荷只有80MW表面看缺电15MW但实际上早晚负荷会有尖峰中午时段恰恰是电力富余阶段本来光伏大发可以完全覆盖负荷甚至反向送电但因为风小系统缺口还是存在。调度结果是电池在上午9点前已经达到SOC 0.910点半光伏出力上升后富余功率开始驱动抽蓄抽水到14点抽蓄蓄水量从0.3上升到0.85左右。18点光伏归零负荷开始向120MW爬升电池从18点开始放电承担晚高峰的快速爬坡部分19点半电池SOC降到0.3抽蓄开始发电接力支撑20点到22点的晚高峰。最终电网购电只在19点到21点之间发生了约20MW的缺口时段峰值购电功率相比无储能场景下降了60%以上。对比无储能方案弃电率从28%降到6%购电成本下降约35%。这个结果说明了“电池抽蓄”的组合在夏季晴天的典型作用电池响应快专门对付晚高峰爬坡抽蓄容量大把中午的富余电量搬到晚上用。4.2 冬季大风天风电逆调峰下的储能调度冬季大风天是另一种极端深夜风大负荷却处于一天最低点。假设凌晨2点负荷只有50MW风电出力高达80MW盈余30MW。此时电池满充容量有限20MW功率全部用于充电还剩10MW只能靠抽蓄抽水吃掉。由于光伏在夜间为0白天负荷普遍偏高调度策略会在早晨6点前就把电池放出一部分腾出容量接收上午的风电盈余抽蓄则等到上午9点负荷爬升后再放水发电。整体看风电反调峰特征明显储能系统在这一场景的利用率比夏季更高但弃电率依然存在因为凌晨盈余时段较长储能容量有限。这个场景里我还特意测了只有电池、没有抽蓄的对照组由于电池容量只有80MWh凌晨连续几个小时的盈余电量很快就充满后续盈余只能弃掉全天弃电率达18%。而加上100MWh抽蓄之后弃电率降到9%。原因很简单抽蓄给系统提供的是大容量的跨时段缓冲这是电池容量很难做到的。4.3 两种储能协同的配置比例经验从两个场景的对比里可以看出一个规律电池和抽蓄在调度中的角色分工非常明确。如果只有电池高频调节没问题但遇到连续多小时的大盈余电量容量很快就见底如果只有抽蓄容量是够的但负荷突然爬升的15分钟窗口内抽蓄根本来不及响应只能依靠电网购电来兜底。配置比例上我个人给出一个经验范围电池与抽蓄的功率比取1:1到1:2容量比取1:1.5到1:3。具体怎么选要靠仿真试算用不同比例跑几天数据对比弃电率和购电成本的变化选择拐点处的配置。不要拍脑袋定容量更不要照搬别人的配置因为负荷曲线和风光资源禀赋不同最优比例差异很大。5. 常见问题与调试体会5.1 时间精度不一致导致曲线错位第一次跑通完整流程时我发现储能充放电曲线在凌晨段出现大量锯齿状跳变一开始以为是调度策略写错了排查后发现是数据时间精度不一致负荷数据是小时级风光预测是15分钟级Pandas拼接时索引没有对齐导致净负荷在部分时段被重复计算。这个问题排查起来很隐蔽曲线看起来规律跳变实际是数据频率没统一。解决方法是先做数据清洗把所有序列重采样到同一个15分钟分辨率用resample方法聚合或插值再做时间索引对齐检查。我建议在数据读取函数里直接断言长度等于96不符合就抛异常提前发现问题。5.2 SOC初值与边界设置引发的冷启动陷阱SOC初始值设置不当会直接影响前面几个小时的调度结果。如果初值给得太低比如0.1而清晨负荷刚好偏高电池直接无电可放调度结果会出现一段购电高峰如果初值给得太高比如0.9而凌晨风电盈余电池又没有空间充电弃电量会异常偏大。我的解决办法是跑多日循环第一天用0.5初值跑完后把第24小时的SOC传递给第二天的初值连续跑7天最后只统计后3天的数据。这样SOC和水位进入稳态冷启动影响被完全消除。这个方法不只适用于电池抽蓄蓄水量也一样处理。5.3 抽蓄频繁启停与实际不符早期版本的调度逻辑是“只要有盈余就抽水只要有缺口就发电”结果抽蓄机组的启停曲线在一天之内切换了十几次明显不符合实际电站运行规则。抽蓄机组的启动过程复杂频繁启停会带来机械损耗和水力冲击实际调度中会限制最小连续运行时间。我在代码里加了状态锁存逻辑记录上一时段抽蓄的状态如果正在抽水则至少持续4个时段1小时才能切换为停机或发电。这个约束看起来简单但对结果的影响很大加了之后抽蓄状态曲线变得平滑更接近实际电站行为同时系统弃电率并没有明显上升。5.4 数值异常与可视化中文问题的处理仿真过程中最常见的数值问题是NaN和Inf。辐照度序列里偶尔会出现0甚至负值温度修正系数代入后可能产生异常数。我养成了一个习惯每个时段计算完功率后都做一次有限值检查发现NaN就打印当前时段和输入数据快速定位问题源头。功率单位也是经典错误源。风速单位m/s没问题但功率如果一部分用kW、一部分用MW最终结果可能离谱到几十万。处理方式是所有数据在读入后统一转成MW并且在函数注释里写明单位避免隔天跑代码时把自己绕晕。画图时中文字体问题前面提过提前配置字体列表就可以Windows下通常用SimHeiLinux下用WenQuanYi Micro Hei就能正常显示。5.5 调度优先级顺序写错的观察方法有个隐蔽的bug很难直接看出来调度函数里如果电池放电和抽蓄发电的优先级写反了系统在晚高峰会先调用抽蓄再调用电池最终结果也能跑通只是购电成本更高、弃电率变化不明显。这类逻辑bug用常规指标对比不容易发现我推荐额外画一张“储能动作状态图”用离散值记录每个时段各储能的具体动作0表示停机、1表示充电/抽水、2表示放电/发电。状态图一旦画出来逻辑顺序一目了然应该大部分时间电池在快速波动、抽蓄在平稳动作如果看到抽蓄频繁爬坡、电池长期闲置那优先级大概率写反了。学会用图表反向验证调度逻辑是这轮项目里最值得推荐的经验之一。最后再分享一个实用建议做这类研究时先跑通确定性仿真再考虑随机规划和不确定性分析。不要一上来就建复杂的随机优化模型否则出了问题你根本分不清是数据问题、模型约束问题还是求解器配置问题。把确定性模型的每个逻辑都验证扎实再考虑扩展进度反而更快。