基于房间温度曲线的逐组暖气片平衡
七组暖气片上的恒温阀用两周学习各房间的升温曲线,之后微调阀门位置把波动控制在 ±0.4 °C,而不是 ±1.6 °C;在一套保温较差的 1970 年代公寓里,燃气消耗下降 12 %。
# HearthNodes recipe 14 - radiator balancing from room curves
alias: "Climate - per room radiator balancing"
id: hn_climate_radiator_balance
description: "Learned per-room offsets hold +/-0.4 C instead of +/-1.6 C"
mode: queued
max_exceeded: 4
trigger:
- platform: state
entity_id: binary_sensor.heating_season_active
to: "on"
- platform: time
at: "02:30:00"
id: nightly_refit
- platform: template
value_template: >-
{{ (states('sensor.living_temperature') | float(20)
- states('input_number.living_target') | float(20)) | abs > 0.8 }}
for: "00:20:00"
id: deviation
variables:
rooms:
living: { sensor: sensor.living_temperature, valve: climate.radiator_valve_living }
study: { sensor: sensor.study_temperature, valve: climate.radiator_valve_study }
main_bed: { sensor: sensor.main_bed_temperature, valve: climate.radiator_valve_main_bed }
second_bed: { sensor: sensor.second_bed_temperature, valve: climate.radiator_valve_second_bed }
bath: { sensor: sensor.bath_temperature, valve: climate.radiator_valve_bath }
hall: { sensor: sensor.hall_temperature, valve: climate.radiator_valve_hall }
kitchen: { sensor: sensor.kitchen_temperature, valve: climate.radiator_valve_kitchen }
condition:
- condition: numeric_state
entity_id: sensor.outdoor_temperature
below: 15
- condition: numeric_state
entity_id: sensor.boiler_flow_temperature
above: 45
action:
- choose:
- conditions:
- condition: trigger
id: nightly_refit
sequence:
- service: script.learn_heating_curve
data:
rooms: "{{ rooms }}"
min_r2: 0.6
- conditions: []
sequence:
- repeat:
for_each: "{{ rooms | dict2items }}"
sequence:
- service: climate.set_temperature
target:
entity_id: "{{ repeat.value.valve }}"
data:
temperature: >-
{{ [[states('input_number.' ~ repeat.key ~ '_target') | float(20)
+ states('input_number.' ~ repeat.key ~ '_offset') | float(0),
5] | max, 30] | min }}
# Offsets are clamped to +/-2 C and are only enabled after a two week learning
# run. More than two heads offline -> balancing stops and every valve goes to the
# plain schedule target, with the notification saying so. Hydraulic faults are
# fixed at the lockshield valve, never in software.
触发器 · state
binary_sensor.heating_season_active
某房间温度偏离其时间表目标超过 0.8 °C 并持续 20 分钟。
分步说明
- climate.radiator_valve_[room]应用由曲线模型学到的逐房间偏移量,限制在 ±2 °C 以内,让升温慢的房间获得比升温快的房间更高的阀门目标。
set_temperature · {{ target + offset }} - script.learn_heating_curve每晚用当天的阀门位置与温度数据重新拟合各房间的一阶响应曲线;若 R² 低于 0.6 则拒绝该拟合结果。
nightly · 02:30 · update coefficients - climate.boiler_flow依据室外温度曲线设定锅炉出水温度,这正是阀门能发挥作用的前提。
set_flow_temp · weather compensated - counter.balance_cycle每周生成逐房间偏差报告,让真正偏小的暖气片以持续负偏差的形式暴露出来。
increment · weekly report
把温度传感器放在人所在的位置,而不是暖气片上
阀头的内置传感器读的是管道,不是房间。把独立传感器装在内墙 1.2 米高、避开直射阳光、离任何热源至少 50 厘米处。仅这一项改动,通常就能消掉七成「温控器不准」的抱怨。
先学两周再信任它
一阶曲线每个房间至少需要十个加热周期才有意义。开启记录、让系统按普通时间表运行两周,然后才启用偏移量。第一天就启用偏移会引发振荡,看起来像硬件故障。
不要用软件去平衡一个水力上没平衡的系统
如果某片暖气底部总是凉的,或者有水流噪声,问题在回水阀,而不在智能阀头。先用温差法调整回水阀:每片暖气进出水温差 10–12 °C。软件修不了水力故障。
硬件
| 型号 | 协议 | 连接 | 在本链路中的作用 |
|---|---|---|---|
| Z-Wave thermostatic radiator valve heads (e.g. Danfoss Ally or Eurotronic Spirit) | zwave |
无线 | 七只阀头,每片暖气一只。之所以用 Z-Wave,是因为它能上报阀门的实际开启百分比,而学习脚本需要这个量。 |
| Room temperature sensors, one per room, 1.2 m height | zwave |
无线 | 与阀头分离——阀头自带的传感器距热管 10 cm,读数会偏高 3 °C。 |
| Outdoor temperature sensor on a north wall | zwave |
无线 | 天气补偿的输入;装在阳光下的传感器会在冬天误关锅炉。 |
失效时怎么办
如果某个阀头失联,它会回到自身的本地时间表,这是一个合理的默认值。如果有两个以上阀头离线,自动化停止平衡,把所有阀门设为不带偏移的时间表目标,并在通知中说明——降级为「笨」系统,好过基于缺失数据做平衡。