气象数据

极端天气下的风光出力冲击与运行预案:ERA5 复盘 + 德国气象局预警实战

· 南京运梦科技算法团队 · 评审 算法负责人

极端天气下的风光出力冲击与运行预案:ERA5 复盘 + 德国气象局预警实战 封面

寒潮压境、台风过境、梅雨连阴、还有那种让风机集体停转的「无风小风」天气——对火电场站来说这些只是值班表上多写几句,但对一座风电场或光伏电站,它们直接决定了当天的发电量、考核电量偏差,甚至整场的并网安全。新能源的「靠天吃饭」属性,本质上是把气象不确定性原封不动地传导到了功率曲线上。本文不谈宏观气候,而是从运行视角出发:用 ERA5 把历史上真实发生过的极端事件逐小时复盘清楚,用德国气象局(DWD)的未来约 7 天预报提前把预警拉响,并把这两件事落到可以写进调度手册的量化口径与运行预案里。

关键要点

  • 极端天气对风光出力至少要拆成四种机理不同的故障模式:寒潮(覆冰 + 高风速切出)、台风(满发到零的避险停机)、连续阴雨(光伏 rsds 长期衰减)、无风小风(区域性大面积低出力)。
  • ERA5 是 ECMWF 第五代再分析数据集,逐小时、0.25° 网格、覆盖 1940 年至今(约滞后 5 天),在运梦气象 API 里对应 dataSourceId="era5",是历史复盘的事实标准。
  • 德国气象局(DWD)预报对应 dataSourceId="ger",覆盖未来约 7 天,字段口径与 ERA5 完全一致,因此历史复盘训练出的事件判据可原样套用在预报上。
  • 务实口径:48 小时内的预报用于触发硬动作(停机、除冰),48 小时外仅用于趋势研判与备用规划;并用 ERA5 复盘出本场的预报偏差订正系数(bias correction)。
  • 轮毂风速应优先用 100m 风分量合成 sqrt(u100² + v100²) 再外推,直接拿 10m 风外推会系统性低估,复盘台风高风速段尤其失真。

四类极端天气,四种完全不同的出力故障模式

很多团队习惯把「极端天气」当成一个笼统的风险标签,但对风光出力而言,它至少要拆成四种机理完全不同的故障模式,预案也完全不同。

寒潮 的杀伤点是双重的。一方面强冷空气过境往往伴随大风,风电出力短时冲高,可能触发高风速切出(典型机型 25 m/s 切出,部分新机型有降功率运行段);另一方面低温会带来叶片覆冰、电气元件低温保护、光伏组件玻璃结霜与积雪遮挡。覆冰导致的功率损失常常不是「停机」这种干脆的状态,而是叶片气动外形被破坏后效率缓慢下降,功率曲线整体下移,最难预测也最难量化。复盘寒潮要同时盯住 tas(气温,判断结冰窗口)、ws/u100/v100(风速与切出)、pr(降水相态决定是否覆冰)。

台风 是风电最经典的极端场景。台风外围环流先带来一段高出力,眼墙逼近时风速越过切出阈值,全场可能在十几分钟内从满发跌到零;台风眼经过时风速骤降又骤升,机组反复启停对传动链是实打实的疲劳损伤。光伏侧则因厚云和强降水,rsds(地表短波辐射,GHI)断崖式下跌。台风的运行预案核心不是「预测发多少电」,而是「预测什么时候必须主动停机避险、什么时候可以恢复」。

连续阴雨(梅雨、华西秋雨)主要打击光伏。rsds 在连阴天可以连续多日维持在晴天的 20%–40%,dni(法向直接辐射)几乎归零、dhi(散射辐射)占比飙升,固定式与跟踪式阵列的出力差异在此时被显著压缩。这类事件持续时间长、强度不极端,但累计电量损失巨大,且容易在月度考核里造成系统性偏差。

无风小风 是最容易被低估的一类。大范围、长持续的静稳天气会让整片区域的风电同时趴窝,这不是单场问题而是系统性的「新能源大面积低出力」事件,对电网备用容量的考验远超台风(台风至少是局地、可预期的)。复盘无风小风,重点看 u100/v100 合成的轮毂高度风速长时间低于切入风速(典型 3 m/s)的持续小时数。

用 ERA5 把历史极端事件复盘清楚

