FHEM Tutorial-Reihe - Part 28: Energiemessung + Notification wenn Spülmaschine fertig

Mit ** gekennzeichne Links auf dieser Seite sind Affiliatelinks.

Wieviel Strom verbrauchen eigentlich Eure Geräte so? Also nicht die kleinen, die selten Mal an sind, sondern wirkliche Energiefresser wie z.B. der Kühlschrank oder ein Warmwasserspeicher. Diese Frage habe ich mir auch gestellt und mir daher für mein Z-Wave-System ein paar von den Fibaro-Zwischensteckern bestellt, welche man sowohl drahtlos schalten kann, als auch die aktuellen Leistungsdaten übermittelt bekommt. Zusätzlich lasse ich mich jetzt per Push-Notification informieren, wenn die Spülmaschine fertig ist und ich diese ausräumen kann.

Was wird benötigt?

  • Eine FHEM-Installation
  • Ein Zwischenstecker, welcher die aktuelle Leistung misst
  • Das entsprechende Interface für FHEM

Video

FHEM-Kurs

Komponenten

Befehle

Generell werden alle Geräte hier beim Pairing automatisch angelegt. Daher brauchen wir nur das notify entsprechend konfigurieren. Da mache ich es eigentlich immer so, dass ich erst das notify mit einem leeren "Aktionsblock" anlege, und später in FHEM dann über den viel besseren Editor dann programmiere.

define n_KU_Spuelmaschine_start notify KU_Spuelmaschine:power:.* {}

Dann bearbeite ich das define und fügen folgenden Inhalt ein:

KU_Spuelmaschine:power:.* {
     if (ReadingsNum("KU_Spuelmaschine", "power", 0) > 10 && ReadingsVal("KU_Spuelmaschine", "running", "off") eq "off") {
          fhem("setreading KU_Spuelmaschine running on");
     }

     if (ReadingsNum("KU_Spuelmaschine", "power", 0) < 1 && ReadingsVal("KU_Spuelmaschine", "running", "off") eq "on") {
          fhem("setreading KU_Spuelmaschine running off");
          fhem("set WEB_Pushover msg 'Spülmaschine' 'Die Spülmaschine ist fertig'");
     }
}

Wie im Video erklärt erledige ich mit einem notify direkt mehrere Aufgaben. Das ist sinnvoll um den Code möglichst kurz zu halten und Dinge die zusammen gehören übersichtlich an einer Stelle zu finden. Möchte ich die Notification also irgendwann einmal nicht mehr haben, lösche ich einfach das komplette notify und muss nicht an zig andere Dummy-Devices denken.

Erklärung

Generell funktioniert das Ganze wie folgt:

  1. Die Spülmaschine wird eingeschaltet und das power-Reading ändert sich, wodurch das notify reagiert
  2. Sollte die Spülmaschine in diesem Moment mehr als 10 Watt verbrauchen, gehen wir davon aus dass sie eingeschaltet wurde und setzen auf der Spülmaschine das Reading "running" auf "on". Falls der Wert kleiner als 10 Watt ist, passiert gar nichts, da das Reading "running" ja noch nicht auf "on" steht.
  3. Jetzt kommen noch zig hundert power-Änderungen, welche den aktuellen Verbrauch dokumentieren. Da aber alle Werte für "power" größer als 1 Watt sind und das Reading "running" ja bereits auf "on" steht, passiert nichts.
  4. Wenn die Spülmaschine fertig ist, schaltet sich diese ab. Dadurch ändert sich das Reading "power" natürlich wieder (z.B. auf 0) und nun greift der zweite Teil des notify, denn 0 ist kleiner als 1 und das Reading "running" steht ja noch auf "on".
  5. Wir setzen also in diesem Fall das Reading "running" wieder auf "off" (um die erste if-Bedingung wieder scharf zu machen) und senden eine Push-Notification, dass die Spülmaschine jetzt fertig ist.

Eigentlich gar nicht so schwer, oder? Und das alles, ohne auch nur an Watchdog, Dummy oder was auch immer zu denken. Keep it simple!

Zusätzliches

Falls der Editor nicht so schön aussehen sollte wie bei mir, setzt das Attribut "JavaScripts" auf dem WEB-Device einmal wie folgt:

attr WEB JavaScripts codemirror/fhem_codemirror.js

Update

FHEM-Kurs
{ReadingsTimestamp("KU_Spuelmaschine", "running", 0)} => Gibt mir die aktuelle Zeit von einem Reading zurück

{time_str2num(ReadingsTimestamp("KU_Spuelmaschine", "running", 0))} => Formatiert die Zeit in einen Unix-Timestamp

