# HearthNodes recipe 24 - rainwater tank top-up
alias: "Water - tank top-up and pump protection"
id: hn_water_tank_topup
description: "Hold 40-85 percent, top up only in the cheap night window"
mode: single
max_exceeded: silent
trigger:
- platform: numeric_state
entity_id: sensor.rain_tank_level
below: 42
id: low
- platform: numeric_state
entity_id: sensor.rain_tank_level
above: 84
id: high
- platform: numeric_state
entity_id: sensor.rain_tank_level
below: 15
id: pump_danger
variables:
topup_valve: valve.mains_topup
pump: switch.tank_pump
pump_cut_pct: 15
pump_restore_pct: 25
topup_stop_pct: 85
max_topup_min: 90
condition:
- condition: template
value_template: >-
{{ (now() - states.sensor.rain_tank_level.last_updated).total_seconds() < 21600 }}
- condition: state
entity_id: binary_sensor.irrigation_running
state: "off"
action:
- choose:
- conditions:
- condition: trigger
id: pump_danger
sequence:
- service: switch.turn_off
target:
entity_id: "{{ pump }}"
- service: input_boolean.turn_on
target:
entity_id: input_boolean.tank_pump_lockout
- service: notify.mobile_app
data:
title: "Tank pump locked out"
message: >-
Level {{ states('sensor.rain_tank_level') }} percent.
Clears above {{ pump_restore_pct }} percent.
- conditions:
- condition: trigger
id: high
sequence:
- service: valve.close_valve
target:
entity_id: "{{ topup_valve }}"
- conditions:
- condition: trigger
id: low
sequence:
- if:
- condition: numeric_state
entity_id: sensor.rain_forecast_24h_mm
below: 2
then:
- service: valve.open_valve
target:
entity_id: "{{ topup_valve }}"
- wait_for_trigger:
- platform: numeric_state
entity_id: sensor.rain_tank_level
above: "{{ topup_stop_pct }}"
timeout:
minutes: "{{ max_topup_min }}"
continue_on_timeout: true
- service: valve.close_valve
target:
entity_id: "{{ topup_valve }}"
else:
- service: logbook.log
data:
name: "top-up deferred"
message: "rain forecast within 24 h"
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.rain_tank_level
above: "{{ pump_restore_pct }}"
sequence:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.tank_pump_lockout
# Probe silent beyond 6 hours -> top-up disabled entirely, pump lockout held: the
# safe state is a partly full tank, never an overflowing one. A reading unchanged
# for 24 hours raises a probe-suspect flag instead of being trusted.
触发器 · numeric_state
sensor.rain_tank_level
水罐液位低于 42 % 或高于 84 %。
分步说明
- valve.mains_topup把市政补水限制在便宜的四小时窗口内;按水罐容积,15 L/min 下补满约需 70 分钟。
open · only during 01:00–05:00 - valve.mains_topup同时使用液位停止与时间停止;否则液位探头卡在低读数时会把花园淹了。
close at 85 % or after 90 min, whichever first - switch.tank_pump低于 15 % 时硬性切断水泵,并要求液位回升到 25 % 以上才解除锁定,避免在跳闸点附近反复启停。
lockout below 15 % - sensor.tank_level_history记录每日液位最高值与最低值,使水罐慢漏或补水阀卡滞能以趋势的形式显现。
log · daily min and max
优先选用压力式探头,而不是超声波
在潮湿的水罐里,超声波传感器会因为换能器表面的凝露产生虚假回波,把满罐读成空罐。装在罐底的压力探头没有可被污染的光路。代价是:如果水面会晃动,需要加一根静水管;对于静态雨水罐这很容易实现。
让水泵锁定具备回差
15 % 切断、16 % 恢复,会让水泵整个下午在跳闸点附近反复启停。10 个百分点的回差带——15 % 切断、25 % 恢复——决定了一台泵能用十年还是三年。
补水同时使用液位停止与时间停止
只靠液位意味着信任探头;只靠时间则会补多或补少。两者并用,探头卡住也不会淹了花园,补水过慢也不会整夜运行。可以刻意把时间停止设为 3 分钟测一次。
硬件
| 型号 | 协议 | 连接 | 在本链路中的作用 |
|---|---|---|---|
| Pressure-based level probe (0.1 % full-scale) | wifi |
有线 | 测量罐底静水压,不受泡沫、凝露或罐体形状影响——不像超声波传感器那样在潮湿罐内会失准。 |
| Motorised ball valve on the mains top-up line | wifi |
有线 | 带位置反馈,使自动化能证明阀门已关闭,而不是假设它关了。 |
| Tank pump with a dry-run protection input | wifi |
有线 | 外部干转保护输入是自动化锁定未能生效时的物理兜底。 |
失效时怎么办
如果液位探头超过 6 小时没有上报,补水完全停用且水泵锁定保持生效——安全状态是水罐不满,而不是溢出。如果探头读数在 24 小时内完全没有变化,自动化会抛出「探头可疑」标记,而不是信任一个冻结的数值。