
Tämä ohje kattaa Thermia Calibra 12 -maalämpöpumpun Modbus TCP -integraation Home Assistantiin sekä EVU/Boost-ohjauksen toteutuksen EM3-laajennusmoduulin kautta. Ohje olettaa että HA Core pyörii Docker-kontissa ja Modbus TCP -yhteys lämpöpumppuun on toimiva.
Arkkitehtuuritausta löytyy sarjan osasta Osa 12 — Thermia Modbus-ohjaus. Käyttöveden PV-ohjauslogiikka, joka rakentuu tämän ohjeen päälle, on kuvattu erillisessä DHW-ohjeessa. Vikatilanteiden kovennuksen tausta on osassa Osa 15 — FMA-kovennus.
Testattu ympäristö
- Thermia Calibra 12
- Firmware 17.03.145
- Home Assistant Core (Docker)
- Modbus TCP, portti 502
- EM3-laajennusmoduuli
- Shelly Pro 2 (SG1/SG2-releet)
Muiden Thermia-mallien ja firmware-versioiden käyttäytyminen voi poiketa tästä ohjeesta.
Tärkeä huomio osoitteistuksesta
Thermian dokumentaatio käyttää De Facto -osoitteita (40001-pohjainen). Home Assistantin Modbus-integraatio käyttää nollapohjaisia osoitteita. Nämä eivät ole sama asia.
| Dokumentaation De Facto | HA YAML address | Tyyppi |
|---|---|---|
| 40006 | 5 | holding |
| 40023 | 22 | holding |
| 40024 | 23 | holding |
| 30016 | 15 | input |
| 30002 | 1 | input |
| 10202 | 201 | discrete input |
| 10205 | 204 | discrete input |
Tämä on yleisin Thermia-integraation virhelähde. Jos rekisteri ei vastaa, tarkista ensin osoitemuoto.
Arkkitehtuuri: kuka päättää, kuka toteuttaa
Vastuunjako on EnergyHubin peruskaava, ja se pätee myös lämpöpumppuun:
Node-RED Priority Resolver — PÄÄTTÄÄ (hpMode: normal / block / boost)
↓ energyhub/command/hp/mode
HA komentovastaanotin — VASTAANOTTAA (input_select.c_hp_mode)
↓
HA relelogiikka (31_load_heatpump) — TOTEUTTAA (Shelly Pro 2 → SG1/SG2)
↓
Thermia EM3 — TOIMII omien rajojensa sisällä
↑
Modbus readback (rekisteri 30083) — VARMISTAA toteuman
HA ei sisällä boost-elinkaarilogiikkaa (odotus, timeout, palautus) — se elää Node-REDin Priority Resolverissa, joka näkee koko järjestelmän tilan (capabilityt, legionella, safety, päivätilat). HA:n tehtävä on kytkeä releet komennon mukaan ja tarjota mitattu tila takaisin telemetriana. Tämä on sama komento ≠ toteuma -periaate joka toistuu koko järjestelmässä.
Modbus-konfiguraatio HA:han
Lisää packages/10_integrations.yaml:iin Thermia-osio. Entiteettinimet noudattavat konventiota modbus_m_hp_* (m_ = mittaus, hp = heat pump):
yaml
- name: thermia
type: tcp
host: !secret thermia_host
port: 502
delay: 1
timeout: 5
retries: 3
retry_on_empty: true
sensors:
# --- Lämpötilat (scale 100 = jaetaan 100:lla) ---
- name: modbus_m_hp_outdoor_temp_c
unique_id: modbus_m_hp_outdoor_temp_c
slave: 1
address: 13 # De Facto 30014
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 60
- name: modbus_m_hp_tap_water_top_c
unique_id: modbus_m_hp_tap_water_top_c
slave: 1
address: 15 # De Facto 30016
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 30
- name: modbus_m_hp_supply_c
unique_id: modbus_m_hp_supply_c
slave: 1
address: 9 # De Facto 30010
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 60
- name: modbus_m_hp_return_c
unique_id: modbus_m_hp_return_c
slave: 1
address: 8 # De Facto 30009
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 60
- name: modbus_m_hp_supply_setpoint_c
unique_id: modbus_m_hp_supply_setpoint_c
slave: 1
address: 18 # De Facto 30019
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 60
- name: modbus_m_hp_compressor_speed_pct
unique_id: modbus_m_hp_compressor_speed_pct
slave: 1
address: 54 # De Facto 30055
input_type: input
data_type: int16
scale: 0.01
unit_of_measurement: "%"
scan_interval: 30
# --- Käyttötila ja prioriteetit ---
- name: modbus_m_hp_running_first_priority
unique_id: modbus_m_hp_running_first_priority
slave: 1
address: 1 # De Facto 30002 — First prioritised demand
input_type: input
data_type: int16
scan_interval: 30
# Arvot (Thermia Modbus protocol for Mega, Genesis platform, v12.00):
# 1=Manuaali, 2=Sulatus, 3=Käyttövesi, 4=Lämmitys,
# 5=Aktiivijäähdytys, 6=Allas, 7=Anti-legionella,
# 98=Valmiustila, 99=Ei vaatimusta, 100=OFF
# --- Smart Grid -tila (readback) ---
- name: modbus_m_hp_smart_grid_mode
unique_id: modbus_m_hp_smart_grid_mode
slave: 1
address: 82 # De Facto 30083 — Comfort mode
input_type: input
data_type: int16
scan_interval: 10
# Arvot: 1=EVU, 4=Normal, 5=Comfort, 6=Boost
# --- Kompressorin estoaika ---
- name: modbus_m_hp_compressor_blocked
unique_id: modbus_m_hp_compressor_blocked
slave: 1
address: 60 # De Facto 30061 — start restriction timer
input_type: input
data_type: int16
scan_interval: 10
# --- Käyttöveden asetusarvot (luku telemetriaa varten) ---
- name: modbus_m_hp_dhw_start_setpoint_c
unique_id: modbus_m_hp_dhw_start_setpoint_c
slave: 1
address: 22 # De Facto 40023
input_type: holding
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 300
- name: modbus_m_hp_dhw_stop_setpoint_c
unique_id: modbus_m_hp_dhw_stop_setpoint_c
slave: 1
address: 23 # De Facto 40024
input_type: holding
data_type: int16
scale: 0.01
unit_of_measurement: "°C"
scan_interval: 300
numbers:
- name: wp_comfort_wheel
unique_id: wp_comfort_wheel
slave: 1
address: 5 # De Facto 40006 — Comfort wheel
input_type: holding
min_value: 16 # Arvoalue alkaa 16°C:sta
max_value: 30
step: 0.5
scale: 0.01 # Rekisterin arvo 2200 = 22.00°C
mode: box
scan_interval: 60
# HUOM: Comfort wheel ohjaa sisälämpötilan tavoitearvoa (°C),
# ei lämpökäyrän siirtoa. Number-entiteetin polling (scan_interval 60)
# toimii samalla kirjoituksen readback-lähteenä (ks. pending/confirmed alla).
Telemetriapayloadin lisärekisterit heat_demand_pct ja immersion_heater_step lisätään samalla kaavalla — tarkista näiden osoitteet oman mallisi ja firmware-versiosi dokumentaatiosta, sillä ne vaihtelevat mallisarjojen välillä. Samasta syystä alkuperäisessä ohjeessa ollut lisälämmittimen esto-switch (De Facto 40322) on jätetty pois: rekisteri on dokumentoitu vain Mega S-E -sarjalle.
EM3-laajennusmoduulin tilat
Thermia Calibra 12:n EM3-moduuli ohjataan kahdella digitaalisella tulolla (SG1 ja SG2):
SG1=0, SG2=0 → Normal — normaali toiminta
SG1=1, SG2=0 → EVU — Smart Grid -esto / kuormanhallintatila
SG1=0, SG2=1 → Comfort — käyttövesi korkeammilla lämpötiloilla
SG1=1, SG2=1 → Boost — käynnistää käyttövesilämmityksen
EnergyHubissa SG1 = Shelly Pro 2 output_0, SG2 = output_1. Tässä asennuksessa entiteetit ovat switch.shellypro2_ec62609153c8_output_0 ja ..._output_1 — käytä omia entiteetti-ID:itäsi.
Aktiivinen tila luetaan rekisteristä 30083 (sensor.modbus_m_hp_smart_grid_mode). Arvot: 1=EVU, 4=Normal, 5=Comfort, 6=Boost. Tämä readback on koko ohjauksen selkäranka — releen kytkeminen ei vielä todista että pumppu on halutussa tilassa.
Komentovastaanotin: MQTT → input_select
Node-RED julkaisee HP-tilan topiciin energyhub/command/hp/mode (payload: normal, block tai boost). HA:n komentovastaanotin päivittää input_select.c_hp_mode-entiteetin, ja varsinainen relelogiikka reagoi sen tilanmuutokseen. Välivaihe input_selectin kautta tekee tilan näkyväksi (Lovelace, historia, muut automaatiot) ja erottaa komennon vastaanoton sen toteutuksesta.
yaml
# 40_optimization.yaml — komentovastaanotin
- alias: "MQTT: HP mode -komento"
id: mqtt_cmd_hp_mode
mode: queued
trigger:
- platform: mqtt
topic: "energyhub/command/hp/mode"
condition:
- condition: template
value_template: "{{ trigger.payload in ['normal', 'block', 'boost'] }}"
action:
- action: input_select.select_option
target:
entity_id: input_select.c_hp_mode
data:
option: "{{ trigger.payload }}"
Relelogiikka (31_load_heatpump.yaml)
Releet ohjataan input_selectin tilan mukaan. Huomaa että normal-haara ei kytke releitä suoraan vaan kutsuu readback-varmistettua skriptiä (seuraava luku):
yaml
- alias: "HP: releohjaus c_hp_mode mukaan"
id: hp_relay_control
mode: restart
trigger:
- platform: state
entity_id: input_select.c_hp_mode
action:
- choose:
# --- EVU: SG1=1, SG2=0 ---
- conditions:
- condition: state
entity_id: input_select.c_hp_mode
state: "block"
sequence:
- action: switch.turn_on
target:
entity_id: switch.shellypro2_ec62609153c8_output_0 # SG1
- action: switch.turn_off
target:
entity_id: switch.shellypro2_ec62609153c8_output_1 # SG2
- action: logbook.log
data:
name: "HP ohjaus"
message: "EVU aktivoitu — kompressori estyy (viive rek. 30061)"
# --- Boost: SG1=1, SG2=1 ---
- conditions:
- condition: state
entity_id: input_select.c_hp_mode
state: "boost"
sequence:
- action: switch.turn_on
target:
entity_id: switch.shellypro2_ec62609153c8_output_0 # SG1
- action: switch.turn_on
target:
entity_id: switch.shellypro2_ec62609153c8_output_1 # SG2
- action: logbook.log
data:
name: "HP ohjaus"
message: "Boost asetettu — Node-RED valvoo elinkaaren"
# --- Normal: readback-varmistettu palautus ---
- conditions:
- condition: state
entity_id: input_select.c_hp_mode
state: "normal"
sequence:
- action: script.force_sg_normal
Boost-haarasta puuttuu tarkoituksella kaikki elinkaarilogiikka: ei wait_templatea, ei timeouttia, ei palautusta. Kaikki tämä — käynnistymisen vahvistus running_prioritysta ja Shelly EM3:n tehosta, timeout, epäonnistumisen ja keskeytyksen erottelu, päivätilat — on Node-REDin Priority Resolverissa, joka lopulta julkaisee normal-komennon kun boost-jakso on käsitelty. Toteutus on kuvattu kokonaisuudessaan DHW-ohjeessa.
force_sg_normal — readback-varmistettu palautus
Normal-tilaan palautus on järjestelmän tärkein yksittäinen tilanvaihto: jos se epäonnistuu hiljaa, pumppu jää EVU-estoon (talo kylmenee) tai Boostiin (käyttövettä lämmitetään tarpeettomasti). Siksi palautus ei koskaan ole pelkkä relekytkentä, vaan skripti joka varmistaa toteuman rekisteristä 30083, yrittää uudelleen ja hälyttää jos palautus ei onnistu:
yaml
script:
force_sg_normal:
alias: "HP: pakota Normal readback-varmistuksella"
mode: single
sequence:
# Ei palautusta emergency-tilassa tai safety tripin aikana —
# niissä tiloissa releiden omistajuus on turvalogiikalla.
- condition: template
value_template: >
{{ is_state('input_boolean.sys_safety_trip', 'off')
and not is_state('input_select.sys_operating_mode', 'emergency') }}
- repeat:
sequence:
- action: switch.turn_off
target:
entity_id: switch.shellypro2_ec62609153c8_output_0
- action: switch.turn_off
target:
entity_id: switch.shellypro2_ec62609153c8_output_1
# Odotetaan readback-sensorin päivitys (scan_interval 10 s)
- delay: "00:00:20"
until:
- condition: or
conditions:
- condition: state
entity_id: sensor.modbus_m_hp_smart_grid_mode
state: "4" # 4 = Normal
- condition: template
value_template: "{{ repeat.index >= 3 }}"
# Jos kolmen yrityksen jälkeenkään readback ei näytä Normalia → hälytys
- if:
- condition: not
conditions:
- condition: state
entity_id: sensor.modbus_m_hp_smart_grid_mode
state: "4"
then:
- action: persistent_notification.create
data:
title: "HP: Normal-palautus EPÄONNISTUI"
message: >
SG-releet komennettiin OFF/OFF mutta rekisteri 30083 =
{{ states('sensor.modbus_m_hp_smart_grid_mode') }}.
Tarkista Shelly Pro 2 ja EM3-kytkentä. Pumppu voi olla
jumissa EVU- tai Boost-tilassa.
- action: logbook.log
data:
name: "HP ohjaus"
message: "VIRHE: force_sg_normal epäonnistui 3 yrityksen jälkeen"
else:
- action: logbook.log
data:
name: "HP ohjaus"
message: "Normal vahvistettu readbackilla (30083=4)"
Kaikki polut jotka palauttavat pumpun Normaliin — DHW-boostin päättyminen, EVU:n purku, safety-tilan purku, manuaalinen palautus — kulkevat tämän skriptin kautta. Yksi toteutus, yksi varmistuslogiikka, yksi hälytyspolku.
Miksi tämä kannattaa: taustalla on kesäkuun 2026 ylivirtaincidentti, jossa hätätilaan lukittunut järjestelmä ei palautunut automaattisesti ja viat paljastuivat vasta jälkikäteen. FMA-kierroksen johtopäätös oli, että jokainen tilan palautuspolku tarvitsee readback-varmistuksen ja epäonnistumisesta pitää syntyä näkyvä hälytys — hiljainen epäonnistuminen on pahin vikaluokka. Tarina kokonaisuudessaan osassa 15.
EVU-ohjaus: esto kalliina tunteina
EVU estää normaalisti kompressorin käynnistymisen Smart Grid -logiikan mukaisesti. Käytetään kun hinta on kallis tai sulake uhkaa.
Tärkeä viive: EVU ei vaikuta välittömästi käynnissä olevaan kompressoriin. Kompressori jatkaa vähintään viisi minuuttia ennen pysähtymistä. Viive on luettavissa rekisteristä 30061 (sensor.modbus_m_hp_compressor_blocked) — kun arvo on 0, kompressori on vapaana.
Viiveellä on suora seuraus kuormanpudotukseen: kun Thermia pudotetaan EVU:lla sulakevaaran takia, vaikutus vaihevirtaan näkyy vasta minuuttien päästä. Pudotuslogiikan on siksi merkittävä pudotus ”vaikutusta odottavaksi” (pending effect) eikä tulkita muuttumatonta virtaa epäonnistumiseksi — muuten se pudottaa turhaan seuraavankin kuorman.
Boost-ohjaus: trigger and release
Boost käynnistää käyttövesilämmityksen korkeammilla lämpötiloilla. Turvallinen malli on trigger-and-release: Boost asetetaan, odotetaan kunnes pumppu käynnistää käyttövesilämmityksen, palautetaan Normal — ja pumppu vie jakson loppuun itse.
Käytännön testien perusteella Boost ei välttämättä käynnistä käyttövesiajoa jos käyttövesi on jo riittävän lämmin. Tällöin running_priority ei muutu arvoon 3 — Node-REDin timeout laukeaa ja tila palautetaan Normaliin ilman vaikutuksia.
Elinkaaren omistaa Node-REDin Priority Resolver, joka:
- asettaa
hpMode: boostkun trigger-ehdot täyttyvät (PV-ylijäämä tai hintaikkuna) eikä estoja ole (capability, legionella, lisälämmitin, päivätilat) - vahvistaa käynnistymisen kahdesta lähteestä: running_priority = 3 (Modbus) ja Shelly EM3:n mittaama teho > vahvistusraja — komento ei ole sama kuin toteuma
- palauttaa
hpMode: normalheti kun Thermia on ottanut työn (→ force_sg_normal) - erottaa timeout-epäonnistumisen (dhw_failed_today) ulkoisesta keskeytyksestä (dhw_cancelled_today), jotta uusintayritykset eivät jää silmukkaan
Koko logiikka parametreineen on DHW-ohjeessa — tässä ohjeessa riittää tietää että HA:n vastuu päättyy releiden kytkemiseen ja readbackin tarjoamiseen.
Comfort wheel -ohjaus: pending/confirmed
Comfort wheel ohjaa sisälämpötilan tavoitearvoa celsiuksina. Käytännössä testattu arvoalue on 16 °C:sta ylöspäin. Rekisteri käyttää kerrointa 100: arvo 2200 = 22,00 °C.
HA:n kirjoitusautomaatio on ennallaan yksinkertainen:
yaml
- alias: "HP Comfort wheel: kirjoitus"
id: hp_comfort_wheel_write
mode: restart
trigger:
- platform: mqtt
topic: "energyhub/command/hp/comfort_wheel"
condition:
- condition: template
value_template: >
{{ trigger.payload | float(-1) >= 16
and trigger.payload | float(-1) <= 30 }}
action:
- variables:
wheel_value: "{{ trigger.payload | float(0) }}"
register_value: "{{ (wheel_value * 100) | round(0) | int }}" # 22.0 → 2200
- action: modbus.write_register
data:
hub: thermia
slave: 1
address: 5 # De Facto 40006
value: "{{ register_value }}"
- action: logbook.log
data:
name: "HP Comfort wheel"
message: "Kirjoitettu: {{ wheel_value }} (rekisteri: {{ register_value }})"
Olennainen ero alkuperäiseen on Node-REDin päässä: kirjoitusta ei pidetä voimassa olevana ennen kuin readback vahvistaa sen. Number-entiteetti number.wp_comfort_wheel pollaa rekisteriä (scan_interval 60) ja arvo kulkee telemetrian kautta Node-REDiin, joka ylläpitää pending/confirmed-tilakonetta:
javascript
// Comfort wheel -kirjoituksen yhteydessä (Priority Resolver / lähetys)
global.set('cw_pending_value', targetC); // esim. 21.0
global.set('cw_pending_since', Date.now());
node.send({ topic: 'energyhub/command/hp/comfort_wheel',
payload: String(targetC) });
// State Collectorissa jokaisella telemetriasyklillä
const pending = global.get('cw_pending_value');
const readback = payload.comfort_wheel_c; // number-entiteetin readback
const since = global.get('cw_pending_since') ?? 0;
if (pending !== null && readback !== null) {
if (Math.abs(readback - pending) < 0.25) {
// Kirjoitus meni perille — pending → confirmed
global.set('cw_confirmed_value', pending);
global.set('cw_pending_value', null);
} else if ((Date.now() - since) > 5 * 60 * 1000) {
// 5 min eikä readback vastaa → kirjoitus hukkui (esim. Modbus-katko).
// Uusi kirjoitusyritys tai hälytys — EI hiljaista ohitusta.
node.warn(`Comfort wheel readback ${readback} ≠ pending ${pending} — uusi yritys`);
global.set('cw_pending_since', Date.now());
node.send({ topic: 'energyhub/command/hp/comfort_wheel',
payload: String(pending) });
}
}
Node-RED lähettää arvon hintatilanteen mukaan:
javascript
// Kallis hinta — lasketaan tavoitelämpötilaa
sendComfortWheel(20.0);
// Normaali
sendComfortWheel(22.0);
// Halpa hinta tai aurinkoylijäämä — nostetaan tavoitelämpötilaa
sendComfortWheel(23.0);
Tilamuunnokset: State Collector, ei template-sensoreita
Alkuperäisessä versiossa tilamuunnokset (wp_operating_mode, wp_hot_water_active jne.) tehtiin HA:n template-sensoreilla. Tästä on luovuttu kahdesta syystä: template-sensorit paketeissa eivät toimineet !include_dir_named-direktiivin kanssa käytetyssä HA-versiossa, ja arkkitehtuurisesti muunnos kuuluu sinne missä tietoa käytetään — Node-REDiin.
HA lähettää raa’at arvot telemetriapayloadissa (energyhub/telemetry/heatpump, retain: false, puuttuva arvo = null, ei nolla), ja Node-REDin State Collector johtaa tilat:
javascript
const runningPriority = payload.running_priority ?? 0;
global.set('m_hp_running_priority', runningPriority);
global.set('m_hp_hot_water_active', runningPriority === 3);
global.set('m_hp_legionella_active', runningPriority === 7);
const sgMode = payload.smart_grid_mode ?? null; // 1=EVU, 4=Normal, 5=Comfort, 6=Boost
global.set('m_hp_smart_grid_mode', sgMode);
Yksi lähde, yksi muunnos, yksi totuus — ja muunnoslogiikka versionhallitussa Node-RED-flow’ssa eikä hajallaan YAML-templateissa.
Testaus
Tarkista rekisterit Developer Tools → Tilat:
sensor.modbus_m_hp_running_first_priority → 3 (käyttövesi), 4 (lämmitys), 7 (legionella)
sensor.modbus_m_hp_smart_grid_mode → 4 (normal), 1 (EVU), 6 (Boost)
sensor.modbus_m_hp_compressor_blocked → 0 (vapaa) tai > 0 (estoaika käynnissä)
sensor.modbus_m_hp_tap_water_top_c → käyttöveden lämpötila °C
Testaa EVU manuaalisesti:
bash
mosquitto_pub -h localhost -t "energyhub/command/hp/mode" -m "block"
# Seuraa: input_select.c_hp_mode → block
# Seuraa: sensor.modbus_m_hp_smart_grid_mode → 1 (EVU)
# Seuraa: sensor.modbus_m_hp_compressor_blocked > 0 (viive käynnissä)
mosquitto_pub -h localhost -t "energyhub/command/hp/mode" -m "normal"
# Seuraa: sensor.modbus_m_hp_smart_grid_mode → 4 (Normal)
# Seuraa lokista: "Normal vahvistettu readbackilla (30083=4)"
Testaa readback-varmistuksen hälytyspolku hallitusti: irrota Shelly Pro 2:n ohjaus hetkeksi (esim. poista rele käytöstä Shellyn omasta käyttöliittymästä), aja normal-komento ja varmista että persistent notification syntyy kolmen yrityksen jälkeen. Palauta rele ja aja normal uudelleen. Hälytyspolku jota ei ole koskaan testattu on hälytyspolku joka ei toimi.
Testaa Boost manuaalisesti:
bash
mosquitto_pub -h localhost -t "energyhub/command/hp/mode" -m "boost"
# Seuraa: sensor.modbus_m_hp_smart_grid_mode → 6 (Boost)
# Seuraa: sensor.modbus_m_hp_running_first_priority → 3 (käyttövesi käynnistynyt)
# Node-RED palauttaa normal kun käynnistyminen on vahvistettu
# (tai timeoutin jälkeen jos vesi oli jo lämmin)
Yleisimmät ongelmat
Rekisteri näyttää väärää arvoa (esim. ~200 °C lämpötilana) Skaalausvirhe. Thermia käyttää kerrointa 100 lähes kaikille lämpötiloille. HA:ssa scale: 0.01. Tarkista että arvo jaetaan 100:lla, ei kerrotaan.
EVU ei vaikuta heti Normaali. Kompressorin minimikäyntiaika suojaa laitetta — EVU vaikuttaa vasta kun kompressori on saanut ajaa vähintään viisi minuuttia. Seuraa sensor.modbus_m_hp_compressor_blocked.
Boost ei käynnistä käyttövesiajoa Käyttövesi on todennäköisesti jo riittävän lämmin. Tarkista sensor.modbus_m_hp_tap_water_top_c. Tämä on normaali tilanne — Node-REDin timeout palauttaa Normalin automaattisesti ja merkitsee päivän yrityksen käsitellyksi.
Smart Grid -tila ei muutu vaikka rele ohjattu Tarkista Shelly Pro 2:n kytkentä EM3-moduuliin. SG1 = output_0, SG2 = output_1. Varmista että EM3-moduuli on asennettu ja aktivoitu pumpun asetuksista. Juuri tämän vikaluokan takia force_sg_normal varmistaa readbackin — releen tila ja pumpun tila voivat erota.
Normal-palautus epäonnistuu toistuvasti (persistent notification) Tarkista ensin Shellyn tavoitettavuus verkossa, sitten relelähtöjen fyysinen toiminta (Shellyn oma UI), sitten johdotus EM3:lle. Jos rekisteri 30083 näyttää oikeaa arvoa mutta hälytys silti syntyy, tarkista readback-sensorin scan_interval suhteessa skriptin delay-arvoon.
Modbus-yhteys katkeaa ajoittain Lisää retry_on_empty: true ja retries: 3 Thermia-hub-konfiguraatioon. Thermia voi ajoittain olla reagoimatta pyyntöihin kompressorin käynnistyksen aikana. Pending/confirmed-malli comfort wheelissä suojaa juuri tältä: katkon aikana hukkunut kirjoitus havaitaan readbackista ja yritetään uudelleen.
Vastuuvapauslauseke
Modbus-kirjoitukset ja rele-ohjaukset tehdään omalla vastuulla. Virheelliset ohjaukset voivat vaikuttaa lämpöpumpun toimintaan. Testaa muutokset hallitusti — ensin manuaalisesti, seuraa pumpun reaktio, varmista palautus ennen automaation käyttöönottoa. Tämä ohje perustuu yhteen laiteasennukseen — käyttäytyminen voi erota eri mallien ja firmware-versioiden välillä.