预案不能拍脑袋,必须建立在历史样本上。ERA5 是 ECMWF 第五代再分析数据集,逐小时、0.25° 网格、覆盖 1940 年至今(约滞后 5 天),是做历史复盘的事实标准——它已经把卫星、地面站、探空等多源观测同化成物理一致的网格场,比单站插值更稳健。在运梦气象 API 里,历史数据对应 dataSourceId="era5",字段沿用 CF 命名约定。

复盘的标准动作是:先用站点坐标拉取目标年份逐小时的 taswsu100v100rsdsprdnidhi,再按上一节的四类机理定义事件判据。几个可直接落地的工程口径:

  • 轮毂高度风速重构:ERA5 的 10m 风(uas/vas)不能直接当轮毂风速用,应优先用 100m 风分量合成 sqrt(u100² + v100²),再用幂律或对数律外推到实际轮毂高度(如 90/110/140 m)。直接拿 10m 风外推会系统性低估,复盘台风高风速段尤其失真。
  • 覆冰窗口判据tas 在 -5℃ 到 2℃ 之间且 pr > 0、相对湿度 hurs 高,标记为潜在覆冰小时。复盘时统计这些小时占当月发电小时的比例,就能量化覆冰对容量系数的拖累。
  • 辐射衰减率:把连阴雨期间逐小时 rsds 与同期晴空理论辐射(可用 clear-sky 模型或历史同分位)做比值,得到「辐射保留率」,这是把光伏电量损失量化进月度报表最直接的指标。
  • 大面积低出力事件:把多个风电场坐标的轮毂风速时间序列对齐,统计「全网同时低于切入风速」的连续小时数分布,用来给电网备用容量配置提供历史依据。

复盘的产出不只是几张图,而是一组可以写进系统的阈值与概率:本场历史上 25 m/s 切出累计多少小时、覆冰季容量系数比正常月下降多少个百分点、连阴雨导致的单次最大累计电量损失是多少 MWh。这些数字直接对接国家「两个细则」下的考核口径——预测偏差的罚分,本质上就是没把这些极端段提前算进功率曲线。

用德国气象局预报把预警提前拉响

复盘解决「认识风险」,预警解决「提前动作」。运梦气象 API 的预报数据使用德国气象局(DWD)数值预报,对应 dataSourceId="ger",覆盖未来约 7 天,字段口径与 ERA5 完全一致——这点对工程很关键:历史复盘训练出的事件判据,可以原样套用在预报数据上,无需重写换名逻辑。

预警的工程实现是把复盘阶段定下的判据,套在滚动更新的预报序列上:

  • 台风大风预警:当未来 72 小时内合成风速预测越过切出阈值,提前生成「计划性停机/降功率」工单,并据此修正上报给调度的功率预测曲线,避免被动停机带来的偏差罚分。
  • 寒潮覆冰预警:用预报的 tas + pr + hurs 命中覆冰窗口时,提前安排叶片加热或除冰预案,并下调对应时段的预测出力。
  • 连阴雨预警:用预报 rsds/dni 的多日衰减提前重估光伏电量,给运营做月度电量兜底测算。
  • 无风小风预警:用预报风速的区域同步低值,提前向调度报送低出力时段,配合备用机组安排。

权衡上要诚实:约 7 天的预报,前 24–48 小时可信度高,越往后不确定性越大。务实做法是把预报当成「概率提示」而非「确定值」——48 小时内用于触发硬动作(停机、除冰),48 小时外仅用于趋势研判与备用规划。同时强烈建议用 ERA5 历史复盘出本场的预报偏差订正系数(bias correction),把 DWD 的网格预报订正到本场实际,再喂给功率预测模型。

在运梦气象 API 上手

下面用一段可运行的 Python,演示一次台风大风事件的复盘:拉取 ERA5 历史逐小时风速分量,合成轮毂高度风速,统计越过切出阈值的小时数。换预报只需把 dataSourceId 改成 ger 并把时间窗换到未来,判据逻辑完全复用。

import os
import math
import requests

API = "https://console.yun-meng.top/api/energy-weather/search/weather/action/downloadSync"
TOKEN = os.environ["YUNMENG_TOKEN"]  # 注册即得,免在代码里硬编码

payload = {
    "dataSourceId": "era5",            # 历史复盘用 era5;未来预警改成 ger
    "lat": 30.5, "lon": 122.0,         # 东海某海上风电场附近
    "stime": "2021-07-20 00:00",       # 复盘一次台风过程
    "etime": "2021-07-28 23:00",
    "fields": ["u100", "v100", "tas", "pr", "rsds"],
    "timezone": "8",                   # 必填,时区偏移,东八区
}

