UPDATE Oktober 2020: Nach dem letzten Update des JS-Adapters kommt es zu Fehlern bei der Benachrichtigung, diese wird mehrfach nach Abschluss des Scripts versendet. Script und Blockly-Export sind im Artikel bereits korrigiert.
Schauen wir uns das hierfür notwendige Script an, die Logik des Scripts funktioniert recht einfach:
- Wir merken uns in einem Status den Zustand der Maschine, am Anfang AUS
- Der Stromverbrauch sollte im Standby oder im Aus-Zustand gering bzw. 0 sein
- Verändert sich dieser Wert, über eine gesetzte Schwelle, d.h. mindestens so viel Leistung muss bezogen werden, setzen wir den Status auf AN
- Solange der momentane Verbrauch der Maschine über dem Schwellwert liegt, bleibt der Zustand auf AN
- Ist die Maschine fertig, sinkt der Stromverbrauch unter den Schwellwert, wir setzen den Status auf AUS und können z.B. per pushover über das Ende des Wasch- oder Trockenvorgangs informieren
- Beachten müssen wir allerdings, dass auch zwischendurch der Stromverbrauch kurzfristig unter den Schwellwert sinken kann. In diesem Fall starten wir einen Timer, nach dessen Ablauf das Ende des Vorgangs getriggert wird. Wird allerdings zwischendurch der Schwellenwert wieder überschritten, löschen wir den Timer und das script wartet auf die nächste Unterschreitung des Schwellwerts.
Außerdem im Script integriert: Ermittlung des Gesamtstromverbrauchs
Auch hierfür ist die Logik relativ simpel, ist allerdings in der Scriptumsetzung etwas komplexer:
- Bei Registrierung des Momentanstromverbrauchs merken wir uns den Wert und einen Timestamp
- Verändert sich der Verbrauch berechnen wir bei dieser Änderungen die zeitliche Differenz zum letzten Timestamp und berechnen den absoluten Verbrauch für dieses Zeitfenster. Wir setzen den Verbrauchswert und den Timestamp neu und warten auf die nächste Änderung des Momentanverbrauchs. Solange die Maschine läuft, summieren wir die Einzelwerte auf und können bei Ende des Vorgangs den Gesamtverbrauch auslesen. 100%ig genau ist diese Methode natürlich nicht, aber ergibt einen sehr guten und nur gering abweichenden Gesamtverbrauch.
Javascript für den ioBroker-Import:
var standby_power, on_power, WON, wait, ts, actual_power, ts_temp, timeout; createState("Waschmaschine.ON", function () { }); createState("Waschmaschine.wait", function () { }); createState("Waschmaschine.power_temp", function () { }); createState("Waschmaschine.power_ts", function () { }); createState("Waschmaschine.power", function () { }); createState("Waschmaschine.power_year", function () { }); on({id: "shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power"/*Power*/, change: "ne"}, function (obj) { var value = obj.state.val; var oldValue = obj.oldState.val; standby_power = 3.5; // Wert, der beim Anschalten überschritten werden muss on_power = 10; WON = getState("javascript.0.Waschmaschine.ON").val; wait = getState("javascript.0.Waschmaschine.wait").val; ts = getState("shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power").ts; actual_power = getState("shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power").val; if (WON != true && actual_power > on_power) { // Waschmaschine ist jetzt angeschaltet setState("javascript.0.Waschmaschine.ON"/*Waschmaschine.ON*/, true, true); setState("javascript.0.Waschmaschine.wait"/*Waschmaschine.wait*/, false, true); setState("javascript.0.Waschmaschine.power_temp"/*Waschmaschine.power_temp*/, actual_power, true); setState("javascript.0.Waschmaschine.power_ts"/*Waschmaschine.power_ts*/, ts, true); setState("javascript.0.Waschmaschine.power"/*Waschmaschine.power*/, 0, true); console.log(('W1: anschalten' + String(actual_power))); } else if (wait == true && actual_power > on_power) { // an und power>onlimit console.log(('W:2 läuft und reset timer und twait ' + String(actual_power))); (function () {if (timeout) {clearTimeout(timeout); timeout = null;}})(); setState("javascript.0.Waschmaschine.wait"/*Waschmaschine.wait*/, false, true); } else if (WON == true && wait != true && actual_power < standby_power) { // Leistung fällt auf Standby-Wert, Waschmaschine vielleicht fertig setState("javascript.0.Waschmaschine.wait"/*Waschmaschine.wait*/, true, true); console.log((['W3: Leistung Standby, starte Timer für Fertig-Meldung',actual_power,ts].join(''))); timeout = setTimeout(function () { setState("javascript.0.Waschmaschine.ON"/*Waschmaschine.ON*/, false, true); ts_temp = getState("javascript.0.Waschmaschine.power").val; setState("javascript.0.Waschmaschine.power_year"/*Waschmaschine.power_year*/, (ts_temp + getState("javascript.0.Waschmaschine.power_year").val), true); }, 1200000); } else if (WON == true) { ts_temp = (new Date().getTime()) - getState("javascript.0.Waschmaschine.power_ts").val; ts_temp = ts_temp / 1000; ts_temp = ts_temp * getState("javascript.0.Waschmaschine.power_temp").val; ts_temp = ts_temp / 3600; setState("javascript.0.Waschmaschine.power_temp"/*Waschmaschine.power_temp*/, actual_power, true); setState("javascript.0.Waschmaschine.power_ts"/*Waschmaschine.power_ts*/, ts, true); setState("javascript.0.Waschmaschine.power"/*Waschmaschine.power*/, (ts_temp + getState("javascript.0.Waschmaschine.power").val), true); console.log(('W4: Waschmaschine läuft' + String(getState("javascript.0.Waschmaschine.power").val))); } }); // Notifications werden auf Basis des Status Waschmaschine.ON versendet on({id: "javascript.0.Waschmaschine.ON"/*Waschmaschine.ON*/, change: "ne"}, function (obj) { var value = obj.state.val; var oldValue = obj.oldState.val; if (getState("javascript.0.Waschmaschine.ON").val == false) { // Wechsel ON>OFF sendTo("pushover", "send", { message: (['Die Waschmaschine ist jetzt fertig!',' Verbrauch: ',Math.round(getState("javascript.0.Waschmaschine.power").val*10)/10].join('')), sound: "" }); } else { // Wechsel ON>OFF sendTo("pushover", "send", { message: 'Die Waschmaschine läuft jetzt!', sound: "" }); } });
Blockly-Export:
standby_power on_power WON wait ts actual_power ts_temp timeout Waschmaschine.ON Waschmaschine.wait Waschmaschine.power_temp Waschmaschine.power_ts Waschmaschine.power Waschmaschine.power_year shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power ne standby_power 3.5 Wert, der beim Anschalten überschritten werden muss on_power 10 WON val javascript.0.Waschmaschine.ON wait val javascript.0.Waschmaschine.wait ts ts shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power actual_power val shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power AND NEQ WON TRUE GT actual_power on_power Waschmaschine ist jetzt angeschaltet javascript.0.Waschmaschine.ON FALSE TRUE javascript.0.Waschmaschine.wait FALSE FALSE javascript.0.Waschmaschine.power_temp FALSE actual_power javascript.0.Waschmaschine.power_ts FALSE ts javascript.0.Waschmaschine.power FALSE 0 log test W1: anschalten actual_power AND EQ wait TRUE GT actual_power on_power an und power>onlimit log test W:2 läuft und reset timer und twait actual_power timeout javascript.0.Waschmaschine.wait FALSE FALSE AND AND EQ WON TRUE NEQ wait TRUE LT actual_power standby_power Leistung fällt auf Standby-Wert, Waschmaschine vielleicht fertig javascript.0.Waschmaschine.wait FALSE TRUE log test W3: Leistung Standby, starte Timer für Fertig-Meldung actual_power ts timeout 20 min javascript.0.Waschmaschine.ON FALSE FALSE ts_temp val javascript.0.Waschmaschine.power javascript.0.Waschmaschine.power_year FALSE ADD 1 ts_temp 1 val javascript.0.Waschmaschine.power_year EQ WON TRUE ts_temp MINUS 1 object 1 val javascript.0.Waschmaschine.power_ts ts_temp DIVIDE 1 ts_temp 1 1000 ts_temp MULTIPLY 1 ts_temp 1 val javascript.0.Waschmaschine.power_temp ts_temp DIVIDE 1 ts_temp 1 3600 javascript.0.Waschmaschine.power_temp FALSE actual_power javascript.0.Waschmaschine.power_ts FALSE ts javascript.0.Waschmaschine.power FALSE ADD 1 ts_temp 1 val javascript.0.Waschmaschine.power log test W4: Waschmaschine läuft val javascript.0.Waschmaschine.power Notifications werden auf Basis des Status Waschmaschine.ON versendet javascript.0.Waschmaschine.ON ne EQ val javascript.0.Waschmaschine.ON FALSE Wechsel ON>OFF 0 text Die Waschmaschine ist jetzt fertig! Verbrauch: 1 3.1234 val javascript.0.Waschmaschine.power Wechsel ON>OFF 0 text Die Waschmaschine läuft jetzt!
Tolle Lösung, ich hatte bisher immer einen Vibrationssensor von Xiaomi eingesetzt. Jetzt werkelt auch bei uns ein Shelly 1PM in ioBroker.
Viele Grüße, Stefan
Liest sich Klasse! Leider ist das Blockly Bild so schlecht, dass man nicht viel erkennen kann. Könntest du das Script exportieren?
Vielen Dank!
Wir haben den Blockly Export für die smarte Waschmaschine in ioBroker abgelegt: Blocky Export smarte Waschmaschine
Hallo,
leider bekomme ich beim importieren eine Fehlermeldung :(
LG
Wie lautet denn die Fehlermeldung?
Bekomme leider auch beim importieren den folgenden Fehler:
TypeError: Block type unspecified: Waschmaschine.ON Waschmaschine.wait Waschmaschine.power_temp Waschmaschine.power_ts Waschmaschine.power Waschmaschine.power_year shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power ne standby_power 3.5 on_power 10 WON val javascript.0.Waschmaschine.ON wait val javascript.0.Waschmaschine.wait ts ts shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power actual_power val shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power EQ actual_power 83.45 actual_power 0.15 AND NEQ WON TRUE GT actual_power on_power noch aus und power>onlimit javascript.0.Waschmaschine.ON FALSE TRUE javascript.0.Waschmaschine.wait FALSE FALSE javascript.0.Waschmaschine.power_temp FALSE actual_power javascript.0.Waschmaschine.power_ts FALSE ts javascript.0.Waschmaschine.power FALSE 0 log test W1: aus und poweron an: actual_power 0 text Die Waschmaschine läuft jetzt! AND EQ wait TRUE GT actual_power on_power an und power>onlimit log test W:2 an und poweron reset timer and twait actual_power wm_off javascript.0.Waschmaschine.wait FALSE FALSE AND NEQ wait TRUE LT actual_power standby_power an und power<standbylimit javascript.0.Waschmaschine.wait FALSE TRUE log test W3: an und standbypower: actual_power ts wm_off 20 min javascript.0.Waschmaschine.ON FALSE FALSE ts_temp val javascript.0.Waschmaschine.power javascript.0.Waschmaschine.power_year FALSE ADD 1 ts_temp 1 val javascript.0.Waschmaschine.power_year 0 text Die Waschmaschine ist jetzt fertig! Verbrauch: 1 3.1234 ts_temp shelly.0.SHSW-PM#B1DE5C#1.Relay0.Switch FALSE TRUE EQ WON TRUE ts_temp MINUS 1 object 1 val javascript.0.Waschmaschine.power_ts ts_temp DIVIDE 1 ts_temp 1 1000 ts_temp MULTIPLY 1 ts_temp 1 val javascript.0.Waschmaschine.power_temp ts_temp DIVIDE 1 ts_temp 1 3600 javascript.0.Waschmaschine.power_temp FALSE actual_power javascript.0.Waschmaschine.power_ts FALSE ts javascript.0.Waschmaschine.power FALSE ADD 1 ts_temp 1 val javascript.0.Waschmaschine.power log test W4: else power gesamt val javascript.0.Waschmaschine.power
„Block type unspecified“ sieht nach einem Fehler in der Zuordnung von Objekten aus. Alle Variablen korrekt im Script und im Objektbaum angelegt? Pfad zum Shelly (shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power) korrekt?
Hm, schade. Das Blockly lässt sich in der Tat nicht importieren. Beim Importiervorgang dicke Fehlermeldungen…
Wir prüfen nochmal den Blockly-Export, wir konnten in einer neuen Instanz importieren. Es liegt wohl an den nicht vorhandenen Ojekten.
Das Javascript interessiert mich sehr, allerdings fehlen da noch ein paar Zeilen oder?
Das WordPress-Plugin hat leider einige Zeilen abgeschnitten, ist jetzt korrigiert.
Schade, lässt sich leider nicht importieren:
Error: textToDom was unable to parse: var standby_power, on_power, WON, wait, ts, actual_power, ts_temp, wm_off;createState(„Waschmaschine.ON“, function () {});createState(„Waschmaschine.wait“, function () {});createState(„Waschmaschine.power_temp“, function () {});createState(„Waschmaschine.power_ts“, function () {});createState(„Waschmaschine.power“, function () {});createState(„Waschmaschine.power_year“, function () {});on({id: „shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power“/*Power*/, change: „ne“}, function (obj) {var value = obj.state.val;var oldValue = obj.oldState.val;standby_power = 3.5;on_power = 10;WON = getState(„javascript.0.Waschmaschine.ON“).val;wait = getState(„javascript.0.Waschmaschine.wait“).val;ts = getState(„shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power“).ts;actual_power = getState(„shelly.0.SHSW-PM#B1DE5C#1.Relay0.Power“).val;if (WON != true && actual_power > on_power) {// noch aus und power>onlimitsetState(„javascript.0.Waschmaschine.ON“/*Waschmaschine.ON*/, true, true);setState(„javascript.0.Waschmaschine.wait“/*Waschmaschine.wait*/, false, true);setState(„javascript.0.Waschmaschine.power_temp“/*Waschmaschine.power_temp*/, actual_power, true);setState(„javascript.0.Waschmaschine.power_ts“/*Waschmaschine.power_ts*/, ts, true);setState(„javascript.0.Waschmaschine.power“/*Waschmaschine.power*/, 0, true);console.log((‚W1: aus und poweron an: ‚ + String(actual_power)));sendTo(„pushover“, „send“, {message: ‚Die Waschmaschine läuft jetzt!‘,sound: „“});} else if (wait == true && actual_power > on_power) {// an und power>onlimitconsole.log((‚W:2 an und poweron reset timer and twait ‚ + String(actual_power)));(function () {if (wm_off) {clearTimeout(wm_off); wm_off = null;}})();setState(„javascript.0.Waschmaschine.wait“/*Waschmaschine.wait*/, false, true);} else if (wait != true && actual_power < standby_power) {// an und power<standbylimitsetState("javascript.0.Waschmaschine.wait"/*Waschmaschine.wait*/, true, true);console.log((['W3: an und standbypower: ',actual_power,ts].join('')));wm_off = setTimeout(function () {setState("javascript.0.Waschmaschine.ON"/*Waschmaschine.ON*/, false, true);ts_temp = getState("javascript.0.Waschmaschine.power").val;setState("javascript.0.Waschmaschine.power_year"/*Waschmaschine.power_year*/, (ts_temp + getState("javascript.0.Waschmaschine.power_year").val), true);sendTo("pushover", "send", {message: (['Die Waschmaschine ist jetzt fertig!',' Verbrauch: ',Math.round(ts_temp*10)/10].join('')),sound: ""});setState("shelly.0.SHSW-PM#B1DE5C#1.Relay0.Switch"/*Switch*/, true);}, 1200000);} else if (WON == true) {ts_temp = (new Date().getTime()) – getState("javascript.0.Waschmaschine.power_ts").val;ts_temp = ts_temp / 1000;ts_temp = ts_temp * getState("javascript.0.Waschmaschine.power_temp").val;ts_temp = ts_temp / 3600;setState("javascript.0.Waschmaschine.power_temp"/*Waschmaschine.power_temp*/, actual_power, true);setState("javascript.0.Waschmaschine.power_ts"/*Waschmaschine.power_ts*/, ts, true);setState("javascript.0.Waschmaschine.power"/*Waschmaschine.power*/, (ts_temp + getState("javascript.0.Waschmaschine.power").val), true);console.log(('W4: else power gesamt' + String(getState("javascript.0.Waschmaschine.power").val)));}});
Und der Screenshot ist leider so klein, dass man es nicht genau erkennen kann …..
Wir werden es in Kürze neu und größer erstellen.
Leider hat das Script-Plugin den Code abgeschnitten, ist jetzt korrigiert. Bitte noch „Shellydevice“ mit dem eigenen Shelly-Device-Namen tauschen.
Viele Grüße
Hi. Frage zum ON/OFF.
Ich habe einen Sonoff POW. Den kann ich ja ebenso nutzen. Davon gehe ich jetzt mal aus.
Ich möchte aber den SONOFF nicht komplett ausschalten. Ist das ausreichend, wenn ich nach dem Pushover den Baustein deaktiviere oder lösche?
Oder habe ich das ganze Falsch verstanden?
Danke Klaus
Ja, genau. Der Baustein ist enthalten, um evt. Standby-Strom zusätzlich zu sparen, kann also problemlos deaktiviert werden. Viel Erfolg!
Hi seit ein paar Tagen (Update Shelly und Update ScriptEnginge) spinnt das Script. Es schickt dann zigmal die Fertigmeldung via Telegram. Ich habe sonst nichts geändert, die States werden meist korrekt aktualisiert. Ich bin ratlos – jemand die gleichen Probleme mit dem Script?
Ja, wir hatten dasselbe Problem, Fehler im Script konnten wir nicht erkennen, das Verhalten hat mit dem Update des Javascript-Adapters letzte Woche wohl zu tun (wir vermuten es hat etwas mit den Timern zu tun). Wir haben die Benachrichtigung jetzt aus dem Script genommen und lassen auf Basis der Status-Variable Waschmaschine.ON notifizieren:
https://www.smarthomejetzt.de/wp-content/uploads/2020/10/update_script.jpg
Wärt ihr so Nett, und passt euren Blockeintrag an? Ich glaube nicht, dass sich das bessern wird. Ich habe sämtliche Timereinstellungen angepasst, ms, wie min alsauch sekunden. Auch Downgrade etc. hat nichts gebracht. Das wäre super :)
Ist bereits angepasst und auch der Blockly-Export ergänzt!
Import ist bei mir auch nicht möglich….
Würde mich anschließen und über einen Skript-Screenshot in besserer Auflösung freuen.
Bastel mir das Skript gern nach.
Das Bild liegt jetzt in besserer Qualität vor. Wird ein Shelly-Produkt eingesetzt empfehlen wir diesen Artikel: https://www.smarthomejetzt.de/mit-dem-shelly-1pm-und-iobroker-jede-waschmaschine-trockner-und-spuelmaschine-smart-machen/
Hallo,
danke für den Artikel und das Script. Ich hätte es gerne unter Blockly eingesetzt, aber leider funktioniert weder der Import über die Blöcke oebn, noch über den extra Link in den Kommentaren. Hier bekomme ich diverse Fehlermeldungen.
Kann der Export noch einmal sauber zur Verfügung gestellt werden?
Danke :)
https://www.smarthomejetzt.de/wp-content/uploads/2020/04/blockly_script_smarte_waschmaschine_iobroker.txt ohne die ersten vier Zeilen testen.
Neues Blockly-Script anlegen, Blockly importieren auswählen, XML-Struktur einfügen und speichern.