Meghalt a Computherm – hogyan csináltam okostermosztátot Shelly-vel és Home Assistanttal
A lassú halál
A Computherm Q7RF termosztátunk már egy ideje nem volt teljesen megbízható.
A tünetek klassikusak voltak: az adó leadta a jelet, a vevő visszajelzett – a piros lámpa felvillant, jelezte, hogy fűtés indult. De a kazánba valójában nem érkezett meg a rövidzár. A fűtésjel elveszett valahol a levegőben :D.
A fűtésszerelő már mondogatta, hogy lassan cserés lesz. Aztán egy kocogtatás, újraszerelés, és megjavult – egy időre. Ez az állapot ment hónapok óta.
Ma este viszont végleg megadta magát.
Hallani lehetett a kattanást a vevőnél – a relé megmozdult. Aztán 0.2 másodperccel később jött a visszakattanás. Ki. Be. Ki. Mintha valami belülről nem bírta volna tartani a kontaktust. Kocogtatás, ütögetés, leszerelélem, visszaszerelélem – semmi. Szeles, hideg este volt, és nem akartam, hogy a família reggel fagyban keljen.
Rendeljek új termosztátot?
Az első gondolat az volt: rendeljek egy új Computherm-et. Van wifis változatuk is – állítólag Home Assistanttal is együttműködik, és örülnék egy magyar márkának. De az online rendelés minimum másnap, de inkább 3 nappal később érkezett volna meg - a hétvége kezdete miatt, és most este kell megoldás, nem holnap.
Akkor esett le, hogy ennél sokkal egyszerűbb a helyzet.
Korábbi szerelgetések alkalmával már jól felmértem, hogyan működik a rendszer. A kazán fűtésjele két pont rövidzárásával adható – ennyi. Ha valamivel be tudom zárni ezt a két pontot, a kazán fűt. Ezt meg tudja csinálni egy relé. Azt meg tudja vezérelni egy Shelly.
Előkerestem egy Shelly 1 Mini Gen3-at, amire nem volt éppen szükség. Fogó, csavarhúzó, WAGO-k, és nekiálltam.
A kazán megnyitása
A kazán előlapját leszedtem. Megkerestem a két pontot, amelyeket rövidre kell zárni a fűtésjelhez – ez megvolt a korábbi tapasztalatokból. A tápfeszültség bekötése mellette volt, ott 2 WAGO-val le tudtam ágazni a Shelly tápellátásához.
A Shelly 1 Mini Gen3 a kazán belsejébe kerül, WAGO összekötőkkel a tápellátás leágazásához.
Áram alá helyeztem, csatlakoztattam a wifi hálózathoz – az extenderem szerencsére elég erős jelet ad ott is. Beállítottam fix IP-t, hogy ne okozzon gondot semmilyen router-újraindítás. Gyors teszt a Shelly appon keresztül: a kapcsolás működött, a kazán elindult.
Ezután összekötöttem az I/O kimeneteket a kazán fűtésjel-pontjaihoz. Áram vissza, újabb teszt – a fűtés beindul, ahogy kell.
A hardver rész 20 perc volt.
Thermosztát logika Home Assistantban
Idáig csak annyit értem el, hogy be tudom kapcsolni a kazánt. De egy valódi termosztáthoz kell az “agy” is – valami, ami tudja, mikor kell fűteni és mikor nem, és amelyik tartani tud egy heti programot.
A generic_thermostat integráció
A Home Assistant beépített generic_thermostat platformja pontosan erre való. Egy virtuális klímaentitást hoz létre két összetevőből:
- egy kapcsolóból – ebben az esetben a Shelly relé
- egy hőmérsékletérzékelőből – a nappaliban már ott van egy Aqara szenzor
Amikor a szobahőmérséklet a beállított célérték alá esik (a konfigurált tolerancián belül), a termosztát bekapcsolja a Shellyt, ami rövidre zárja a kazán fűtésjel-pontjait. Ha a hőmérséklet eléri a célértéket, kikapcsol. Ez hisztézises szabályozás – pontosan így működnek a klasszikus bimetál termosztátok is.
A konfiguráció:
climate:
- platform: generic_thermostat
name: "Házifűtés"
heater: switch.futesi_relay
target_sensor: sensor.nappali_homerseklet_homerseklet
min_temp: 15
max_temp: 25
cold_tolerance: 0.3
hot_tolerance: 0.3
precision: 0.1
target_temp: 20
initial_hvac_mode: "heat"A cold_tolerance és hot_tolerance értékek szabályozzák a hisztézist: 0.3 fokkal a célhőfok alatt bekapcsol, 0.3 fokkal felette kikapcsol. Ez elég szoros vezérlés – a kazán nem fog percenként ki-be kapcsolgatni, de a hőmérséklet sem fog sokat ingadozni.
Érdekes módon épp a közelmúltban próbáltam hisztézist beállítani egy Moes Zigbee termosztáton – és nem sikerült. A készülék firmware-je egyszerűen nem tette lehetővé. Ez a két sor konfigurációban jól összefoglalja, hogy mit jelent az, ha az ember nem egy eszköz zárt programjára van bízva, hanem maga tartja a kezében a vezérlési logikát.
A heti program
A generic_thermostat maga nem tartalmaz időzítő logikát – ez nem hiba, hanem tervezési döntés. A HA-ban a schedule külön komponens: időalapú automatizálások állítják be a célhőmérsékletet a climate entitáson.
Az egész konfiguráció egy HA package fájlba kerül (packages/heating.yaml), hogy ne keveredjen az automations.yaml tartalmával. A program:
- Hétköznap: 18°C éjjel (22:00-tól) → 21°C reggel (06:00) → 19°C nappal (08:00, amikor mindenki elmegy) → 21°C este (16:00)
- Hétvégén: 18°C éjjel (23:00-tól) → 21°C nappal (08:00)
Egy példa automatizálás:
- alias: "Fűtés: esti program (hétköznap)"
# TRIGGER: minden nap 16:00-kor elsül
trigger:
- platform: time
at: "16:00:00"
# CONDITION: de csak akkor fut le, ha éppen hétköznap van
condition:
- condition: time
weekday: [mon, tue, wed, thu, fri]
# ACTION: lépések sorban
action:
# 1. Jelzőzászló BE – jelzi, hogy most egy automatizálás állítja a hőmérsékletet,
# nem ember. Ez megakadályozza, hogy az override-detektáló tévesen beinduljón.
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
# 2. Ha éppen fut egy kézi override timer (pl. valaki korábban felnyomta 23°C-ra),
# azt töröljük – a program visszaveszi az irányítást.
- service: timer.cancel
target: { entity_id: timer.futes_override }
# 3. A lényeg: beállítjuk a célhőmérsékletet 21°C-ra.
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 21 }
# 4. Várunk 3 másodpercet, hogy a climate entitás state-je biztosan frissüljön,
# mielőtt a zászlót visszakapcsoljuk.
- delay: "00:00:03"
# 5. Jelzőzászló KI – ettől fogva az override-detektálás újra aktív.
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }Az input_boolean.futes_auto_beallitas szerepét mindjárt kifejtem.
Teljes heating.yaml package (climate + timer + automatizálások)
# packages/heating.yaml
climate:
- platform: generic_thermostat
name: "Házifűtés"
unique_id: hazifutes_generic
heater: switch.futesi_relay
target_sensor: sensor.nappali_homerseklet_homerseklet
min_temp: 15
max_temp: 25
cold_tolerance: 0.3
hot_tolerance: 0.3
precision: 0.1
target_temp: 20
initial_hvac_mode: "heat"
away_temp: 16
timer:
futes_override:
name: "Fűtés ideiglenes hőmérséklet"
duration: "02:00:00"
restore: true
icon: mdi:timer-outline
input_boolean:
futes_auto_beallitas:
name: "Fűtés: automatikus beállítás folyamatban"
icon: mdi:cog-outline
automation:
- id: futes_program_ejjel_hetkoznap
alias: "Fűtés: éjjeli program (hétköznap)"
trigger:
- platform: time
at: "22:00:00"
condition:
- condition: time
weekday: [mon, tue, wed, thu, fri]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 18 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_program_reggel_hetkoznap
alias: "Fűtés: reggeli program (hétköznap)"
trigger:
- platform: time
at: "06:00:00"
condition:
- condition: time
weekday: [mon, tue, wed, thu, fri]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 21 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_program_nappal_hetkoznap
alias: "Fűtés: nappali program (hétköznap)"
trigger:
- platform: time
at: "08:00:00"
condition:
- condition: time
weekday: [mon, tue, wed, thu, fri]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 19 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_program_este_hetkoznap
alias: "Fűtés: esti program (hétköznap)"
trigger:
- platform: time
at: "16:00:00"
condition:
- condition: time
weekday: [mon, tue, wed, thu, fri]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 21 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_program_reggel_htvege
alias: "Fűtés: reggeli program (hétvége)"
trigger:
- platform: time
at: "08:00:00"
condition:
- condition: time
weekday: [sat, sun]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 21 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_program_ejjel_htvege
alias: "Fűtés: éjjeli program (hétvége)"
trigger:
- platform: time
at: "23:00:00"
condition:
- condition: time
weekday: [sat, sun]
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: timer.cancel
target: { entity_id: timer.futes_override }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data: { temperature: 18 }
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }
- id: futes_override_detektalas
alias: "Fűtés: kézi override detektálás"
trigger:
- platform: state
entity_id: climate.hazifutes
attribute: temperature
condition:
- condition: state
entity_id: input_boolean.futes_auto_beallitas
state: "off"
- condition: template
value_template: >
{{ trigger.from_state is not none
and trigger.to_state is not none
and trigger.from_state.state not in ['unavailable','unknown']
and trigger.to_state.state not in ['unavailable','unknown'] }}
action:
- service: timer.start
target: { entity_id: timer.futes_override }
data: { duration: "02:00:00" }
- id: futes_override_vege
alias: "Fűtés: override lejárt, visszaáll programra"
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.futes_override
action:
- service: input_boolean.turn_on
target: { entity_id: input_boolean.futes_auto_beallitas }
- service: climate.set_temperature
target: { entity_id: climate.hazifutes }
data:
temperature: >
{% set h = now().hour %}
{% set wd = now().weekday() %}
{% if wd < 5 %}
{% if h >= 22 or h < 6 %}18
{% elif h >= 6 and h < 8 %}21
{% elif h >= 8 and h < 16 %}19
{% else %}21{% endif %}
{% else %}
{% if h >= 23 or h < 8 %}18
{% else %}21{% endif %}
{% endif %}
- delay: "00:00:03"
- service: input_boolean.turn_off
target: { entity_id: input_boolean.futes_auto_beallitas }A kézi override megoldása
Eddig volt egy automatikusan futó programom. De a feleségem elvárása egyszerű volt: ha hazajön és fázik, tudjon benyomni egy hőmérsékletet – aztán álljon vissza magától. Ne kelljen emlékezni semmire, ne kelljen visszakapcsolni.
A Lovelace thermostat kártyán közvetlenül lehet változtatni a célhőmérsékletet. Az ötlet az volt, hogy ha valaki kézzel változtatja ezt az értéket, induljon el egy 2 órás visszaszámláló. Amikor lejár, a rendszer visszaállítja az éppen aktuális program-hőmérsékletet.
A trükkös rész: honnan tudja, hogy ember nyúlt hozzá?
Az automatizálások is változtatják a climate entitás hőmérsékletét – nem akarom, hogy az ilyenkor is elindítsa a timert. Erre egy belső jelzőzászló, egy input_boolean szolgál:
- Mielőtt bármely program-automatizálás beállítja a hőmérsékletet, bekapcsolja ezt a zászlót.
- Az override-detektáló automatizálás csak akkor indul el, ha a zászló ki van kapcsolva.
- 3 másodperccel az automatizálás végén a zászló visszakapcsol.
- id: futes_override_detektalas
alias: "Fűtés: kézi override detektálás"
trigger:
- platform: state
entity_id: climate.hazifutes
attribute: temperature
condition:
- condition: state
entity_id: input_boolean.futes_auto_beallitas
state: "off"
action:
- service: timer.start
target: { entity_id: timer.futes_override }
data: { duration: "02:00:00" }Amikor a 2 óra lejár, egy Jinja template kiszámolja, hogy melyik időszak lenne éppen aktív (reggel, nappal, este, éjjel, hétvége), és visszaállítja a megfelelő hőmérsékletet. Ha viszont a 2 óra lejárta előtt eljön egy program-időpont (pl. 22:00), az automatizálás törli a timert és felülírja a hőmérsékletet – az override tehát korábban is véget érhet.
Pontosan úgy viselkedik, mint egy hagyományos termosztát “felülbíráló” gombja – csak nem kell hozzá fizikai gomb.
Dashboard és az HA app
A konfiguráció megvolt, pusholás, HA újraindítás. Az entitás megjelent, a klíma kártya azonnal működött.
Egyetlen apróság maradt: a kártya 22°C-t mutatott, pedig a szenzor 22.3°C-t mért. A precision: 0.5 nemcsak a megjelenítés pontosságát szabályozza, hanem azt is, hogy milyen léptékben lehet beállítani a célhőmérsékletet. 0.1-re állítva pontosan azt mutatja, amit a szenzor mér.
Ezután következett a feleségem bevezetése a HA app világába. Telepítés iPhone-ra, külön felhasználó létrehozása, és egy dedikált dashboard, ahol egyelőre csak a thermosztát kártya van – semmi más, semmi zavaró.
A dedikált dashboard – csak a thermosztát, minden más el van rejtve.
Ha fázik: megnyitja az appot, húzza feljebb a csúszkát. Két óra múlva visszaáll magától.
Összegzés
Ami tűzoltásnak indult, az egy tartós megoldás lett – és valószínűleg jobb, mint az, amit lecseréltünk.
A Computherm Q7RF egyirányú rádiókapcsolattal dolgozott: az adó jelet küldött, a vevő fogadta (vagy nem). Nem volt visszajelzés arról, hogy a kazán valóban fűt-e. Most van egy Home Assistant entitás, amely mutatja az aktuális és a célhőmérsékletet, a kazán relé státuszát, és az egész vezérelhető telefonról – bárhonnan.
A hőmérsékletérzékelők már ott voltak a ház különböző pontjain, extra hardverre nem volt szükség. A Shelly 1 Mini Gen3 pár ezer forint. Az egész megoldás olcsóbb volt egy új termosztátnál, és sokkal rugalmasabb.
Ha egyszer több zónát szeretnék vezérelni, vagy jelenlétalapú automatizmust akarok beépíteni – a rendszer készen áll rá.
A legjobb megoldás az, amelyik akkor is jól működik, amikor senki nem gondol rá.