OpenHAB Fußbodenheizung Thermostat mit Shelly Relais

Hier eine Anleitung, wie man mit Hilfe von openHAB und einem oder mehreren Shelly Relais die Fußbodenheizung Smart machen kann. Ich habe hierzu sehr lange recherchiert und versucht mich an Standard Lösungen, bereits vorhandenen openHAB Lösungen und Regelwerken zu orientieren. Leider gab es für mich keine Lösung die ich für michvernünftig adaptieren konnte. Auch die Lösung von Shelly selbst, ein virtuelles Thermostat, mit Hilfe eines Shelly Temperatur Sensors und einem Shelly Relais zu nutzen, hat mich alleine aus dem Grund, dieses nicht auch noch über openHAB steuerbar zu machen, nicht überzeugt. Eine alternativ Lösung zu diesem Ganzen hier, ist es ein Shelly Walldisplay zu nutzen. Möchte man es in jedem Raum nutzbar machen, wird dies jedoch eine sehr kostspielige Lösung und wird auch Stand heute noch nicht im Thermostat Mode vom openHAB Shelly Binding unterstützt.
Lösungsbeschreibung
Zunächst einmal verwende ich an jedem Fußbodenzeizungsstellantrieb ein Shelly Relais (bei mir: Shelly 1 oder Shelly 1mini (Gen3)). Dies macht es dann möglich einfach per Ein- und Aus- Befehl, die Heizung An oder Aus zuschalten. Die Shelly Relais kann man ganz einfach anstelle des bereits vorhanden Raumthermostates anschließen. Ich habe bei mir die alten Thermostate komplett ausgebaut und dann durch eine Blind-Abdeckung die Wanddose verschlossen. Um nun die Heizung Temperatur gesteuert zu nutzen, braucht man noch einen Smarten Temperatur Sensor, der ebenfalls am Ende in openHAB nutzbar ist. Die einfachste und sicher beste Lösung ist es ein Shelly Blu H&T Sensor zu kaufen, diesen kann man dann einfach im Raum dort platzieren, wo man die Temperatur messen möchte, oder ihn einfach auf die Blind Abdeckung kleben. Ich gehe weiter unten noch auf die verschiedenen Möglichkeiten von Temperatur Sensoren ein. Nachdem wir nun den Heizungsventilschalter und den Temperatursensor in openHAB nutzbar haben, verheiraten wir das Ganze dann mittels speziell angelegten Items und einem passenden Regelwerk.
Die Raumtemperatur Regelung in meiner Beschreibung hier bietet die folgenden Features:
- Temperaturgesteuerte Raumklimaregelung
- Raum Nachtabsenkung (Zeit gesteuert)
- Booster Mode (öffnet Heizungsventil für x Minuten)
- Smart-Grid Steuerung (Erhöhung der Raumtemperatur bei SmartGrid-Grün Modus)
- Raum Abwesenheitsabsenkung (Bei vorhanden Anwesenheitsschalter)
- Regelwerk vereinfacht durch Blockly Library
- List Widget zum Einstellen der Raumtemperatur und Anzeige des Thermostatsstatus
- Einbindung in Amazon Alexa und Apple Home für die Sprachsteuerung
Voraussetzungen
- funktionsfähiges openHAB Setup
- installiertes openHAB Shelly Binding
- vorhandener Fußbodenheizung Stellantrieb
- ggf. vorhandenes Wandthermostat für die Fußbodenheizung
- Shelly Relais, zum Beispiel:
- Raum Temperatur Sensor, zum Beispiel:
Shelly Relais an Stellantrieb anschließen
Der erste Schritt in die smarte Zukunft der Fußbodenheizung ist der Anschluss des Shelly Relais an das Fußbodenheizungsstellventil.
Hierzu einmal folgendes Anschlussbild bei der Nutzung eines Shelly 1:
Ich habe hier einfach die vorhanden Thermostate, die vom Anschluss her identisch waren durch den Shelly 1 ausgetauscht und am ende mit deiner Blind Abdeckung die Wanddose wieder verschlossen. Wahlweise kann man auch direkt im Heizkreisverteiler Kasten den Shelly anschließen. Vorteil der Lösung mit dem Thermostat-Austausch, man kann ganz einfach wieder zurück zur alten Lösung.
Temperatur Sensor