{gettimeofday()} => 1529514418.37716 (aus Time::HiRes, gibt die Sekunden und Mikrosekunden seit 01.01.1970 00:00 zurück)
{time()} => 1529514712 (gibt die Sekunden seit 01.01.1970 00:00 zurück => Unix Timestamp)
{localtime()} => Wed Jun 20 19:08:33 2018 (gibt ein Array zurück => $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
{gmtime()} => Wed Jun 20 17:10:32 2018 (genau wie localtime, nur GMT und nicht aktuelle Zeitzone)
{TimeNow()} => 2018-06-20 19:05:57 entspricht FmtDateTime(gettimeofday());

{time_str2num(TimeNow())} => Wandelt ein FHEM-Datum in einen Unix-Timestamp um (in diesen Fall den aktuellen Zeitpunkt) => Ist also genau das gleiche wie {time()}

{time() - time_str2num(ReadingsTimestamp("KU_Spuelmaschine", "running", 0))}

Generell gilt:

Unix-Timestamp zu FHEM-Format -> {FmtDateTime(...)}
FHEM-Format zu Unix-Timestamp -> {time_str2num(...)}

Für die myUtils - eine Funktion um mit Zeitdifferenzen leichter zu Arbeiten. Die Funktion gibt entweder die Zeit in Sekunden seit der Änderung des angegebenen Readings zurück, oder -1 falls das Reading nicht gefunden wurde. Theoretisch könnte auch 0 zurückgegeben werden, wenn diese Funktion in der gleichen Sekunde nach der Änderung eines Readings aufgerufen wird.

sub secondsSinceReadingChange($$) {
    my ($device, $reading) = @_;
    my $readingsTimestamp = ReadingsTimestamp($device, $reading, "failed");

    if ($readingsTimestamp ne "failed") {
        return time() - time_str2num($readingsTimestamp);
    } else {
        return -1;
    }
}
KU_Spuelmaschine:power:.* {
    # Wenn die Spülmaschine eingeschaltet wurde
    if (ReadingsNum($NAME, "power", 0) > 10 && ReadingsVal($NAME, "running", "off") eq "off") {
        fhem("setreading $NAME running on");
    }

    # Wenn die Spülmaschine länger als 5 Minuten lief und dann keinen Strom mehr verbraucht -> Notification
    if (ReadingsNum($NAME, "power", 0) < 1 && ReadingsVal($NAME, "running", "off") eq "on") {
        if (secondsSinceReadingChange($NAME, "running") > 300) {
            fhem("set WEB_Pushover msg 'Spülmaschine' 'Die Spülmaschine ist fertig'");
            fhem("set lametric msg 'i1167' 'Spülmaschine fertig' 'notifications:water1' '1'");
            fhem("set Wunderlist addTask Spülmaschine ausräumen");
        }

        fhem("setreading $NAME running off");
    }

    # Wenn Fehler aufgetreten ist, und die Spülmaschine nach 4 Stunden nicht automatisch ausgegangen ist
    if (secondsSinceReadingChange($NAME, "running") > 14400 && ReadingsVal($NAME, "running", "off") eq "on") {
        fhem("setreading $NAME running off");

        fhem("set WEB_Pushover msg 'Spülmaschine' 'Die Spülmaschine läuft seit 4 Stunden und ist nicht ausgegangen'");
    }
}

Newsletter

Trage Dich jetzt in den Newsletter ein und genieße dadurch viele Vorteile:

  • 5€-Gutschein als Dankeschön
  • Zugang zu exklusiven Inhalten
  • Rabattaktionen für Kurse
  • Angebote für Produkte

* Durch Angabe meiner E-Mail-Adresse erkläre ich mich damit einverstanden, dass mir regelmäßig Informationen und Produktempfehlungen aus dem Fachgebiet Smart Home zugesendet werden. Mit dem Eintrag akzeptieren Sie unsere Datenschutzbestimmungen. Meine Einwilligung kann ich jederzeit widerrufen.

Matthias Kleine

Matthias Kleine

Großer Fan und Anhänger von OpenSource-Projekten und erweiterbaren Haus-Automatisierungskomponenten. Je offener und flexibler das System, desto besser. Ich lege mich ungern auf einzelne Protokolle oder Standards fest, sondern probiere aus allen Welten das Beste zu verheiraten. Unterwegs als Softwareentwickler, Trainer und Blogger im Bereich Smart Home.

Auf YouTube und hier im Blog gibt es bereits unzählige kostenlose Videos, Informationen und Tutorials. Wenn Dir das noch nicht reicht, ist ein Training genau das richtige für Dich! Die folgenden Trainings haben den Vorteil, dass immer von Anfang an gestartet wird und Du ohne Vorwissen teilnehmen kannst.