第一章:削峰填谷算法基础 — 从原理到代码落地

各位同学好,我是老张。在电力系统干了十几年,从变电站值班到储能项目设计,踩过的坑不少。今天咱们聊的「削峰填谷」,说白了就是利用储能系统在电价低时充电、电价高时放电,赚取价差。听起来简单吧?但实际落地时,算法怎么写、参数怎么调,门道可不少。

我个人习惯把这类问题拆成三步:策略定义 → 逻辑实现 → 收益计算。这一章咱们就围绕这三步,把基础算法讲透。

1.1 固定时间段充放电策略

这是最直观的策略。你想想看,电网的峰谷时段通常是固定的。比如:

  • 谷时段:00:00 - 08:00,电价 0.3 元/kWh
  • 峰时段:10:00 - 12:00、14:00 - 16:00,电价 1.2 元/kWh
  • 平时段:其余时间,电价 0.7 元/kWh

那策略就很简单:谷时段充电,峰时段放电,平时段不动作。我在早期做的一个工业园区项目里,就是用的这种策略。当时业主说「别整太复杂,能省钱就行」——嗯,这种场景下固定时段策略完全够用。

核心逻辑: 根据当前时间判断所属时段,执行对应的充放电动作。

代码实现如下:

def fixed_time_strategy(current_hour, soc, battery_capacity):
    """
    固定时间段策略
    :param current_hour: 当前小时 (0-23)
    :param soc: 当前荷电状态 (0-1)
    :param battery_capacity: 电池容量 (kWh)
    :return: 充放电功率 (kW),正为充电,负为放电
    """
    # 谷时段:充电
    if current_hour in [0,1,2,3,4,5,6,7]:
        if soc < 0.9:  # 留10%余量
            return 0.5 * battery_capacity  # 0.5C充电
        else:
            return 0
    # 峰时段:放电
    elif current_hour in [10,11,14,15]:
        if soc > 0.2:  # 保留20%底线
            return -0.5 * battery_capacity  # 0.5C放电
        else:
            return 0
    # 平时段:不动作
    else:
        return 0

这里有个细节:为什么要留余量? 我在项目中遇到过,电池SOC冲到100%后,如果电网突然波动,BMS会强制停机。所以建议充电上限设90%,放电下限设20%。

1.2 阈值触发策略

固定时段策略有个硬伤:如果某天电价波动异常,或者电网负荷特殊,它不会灵活调整。这时候就需要阈值触发策略。

说白了,就是设定一个电价阈值:电价高于阈值就放电,低于阈值就充电。这个阈值怎么定?我一般用历史电价的80%分位数作为放电阈值,20%分位数作为充电阈值。

小技巧: 阈值可以动态调整。比如每周重新计算一次分位数,适应季节性变化。

代码实现:

def threshold_strategy(current_price, charge_threshold, discharge_threshold, soc):
    """
    阈值触发策略
    :param current_price: 当前电价 (元/kWh)
    :param charge_threshold: 充电阈值
    :param discharge_threshold: 放电阈值
    :param soc: 当前荷电状态
    :return: 充放电功率
    """
    # 电价低,充电
    if current_price <= charge_threshold and soc < 0.9:
        return 0.5 * battery_capacity
    # 电价高,放电
    elif current_price >= discharge_threshold and soc > 0.2:
        return -0.5 * battery_capacity
    else:
        return 0

你可能会问:两个策略哪个好?我的经验是:固定时段策略适合峰谷价差稳定、时段分明的场景;阈值策略适合电价波动大、有现货市场的场景。比如广东的电力现货市场,电价一天能变几十次,阈值策略就明显更优。

1.3 收益计算函数

策略写好了,怎么算赚了多少钱?收益计算其实就一个公式:

收益 = 放电收入 - 充电成本 - 电池损耗成本

其中电池损耗成本容易被忽略。我记得有个项目,业主只看充放电价差,觉得稳赚不赔。结果运行一年后,电池容量衰减了15%,换电池的费用把利润全吃掉了。所以咱们做收益测算时,一定要把循环寿命成本算进去。

完整收益计算函数:

def calculate_profit(charge_energy, discharge_energy, charge_price, discharge_price, 
                     battery_cost_per_kwh, cycle_life):
    """
    计算净收益
    :param charge_energy: 充电量 (kWh)
    :param discharge_energy: 放电量 (kWh)
    :param charge_price: 平均充电电价 (元/kWh)
    :param discharge_price: 平均放电电价 (元/kWh)
    :param battery_cost_per_kwh: 电池每kWh成本 (元)
    :param cycle_life: 电池循环寿命 (次)
    :return: 净收益 (元)
    """
    # 充放电收入
    income = discharge_energy * discharge_price
    # 充电成本
    cost_charge = charge_energy * charge_price
    # 电池损耗成本:每充放1kWh,损耗电池寿命的1/cycle_life
    cost_degradation = (charge_energy + discharge_energy) / 2 * (battery_cost_per_kwh / cycle_life)
    
    net_profit = income - cost_charge - cost_degradation
    return net_profit
注意: 电池损耗成本的计算方式有很多种,这里用的是线性简化模型。实际项目中,建议用雨流计数法或基于SOC变化量的非线性模型,更准确。

1.4 知识体系总览

下面这张图把本章的核心逻辑串起来了。我画图时习惯用流程图,因为一眼就能看出数据怎么流动、决策怎么分支。

削峰填谷算法基础 — 知识体系 输入数据 策略选择 固定时段策略 阈值触发策略 动态优化策略 收益计算函数 净收益 / 策略评估

从图中可以看到,输入数据(电价、时段、SOC)经过策略选择,最终通过收益计算函数输出结果。本章我们实现了固定时段和阈值触发两种策略,动态优化策略会在后续章节展开。

1.5 本章小结

嗯,这一章咱们把基础打牢了。核心就三件事:

  • 固定时段策略:简单可靠,适合峰谷分明的场景
  • 阈值触发策略:灵活适应,适合电价波动大的市场
  • 收益计算函数:别忘了算电池损耗成本,否则账面好看实际亏钱

我在实际项目中,经常把这两种策略组合使用:平时用固定时段,遇到电价异常波动时切换到阈值触发。代码里加个判断条件就行,不复杂。

下一章咱们会聊「动态规划在储能调度中的应用」,那才是真正考验算法功底的地方。不过别急,先把今天的内容消化掉——代码跑一遍,看看不同参数下收益怎么变,你会有新发现的。


公众号:蓝海资料掘金营,微信deep3321