# HearthNodes recipe 17 - dishwasher to the cheapest block
alias: "Energy - dishwasher waits for the cheapest two hours"
id: hn_energy_cheap_tariff_dishwasher
description: "Defer to the lowest mean-price 2 hour block of the next 14 hours"
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: binary_sensor.dishwasher_ready
to: "on"
variables:
horizon_h: 14
block_h: 2
prices: "{{ state_attr('sensor.day_ahead_prices','prices') }}"
best_block: "{{ prices | hn_cheapest_block(block_h, horizon_h) }}"
deadline: "{{ now() + timedelta(hours = horizon_h) }}"
condition:
- condition: template
value_template: "{{ prices is not none and prices | count > horizon_h * 4 }}"
- condition: state
entity_id: input_boolean.dishwasher_run_now
state: "off"
action:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.dishwasher_deadline
data:
datetime: "{{ deadline.isoformat() }}"
- service: notify.mobile_app_primary
data:
title: "Dishwasher scheduled"
message: >-
Running {{ best_block.start }} to {{ best_block.end }} at
{{ best_block.mean_price }} c/kWh
- wait_for_trigger:
- platform: time
at: "{{ best_block.start }}"
timeout: "{{ deadline - now() }}"
continue_on_timeout: true
- service: switch.turn_on
target:
entity_id: switch.dishwasher_socket
- wait_for_trigger:
- platform: numeric_state
entity_id: sensor.dishwasher_plug_power
below: 3
for: "00:20:00"
timeout: "03:00:00"
- service: switch.turn_off
target:
entity_id: switch.dishwasher_socket
# Deadline within 4 hours and no cheap block found -> run now regardless of price.
# The socket is only energised if the machine actually resumes after power-up;
# test that before relying on this method.
触发器 · state
binary_sensor.dishwasher_loaded
洗碗机门关闭并已选择程序,「可运行」按钮被按下。
分步说明
- switch.dishwasher_socket在选定区间的起点给洗碗机插座通电;程序本身由人在机器面板上设定。
turn_on at start of cheapest 2h block - input_datetime.dishwasher_deadline在按下按钮时记录截止时间,避免深夜按下后无声地滚到第二天。
set · press time + 14 h - notify.mobile_app通知中说明选定区间及其电价,让家人看得到这个决策,而不是猜为什么机器凌晨两点启动。
send · 'Running 02:00–04:00 at 11.4 ¢/kWh' - switch.dishwasher_socket循环结束后切断待机电源,同时也避免机器被长时间通电好几天。
cut power 20 min after programme end
优化的是区间,不是某一时刻
挑出最便宜的一小时很简单,但也是错的,因为洗碗机循环要 2–3 小时,可能跨过边界。应计算该时间范围内每一个连续两小时区间的平均电价,选均值最低的那个。在典型的一天里,这个方法与朴素做法相比会把启动时间挪动 40–90 分钟。
在配方里保留硬性截止
没有截止时间的推迟配方,迟早会因为整晚电价都高而让一家人没有干净盘子用。14 小时覆盖从夜间按下按钮到第二天晚饭。把截止写进触发器,而不是写进一条提醒。
确认机器在恢复供电后能续跑
很多洗碗机断电后不会继续程序,而是停在待机。在依赖插座方案之前先实测。如果你的机器不能续跑,就改用机器自带的延时启动,自动化只负责发送通知告诉你该设到几点。
硬件
| 型号 | 协议 | 连接 | 在本链路中的作用 |
|---|---|---|---|
| Zigbee smart plug rated 16 A with energy metering | zigbee |
无线 | 控制电器开合并确认循环确实取电;一台「启动了」但功率为 0 W 的洗碗机并没有真的运行。 |
| Day-ahead price feed (any tariff API) | wifi |
有线 | 每天 13:00 发布未来 24 小时电价;本配方只需其中未来 14 小时。 |
| Door contact on the dishwasher | zigbee |
无线 | 提供「已装载并关门」信号,为偏好免按钮的家庭替代手动按键。 |
失效时怎么办
如果电价数据源失效,洗碗机按家庭默认的 02:00 启动,而不是让碗一直没洗。如果距截止不足 3 小时且仍未出现便宜窗口,则立即以当前电价运行,因为第二天早上水槽里堆着脏碗,比 20 分钱的差价更糟。