Ziel: Automatische Steuerung der Temperatur auch mit Zeitschaltung.
Komponenten:
Temperatur Sensor Addon:
Sensor: DS18B20 Temperatursensor: (waren 5 Stk. habe also noch welche in Reserve)
Dichtmasse die unter Wasser aushärtet: hatte ich schon.
Raspberry hatte ich schon. Hat mich also ca. € 31,- gekostet und etwas Zeit
Zeitaufwand Montage: ca. 1,5h (habe ich mit meinem Sohn gemeinsam gemacht, er ist jetzt in der 3. Klasse HTL Mechatronik)
Zeitaufwand mit IoBroker: schwer zu schätzen, aber ein paar Stunden waren es schon, habe das zum Ersten mal gemacht.
Einbau:
der Shelly (ist im Elektronikschrank, wo auch die Original Whirlpool Steuerung ist) schaltet die Umwälzpumpe.
Für den Temperaturfühler habe ich ein Loch gebohrt, neben dem Fühler von der Original- Steuerung. Danach DS18B20 reingesteckt und innen mit der Klebemasse abgedeckt/abgedichtet (Ich habe dazu das Pool nicht ausgelassen - diese Dichtmasse härtet auch unter Wasser aus).
IoBroker Datenpunkte:
Zuerst habe ich ein paar Datenpunkte angelegt um diverse Zustände zu speichern (siehe Screenshot)
Skript Poolsteuerung:
Es gibt zwei Zustände für “pool_vorheizen”: “true” - auf Betriebstemperatur; “false” - auf Standby-Temperatur. Je nachdem wird versucht, die jeweilige Temperatur zu erreichen.
Jedes mal wenn, der Temp-Fühler eine Temperatur meldet, wird entweder die Pumpe eingeschalten bzw. ausgeschalten.
Zur Erklärung: Das Pool ist immer eingeschalten, wenn ein Durchfluss ist, dann merkt das die Heizung und heizt auf die am Pool selbst eingestellte Temperatur (habe ich einfach auf maximal Temp. eingestellt). Ist kein Durchfluss, schaltet die Heizung sich selbst ab. Ich weiss natürlich nicht, ob das bei anderen Whirlpools auch so funktioniert.
var timeout;
on({id: "0_userdata.0.pool_vorheizen"/*pool_vorheizen*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
if ((obj.state ? obj.state.val : "")) {
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, getState("0_userdata.0.pool_bade_temp").val);
} else {
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, getState("0_userdata.0.pool_standby_temp").val);
}
timeout = setTimeout(function () {
setState("shelly.0.SHSW-PM#68C63AFAD34C#1.Relay0.Switch"/*Switch*/, ((obj.state ? obj.state.val : "") && getState("shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2").val <= getState("0_userdata.0.pool_soll_temp").val));
}, 500);
});
on({id: "shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2"/*WasserTemp*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
setState("shelly.0.SHSW-PM#68C63AFAD34C#1.Relay0.Switch"/*Switch*/, (getState("0_userdata.0.pool_soll_temp").val > getState("shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2").val));
});
on({id: "0_userdata.0.pool_bade_temp"/*pool_bade_temp*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, getState("0_userdata.0.pool_bade_temp").val);
});
on({id: "0_userdata.0.pool_standby_temp"/*pool_standby_temp*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, getState("0_userdata.0.pool_standby_temp").val);
});
Alles anzeigen
Skript pool_winterbetrieb:
Die Pumpe soll sich alle 2 Stunden einschalten für 10 Minuten, damit keine Leitungen einfrieren können. Die “Soll” Temperatur wird auf 10°C gesetzt. Das Skript Poolsteuerung hält dann diese Mindesttemperatur.
Ob es funktioniert, werde ich erst im Winter herausfinden.
var Motor_einschalten;
on({id: "0_userdata.0.pool_winterbetrieb"/*pool_winterbetrieb*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
if ((obj.state ? obj.state.val : "")) {
(function () {if (Motor einschalten) {clearSchedule(Motor einschalten); Motor einschalten = null;}})();
setState("0_userdata.0.pool_vorheizen"/*pool_vorheizen*/, false);
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, 10);
Motor_einschalten = schedule('* */2 * * *', function () {
setState("shelly.0.SHSW-PM#68C63AFAD34C#1.Relay0.Switch"/*Switch*/, true);
setStateDelayed("shelly.0.SHSW-PM#68C63AFAD34C#1.Relay0.Switch"/*Switch*/, false, 300000, false);
});
} else {
(function () {if (Motor einschalten) {clearSchedule(Motor einschalten); Motor einschalten = null;}})();
setState("0_userdata.0.pool_soll_temp"/*pool_soll_temp*/, getState("0_userdata.0.pool_standby_temp").val);
}
});
Alles anzeigen
Skript-Timer (kein Screenshot, habe es nicht komplett auf einen Bildschirm gebracht):
Wenn der Timer eingeschaltet wird, soll er anhand der aktuellen Temperatur berechnen, wann der Pool eingeschalten werden muss, damit es zur eingestellten Zeit die Betriebstemperatur hat (ich weiß er schafft ca. 2°C pro Stunde). Dann wird ein Cron-Job aktiviert, der den Status vom Pool auf Betrieb setzt. -> Das funktioniert soweit.
Eigentlich sollte das Skript auch immer, wenn sich die Temperatur ändert eine neue Berechnung der Zeit bis zum Einschalten machen. Da ist noch der Wurm drinnen, das geht noch nicht.
var PoolAnUm, PoolAnUm1;
on({id: "0_userdata.0.pool_timer"/*pool_timer*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
setStateDelayed("0_userdata.0.timer_uhrzeit_berechnet"/*timer_uhrzeit_berechnet*/, ('' + formatDate(getDateObject((parseFloat(getDateObject(getState("0_userdata.0.timer_uhrzeit").val).getTime()) - Math.round(getState("0_userdata.0.pool_bade_temp").val - getState("shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2").val) * 1800000)), "hh:mm")), 1000, true);
if ((obj.state ? obj.state.val : "")) {
(function () {if (PoolAnUm) {clearSchedule(PoolAnUm); PoolAnUm = null;}})();
PoolAnUm = schedule(('' + (getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getMinutes())).trim() + ' ' + ('' + getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getHours()).trim() + ' ' + '*'.trim() + ' ' + '*'.trim() + ' ' + '*'.trim(), function () {
setStateDelayed("0_userdata.0.pool_vorheizen"/*pool_vorheizen*/, (obj.state ? obj.state.val : ""), 1000, true);
});
console.log(('' + (getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getMinutes())).trim() + ' ' + ('' + getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getHours()).trim() + ' ' + '*'.trim() + ' ' + '*'.trim() + ' ' + '*'.trim());
} else {
(function () {if (PoolAnUm) {clearSchedule(PoolAnUm); PoolAnUm = null;}})();
console.log('Stop CRON');
}
});
schedule('{"time":{"exactTime":true,"start":"00:00"},"period":{"weeks":1,"dows":"[0]"}}', function () {
(function () {if (PoolAnUm) {clearSchedule(PoolAnUm); PoolAnUm = null;}})();
setStateDelayed("0_userdata.0.pool_vorheizen"/*pool_vorheizen*/, false, 1000, true);
});
on({id: "shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2"/*temperatureC2*/, change: "ne"}, function (obj) {
var value = obj.state.val;
var oldValue = obj.oldState.val;
setStateDelayed("0_userdata.0.timer_uhrzeit_berechnet"/*timer_uhrzeit_berechnet*/, ('' + formatDate(getDateObject((parseFloat(getDateObject(getState("0_userdata.0.timer_uhrzeit").val).getTime()) - Math.round(getState("0_userdata.0.pool_bade_temp").val - getState("shelly.0.SHSW-PM#68C63AFAD34C#1.ext.temperatureC2").val) * 1800000)), "hh:mm")), 1000, true);
if (getState("0_userdata.0.pool_timer").val) {
(function () {if (PoolAnUm) {clearSchedule(PoolAnUm); PoolAnUm = null;}})();
PoolAnUm1 = schedule(('' + (getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getMinutes())).trim() + ' ' + ('' + getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getHours()).trim() + ' ' + '*'.trim() + ' ' + '*'.trim() + ' ' + '*'.trim(), function () {
setStateDelayed("0_userdata.0.pool_vorheizen"/*pool_vorheizen*/, (obj.state ? obj.state.val : ""), 1000, true);
});
console.log(([('' + getDateObject(getState("0_userdata.0.timer_uhrzeit").val).getHours()),':',('' + (getDateObject(getState("0_userdata.0.timer_uhrzeit").val).getMinutes()))].join('')));
console.log(('' + (getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getMinutes())).trim() + ' ' + ('' + getDateObject(getState("0_userdata.0.timer_uhrzeit_berechnet").val).getHours()).trim() + ' ' + '*'.trim() + ' ' + '*'.trim() + ' ' + '*'.trim());
} else {
(function () {if (PoolAnUm) {clearSchedule(PoolAnUm); PoolAnUm = null;}})();
console.log('Timer Pool Stop');
}
console.log('XXXXXXXXXXXXXXX');
});
Alles anzeigen
VIS:
hier kann das Pool ein/aus/Winter geschalten werden, die Temperaturen gesetzt und der Timer aktiviert werden.
Das war jetzt nur eine grobe Übersicht, wenn jemand Fragen dazu hat, dann bitte bei mir melden.
Mir hat das Projekt Spaß gemacht. Mal schauen was als nächstes Smart wird bei mir zu Hause