Generell könnt ihr für diese Lösung hier jeden Temperatur Sensor verwenden, den ihr in openHAB einbinden könnt und am Ende die Temperatur des Raumes in °C ausgibt. Ich selbst nutze verschiedenste Lösungen, die alle vor und Nachteile haben. Meine präferierte Lösung ist die Verwendung des Shelly Blu H&T Sensors. Dieser lässt sich wie das Relais auch sehr einfach in openHAB einbinden, die smarte Lösung wäre rein theoretisch auch mittels Shelly App und dem virtuellen Shelly Thermostat nutzbar und er liefert die Daten in einem angemessenen Zeitrahmen. Dies ist zum Beispiel beim Shelly H&T im Batteriebetrieb nicht ganz so optimal, da hier bei geringer Temperaturschwankung nur alle paar Stunden ein Update an openHAB geschickt wird.
Weitere Lösungen die ich einsetze sind auch zum Beispiel:
- Netatmo Smarte Wetterstation
- Raspberry Pi DHT22 Temperatur Sensor
- Raspberry Pi BME680 Gas Sensor
- Raspberry Pi zero w zur Raumluft und Luftqualitätsüberwachung
Die Sensoren Sollten im besten Fall dort positioniert werden, wo man sich im Raum befindet, also zum Beispiel im Wohnzimmer in der näher der Couch. Vermeidet es die Sensoren dort anzubringen, wo die Messungen zum Beispiel durch Geräte, mit Wärmeentwicklung verfälscht werden. Auch sollten das Anbringen an Außenwänden vermieden werden.
Einbinden in openHAB und anlegen Helferitems
Um nun unsere Heizungssteuerung nach openHAB zu bekommen, benötigen wir als erstes ein Gruppen Item, unter welcher wir dann die ganzen Items zur Steuerung der Heizung hinzufügen. Ich nutze dafür eine Gruppe, die wie folgt aus sieht:
Die Parent Gruppe ist bei mir, der Ort, an dem das Thermostat sich befindet. ansonsten sollte man die Semantic Class HVAC (Heizung und Klima) auswählen. Label und Itemname ist jedem selbst überlassen. Typ ist selbstverständlich "Gruppe".
Nun benötigen wir in der Gruppe die folgenden Items:
- Heizungsventil Switch item (über Shelly Binding)
- Temperatur Sensor Item (H&T sensor Item)
- Luftfeuchtigkeit Sensor Item (H&T sensor Item)
- Thermostat Switch Item (Helferitem)
- Solltemperatur Item (Helferitem)
Ich habe noch zusätzlich ein Item für den Luftfeuchtigkeit Alarm und den Batterieladezustand meines H&T Sensors, die beiden Items sind aber für die Anleitung hier irrelevant. Die beiden Helferitems habe ich wie folgt angelegt:
Thermostat Switch Item:
Solltemperatur Item:
In den Metadaten des Item habe ich noch die folgende "State Description" ergänzt ergänz um den Min und Max Temperatur Wert festzulegen und das die Temperatur einstellen im 0.1 er Steps geschieht:
value: " "
config:
pattern: "%0.1f %unit%"
step: "0.1"
min: "18"
max: "30"
Booster Mode
Um den Booster Mode zu verwenden, bei dem entsprechend eines Booster Switch Items die Logik der automatischen Heizungssteuerung für X Minuten (hier 45min) überschrieben wird, benötigen wir ein oder für jeden Raum ein eigenes Booster Switch Item. Ich verwende bei mir nur ein Booster Item für alle Räume, da ich, wenn die Photovoltaikanlage im Winter gut produziert einfach alle Räume auf einmal heizen möchte.
Es handelt sich hierbei um ein Standard Switch Item:
Damit das ganze nun auch zeitgesteuert funktioniert, wird noch ein kleines Regelwerk benötigt:
Blockly Regelwerk:
hier der Code zum Copy and Pasten. Es muss vorher ein Label Name für die Regel vergeben werden.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: Fussbodenheizung_Boost
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
type="controls_if" id="/W,=j[B]jMmVBr}c6~HD" x="446" y="420"><mutation
elseif="1"></mutation><value name="IF0"><block type="logic_compare"
id="wMq2Ztf0}1XPe(h7832B"><field name="OP">EQ</field><value
name="A"><block type="oh_getitem_state" id="Tq*sPe7tDt*OG!oyw;PW"><value
name="itemName"><shadow type="oh_item"
id="|vg(iqsH`~;y]-VjAt#i"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="@=Wk0yUlg.U,uD2}y!Mw"><mutation itemName="Fussbodenheizung_Boost"
itemLabel="Fußbodenheizung Booster"></mutation><field
name="itemName">Fussbodenheizung_Boost</field></block></value></block></value><value
name="B"><block type="text" id=".*$$8|,6`E`PI9zOvS3A"><field
name="TEXT">ON</field></block></value></block></value><statement
name="DO0"><block type="oh_event" id="uq@8EAbK]ut=/Rs/YUpW"><field
name="eventType">sendCommand</field><value name="value"><shadow
type="text" id="m7.d)uvNi-=,*+-E5}_a"><field
name="TEXT">value</field></shadow><block type="text"
id="mkEm(NWV$Wweiww83]=q"><field
name="TEXT">ON</field></block></value><value name="itemName"><shadow
type="oh_item" id="O]`Z=*@+a)j2CR}gct;]"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="4%VX0C#oTdK[;xo9T{8y"><mutation itemName="Heatingvalve_ALL"
itemLabel="Alle Heizungsventile"></mutation><field
name="itemName">Heatingvalve_ALL</field></block></value><next><block
type="oh_timer" id="@KC8S/mzYie!FOYqSc2d"><field
name="delayUnits">plusMinutes</field><field
name="cache">private</field><value name="delay"><shadow
type="math_number" id="i@_e/3B`7DqqCiW)gB1i"><field
name="NUM">10</field></shadow><block type="math_number"
id="{GasnEcG0=%%I0k|a~vA"><field
name="NUM">45</field></block></value><value name="timerName"><shadow
type="text" id="nVAX@5dahI+5S[E+8k.t"><field
name="TEXT">MyTimer</field></shadow><block type="text"
id="o3n/$*c_VWe}/FCizxQ/"><field
name="TEXT">HeatingBoost</field></block></value><value
name="context"><shadow type="oh_logic_undefined"
id=":q76[AYLS():8(_%f5Yi"></shadow></value><statement
name="timerCode"><block type="oh_event" id="oD*/)JSS%kH(TxNs.6/;"><field
name="eventType">sendCommand</field><value name="value"><shadow
type="text" id="m7.d)uvNi-=,*+-E5}_a"><field
name="TEXT">value</field></shadow><block type="text"
id="3u]Ry-Ctul)32=mnp`dV"><field
name="TEXT">OFF</field></block></value><value name="itemName"><shadow
type="oh_item" id="O]`Z=*@+a)j2CR}gct;]"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="`0ns}ek{wsxP|Oywq.bc"><mutation itemName="Heatingvalve_ALL"
itemLabel="Alle Heizungsventile"></mutation><field
name="itemName">Heatingvalve_ALL</field></block></value><next><block
type="oh_event" id="oLDe1d;vjfqP*{I(=K(;"><field
name="eventType">sendCommand</field><value name="value"><shadow
type="text" id="m7.d)uvNi-=,*+-E5}_a"><field
name="TEXT">value</field></shadow><block type="text"
id="jSUBR8UNH-#e`?JGG1^*"><field
name="TEXT">OFF</field></block></value><value name="itemName"><shadow
type="oh_item" id="O]`Z=*@+a)j2CR}gct;]"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="0dy-%@z1nwPbkvo7.v/^"><mutation itemName="Fussbodenheizung_Boost"
itemLabel="Fußbodenheizung Booster"></mutation><field
name="itemName">Fussbodenheizung_Boost</field></block></value></block></next></block></statement></block></next></block></statement><value
name="IF1"><block type="logic_operation"
id="7r`mjh{@h%o-P`x#s,jx"><field name="OP">AND</field><value
name="A"><block type="oh_timer_isActive"
id="?uv4Wv^bhke:]`Z)t-(I"><field name="cache">private</field><value
name="timerName"><shadow type="text" id="wviGFtaSPUv(;b*G9Xd9"><field
name="TEXT">MyTimer</field></shadow><block type="text"
id=",H}-Uk2a0.rXD~yY~hk8"><field
name="TEXT">HeatingBoost</field></block></value></block></value><value
name="B"><block type="logic_compare" id="F0@*OC3`fW~Pne6ArNk{"><field
name="OP">EQ</field><value name="A"><block type="oh_getitem_state"
id="mb|tE(UB^H=+gMbBD9;o"><value name="itemName"><shadow type="oh_item"
id="|vg(iqsH`~;y]-VjAt#i"><mutation itemName="MyItem"
itemLabel="MyItem"></mutation><field
name="itemName">MyItem</field></shadow><block type="oh_item"
id="^rS73[]o5odr?C39EHT%"><mutation itemName="Fussbodenheizung_Boost"
itemLabel="Fußbodenheizung Booster"></mutation><field
name="itemName">Fussbodenheizung_Boost</field></block></value></block></value><value
name="B"><block type="text" id="}bR,?D(4OdX|Pe=]yQl:"><field
name="TEXT">OFF</field></block></value></block></value></block></value><statement
name="DO1"><block type="oh_timer_cancel"
id="s^WIpW@QxSVOrB5#xn!X"><field name="cache">private</field><value
name="timerName"><shadow type="text" id=":?NN:hea_@T*c3]BhRai"><field
name="TEXT">MyTimer</field></shadow><block type="text"
id="^_^nd.mNbvI5+gS+Y(%e"><field
name="TEXT">HeatingBoost</field></block></value></block></statement></block></xml>
type: application/javascript
script: >
if (items.getItem('Fussbodenheizung_Boost').state == 'ON') {
items.getItem('Heatingvalve_ALL').sendCommand('ON');
if (cache.private.exists('HeatingBoost') === false || cache.private.get('HeatingBoost').hasTerminated()) {
cache.private.put('HeatingBoost', actions.ScriptExecution.createTimer('HeatingBoost', time.ZonedDateTime.now().plusMinutes(45), function (timer_context) {
items.getItem('Heatingvalve_ALL').sendCommand('OFF');
items.getItem('Fussbodenheizung_Boost').sendCommand('OFF');
}, undefined));
};
} else if ((cache.private.exists('HeatingBoost') &&
cache.private.get('HeatingBoost').isActive()) &&
items.getItem('Fussbodenheizung_Boost').state == 'OFF') {
if (cache.private.exists('HeatingBoost')) { cache.private.remove('HeatingBoost').cancel(); };
}
type: script.ScriptAction
Thermostat Regelwerk mit Blockly Library
Um mir das Leben und viel Copy and Paste zu ersparen habe ich mir mittels selbst erstellter Blockly Library ein Regelwerk erstellt, welches ich ganz einfach in meine Blockly Regeln einbauen kann. Den kompletten Code meiner Blockly Libraries bekommt ihr bei GitHub, ist weiter unten verlinkt. Diesen könnt ihr in openHAB unter Entwickler Tools --> Block Libraries
einfach via Copy and Paste einfügen.
Hier der aktueller Code bei GitHub:
Habt ihr das getan, könnt ihr für jeden Raum einfach eine Regel erstellen, die wie folgt aus sieht:
Ihr könnt die Regel auch einfach alle X Minuten triggern, falls ihr dies möchtet. ich bin hier aber eher der Fan von einer direkt Triggerung, falls ein Zustand sich ändert.
Als Script unter Then, wählt ihr Blockly aus. Ihr findet dann unter Libraries --> Blocklibraries Laub-home.de
, den großen Control Thermostat Block, den ihr einfügen könnt.
Pflicht ist es hier nun die vorher angelegten Items auszuwählen:
- Thermostat Switch Item
- Raum Solltemperatur Item
- Heizungsventil Switch Item (vom Shelly Relais)
- Raum Temperatur Sensor Item
- alles andere könnt ihr so lassen wie es ist um die Grundfunktionen zu nutzen.
Optionale Settings:
- LogLevel, möchtet ihr zum Debuggen den LogLevel Ändern, könnt ihr das direkt mit dem Menü machen.
- Habt ihr das Booster Item von weiter oben angelegt und möchtet es verwenden, dann nutzt get state of item --> Booster Item
- Solltet ihr einen An/Abwesenheitsschalter nutzen, dann auch einfach wie im Screenshot hinzufügen
- Ich habe zusätzlich noch die Möglichkeit meinen Wärmepumpe Smart-Grid Status mit einzubinden, um bei Status grün, die Raum Solltemperatur nochmals zu erhöhen, solange der Status auf Grün ist.
Thermostat Widget
Ich habe mir ein einfaches Thermostat List Widget für die Steuerung und den Klimastatus im Raum gebaut:
- Zeigt die aktuelle Raumtemperatur und (Luftfeuchtigkeit) an
- Einstellung der Solltemperatur
- Icon zeigt mit. Rot an, das aktuell nicht geheizt wird (Heizungsventil Item aus) bei grün wird geheizt (Heizungsventil Item an)
- ebenfalls zeigt die Farbe der Solltemperatur Einstellung mit grün (aus) und orange (an) den Zustand des Heizungsventils an.
- das Symbol vor "aktuell" zeigt an, ob der Thermostat Switch aktiviert ist (grün) oder nicht (rot)
hier der Code für das Hinzufügen in openHAB unter Entwicklertools --> Widgets
:
uid: thermostat_list_widget
tags:
- heating
- temperature
- thermostat
props:
parameters:
- description: The label for the widget
label: Title
name: title
required: false
type: TEXT
- context: item
description: Setpoint temperature item
label: Setpoint Temperature
name: item
required: false
type: TEXT
- context: item
description: Current Temp item
label: Current temperature
name: isttemp
required: false
type: TEXT
- context: item
description: Current Humidity item
label: Current humidity
name: isthumidity
required: false
type: TEXT
- context: item
description: Thermostat item
label: Thermostat
name: istthermostat
required: false
type: TEXT
- context: item
description: Heatingvalve item
label: Heatingvalve
name: istvalve
required: false
type: TEXT
- description: Icon
label: List Icon
name: seticon
required: false
type: TEXT
- description: Min Value
label: Min
name: minset
required: false
type: TEXT
- description: Min Value
label: Max
name: maxset
required: false
type: TEXT
- description: Min Value
label: step
name: stepset
required: false
type: TEXT
parameterGroups: []
timestamp: Dec 3, 2024, 1:04:23 PM
component: oh-stepper-item
config:
actionAnalyzerCoordSystem: time
actionAnalyzerItems:
- =props.isttemp
- =props.item
- =props.istvalve
color: "=(items[props.istvalve].state == 'ON') ? 'yellow' : 'green'"
fill: true
icon: "=props.seticon ? props.seticon : 'iconify:mdi:heated-floor'"
iconColor: "=(items[props.istvalve].state == 'ON') ? 'green' : 'red'"
item: =props.item
max: "=props.maxset ? props.maxset : 30"
min: "=props.minset ? props.minset : 18"
round: true
small: false
step: "=props.stepset ? props.stepset : 0.1"
subtitle: "= (items[props.istthermostat].state == 'ON' ? '🟢' : '🔴') + '
aktuell: ' + items[props.isttemp].state + ' (' +
items[props.isthumidity].state + ')'"
title: "=props.title ? props.title : props.item"
den aktuellen Code im GitHub Repository findet ihr hier:
Nun kann man das Widget dem jeweiligen Solltemperatur Item als Default List Widget via Metadata mitgeben und entsprechend konfigurieren: