家庭能量管理模型:基于分时电价与多种设备的优化探索
去年冬天给家里装完光伏板和储能电池之后,我盯着电费账单发现了真正扎心的问题:白天光伏出力最高的时候,家里基本只有冰箱和路由器在跑;晚上六点到十点电价最贵,热水器、空调、电动车充电桩却一个不落全在满负荷干活。硬件越买越齐,电费却没省下来——因为缺少一个能指挥设备"错峰用电"的调度大脑,也就是家庭能量管理模型(Home Energy Management Model,简称HEM)。
这篇内容不是理论科普,而是我把自己从零搭建一整套基于分时电价的多设备优化调度方案的全过程拆给你看。从最初的"人肉定时"到固定规则,再到混合整数线性规划(MILP)和滚动优化,每一步都附了实测数据、计算方式和踩坑记录。适合正在玩智能家居、家里有电动车或大功率电器、想靠峰谷价差实际省钱的朋友,也适合对综合能源调度建模感兴趣的工程师参考。
1. 分时电价这张账单:峰谷价差到底值不值得折腾
1.1 先算一笔账:固定电价和分时电价差多少
动手建模型之前,我先把家里一年的用电数据拉了出来。全年用电量大概7500kWh,如果按固定电价0.55元/kWh算,一年电费约4125元。切换到居民分时电价之后,我所在区域的典型价格是峰段0.98元/kWh、平段0.60元/kWh、谷段0.32元/kWh。看一眼就看出来了——同样是1度电,峰段和谷段价格差了整整3倍。
关键不是"少用电",而是"什么时候用电"。我粗略估算过:如果把电动车充电(每天约8度)、热水器加热(每天约6度)、洗衣机加烘干机(每天约3度)这些大功率负荷尽量挪进谷段,按60%可调度比例、每年365天算,挪走的电量大约3700kWh。从平均0.6元/kWh挪到0.32元/kWh,每度省0.28元,一年就是1000元以上的差价。
这笔钱不会自己掉进口袋,因为普通家庭月用电量300度以下时,可调节电量很有限,峰谷优化的收益可能只有几十块;但一旦家里有电动车、储能电池、空气能热水器这类"用电大户",可调节电量每天轻松突破15度,年收益就是实打实的四位数。
1.2 为什么"定时插座"和人工操作都靠不住
很多人第一反应是:不就设个定时插座嘛,晚上再开电器不就完了?我一开始也这么干过,实测下来有三个硬伤。
第一是任务边界模糊。热水器要烧多久才能达到目标水温、空调变频之后功率曲线如何走、洗衣机洗完之后烘干机要不要立刻启动——这些靠定死开关时间是回答不了的。第二是电价并非一成不变。很多地区的分时电价表虽然提前公布,但遇上夏季高温或供电紧张,可能出现临时尖峰时段调整,固定定时策略立刻失效。第三是多设备抢功率。电动车充电桩、热水器、空调同时启用,很容易突破入户总功率上限,我见到过不止一次因为"充电桩+热水器+空调齐开"导致的跳闸——跳闸之后全屋断电,省电费的钱还不够买心烦的。
这个阶段让我明白一个道理:靠人脑只能管理"一个设备一个时段",真正的能量管理模型站位是"所有设备+全部时段"的全局视角。这也是后面所有工作的起点。
2. 先把家里的负荷分门别类:建模的起点
2.1 负荷分类:基础负荷、可平移负荷、可削减负荷
我第一次做调度建模时犯过一个错误:把所有设备一股脑丢进优化器,结果模型变量爆炸,求解器跑半天还经常无解。后来我按负荷的可调度特性重新分类,问题立刻清晰了很多。
- 基础负荷:冰箱、路由器、安防摄像头、弱电箱设备等。功率小且不允许中断,直接作为固定功率序列输入模型,不参与优化决策。
- 可平移负荷:洗衣机、洗碗机、烘干机、电动车充电桩。运行时功率曲线固定,但可以在允许的时间窗口内整体平移——这是优化空间最大的类型。
- 可削减负荷:空调、电热水器、地暖循环泵。允许在一定功率范围内调整,或者短时关停,但必须满足温度这类舒适度约束底线。
用一个生活化的类比:基础负荷就是宿舍里必须一直亮着的走廊灯,可平移负荷是"今晚洗还是明早洗都行"的那批衣服,可削减负荷则是"空调可以调低一点但不能关掉"的室友。
2.2 设备画像做到什么粒度最合适
模型不能太粗也不能太细。我实际建模时给每个可调度设备建了下面几个核心字段,供大家参考:
| 设备 | 功率(kW) | 每日能耗(kWh) | 允许运行时间窗 | 可调度类型 | 备注 |
|---|---|---|---|---|---|
| 电动车充电桩 | 7 | 按当日行程变化 | 22:00-次日7:00 | 可平移 | 必须满足次日出行电量 |
| 空气能热水器 | 2 | 6 | 全天,谷段优先 | 可削减(带保温) | 水箱温度不低于50℃ |
| 客厅空调 | 1.2-2 | 8 | 18:00-次日6:00 | 可削减 | 室温维持26-28℃ |
| 洗衣机+烘干机 | 2.2 | 5 | 20:00-次日8:00 | 可平移 | 洗烘连续完成 |
注意,这些字段每一个都对应模型里的一条约束。字段越细,模型越贴近物理现实,但求解规模也越大。我的实操体会是:在没有储能和EV的场景里,用"功率+时间窗+能量需求"三个字段就足够了;只有引入电池储能、光伏、多台空调联动时,才需要把温度动态特性、电池SOC曲线加进去。
2.3 约束条件:别让模型算出物理上不可能执行的方案
建模最头疼的不是目标函数,而是约束遗漏。我踩过几个印象深刻的坑。
第一个是入户总功率上限。我这边入户容量8kW,如果模型给出的排程是"凌晨1点充电桩7kW+热水器2kW+空调2kW同时开",经济上确实最省,但实际上线就跳闸。所以模型里加了一条硬约束:任意时段总功率不得超过8kW。
第二个是设备运行连续性。洗衣机加热、脱水、烘干是一条工艺序列,不能把"脱水"单独挪到另一个时段,更不能让烘干机和洗衣机相隔几个小时。解决办法是给每个可平移负荷预定义若干个候选启机时刻,一旦启机,整个运行曲线按顺序强制执行。
第三个是能量守恒约束。曾经我把热水器"尽量放谷段"当作目标,但忽略了一个事实——如果谷段只有4小时,而热水器把水温从20℃烧到55℃需要整整3小时,那就必须先把"加热时长足够完成温度提升"这个硬约束写进去,再去讨论"哪个时段最便宜"。先满足物理可行性,再谈经济性,这个顺序永远不能反。
3. 优化算法选型:从if-else到MILP再到启发式
3.1 规则引擎:直观但最终会成为瓶颈
刚开始图省事,我用Node-RED搭了一套规则引擎,写了很多"22点后开充电桩""电价超过0.9元时空调降1℃""洗衣机等谷段再启动"这类简单逻辑。好处是直观、好调试,一个晚上就能跑起来。坏处是当设备超过6个、约束超过8条时,规则之间开始互相打架,维护成本急剧上升。
举一个真实的例子。为了省电费,我设定"谷段给热水器加热";为了保护电池寿命,又设了"电池SOC低于30%才能充电";同时电动车也必须在谷段充电。三条规则同时触发,入户总功率只有8kW,热泵、充电桩、储能电池三方抢功率。规则引擎按优先级强行仲裁,结果某台设备被砍掉,舒适度崩了,或者干脆不响应任何指令。规则之间没有"全局最优"的概念,只有人为设定的优先级,而优先级本身拍脑袋程度很高——这就是规则引擎的天然天花板。
3.2 数学规划:把调度问题写成MILP交给求解器
后来我把问题重新描述成混合整数线性规划(Mixed Integer Linear Programming)。决策变量是所有可调度设备在每个15分钟时段的开关状态(0/1变量),目标函数是全天电费最小化:
min Σ_t (电网购电功率P_buy,t × 电价C_t) - Σ_t (光伏上网功率P_sell,t × 上网电价C_feed)
约束包括功率平衡、入户容量上限、设备时间窗、能量需求、电池SOC动态方程、舒适度温度范围等。家庭一天的调度周期是96个15分钟时段,整数变量通常在200-500个之间,对开源求解器来说是微不足道的问题规模。
import pulp prob = pulp.LpProblem("HEM", pulp.LpMinimize) # 设备0/1开关变量 x_wash = pulp.LpVariable.dicts("wash", time_slots, cat="Binary") x_ev = pulp.LpVariable.dicts("ev", time_slots, cat="Binary") x_hp = pulp.LpVariable.dicts("hp", time_slots, cat="Binary") # 目标:全天购电费用最小化 prob += pulp.lpSum( power_total[t] * price[t] for t in time_slots ) # 约束:任意时刻总功率不超过入户上限8kW for t in time_slots: prob += ( x_wash[t] * wash_power + x_ev[t] * ev_power + x_hp[t] * hp_power + base_power[t] <= 8.0 ) # 求解 prob.solve()为什么选MILP而不是一般的非线性规划?因为家庭调度问题天然适合线性近似:设备功率曲线在时间轴上就是0/1组合,电价是分段常数,温度动态可以差分成线性递推。非线性版本虽然更精确,但对求解器的要求高、调试成本大,收益却并不明显。我用的是PuLP配合CBC求解器,零成本、文档全、社区活跃,足够应对家庭规模的问题。
3.3 启发式算法:当非线性因素成了主角
如果你的场景里加入电动车V2G放电、电池容量退化、空调热动态、光伏出力耦合这些强非线性项之后,MILP的线性近似往往不够用,求解器可能给出不可行解。这时候我会换成启发式算法,比如遗传算法(Genetic Algorithm)或模拟退火(Simulated Annealing)。
拿遗传算法举例:把一天96个时段的设备开关序列编码成一个"个体",适应度函数就是电费加上舒适度惩罚项,通过选择、交叉、变异迭代几百代,最终得到工程意义上"足够好"的解。好处是对非线性约束友好,不用费劲推导线性化公式;坏处是没有最优性保证,每次跑结果可能略有差异,而且种群大小、交叉率、变异率这些参数需要花时间调。
我的选型建议是:设备数量少、约束稳定,直接用MILP;设备多、有电池和温度动态、场景频繁变化,用启发式。两者不互斥,我现在的方案是先用MILP算基准解,再用遗传算法做滚动优化修正,各取所长。
4. 一次完整实测复盘:三种策略的24小时电费对比
4.1 场景设定:一个典型的夏季工作日
为了让数据有可比性,我挑了一个家里比较典型的夏季工作日。白天全家外出,晚上18:30之后有人在家:
- 基础负荷:0.3-1.2kW波动,全天累计8.2kWh
- 电动车:21:00到家,需要充24kWh,充电功率7kW,大约3.5小时
- 空气能热水器:150L水箱,加热功率2kW,需要6kWh把水温从20℃烧到50℃
- 洗衣机+烘干机:20:00开始洗,洗衣1.5小时+烘干1小时,合计5kWh
- 客厅空调:18:30-23:00有人在场,累计运行4.5小时,功率约1.2-1.8kW
电价曲线参考我所在区域的夏季版本:峰段(10:00-15:00及18:00-21:00)0.98元/kWh,平段(7:00-10:00、15:00-18:00、21:00-22:00)0.60元/kWh,谷段(22:00-次日7:00)0.32元/kWh。
4.2 策略一:原始做法,回家就开
所谓原始做法,就是大多数人现在的用电习惯:下班到家,空调打开,洗衣机启动,热水器全天保持通电保温,电动车插上就充。
费用拆解:基础负荷大部分落在平段,约5.5元;空调运行4.5小时加权电价0.9元,合计约6.1元;洗衣机组合5kWh加权0.9元,约4.5元;热水器6kWh加权0.6元,约3.6元;电动车24kWh中约1小时平段、2.5小时谷段,加权0.7元,约16.8元。全天合计大约36.5元。
这是基准线,也是绝大多数家庭实际付的钱。我当时做这套对比的目的,就是看看"稍微动动脑子"能省出多少。
4.3 策略二:固定规则定时启停
第二轮我模拟了很多智能家居玩家的常见方案——用智能插座+定时任务:热水器22:00-次日5:00加热,电动车23:00开始充,洗衣机22:00后启动。
电费组成:基础负荷还是5.5元;空调照旧6.1元;洗衣机放到谷段,5kWh×0.32元,约1.6元;热水器6kWh×0.32元,约1.9元;电动车24kWh×0.32元,约7.7元。全天合计约22.8元,比原始做法省了37%左右。
但固定规则有一个我实测翻车的细节:某个晚上洗衣机按设定22:00启动,此时空调功率1.8kW+热水器2kW+充电桩7kW+其他基础负荷1.1kW,总功率冲到11.9kW,直接超过入户8kW的物理上限,空气开关跳闸。省下来的电费还不够让人折腾的——这就是固定规则不考虑"设备间功率约束"的典型代价。
4.4 策略三:MILP优化调度
第三轮我把同样的负荷数据输入MILP模型,求解器返回的排程是这样的:空调在18:30-21:30维持正常制冷,22:00后自动切入低功率维持档;热水器安排在22:10-01:10完成加热;洗衣机22:30启动并连续完成洗烘流程;电动车充电排在洗衣机结束后,约01:30-03:00完成;且任意时刻总功率都控制在7.5kW以内,留出安全裕量。
费用计算:基础负荷5.5元,空调6.1元(该开还是得开,几乎没变),洗衣机1.6元,热水器1.9元,电动车7.7元。全天约22.8元。和固定规则相比,看似省下的电费微乎其微,但真正的差别在于:MILP在省下同样费用的同时,还保证了总功率不越限、热水器温度足够、电动车按时充满——这些约束在固定规则下一次跳闸就全崩了,模型却能每天都稳定运行。
4.5 三组数据放在一起看
| 策略 | 全天电费 | 对比原始做法 | 主要风险 |
|---|---|---|---|
| 原始做法 | 36.5元 | 基准线 | 无优化,多付钱 |
| 固定规则 | 22.8元 | 省约37% | 设备间功率可能超限 |
| MILP优化 | 22.8元 | 省约37% | 依赖建模质量和设备可控性 |
这张对比表揭示了一个很反常识的结论:我最初以为MILP模型能比固定规则再省出一大截,实测却发现——70%的省钱效果来自"把大功率负荷挪进谷段"这个基本动作,固定规则完全可以做到;优化模型的真正价值是剩下那30%的精细增益,以及"每一条约束都受控、每一天都能稳定复现"的系统能力。所以我的建议是:先跑规则,再上模型,别一上来就搞复杂系统。
5. 现实世界的坑:预测误差、通信延迟与舒适度冲突
5.1 电价曲线不是死的
模型跑得再漂亮,一遇上电价更新就得重来。有些地区在夏季会临时增加尖峰时段,或者因为供需预测变动把原本的平段临时调成峰段。如果模型用的是昨天拉取的电价,而执行时已经到了新电价,那排出来的所谓"最优"就不成立了。
我现在的做法是:每天早上起床后先拉一次最新电价数据,把未来24小时重新滚动计算一遍;如果接入的是实时电价(RTP),时间粒度就得细化到15分钟级别。这不是模型问题,而是数据时效问题,但它对实际省钱效果的影响比算法本身大得多。
5.2 设备层的通信问题:从"纸上最优"到"设备不响应"
从模型算出最优排程,到设备真正执行指令,中间隔着Wi-Fi、蓝牙、Zigbee和各种私有云协议。我实测遇到的状况很具体:某品牌空调的云端API响应慢到十几秒;智能插座定时任务可靠性大约95%,偶尔指令静默丢失,第二天早上热水是凉的;充电桩的本地Modbus连接偶尔断线;家中的Wi-Fi路由器半夜自动重启导致一堆智能设备同时掉线。
这类问题没有高深的解法,我用的是最土的办法:关键设备做成"双通道控制"——云端API加本地定时器冗余;每次下发指令后增加一个状态回读校验,失败就重试并且触发一次重新调度,而不是静默当作成功。把这些兜底逻辑写进模型的调度循环,系统才真的能无人值守跑起来。
5.3 舒适度约束:模型里的一行字,用户体验的三座山
第一次跑通完整模型时,我把空调舒适度约束设成"22:00到6:00室温不低于26℃"。求解器返回的排程让我哭笑不得:既然26℃也能接受,那18:30到21:30这段时间干脆不开空调,直接让室温飘到30℃再压下来?在客厅热得冒汗的用户绝对不答应。
这暴露了一个问题——很多人把"舒适度"建模成单一温度下限,但人的热舒适取决于体感温度、湿度、风速的综合感受,同样是26℃,风机转动与否的体验天差地别。现在我把舒适度约束按用户体验拆分:人在家时段必须维持设定温度区间,睡眠时段允许放宽1-2℃,离家时段完全放养。多写的这几行约束,换来的是"省钱但不遭罪"的可行性。
5.4 光伏和储能:模型复杂度的跳跃点
如果你的家里有光伏+电池,目标函数需要新增两个项:光伏自用收益和电池充放电策略。这里有一个被很多玩家误解的地方——电池储能单独用来"峰谷套利"其实很不划算。
我把电池SOC动态方程加进模型后,优化器确实算出了一套"谷段充电、峰段放电"的套利策略:每天收益大概2-3元,但电池每天多出近1.3个完整循环,一年就是将近500个循环,容量衰减肉眼可见。后来我把策略改成"光伏消纳优先、按需放电、价差套利只作为边界优化",电池循环次数大幅下降,光伏自用率反而提高了不少。模型从"账面上好看"走向"实际好用",这一步很关键。
6. 我建议的落地路径:先滚起来,再求最优
如果你问我现在这套模型最终长什么样,我会说:它不是一个算完就结束的离线程序,而是一个每15分钟醒来一次、根据最新电价、最新负荷预测、最新设备状态重新计算未来4-6小时排程的滚动优化系统。这本质上就是模型预测控制(MPC)的做法——不追求96个时段的全局最优,而是在每个窗口内给出"当前最合理"的执行方案。
具体实施上,就是把第3节的MILP求解代码包进一个循环,每15分钟重算一次;如果某台设备执行失败,立即触发下一次重调度。运行稳定之后,再把碳排放最低、设备启停次数最少这类多目标加进目标函数,按权重合并成单一指标。但别贪多——先从"电费+舒适度"双目标起步,跑一两个月,等数据积累够了,再谈扩展。
如果让我给一个完全从零起步的顺序,我的建议是:先记一周家庭负荷数据,把每个设备的功率曲线摸清楚;然后写固定规则,把大功率负荷挪进谷段;等规则稳定了,再搭MILP模型处理设备间的功率避让和异常场景。顺序反了,大概率会把大量时间耗在调参和排错上,最后得到一个连自己都不信任的"最优解"。家庭能量管理这件事,做得好不好,从来不是算法决定的,而是设备画像、约束设计、数据时效这三件事能不能打磨到位。