Dieses Projekt realisiert eine Temperaturregelung einzelner Heizkreise, hier: klassische Heizkörper. Es ist darauf ausgelegt, auch bei Ausfall des Haushalt internen WLAN noch genutzt werden zu können. Die Hardware besteht aus einem Shelly Plus 1 mit AddOn, einem Sensor - DHT22 oder DS18B20, zwei Mikrotastern, einem Elko und einem Widerstand. Zusätzlich wird ein Stellantrieb zum öffnen/schließen des Heizkreisventils benötigt. Das gesamte Gerät aus obigen Teilen ersetzt einen Shelly TRV komplett. Die Mikrotaster + Elko + Widerstand sind nicht zwingend erforderlich, bieten aber für nicht IT affine Anwender eine schlichte Einstellung der Zieltemperatur ohne modernen IT "Schnickschnack". 😉
Neu: Skript geringfügig geändert
Inhalt
Eigenschaften
Die wichtigsten Eigenschaften des Gerätes sind
- Autarkie, d.h. die Regelung arbeitet, solange sie mit el. Energie (230V) versorgt wird, unabhängig von sonstigen Umgebungen.
- Einstellbarkeit auch bei Ausfall des WLAN oder eines übergeordneten Systems. Bei WLAN Ausfall kann der Shelly eigene Access Point verwendet werden.
Beide Eigenschaften werden wie folgt erfüllt.
zu 1.
Die Regelung ist im Skript implementiert und kann bei Bedarf verändert werden. Aktuell ist eine Zweipunktregelung implementiert, mit Schalthysterese. Die Schaltschwellen sind im Skript verankert und gelten relativ zur eingestellten Zieltemperatur. Bei Unterschreitung der unteren Schwelle wird das Ventil per einschalten des Ventilantriebs geöffnet. Bei Überschreitung der oberen Schaltschwelle wird das Ventil per ausschalten des Ventilantriebs geschlossen. Diese Regelung hat sich bisher bewährt, obwohl sie Raum lässt für Verbesserungen feinfühligerer Art.
zu 2.
Zur einfachen Einstellung sind zwei Mikrotaster am AddOn, also mit Niedrigspannung betrieben, vorgesehen. Ein Taster zum erhöhen, der andere zum absenken der Zieltemperatur - je Tastendruck um bspw. 0,5°C. Als Rückmeldung wird das Ausgangsrelais 1s lang eingeschaltet, was zwei leise Klicklaute ergibt. Ein Taster wird für den digitalen, der andere für den analogen Eingang verwendet. Die Schaltung aus R und C zum S2 ist erforderlich, weil die Firmware eine Spannungsänderung am analogen Eingang nur meldet, wenn diese eine gewisse Mindestdauer lang anliegt. Hier wird selbstverständlich die analoge Eingangsspannung binär interpretiert (Low vs. High). Früher hätte ich vermutlich ein Potentiometer am analogen Eingang und eine LED-Balkenanzeige verbastelt, was ich mittlerweile als eher zu sehr retrospektiv einstufe. 😉
Mikrotaster am AddOn - S1 und S2
Diese Beschaltung ist für die autarke Heizkreisregelung nicht erforderlich, weil dafür das Skript auch eine Webseite zur Verfügung stellt. Mit Hilfe der Taster können jedoch wenig IT affine Nutzer die Zieltemperatur schrittweise ändern.
Zu den Schaltungen gilt mein Dank an Rolf aus dem Forum. Die Dimensionierungen beider Varianten sind noch geschätzt und sollten geprüft werden.
Zusätzlich stellt das Skript einen anwendungsspezifischen Webserver bereit. Dieser liefert auf Anfrage eine interaktive Webseite, welche reichhaltige Informationen bietet.
NEU: Das aktuelle Skript zeigt die folgende Webseite.
Anwendung
Die Zeitangaben auf der Webseite sollen dem Anwender die Aktualität der gelieferten Daten mitteilen. Ist diese Zeitangabe alt, ist entweder ein Modus ohne Neuladen ausgewählt oder das Skript arbeitet nicht wie gewünscht. Liegt die Zeitangabe im nahen Bereich des Jahres 1970, so verfügt der Shelly mangels Internetzugang und zwischenzeitlichem Stromausfall nicht über die aktuelle Zeit. Man kann dann bspw. sein Smartphone als Hotspot per mobilem Netz kurzzeitig (1 Minute genügt) zum Zugriff auf das Internet zur Verfügung stellen. Damit der Shelly einen Zeitserver erreichen kann, muss er per WiFi-Einstellung für den Zugriff auf das Smartphone eingerichtet sein, bspw. im zweiten WiFi-Eintrag.
Die mittlere Tabelle zeigt acht Wochenpläne, die einzeln editierbar sind. Meine Versuche, die Wochenpläne komplett editierbar zu gestalten, schlugen mangels erforderlichem RAM fehl. Inzwischen bietet die Webseite in der unteren Tabelle, unter den acht Wochenplänen, die komplette Editierbarkeit eines Wochenplans.
Diese Webseite bietet folgende Einstellmöglichkeiten.
-
- Der Wiederholmodus - am oberen Rand - bietet alle im Skript verankerten Modi zirkular an.
In der ersten Zeile steht der aktuelle Modus, hier "alle 60s", was sagen soll, dass diese Webseite in Abständen von 60s neu abgefragt wird. Gewünschte Modi können im Skript konfiguriert werden.
Darunter steht, als Link, der nächste Modus, hier "per Taster einstellen". Dieser Modus lädt die Webseite jede Sekunde neu. Er ist für temporären Einsatz ausschließlich dazu gedacht, zügige Rückmeldungen bei Einstellen der Zieltemperatur per Mikrotaster zu liefern, weil keine Anzeige zur Verfügung steht. Zwischen jeweils zwei Tastendrücken ist aus verschiedenen Gründen mindestens 1s zu warten. - Die Zieltemperatur - in der oberen Tabelle, letzte Zeile erstes Feld - kann mit Hilfe zweier Links (hier die beiden Dreiecke als Pfeile) entsprechend der Mikrotaster um jeweils eine Temperaturstufe erhöht bzw. abgesenkt werden. Die Anzeige wird nach ca. 1s aktualisiert.
- Jeder der vorgesehenen acht Wochenpläne kann durch Veränderung der Aktivität, der Uhrzeit und der Zieltemperatur eingestellt werden. Leider können die Wochentage zu einem Wochenplan hier nicht editiert werden. Meine Versuche, dies für intuitive Nutzung zu implementieren, schlugen mangels verfügbarem RAM fehl. Ich arbeite an einem Konzept, welches vielleicht das Speicherproblem lösen kann. Um die Wochentage eines Wochenplans zu ändern, muss man bis auf weiteres ein anderes Werkzeug verwenden, bspw. https://tools.eichelsdoerfer.net/schedjob.html.
NEU:
Das Skript vom 2024-01-23 ermöglicht auch das Editieren der Wochentage, allerdings ausschließlich als Zahlenliste mit Elementen von 0 (für Sonntag) bis 6 (für Samstag). Das Skript prüft die Wochentag-Zahlenliste auf Fehler. Liegt ein Fehler vor, wird die Wochentagliste ignoriert. Tests zeigten, dass die Firmware auch Wiederholungen von Wochentagen passend verarbeitet. Das Skript prüft somit nur, ob die Liste aus Wochentagsnummern (0 bis 6) besteht. Werte wie 3.2 oder 3.8 werden als 3 verwendet, Nachpunktstellen werden schlicht abgeschnitten.
Beispiele:
0,5,2,4,1 ergibt die Wochentage Sonntag, Freitag, Dienstag, Donnerstag, Montag
1,1,2, 5,2 ergibt die Wochentage Montag, Dienstag Freitag
Um einen Zeitplan für die Wochentage Sonntag, Dienstag, Donnerstag einzustellen, ist die folgende Liste geeignet: 0,2,4
Enthaltene Leerzeichen beseitigt das Skript, damit die Liste an die Firmware syntaktisch richtig übergeben wird.
- Der Wiederholmodus - am oberen Rand - bietet alle im Skript verankerten Modi zirkular an.
Das Skript
Das ältere Skript kann hier als ZIP Archiv heruntergeladen werden: app_2024-01-09_01.zip - dieses beinhaltet leider als Skript Id fest die Nummer 1, was dann als Fehler auftritt, wenn das Skript eine andere Id hat.
Das aktuelle Skript beinhaltet zusätzlich die Einstellbarkeit der Wochentage als Eingabe in ein Textfeld und kann als ZIP Archiv heruntergeladen werden: app_2024-02-22_01.zip. In der aktuellen Fassung sollte ein Link-Fehler (null) nicht mehr auftreten. Dieses Skript arbeitet bisher stabil. Im Skript ist der Variablen "Device" (am Skriptanfang) der gewünschte Name zuzuordnen, damit dieser auf der Webseite passend angezeigt wird.
Das von mir zusammengestellte Skript befindet sich nach wie vor im Entwicklungsstadium, arbeitet aber nach meinen Tests stabil. Prinzipiell kann die Webseite von mehreren Endgeräten (Smartphone, Tablet, PC) gleichzeitig angefordert werden. Allerdings kann nicht erwartet werden, dass der eingestellte Modus (s.o.) auf jedem Endgerät individuell nutzbar ist. Letzteres wäre zwar implementierbar, ich halte solches jedoch für unangemessen.
Es kommuniziert zusätzlich per MQTT, was für den Einsatzzweck nicht zwingend erforderlich ist - kann bei Bedarf also entfernt werden. Ich nutze ein von mir zusammengestelltes "smartcenter", welches Mosquitto, Node-RED, InfluxDB und Grafana beinhaltet. Die Kommunikation zwischen dem Shelly und meinen Node-RED Flows findet in erster Linie per MQTT statt. Wer dieses Projekt in der schlankesten Fassung nutzen will, kann es ohne diese Dinge tun und braucht weder ein zusätzliches "übergeordnetes" System, noch MQTT. Allerdings ist mein Dashboard (Node-RED) für viele IoT Geräte gestaltet und ich kann per Grafana Temperaturverlauf, Zieltemperaturen und Ventil-Öffnungsvorgänge in der Historie einsehen. Insbesondere Letzteres dient in meiner Arbeit auch der Überprüfung der Zuverlässigkeit/Stabilität meiner Implementationen, was ein üblicher Anwender vermutlich nicht braucht.
Wochenpläne
Die Wochenpläne sind Schedule Jobs, welche auch noch spezifischer ausgestaltet werden können. In diesem Fall sind sie ausschließlich in dieser eingeschränkten, aber angemessenen Fassung als reine Wochenpläne eingesetzt. Sie müssen mit einem anderen Werkzeug, wie das bereits erwähnte https://tools.eichelsdoerfer.net/schedjob.html angelegt werden. Ich habe dafür genau acht Schedule Jobs vorgesehen. Vermutlich reichen diese acht für die Heizkreisregelung aus. Zudem sind so bis zu acht weitere zusätzliche Schedule Jobs für spezielle Aufgaben möglich, bspw. zum regelmäßigen öffnen und schließen des Ventils zwecks Erhaltung dessen Gängigkeit. Für Letzteres nutze ich derzeit die in der Abbildung zu sehenden letzten beiden Wochenpläne 7 und 8. Es genügt aber vermutlich, dafür einen oder zwei zusätzliche Schedule Jobs einzusetzen, die dieses Öffnen/Schließen nur einmal pro Monat durchführen. So bleiben alle acht obiger Pläne für die Anwendung erhalten. Alle acht Wochenpläne sind unbedingt vor allen anderen, evtl. zusätzlichen Schedule Jobs anzulegen. Diese müssen also die ID Werte 1 bis 8 tragen. Danach können weitere Jobs angelegt werden.
Meine Webseite zum anlegen, ändern und löschen von Schedule Jobs ist sehr vielseitig nutzbar. Für dieses Projekt ist jeweils die Funktion u_set_tT(<Zieltemperatur>) einzusetzen. Den Funktionsnamen habe ich gewählt, weil er Benutzer (user, u) setzt (set) Zieltemperatur (target temperature, tT) symbolisieren soll. So ist es bei Bedarf auch möglich, alle solcher Benutzer spezifischen Schedule Jobs per Skript zu selektieren. Zum Anlegen aller acht Jobs, kann man folgendermaßen vorgehen.
- IP Adresse des Shelly eingeben - unter 1.
- Bei Bedarf, als Zwischenschritt und zur Prüfung, ob noch irgendwelche Jobs eingetragen sind, alle Jobs auflisten lassen - unter 2.
- Falls nicht vorgesehene Jobs existieren, diese löschen - unter 9.
- Wenn die Skript Id unbekannt sein sollte, diese ermitteln - unter 3.
- Schließlich acht Jobs anlegen. Dies kann unter Punkt 4 der Webseite geschehen, was allerdings eingeschränkt ist. Die flexiblere Möglichkeit existiert unter Punkt 6.
Für beide folgenden, alternativen Wege gilt: Unter aktiv ist nur dann der Haken zu setzen, wenn der entsprechende Job freigegeben (enable=true) werden soll.
- Unter Punkt 4: Acht mal den gleichen, nicht denselben, Job anlegen.
Hierzu jeweils dieselbe Skript Id, Stunde, Minute (Sekunde auf 0 belassen) und unter Funktionsaufruf u_set_tT(18) eintragen. Statt 18 kann selbstverständlich auch ein anderer Wert gewählt werden. - Unter Punkt 6: Hier ist der timespec Wert unter Beachtung dessen Syntax/Struktur einzutragen. Der Funktionsaufruf ist auch hier u_set_tT(...).
Die timespec Zeichenkette ist wie folgt zusammenzustellen - s.a. die komplette Dokumentation hier: https://github.com/mongoose-os-libs/cron. Zahlen ohne führende Nullen, Zwischen den Werten als Trenner ein Leerzeichen.
Sekunde, Minute, Stunde, Tag des Monats, Monat als Zahl, Liste der Wochentage als Zahlenfolge (Sonntag = 0).
Beispiel: 0 30 6 * * 0,3,6 ergibt einen Job für Sonntag, Mittwoch und Samstag um 6:30 Uhr.
Man kann statt Monate und Wochentage als Zahlen auch deren engl. abgekürzte Namen verwenden, was ich in dieser Anwendung nicht vorgesehen habe. Wenn ein Eintrag beliebig ist, ist dafür das Asterisk (*) einzusetzen. Wenn der Job für alle Wochentage gelten soll, genügt an letzter Stelle ein Asterisk statt 0,1,2,3,4,5,6.
- Unter Punkt 4: Acht mal den gleichen, nicht denselben, Job anlegen.
Später kann per vom Skript gelieferter Webseite, wie oben beschrieben, jeder Wochenplan geändert werden - allerdings ohne die Wochentage zu ändern. Wer vorher die Wochenpläne genauer plant, mag bereits im obigen Verfahren die gewünschten Werte passend eintragen.
Meine Empfehlung:
Man lege bspw. für Werktage drei Jobs an, die für Montag bis Freitag gelten und für die Wochenenden drei Jobs für Samstag und Sonntag. Dann findet man später zumeist eine gute Möglichkeit, die Daten wie Uhrzeit und Zieltemperatur anzupassen, ohne die Wochentage ändern zu müssen.
Das aktuelle Skript ermöglicht nun auch das Editieren der Wochentage per Zahlenliste - s.o.
Verbesserte Temperaturregelung
Zunächst soll der folgende Screenshot den geregelten Temperaturverlauf am Beispiel des Frostschutzes in meinem alten "Wintergarten" verdeutlichen - Daten aus einer INfluxDB, dargestellt per Grafana.
Er zeigt, dass die Temperatur erhebliche Überschwinger aufweist, welche ich bestrebt bin zu reduzieren. Es geht im weiteren ausschließlich um diese Überschwinger, also die maximale Temperatur zwischen zwei Einschaltpulsen (weiß).
Ich habe, zunächst theoretisch, ein Verfahren für eine günstigere Temperaturregelung zusammengestellt. Dessen Implementation im Skript und dessen Prüfung auf eine angemessene Wirksamkeit muss noch erfolgen. Diesem Verfahren liegt folgende Überlegung zu Grunde.
Ist der Temperaturüberschwinger zu groß, kann der Ventil-Stellantrieb weniger lange eingeschaltet werden. Ist er zu klein, liegen die Einschaltpulse dichter beieinander als erforderlich. Ich definiere also eine angestrebte maximale Temperaturüberschreitung zwischen zwei Einschaltpulsen, kurz TmZ für Zielwert der maximalen Temperatur (zwischen zwei Einschaltpulsen). Das Verfahren soll mit jedem neuen Einschaltpuls vorausschauend die angemessene Dauer dieses Impulses berechnen und so die Einschaltdauer ständig anpassen.
Das Verfahren
Nach Skriptstart erfolgt zunächst die simple Zweipunktregelung wie bisher. Nach wie vor wird eine Unterschreitung der unteren Schaltschwelle als Trigger für einen Einschaltpuls verwendet. Neu ist, dass die Dauer der Einschaltpulse nachgeführt werden sollen.
Hierfür werden zusätzlich gemessen
- die Dauer des letzten Einschaltpulses tletzt ,
- die maximale Temperatur Tmax zwischen dem letzten Einschalten und dem gerade anstehenden Einschalten.
Ich führe einen Konfigurationsparameter ein, den ich "relative Zieltemperaturüberschreitung" nenne, kurz Trel. Diesen führe ich vorbetrachtend ein als Trel = ΔTmax / TZiel = (Tmax - TZiel) / TZiel = Tmax / TZiel - 1.
Dieser Parameterwert ist abzuleiten aus der Umgebung des Heizkreises. Er ergibt sich aus einer dort typischen mittleren Zieltemperatur TZiel und der angestrebten maximalen Temperatur TmZ zwischen zwei Einschaltpulsen. In obiger Gleichung ersetze ich also Tmax (gemessen) durch TmZ (Parameter) und definiere abschließend
Trel = ΔTmZ / TZiel = (TmZ - TZiel) / TZiel = TmZ / TZiel - 1
Anlass zu diesem Verfahren ist der Frostschutz des im alten Wintergarten befindlichen Heizkörpers, weshalb ich diesen als Beispiel verwende.
Beispiel: TZiel = 5°C, TmZ = 6°C ==> Trel = 6 / 5 - 1 = 1 / 5 = 0,2 (Konfigurationsparameter)
Aus dem konstanten Parameter Trel und der Variablen TZiel ergibt sich der im weiteren verwendete variable Parameter TmZ.
TmZ = (Trel + 1) * TZiel , z.B. 1,2 * TZiel
An Hand der Messwerte tletzt und Tmax sowie des berechneten Parameters TmZ wird zwischen dem letzten Einschaltpuls (nach Skriptstart also der erste) und der aktuellen Unterschreitung der unteren Schaltschwelle die Dauer tein des nun folgenden Einschaltpulses wie folgt berechnet.
Tmax > TmZ ==> tein = 0,9 * tletzt
Tmax < TmZ ==> tein = 1,1 * tletzt
sonst tein = tletzt
Die Faktoren 0,9 und 1,1 basieren auf einem relativen Änderungswert von 10% bezogen auf die letzte Einschaltpuls-Dauer tletzt. Diese 10% sind von mir als vermutlich tauglich angenommen und können bei Bedarf später konfiguriert werden. Die Pulsdauern sollten sukzessive so angepasst werden, dass damit die TmZ approximiert wird.
Im Skript wird somit nach dem ersten Einschaltpuls (nach Skriptstart) für alle folgenden Einschaltpulse ein Timer verwendet. Zur Sicherheit plane ich noch eine Temperaturüberwachung, die auf Grund einer grenzwertigen Übertemperatur (Konfigurationsparameter) das Einschalten unmittelbar beendet.
Optionale Vorhaben
Dieses Projekt wird von mir weiter gepflegt. So kann ich bspw. bei Bedarf eine Anwendung bezogene Konfiguration vorsehen, die einen Eingriff in das Skript überflüssig macht. Hierfür kann ich eine spezielle Webseite zusammenstellen, die fast jeder Anwender nutzen kann. Derzeit fokussiere ich allerdings eine bessere usability für wenig IT affine Anwender. Hierzu sollen gewisse Teile nur bei Bedarf "aufgeklappt" werden. Zusätzlich strebe ich an, auch die Wochentage eines Wochenplans auf der vom Shelly gelieferten Webseite editierbar zu machen. Ein Konzept steht, die Realisierbarkeit ist allerdings wegen RAM Begrenzung nicht sichergestellt.
Neuere Kenntnisse in Browser basiertem JavaScript erlauben es, die bisher von einem Skript gelieferte Webseite auf mehrere Skripte aufzuteilen und die Usability zu verbessern. Dies will ich bei Gelegenheit versuchen.
2024-02-22