Meine Fußbodenheizung (Warmwasser) wurde bisher mit Busch-Jäger Bimetall-Thermostaten gesteuert. Das lief zwar gut, aber es gab keine Möglichkeit für Nachtabsenkung oder Abwesenheitsschaltung. Als SmartHome-Freak will ich aber alles per Tablett steuern. Es folgten einige Versuche mit fertigen Elektronik-Thermostaten, MAX! und HomeMatic, aber nichts war wirklich befriedigend - teils auch sehr teuer. Seit längerer Zeit setze ich im Haus Shellies für die Lichtschalter ein, welche per WiFi angebunden sind und in eine Unterputzdose passen. Diese sind preisgünstig, zuverlässig und können per MQTT in OpenHAB eingebunden werden. Den Shelly HT setze ich nicht ein, weil er ein Standalone-Gerät mit Batteriebetrieb ist und deshalb nur sehr selten Temperatur-Updates an OpenHAB sendet. Seit Allterco einen Temperatursensor-Addon für den Shelly 1 anbietet, habe ich mit dem Gedanken gespielt, dieses Duo für das Thermostat zu verwenden. |
Funktionsweise
Der Shelly 1 mit dem Addon läuft als Zweipunktregler über die "Temperature Actions". Das funktioniert auch, wenn das WLAN oder OpenHAB nicht funktionieren sollten. Die Schaltschwellen werden dem Shelly 1 über HTTP-Befehle aus OpenHAB vorgegeben. MQTT funktioniert nicht für diese Parameter, evtl. einmal in einer späteren Firmware.
Der Shelly gibt alle Messwerte und die Relaisstellung per MQTT an OpenHAB zurück, so dass sie dort in der Sitemap angezeigt werden können. Das Relais steuert meine Heisswasserventile im Heizverteiler an.
Es gibt ein paar globale virtuelle Schalter für alle Thermostatventile:
- Heizung Ein/Aus (Sommer/Winter)
- Tag-/Nacht-Umschaltung per CRON. Nachts werden niedrigeren Temperaturen verwendet.
- Hysterese: das ist der Abstand in °C zwischen Ein- und Ausschalten der Thermostate. Da der Shelly nur auf 0,1°C genau misst, sollten mindestens 0,2°C eingestellt werden
Meine Fußboden-Heizungspumpe ist leider nicht elektronisch geregelt, weshalb sie früher den gesamten Winter hindurch lief. Die Pumpe hat einen eigenen Shelly 1 erhalten, welcher von der Gruppe aller Thermostatventile gesteuert wird. Ist mindestens ein Ventil eingeschaltet, läuft auch die Pumpe. Erst wenn alle Ventile aus sind, wird auch die Pumpe ausgeschaltet.
Hardware
Kauf-Hardware
- 1x Shelly 1, 10,90€
- 1x Temperatursensor-Addon, 6,90€
- 1x DS18B20-Sensor im TO92-Gehäuse, 1,20€
Die Gesamtkosten für ein Thermostat betragen also 19€.
Links der Shelly 1 und rechts das Temperatursensor-Addon. Das Addon wird in die Programmierbuchse des Shelly eingesteckt. | |
Der Temperatursensor DS18B20 im TO92-Gehäuse |
3D-Druck-Gehäuse
Es gibt kein passendes Thermostatgehäuse von Busch Jäger, deshalb habe ich selbst eines konstruiert - es besteht aus der Wandplatte, dem Shelly-Adapter und dem Deckel für den Sensor. Ihr könnt es bei Thingiverse herunterladen: https://www.thingiverse.com/thing:4579411
Oben der runde Shelly-Adapter, darunter die Wandplatte und die Abdeckung. |
Software für die Shellies
Der Shelly 1 ist mit der derzeit aktuellen Shelly-Firmware 1.8.0 bestückt.
Bei der Einrichtung über die Weboberfläche muß man im Shelly die Zugangsdaten des eigene WLAN und des MQTT-Servers eingeben. Der MQTT-Server Mosquitto befindet sich mit OpenHAB auf dem Raspberry Pi.
Montage
Der Shelly-Adapter wird mit M3x12-Schrauben an der Wandplatte befestigt. Die Schraube in der Mitte ist eine M3x16 für die Verschraubung des Deckels. | |||||||||||||
Die M3-Muttern werden mit einem Lötkolben in das PLA-Gehäuse eingepresst. Das dauert nur wenige Sekunden. | |||||||||||||
Der Shelly 1 wird jetzt von oben in den Adapter gedrückt, bis er auf der Verschraubung sitzt. Der Adapter ist einige Millimeter von der Wandplatte entfernt. Dies verringert eine Wärmeübertragung des Shelly auf die Wandplatte, hinter welcher der Sensor sitzt. | |||||||||||||
Das Temperatursensor-Addon wird jetzt auf der Programmierbuchse des Shelly aufgesteckt. Die drei Drähte werden durch das Loch der Wandplatte geführt. | |||||||||||||
Auf der Vorderseite werden die drei Drähte herausgeführt. Der Busch Jäger-Rahmen passt sehr gut auf die Wandplatte. |
|||||||||||||
Die Drähte werden etwas gekürzt und dann an den DS18B20 angelötet. Schrumpfschläuche verhindern einen Kurzschluss. Die Belegung:
|
|||||||||||||
Unbedingt die Sicherung ausschalten und nachprüfen, ob die Drähte spannungsfrei sind! Nach Abnehmen des alten Thermostats, werden jetzt die 230V-Drähte an den Shelly angeschlossen. |
|||||||||||||
Nach Festziehen und Kontrolle der Klemmen, wird der Addon aufgesteckt. | |||||||||||||
Das Modul wird in die Unterputzdose eingeschoben und die Wandplatte mit zwei Schrauben befestigt. | |||||||||||||
Der angelötete Temperatursensor wird in die Nut des Deckels eingeklemmt. Evtl. mit etwas Heißkleber sichen. | |||||||||||||
Jetzt setzt man die Busch Jäger Rahmen auf und verschraubt des Deckel mit der Zentralschraube. Fertig! Jetzt kann man die Sicherung wieder einschalten und testen, ober der Shelly 1 per Web-Interface erreichbar ist. |
OpenHAB Things
Jedes Thermostat ist ein eigenes Thing mit jeweils zwei Channels: Temperatur und Relais. Erstellt eine Datei things/mqtt.things mit folgendem Inhalt:
//---------------------------------------------------------------------------------- // Shelly 1 mit Temperature Addon for WZ-Thermostat Thing mqtt:topic:HZ_WZ_FloorThermostat "Th-HZ-WZ-FloorThermostat" { Channels: Type number : chTemp "Temperatur" [ stateTopic="shellies/shelly1-A4CF12F3E44D/ext_temperature/0" ] Type switch : chRelais "Ventilausgang" [ stateTopic="shellies/shelly1-A4CF12F3E44D/relay/0", on="on", off="off", commandTopic="shellies/shelly1-A4CF12F3E44D/relay/0/command", on="on", off="off" ] }
Den MQTT-Pfad zum Shelly findet man am Besten mit dem "MQTT-Explorer" (Windows) heraus:
Könnt Ihr über den Windows-Store für Windows 10 herunterladen.
OpenHAB Items
Für jedes Thing (=Thermostat) müssen zwei Items angelegt werden. Erstellt eine Datei items/mqtt.items mit folgendem Inhalt:
// shelly1-A4CF12F3E44D Number It_WZ_ActTemperature "Wohnzimmer Temperatur [%.1f °C]" (gPersistMapDB, Thermostat) { channel="mqtt:topic:HZ_WZ_FloorThermostat:chTemp", alexa="TemperatureSensor.temperature" } Switch It_WZ_RelaisThermostat "Wohnzimmer Thermostatventil [MAP(onoff.map):%s]" (gPersistMapDB, gHeatingValves) { channel="mqtt:topic:HZ_WZ_FloorThermostat:chRelais" }
Zusätzlich werden noch virtuelle Items für die Temperaturen und Tag/Nacht- bzw. Sommer/Winter-Einstellung benötigt:
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Fußbodenheizung mit Shelly 1 & Temperatur-Addon: // Globale Werte: Group:Switch:OR(ON, OFF) gHeatingValves "Heizventile [MAP(onoff.map):%s]" (Home) Number vIt_HZ_Hysterese "Fußbodenheizung Hysterese [%.1f °C]" (gPersistMapDB) Switch vIt_HZ_OnOff "Fußbodenheizung [MAP(onoff.map):%s]" (gPersistMapDB) Switch vIt_HZ_DayNight "Fußbodenheizung Programm [MAP(heating.map):%s]" (gPersistMapDB) Group Thermostat "Wohnzimmer" {alexa="Endpoint.Thermostat"} // Thermostat GF_LivingRoom: Number vIt_HZ_WZ_SollTag_upper "Wohnzimmer Solltemperatur Tag [%.1f °C]" (gPersistMapDB, Thermostat) {alexa="ThermostatController.upperSetpoint"} Number vIt_HZ_WZ_SollTag_lower "Wohnzimmer Solltemperatur Tag Start [%.1f °C]" (gPersistMapDB) Number vIt_HZ_WZ_SollNacht_upper "Wohnzimmer Solltemperatur Nacht [%.1f °C]" (gPersistMapDB) Number vIt_HZ_WZ_SollNacht_lower "Wohnzimmer Solltemperatur Nacht Start [%.1f °C]" (gPersistMapDB)
OpenHAB Rules
Erstellt eine Datei rules/heating.rules mit folgendem Inhalt:
//================================================================================== // Global Thermostat Rules: //---------------------------------------------------------------------------------- // Nightly temperature reduction for all thermostats: // http://www.cronmaker.com/;jsessionid=node01fm60c8kkb5fb1uiiavit2knbt5438.node0?0 // Night reduction starting everyday at 19:30 rule "FloorHeating_NightReduction" when Time cron "0 30 19 1/1 * ? *" then vIt_HZ_DayNight.sendCommand( 'OFF' ) logInfo( "FloorHeating_NightReduction", "Rule FloorHeating_NightReduction ...") end //---------------------------------------------------------------------------------- // Daily temperature operation for all thermostats: // http://www.cronmaker.com/;jsessionid=node01fm60c8kkb5fb1uiiavit2knbt5438.node0?0 // Day operation starting everyday at 07:00 rule "FloorHeating_DayOperation" when Time cron "0 0 7 1/1 * ? *" then vIt_HZ_DayNight.sendCommand( 'ON' ) logInfo( "FloorHeating_DayOperation", "Rule FloorHeating_DayOperation ...") end //---------------------------------------------------------------------------------- // Floor Heating Pump: shellies/shelly1-A4CF12F48853 rule "FL_FloorHeatingPump" when Item gHeatingValves received update then if(gHeatingValves.state==ON){ // Switch ON=pump running It_FL_Pump.sendCommand( "ON" ) logInfo( "FL_FloorHeatingPump", "Heating ON" ) } else { // Switch OFF=pump not running It_FL_Pump.sendCommand( "OFF" ) logInfo( "FL_FloorHeatingPump", "Heating OFF" ) } end //================================================================================== // Thermostat Wohnzimmer: //---------------------------------------------------------------------------------- // Calculate lower DAY setpoint if hysterese or upper setpoint have changed rule "WZ_Thermostat_LowerSetpointDay" when Item vIt_HZ_Hysterese changed or Item vIt_HZ_WZ_SollTag_upper changed then var Double UpperSetpoint = ( vIt_HZ_WZ_SollTag_upper.state as Number ).doubleValue() var Double Hysterese = ( vIt_HZ_Hysterese.state as Number ).doubleValue() var Double LowerSetpoint = UpperSetpoint - Hysterese vIt_HZ_WZ_SollTag_lower.sendCommand( LowerSetpoint ) logInfo( "WZ_Thermostat_LowerSetpointDay", "Rule WZ_Thermostat_LowerSetpointDay: " + "TagLower= " + LowerSetpoint ) end //---------------------------------------------------------------------------------- // Calculate lower NIGHT setpoint if hysterese or upper setpoint have changed rule "WZ_Thermostat_LowerSetpointNight" when Item vIt_HZ_Hysterese changed or Item vIt_HZ_WZ_SollNacht_upper changed then var Double UpperSetpoint = ( vIt_HZ_WZ_SollNacht_upper.state as Number ).doubleValue() var Double Hysterese = ( vIt_HZ_Hysterese.state as Number ).doubleValue() var Double LowerSetpoint = UpperSetpoint - Hysterese vIt_HZ_WZ_SollNacht_lower.sendCommand( LowerSetpoint ) logInfo( "WZ_Thermostat_LowerSetpointNight", "Rule WZ_Thermostat_LowerSetpointNight: " + " NachtLower= " + LowerSetpoint ) end //---------------------------------------------------------------------------------- // Send new values to the Shelly via HTTP if one of the values has been switched or // The switch DAY/NIGHT has changed rule "WZ_Thermostat_SetShelly" when Item vIt_HZ_WZ_SollTag_upper changed or Item vIt_HZ_WZ_SollTag_lower changed or Item vIt_HZ_WZ_SollNacht_upper changed or Item vIt_HZ_WZ_SollNacht_lower changed or Item vIt_HZ_DayNight changed then Thread::sleep(200) var Double UpperSetpoint var Double LowerSetpoint if(vIt_HZ_DayNight.state==ON){ // Switch ON=Day setpoints UpperSetpoint = ( vIt_HZ_WZ_SollTag_upper.state as Number ).doubleValue() LowerSetpoint = ( vIt_HZ_WZ_SollTag_lower.state as Number ).doubleValue() } else { // Switch OFF=Night setpoints UpperSetpoint = ( vIt_HZ_WZ_SollNacht_upper.state as Number ).doubleValue() LowerSetpoint = ( vIt_HZ_WZ_SollNacht_lower.state as Number ).doubleValue() } // Send http to Shelly: var String httpString = "" httpString = "http://10.2.10.56/settings/ext_temperature/0?overtemp_threshold_tC=" + String::format("%.2f",UpperSetpoint) sendHttpGetRequest(httpString) logInfo( "WZ_Thermostat_SetShelly", "Rule WZ_Thermostat_SetShelly: " + httpString ) httpString = "http://10.2.10.56/settings/ext_temperature/0?undertemp_threshold_tC=" + String::format("%.2f",LowerSetpoint) sendHttpGetRequest(httpString) logInfo( "WZ_Thermostat_SetShelly", "Rule WZ_Thermostat_SetShelly: " + httpString ) end //----------------------------------------------------------------------------------EVERY Thermostat // Switch Shelly ON/OFF for SUMMER/WINTER switch rule "WZ_Thermostat_HeatingOnOff" when Item vIt_HZ_OnOff changed then var String httpString = "" if(vIt_HZ_OnOff.state==ON){ // Switch ON=heating running httpString = "http://10.2.10.56/settings/ext_temperature/0?overtemp_act=relay_off" sendHttpGetRequest(httpString) logInfo( "WZ_Thermostat_HeatingOnOff", "Heating ON: " + httpString ) httpString = "http://10.2.10.56/settings/ext_temperature/0?undertemp_act=relay_on" sendHttpGetRequest(httpString) logInfo( "WZ_Thermostat_HeatingOnOff", "Heating ON: " + httpString ) } else { // Switch OFF=heating switched off httpString = "http://10.2.10.56/settings/ext_temperature/0?overtemp_act=disabled" sendHttpGetRequest(httpString) logInfo( "WZ_Thermostat_HeatingOnOff", "Heating ON: " + httpString ) httpString = "http://10.2.10.56/settings/ext_temperature/0?undertemp_act=disabled" sendHttpGetRequest(httpString) It_WZ_RelaisThermostat.sendCommand( OFF ) logInfo( "WZ_Thermostat_HeatingOnOff", "Heating ON: " + httpString ) } end
OpenHAB Map
Erstellt eine Datei transform/onoff.map mit folgendem Inhalt:
ON=EIN on=EIN On=EIN 1=EIN OFF=AUS off=AUS Off=AUS 0=AUS NULL=undefiniert UNDEF=undefiniert -=undefiniert
OpenHAB Sitemap
Erstellt eine Datei sitemaps/heating.sitemap mit folgendem Inhalt:
sitemap heating label="Fußbodenheizung" { Frame label="Globale Einstellung Fußbodenheizung" { Setpoint item=vIt_HZ_Hysterese minValue=0.1 maxValue=4.0 step=0.1 Switch item=vIt_HZ_OnOff Switch item=vIt_HZ_DayNight Default item=gHeatingValves Default item=It_FL_Pump } Frame label="Heizung Wohnzimmer" { Text item=It_WZ_ActTemperature Switch item=It_WZ_RelaisThermostat Setpoint item=vIt_HZ_WZ_SollTag_upper minValue=4.5 maxValue=35 step=0.5 Text item=vIt_HZ_WZ_SollTag_lower Setpoint item=vIt_HZ_WZ_SollNacht_upper minValue=4.5 maxValue=35 step=0.5 Text item=vIt_HZ_WZ_SollNacht_lower } }
Das Ergebnis im Browser:
Die verwendeten Icons für Ventile und Pumpe sind nicht in OpenHAB enthalten, Ihr müsst eigene verwenden.
Fazit und Ausblick
Das Projekt mit seinen fünf Thermostaten hat mich ein paar Tage beschäftigt, speziell das Design und der 3D-Druck. Nach dem Einbau und der Konfiguration funktioniert es fehlerfrei. Jetzt muß nur noch der Winter kommen - das ist dann der harte Praxistest. Aktuell versuche ich die Steuerung der Temperaturen über Alexa vorzunehmen, aber das ist ein anderes Thema.
Was könnte man noch verbessern?
- Eigene Zeiten für jedes einzelne Thermostat verwenden
- Abwesenheit der Hausbewohner zur Absenkung auch tagsüber
- Alexa für die Einstellungen verwenden