OpenHAB Fußbodenheizung Thermostat mit Shelly Relais

Aus Laub-Home Wiki

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

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:

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: