Letzte Aktualisierung am 15. Januar 2023
Mein Projekt „Homematic – Sauna 2.0“ habe ich weiterentwickelt und um zusätzliche Sicherheitsfunktionen sowie die Berechnung von Betriebsstunden des Saunaofens und Zeiten/Kosten der Saunanutzung ergänzt.
Updatemaßnahme / Zusatzfunktionalität
- Aktualisierung des Skripts vom Sauna-Homeduino auf die derzeit aktuellste Version
- Abschaltung bei Übertemperatur und mit einem Notaus
- Verhinderung eines versehentlichen Einschaltens
- Ermittlung der Betriebsstunden des Saunaofens
- Berechnung von Zeiten und Kosten der Saunanutzung
- Anpassung der Statusseite und der Kabinenanzeige in der aio NEO App
Das Projekt wird in den Artikeln „Homematic-Sauna 3.0“ (Aufguss Automatik und Lüftung) sowie „Homematic-Sauna 3.1“ (verbesserter Lüftungsschieber) fortgeschrieben.
Homeduino Update
Da ich aufgrund fehlender vorkonfigurierter Ports den Sauna-Homeduino ohnehin neu programmieren musste, habe ich die Gelegenheit genutzt, gleich das Update „hduino415_LAN“ vom 14.11.2020 (geänderte 8181-Requests für aktuelle CCU2 /3 Firmware) durchzuführen.
Die beiden zusätzlich verwendeten Ports…
homeduino_sauna_D18 | Sauna Ofen | Digital-In |
homeduino_sauna_D19 | Sauna Notaus | Digital-In |
…und die zugehörigen Systemvariablen…
homeduino_sauna_D18 | Logikwert | wahr = aus falsch = ein |
homeduino_sauna_D19 | Logikwert | wahr = ausgelöst falsch = nicht ausgelöst |
Link zum aktualisierten Homeduino-Sketch.
Zusätzliche Sicherheitsmaßnahmen
Im ersten Artikel „Homematic – Sauna 2.0“ habe ich bereits dargestellt, dass – aus Gründen des Versicherungsschutzes und weil die originäre analoge Regelung des Saunaofens perfekt funktioniert – in keiner Weise in das originäre System aus Ofen und zugehöriger Ofensteuerung eingegriffen wurde, jedoch ein Homematic Aktor die Spannungsversorgung der bestehenden Ofensteuerung ein und nach maximal drei Stunden wieder ausschaltet. Auch einem Stromausfall muss der Ofen nach Rückkehr der Spannungsversorgung somit wieder manuell eingeschaltet werden.
Obwohl die hiesige Sauna, die aus den 90er Jahren stammt, in Bezug auf die zwischenzeitlich aktualisierten Sicherheitsbestimmungen für Saunen einen Bestandsschutz geniest, wurden somit erste zusätzliche technische Sicherheitsfunktionen in Richtung der neuen Bestimmungen realisiert.
Auch eine Zusatzabfrage vor dem Einschalten mit dem nunmehr geforderten Hinweis, dass der Ofen vorher zu kontrollieren ist, wurde bereits eingebaut…

Eine Ferneinschaltung des Saunaofens ist unter bestimmten technischen Voraussetzungen zwar grundsätzlich zulässig, kommt für mich aus Sicherheitsgründen jedoch keinesfalls infrage und wird dadurch verhindert, dass – wie schon immer – zusätzlich der originäre Schalter an der bestehenden Ofensteuerung eingeschaltet sein muss.
Ergänzend habe ich zwischenzeitlich eine Funktion realisiert, die erfordert, dass unmittelbar vor Einschalten des Ofensteuergeräts die Tür einmal vor Ort verriegelt gewesen sein muss. Die Idee dahinter ist, einen kurzen Blick auf den Ofen zu werfen, um zu vermeiden, dass dort seit der letzten Inaugenscheinnahme etwas abgelegt wurde.
Eine zusätzliche Systemvariable…
Sauna Tür Bewegung | Logikwert | wahr = Tür vor max 30 Sek geändert falsch = nicht bewegt |
…wird beim Öffnen oder Schließen der Tür für 30 Sekunden auf „wahr“ gesetzt…

…und als Bedingung beim Einschalten des Ofens vorausgesetzt…

Ein zweites Programm setzt die Variable sicherheitshalber zusätzlich alle drei Minuten auf „falsch“…

Der Status dieser Sicherheitsfunktion wird im Einschaltdialog angezeigt…


Ein versehentliches Einschalten der Spannungsversorgung der Ofensteuerung sollte damit ausgeschlossen sein.
Saunen haben üblicherweise einen Sicherheitstemperaturbegrenzer, der den Saunaofen bei zu hoher Temperatur (~ 130 °C) abschaltet. Damit es im Fehlerfall erst gar nicht so weit kommt, wurde programmseitig ein Sicherheitstemperaturwächter ergänzt der die Ofensteuerung bei einem Temperaturgrenzwert von 110 °C von der Spannungsversorgung trennt (Hinweis: am Port D25 wird der Fühler der Ofentemperatur ausgewertet)…

Darüber hinaus bietet ein Notausschalter die Möglichkeit zur manuellen Abschaltung der Spannungsversorgung der Saunaofensteuerung – und damit auch des Ofens – im Notfall. Dieser Schalter zieht den Port D19 des Sauna-Homeduinos (+5 Volt Schutzkleinspannung) permanent nach Masse. Bei manueller Aktivierung des Notaus oder einem Kabelbruch, wird die Ofensteuerung abgeschaltet.
Damit der gewählte Notausschalter keinen Hitzeschaden nimmt, liegt er mit aufgeklebten Füßen auf dem kühlen Boden…

Die Auslösung wird auf der Steuerungsseite und der Kabinenanzeige in der aio NEO App plakativ angezeigt…


Betriebsstunden und Kosten
Die Berechnung erfolgt in Anlehnung an das bewährte Vorgehen im Ölverbrauchs-Tutorial, wobei mir die Daten der aktuellen Sitzung, im Kalenderjahr und insgesamt genügen. Weitere Daten lassen sich bei Bedarf ergänzen.
Zur Ermittlung der Betriebszeit des Saunaofens wird dessen Einschaltzustand außerhalb der Kabine potenzialfrei abgegriffen und über einen als Digital-In konfigurierten Port des Homeduino ausgewertet.
In der aio NEO App wird der eingeschaltete Ofen mit gelben Balken auf der Steuerungsseite und der Kabinenanzeige dargestellt…