resp = requests.post(
    API,
    headers={"Authorization": f"Bearer {TOKEN}"},
    json=payload,
    timeout=600,
)
resp.raise_for_status()

result = resp.json()                   # 统一 JSON envelope,无 CSV/NetCDF
if not result.get("success"):
    raise RuntimeError(result.get("msg", "查询失败"))

data = result["data"]
times = data["timeList"]
u100, v100 = data["u100"], data["v100"]

CUT_OUT = 25.0   # 切出风速 m/s
ALPHA = 0.11     # 海上幂律指数,u100/v100 已是 100m 风,这里再外推到 110m 轮毂
HUB = 110.0

cut_out_hours = 0
peak_ws = 0.0
for t, u, v in zip(times, u100, v100):
    ws100 = math.hypot(u, v)
    ws_hub = ws100 * (HUB / 100.0) ** ALPHA   # 幂律外推到轮毂高度
    peak_ws = max(peak_ws, ws_hub)
    if ws_hub >= CUT_OUT:
        cut_out_hours += 1
        print(f"{t}  轮毂风速={ws_hub:.1f} m/s  >= 切出,需停机避险")

print(f"过程峰值轮毂风速 {peak_ws:.1f} m/s,累计触发切出 {cut_out_hours} 小时")

要点:响应是统一 JSON envelope,必须用 resp.json() 解析后取 result["data"],再按字段名取 data["timeList"]data["u100"] 等等长数组,下标一一对应——接口不返回 CSV 或 NetCDF,也没有 format 参数。把这段逻辑封装成函数后,历史复盘(era5)与未来预警(ger)就是同一套代码、不同数据源,这正是 ERA5 与德国气象局字段口径统一带来的工程红利。

收尾:把气象数据变成调度手册里的硬动作

极端天气治理的闭环是「复盘定阈值、预报触动作、事后再回测」。ERA5 让你知道本场历史上极端事件的真实强度与频次,德国气象局让你在未来约 7 天里提前一步;中间的桥梁,是用历史订正预报、用统一字段口径让两端代码复用。当你能把「台风将在 36 小时后越过切出风速、需提前 6 小时降功率」这类判断写进系统、自动生成工单并修正上报曲线时,气象数据就不再是事后解释偏差的借口,而是真正降低考核罚分、保障并网安全的运行能力。建议从一两类对本场最致命的事件入手,先把判据和阈值跑通,再逐步覆盖四类场景。

常见问题

极端天气下风光出力的故障模式有哪些? 至少要拆成四类机理完全不同的模式:寒潮(叶片覆冰 + 低温保护 + 高风速切出)、台风(风速越过切出阈值导致从满发跌到零、需主动停机避险)、连续阴雨(光伏 rsds 长期维持在晴天的 20%–40%,累计电量损失巨大)、无风小风(大范围静稳天气导致区域性大面积低出力)。每类预案完全不同。

用 ERA5 复盘极端天气该看哪些气象字段? 按四类机理选字段:寒潮同时盯 tas(结冰窗口)、ws/u100/v100(风速与切出)、pr(降水相态);台风看合成风速与 rsds;连阴雨看 rsdsdnidhi;无风小风看 u100/v100 合成的轮毂风速低于切入风速(典型 3 m/s)的持续小时数。

为什么不能直接用 ERA5 的 10m 风当轮毂风速? ERA5 的 10m 风(uas/vas)直接外推会系统性低估,复盘台风高风速段尤其失真。应优先用 100m 风分量合成 sqrt(u100² + v100²),再用幂律或对数律外推到实际轮毂高度(如 90/110/140 m)。

德国气象局预报能提前多久预警,可信度如何? 覆盖未来约 7 天。前 24–48 小时可信度高,越往后不确定性越大。务实做法是把预报当成「概率提示」:48 小时内用于触发硬动作(停机、除冰),48 小时外仅用于趋势研判与备用规划,并建议用 ERA5 复盘出本场的预报偏差订正系数把网格预报订正到本场实际。

历史复盘和未来预警的代码能复用吗? 能。运梦气象 API 里历史数据用 dataSourceId="era5"、预报用 dataSourceId="ger",两者字段口径完全一致。把拉取与判据逻辑封装成函数后,历史复盘与未来预警就是同一套代码、不同数据源,无需重写换名逻辑。

参考与延伸阅读