Erforderliche Systemvariablen…
Sauna Ofen Betriebsminuten aktuelle Sitzung | Zahl | Minimalwert: 0 Maximalwert: 600 | Minuten |
Sauna Ofen Betriebsstunden aktuelle Sitzung | Zahl | Minimalwert: 0 Maximalwert: 10 | Stunden |
ZahlSauna Ofen Betriebsstunden gesamt | Zahl | Minimalwert: 0 Maximalwert: 65000 | Stunden |
Sauna Ofen Betriebsstunden Kalenderjahr | Zahl | Minimalwert: 0 Maximalwert: 1000 | Stunden |
Sauna Ofen letzte Ausschaltzeit | Zeichenkette | ||
Sauna Ofen letzte Einschaltzeit | Zeichenkette | ||
Sauna Ofen Verbrauch aktuelle Sitzung | Zahl | Minimalwert: 0 Maximalwert: 10 | Euro |
Sauna Ofen Verbrauch gesamt | Zahl | Minimalwert: 0 Maximalwert: 65000 | Euro |
Sauna Ofen Verbrauch Kalenderjahr | Zahl | Minimalwert: 0 Maximalwert: 1000 | Euro |
Sauna Sitzung letzte Ausschaltzeit | Zeichenkette | ||
Sauna Sitzung letzte Einschaltzeit | Zeichenkette | ||
Sauna Sitzungsdauer | Zahl | Minimalwert: 0 Maximalwert: 1000 | Minuten |
Strom Grundpreis je kwh | Zahl | Minimalwert: 0 Maximalwert: 10 | Euro |
Bei der Berechnung wird zwischen der Dauer der Saunasitzung (Zeit von Hochfahren bis zum Herunterfahren der Sauna) und der realen Betriebszeit des Ofens unterschieden.
Betriebszeit des Ofens
Das folgende Skript wird mit jedem Einschalten des Ofens über die Systemvariable „homeduino_sauna_D18“ getriggert und speichert die jeweilige Einschaltzeit…
var EinZeit= dom.GetObject("Sauna Ofen letzte Einschaltzeit");
EinZeit.State(system.Date("%F %T")); !Speichern der Einschaltzeit
Beim Ausschalten der Systemvariable „homeduino_sauna_D18“ wird die Einschaltdauer des Ofens berechnet und kumuliert. Daraus werden die Betriebszeiten und Kosten der Sitzung, des laufenden Jahres und insgesamt berechnet…
var AusZeit= dom.GetObject("Sauna Ofen letzte Ausschaltzeit");
var EinZeit= dom.GetObject("Sauna Ofen letzte Einschaltzeit");
var KumZeitG= dom.GetObject("Sauna Ofen Betriebsstunden gesamt");
var KumVerbrauchG= dom.GetObject("Sauna Ofen Verbrauch gesamt");
var KumZeitJ= dom.GetObject("Sauna Ofen Betriebsstunden Kalenderjahr");
var KumVerbrauchJ= dom.GetObject("Sauna Ofen Verbrauch Kalenderjahr");
var KumZeitS= dom.GetObject("Sauna Ofen Betriebsstunden aktuelle Sitzung");
var KumZeitSm= dom.GetObject("Sauna Ofen Betriebsminuten aktuelle Sitzung");
var KumVerbrauchS= dom.GetObject("Sauna Ofen Verbrauch aktuelle Sitzung");
var Strompreis= dom.GetObject("Strom Grundpreis je kwh");
! Speichern der Ausschaltzeit
AusZeit.State(system.Date("%F %T"));
! Den Einschaltzeit String aus der Systemvariablen in ein Zeitobjekt umwandeln
time t = EinZeit.State().ToTime();
! Die aktuelle (Ausschalt)Zeit String erzeugen und in ein Zeitobjekt umwandeln
time t1 = system.Date("%F %T").ToTime();
! Das Zeitobjekt Einschaltzeit in Sekunden seit 1.1.1970 umwandeln
var x = t.ToInteger();
! Das Zeitobjekt aktuelle Zeit in Sekunden seit 1.1.1970 umwandeln
var x1 = t1.ToInteger();
!Die Differenz ist die Einschaltdauer in Stunden (x0) bzw. Minuten (y0)umgerechnet
var x0 = 0.01*(x1-x)/36;
var y0 = (x1-x)/60;
! Die Einschaltdauer gesamt kumulieren = Ofen Betriebsstunden
var gelaufenG = x0 + KumZeitG.State();
! Die Betriebsstunden gesamt in die Systemvariable einstellen
KumZeitG.State(gelaufenG.Round(2));
! Berechnung des Verbrauchs gesamt mit 6 kW Ofen
var verbrauchtG = gelaufenG * 6.00 * Strompreis.Value();
! Verbrauch gesamt in die Systemvariable einstellen
KumVerbrauchG.State(verbrauchtG);
! Die Einschaltdauer im aktuellen Kalenderjahr kumulieren = Ofen Betriebsstunden
var gelaufenJ = x0 + KumZeitJ.State();
! Die Betriebsstunden im aktuellen Kalenderjahr in die Systemvariable einstellen
KumZeitJ.State(gelaufenJ.Round(2));
! Berechnung des Verbrauchs im aktuellen Kalenderjahr mit 6 kW Ofen
var verbrauchtJ = gelaufenJ * 6.00 * Strompreis.Value();
! Verbrauch im aktuellen Kalenderjahr in die Systemvariable einstellen
KumVerbrauchJ.State(verbrauchtJ.Round(2));
! Die Einschaltdauer der aktuellen Sitzung kumulieren = Ofen Betriebsstunden
var gelaufenS = x0 + KumZeitS.State();
var gelaufenSm = y0 + KumZeitSm.State();
! Die Betriebsstunden der aktuellen Sitzung in die Systemvariable einstellen
KumZeitS.State(gelaufenS.Round(2));
KumZeitSm.State(gelaufenSm.Round(2));
! Berechnung des Verbrauchs der aktuellen Sitzung mit 6 kW Ofen
var verbrauchtS = gelaufenS * 6.00 * Strompreis.Value();
! Verbrauch der aktuellen Sitzung in die Systemvariable einstellen
KumVerbrauchS.State(verbrauchtS.Round(2));
Da der Ofen in der Sauna der eindeutige Kostentreiber ist, wurden die sonstigen Kosten (Beleuchtung etc.) vernachlässigt und nicht einbezogen. Das wäre aber durchaus möglich, z.B. überschlägig mit einem Faktor oder einer Sitzungspauschale.
Der Reset der Jahreswerte geschieht zum 31.12. 23:59 eines jeden Jahres mit diesem Skript…
var sJz = dom.GetObject("Sauna Ofen Betriebsstunden Kalenderjahr");
var sJg = dom.GetObject("Sauna Ofen Verbrauch Kalenderjahr");
sJz.State(0.00);
sJg.State(0.00);
Ich mache das zusammen mit allen anderen Zählern in einem gemeinsamen Skript und lasse mir vor dem Zurücksetzten die Jahreswerte über Pushover zusenden.
Der Reset der Ofendaten aus der letzten Sitzung ist im folgenden Absatz beschrieben. Ein Zurücksetzen bzw. eine Anpassung der Gesamtwerte ist nicht erforderlich und bei Bedarf durch einen manuellen Eintrag in die entsprechenden Systemvariablen durchzuführen.
Dauer der Saunasitzung
Die Sitzung wird beim Hochfahren des Saunasystems über einen geeigneten Trigger mit diesem Skript gestartet,…
var AusZeit= dom.GetObject("Sauna Sitzung letzte Ausschaltzeit");
var EinZeit= dom.GetObject("Sauna Sitzung letzte Einschaltzeit");
var KumZeitS= dom.GetObject("Sauna Ofen Betriebsstunden aktuelle Sitzung");
var KumZeitSm= dom.GetObject("Sauna Ofen Betriebsminuten aktuelle Sitzung");
var KumVerbrauchS= dom.GetObject("Sauna Ofen Verbrauch aktuelle Sitzung");
var KumZeitZ= dom.GetObject("Sauna Sitzungsdauer");
EinZeit.State(system.Date("%F %T"));
AusZeit.State("-")
KumZeitS.State(0.00);
KumZeitSm.State(0.00);
KumVerbrauchS.State(0.00);
KumZeitZ.State(0.00);
…das die Einschaltzeit speichert und die Daten der letzten Saunasitzung (inklusive der Ofendaten) zurücksetzt.
Mit einem geeigneten Trigger beim Herunterfahren des Systems berechnet das folgende Skript die Saunagangdauer und versendet die relevanten Angaben zur Saunasitzung mittels Pushover…
var AusZeit= dom.GetObject("Sauna Sitzung letzte Ausschaltzeit");
var EinZeit= dom.GetObject("Sauna Sitzung letzte Einschaltzeit");
var KumZeitZ= dom.GetObject("Sauna Sitzungsdauer");
! Speichern der Ausschaltzeit
AusZeit.State(system.Date("%F %T"));
! Den Einschaltzeit String aus der Systemvariablen in ein Zeitobjekt umwandeln
time t = EinZeit.State().ToTime();
! Die aktuelle (Ausschalt)Zeit String erzeugen und in ein Zeitobjekt umwandeln
time t1 = system.Date("%F %T").ToTime();
! Das Zeitobjekt Einschaltzeit in Sekunden seit 1.1.1970 umwandeln
var x = t.ToInteger();
! Das Zeitobjekt aktuelle Zeit in Sekunden seit 1.1.1970 umwandeln
var x1 = t1.ToInteger();
!Die Differenz ist die Einschaltdauer in Minuten (y0)umgerechnet
var y0 = (x1-x)/60;
! Die Einschaltdauer gesamt kumulieren = Dauer der aktuellen Sitzung
var gelaufenZ = y0 + KumZeitZ.State();
! Die Sitzungsdauer in die Systemvariable einstellen
KumZeitZ.State(gelaufenZ.Round(2));
! Nachricht verschicken
var AusZeitM= dom.GetObject("Sauna Sitzung letzte Ausschaltzeit").Value().ToString().Substr(11,5);
var EinZeitM= dom.GetObject("Sauna Sitzung letzte Einschaltzeit").Value().ToString().Substr(11,5);
var KumZeitZM= dom.GetObject("Sauna Sitzungsdauer").Value().ToString(0);
var KumZeitSmM= dom.GetObject("Sauna Ofen Betriebsminuten aktuelle Sitzung").Value().ToString(0);
var KumVerbrauchSM= dom.GetObject("Sauna Ofen Verbrauch aktuelle Sitzung").Value().ToString(2);
string MailText;
string sDate = system.Date("%d.%m.%Y");
MailText = "Die Saunasitzung am " # sDate # " dauerte " # KumZeitZM # " Minuten.%0A%0ASie begann " # EinZeitM # " Uhr und endete " # AusZeitM # " Uhr.%0A%0ADer Ofen war " # KumZeitSmM # " Minuten eingeschaltet, dabei entstanden Kosten von " # KumVerbrauchSM # " Euro.";
string teilstr;
string sendmail = "";
foreach(teilstr, MailText.Split(" ")) {
sendmail = sendmail # "+" # teilstr;
}
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("extra/curl -s -d token=TOKEN -d user=USER -d message='"#sendmail#"' -d sound=bike http://api.pushover.net/1/messages.json");

Die Angaben sind bis zum nächsten Hochfahren der Sauna auch in der aio NEO App abrufbar, wobei die Gesamt- und Jahresangaben zur besseren Übersicht auf ganze Zahlen gerundet angezeigt werden…

Ich benötige die Informationen zur Saunasitzung, weil ich die Saunabesuche in mein Lauftagebuch eintrage. In einem späteren Schritt will ich mal versuchen, die Daten über dessen API automatisch ins Tagebuch zu schreiben.