Hauptmenü

neues Modul DOIF

Begonnen von Damian, 21 Mai 2014, 15:53:18

Vorheriges Thema - Nächstes Thema

Brockmann

Zitat von: Simon74 am 07 August 2014, 14:49:59
ich würde gerne im DOELSEIF Teil einen "at" Eintrag definieren, jedoch nur wenn dieser "at" noch nicht vorhanden ist.
Ich habe es mal so versucht, was nicht funktioniert:
DOIF (wenn dies und das) (tu das) DOELSEIF ([wz.led.off] ne "") (define wz.led.off at +00:15 set t5.wz.bs1.b:FILTER=STATE!=off off)
Das kann so nicht gehen. Du fragst damit ja eine Eigenschaft eines Objekts ab, das nicht existiert. Und das gibt einen Fehler.
Die Existenz von Objekten kannst Du mit defined $defs{<Objektname>} abfragen, also ungefähr (ungetestet):
DOELSEIF(not defined $defs{wz.led.off})(define...)
(Diese Bedingung würde so aber nie getriggert werden, also der Trigger für das DOIF muss aus einer der anderen Bedingungen kommen!)

Brockmann

Ich habe folgendes als DOIF erstellt:
([FHEM_Kalender:modeStarted] ne "")
    (
    setreading Datastore Cal_start_sum (get FHEM_Kalender summary [FHEM_Kalender:modeStarted]),
    setreading Datastore Cal_start_loc (get FHEM_Kalender location [FHEM_Kalender:modeStarted])
    )

In den Readings habe ich dann stehen:

Cal_start_loc    (get FHEM_Kalender location 2vdojpgsnaoneamvfiqcgooglecom)    2014-08-07 14:44:03
Cal_start_sum    (get FHEM_Kalender summary 2vdo5og6naoneamvfpqcgooglecom)     2014-08-07 14:44:03


Also der Ausdruck in eckigen Klammern wird ausgewertet, aber der Rest nicht. Gibt es eine Möglichkeit, den Rückgabewert der get-Funktion ins Reading zu schreiben?
Ich habe schon verschiedene Varianten von Kombinationen von Klammern, fhem"..." usw ausprobiert, aber ich bekomme es nicht hin.

Damian

Zitat von: Brockmann am 07 August 2014, 15:25:58
Das kann so nicht gehen. Du fragst damit ja eine Eigenschaft eines Objekts ab, das nicht existiert. Und das gibt einen Fehler.
Die Existenz von Objekten kannst Du mit defined $defs{<Objektname>} abfragen, also ungefähr (ungetestet):
DOELSEIF(not defined $defs{wz.led.off})(define...)
(Diese Bedingung würde so aber nie getriggert werden, also der Trigger für das DOIF muss aus einer der anderen Bedingungen kommen!)
Eigentlich war meine Idee bei DOIF notify, at, watchdog nicht mehr benutzen zu müssen, da diese Funktionalität in DOIF steckt. Wenn du nur eine Verzögerung haben willst, dann kannst du das einfach mit dem wait-attribut realisieren.

... DOELSEIF ([wz.led.off] ne "") (set t5.wz.bs1.b:FILTER=STATE!=off off)
attr modulname wait ...:900

auch den Filter kannst du dir sparen, da bei DOIF im Gegensatz zu notify nur einmal geschaltet wird.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Zitat von: Brockmann am 07 August 2014, 15:29:39
Ich habe folgendes als DOIF erstellt:
([FHEM_Kalender:modeStarted] ne "")
    (
    setreading Datastore Cal_start_sum (get FHEM_Kalender summary [FHEM_Kalender:modeStarted]),
    setreading Datastore Cal_start_loc (get FHEM_Kalender location [FHEM_Kalender:modeStarted])
    )

In den Readings habe ich dann stehen:

Cal_start_loc    (get FHEM_Kalender location 2vdojpgsnaoneamvfiqcgooglecom)    2014-08-07 14:44:03
Cal_start_sum    (get FHEM_Kalender summary 2vdo5og6naoneamvfpqcgooglecom)     2014-08-07 14:44:03


Also der Ausdruck in eckigen Klammern wird ausgewertet, aber der Rest nicht. Gibt es eine Möglichkeit, den Rückgabewert der get-Funktion ins Reading zu schreiben?
Ich habe schon verschiedene Varianten von Kombinationen von Klammern, fhem"..." usw ausprobiert, aber ich bekomme es nicht hin.

Ergebnisse von FHEM-Befehlen innerhalb von FHEM-Befehlen direkt auszuwerten ist nicht vorgesehen. Dann wirst du wohl einen Umweg über Perl machen müssen. Den entsprechenden Perl-Code musst du in geschweifte Klammern setzen:  ({....}).

Gruß

Damian




Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Simon74

Zitat von: Damian am 07 August 2014, 15:57:18
Eigentlich war meine Idee bei DOIF notify, at, watchdog nicht mehr benutzen zu müssen, da diese Funktionalität in DOIF steckt. Wenn du nur eine Verzögerung haben willst, dann kannst du das einfach mit dem wait-attribut realisieren.

... DOELSEIF ([wz.led.off] ne "") (set t5.wz.bs1.b:FILTER=STATE!=off off)
attr modulname wait ...:900

auch den Filter kannst du dir sparen, da bei DOIF im Gegensatz zu notify nur einmal geschaltet wird.

Gruß

Damian

Dankeschön !

jens

Hallo,
ich versuche das Waschmaschinen-Scenario, welches hier im Thread schon behandelt wurde, nachzustellen. So weit funktioniert das Ganze auch, allerdings bekommen ich bei einem fhem neustart immer eine Pushnotification.

Ich benutzte die letzte von Damian gepostete DOIF Funktion.
   
define di_Waschmaschine DOIF ([CUL_EM_8:peak]<0.04) (set Notifications msg 'Keller' 'Waschmaschine FERTIG!!!' '' 0 '')
attr di_Waschmaschine icon scene_washing_machine
attr di_Waschmaschine loglevel 6
attr di_Waschmaschine room Smart
attr di_Waschmaschine wait 300

Muß ich damit leben, da der erste Statuswechsel ja erst nach dem restart passiert, oder kann ich das "peak reading" irgendwie initalisieren?

Vielen Dank,
Jens

Brockmann

Zitat von: jens am 08 August 2014, 11:10:00
Muß ich damit leben, da der erste Statuswechsel ja erst nach dem restart passiert, oder kann ich das "peak reading" irgendwie initalisieren?
Ansich sollten die States auch von DOIFs im Statefile gesichert und beim Neustart wieder eingelesen werden. Du müsstest nur dafür sorgen, dass regelmäßig ein WriteStatefile durchgeführt wird, beispielsweise so:
define StateFile_schreiben at +*01:00:00 {WriteStatefile}
Das schreibt einmal pro Stunde den aktuelle Stand ins Statefile. Man kann das natürlich alternativ auch an bestimmte wichtige Ereignisse/Aktionen dranhängen.
Bei einem Neustart wird direkt nach dem Einlesen der fhem.cfg auch das Statefile eingelesen, so dass alle Objekte wieder in dem Zustand sind, den sie beim letzten Schreiben des Statefiles hatten.

Damian

Zitat von: Brockmann am 08 August 2014, 11:29:26
Ansich sollten die States auch von DOIFs im Statefile gesichert und beim Neustart wieder eingelesen werden. Du müsstest nur dafür sorgen, dass regelmäßig ein WriteStatefile durchgeführt wird, beispielsweise so:
define StateFile_schreiben at +*01:00:00 {WriteStatefile}
Das schreibt einmal pro Stunde den aktuelle Stand ins Statefile. Man kann das natürlich alternativ auch an bestimmte wichtige Ereignisse/Aktionen dranhängen.
Bei einem Neustart wird direkt nach dem Einlesen der fhem.cfg auch das Statefile eingelesen, so dass alle Objekte wieder in dem Zustand sind, den sie beim letzten Schreiben des Statefiles hatten.

Das wird leider z. Zt. nicht helfen. Ich merke mir den letzten Zustand in Internals nicht in Readings, diese werden beim Neustart neugesetzt. Damit der Zustand ein Reboot überlebt, müsste ich mir den letzten Zustand in den Readings merken (das Reading last_cmd wird jetzt schon gesetzt aber nicht ausgewertet)

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Brockmann

Zitat von: Damian am 08 August 2014, 11:45:35
Das wird leider z. Zt. nicht helfen. Ich merke mir den letzten Zustand in Internals nicht in Readings, diese werden beim Neustart neugesetzt. Damit der Zustand ein Reboot überlebt, müsste ich mir den letzten Zustand in den Readings merken (das Reading last_cmd wird jetzt schon gesetzt aber nicht ausgewertet)
Ah, sorry, ich hatte angenommen, dass die Readings ausschlaggebend wären.

Damian

Zitat von: Brockmann am 08 August 2014, 11:50:09
Ah, sorry, ich hatte angenommen, dass die Readings ausschlaggebend wären.
Ich werde das in der nächsten Version auf Reading-Auswertung umstellen. Dann wird der Zustand erhalten bleiben und das Kommando nicht erneut ausgeführt.

Gruß

Damian


Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#340
Finale Eincheck-Version ist fertig.

Ich habe nun meine Vorstellungen umgesetzt und die hier besprochenen Probleme behoben.

Die wichtigsten Neuerungen (siehe dazu Beispiele im ersten Post) sind:

+reine Statusanzeige ohne Ausführung von Kommandos
+Angabe von Readings, Stati und Internals sowie Perlberechnungen im Status des Moduls


Bitte die erweiterte Dokumentation im ersten Post beachten.

Achtung: Diese Version ist intern nicht abwärtskompatibel zu der vorherigen. Daher:

System  anhalten, Modul kopieren, System wieder hochfahren (kein reload)

Danach bei allen bereits definierten DOIF-Modulen über die Weboberfläche auf DEF klicken und über modify-Button bestätigen.

Da die bisherigen Versionen recht stabil liefen, erwarte ich keine großen Überraschungen bzgl. der Stabilität. Wenn im Laufe nächster Woche keine gravierenden Mängel auffallen, werde ich die Doku aus dem ersten Post noch in der Source aktualisieren und das Modul einchecken.

Gruß

Damian

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

jens

Hallo Damian,
ich kann bestätigen, dass mein Waschmaschinen DOIF jetzt voll funktioniert. D.h. nach einem Neustart gibt es keine "falsche" Notification mehr. Super! Vielen Dank für die rasche Implementierung!

Gruss,
Jens

Brockmann

Verträgt sich DOIF eigentlich mit IF?

Also mir ist schon klar, dass DOIF das IF eigentlich überflüssig machen sollte. Aber ich habe beispielsweise einen Anwendungsfall, wo beim Triggern eines Ereignisses bestimmte Aktionen immer durchgeführt werden sollen, andere nur in Abhängigkeit von weiteren Bedingungen. Bei einem reinen DOIF müsste ich die "Immer-Aktionen" in jedem Ausführungsteil wiederholen, was ja nicht Sinn der Sache ist. Deshalb dachte ich mir, ich setze in den Ausführungsteil des DOIF ein paar IFs rein. Aber ich habe das Gefühl, dass es da ein grundsätzliches Problem gibt.
([Datastore])
    (
    IF ([Datastore] eq "Test")(trigger global Datastore_Test)
    )

sollte formal korrekt sein, oder? Führt aber mit set Datastore Test zur Fehlermeldung:
IF (Test eq "Test") (trigger global Datastore_Test) : Bareword "Test" not allowed while "strict subs" in use at (eval 96002) line 1.
set Datastore "Test" hingegen klappt.
Um die "verschwundenen" Anführungszeichen zurückzubekommen, habe es dann testweise mal in
    IF ("[Datastore]" eq "Test")(trigger global Datastore_Test)
geändert und überraschenderweise scheint es so zu funktionieren.

Ist das ein ungewollter Seiteneffekt bei der Kombination von IF und DOIF oder ist das so beabsichtigt? Dann sollte man das vielleicht noch dokumentieren.

Damian

#343
Zitat von: Brockmann am 11 August 2014, 09:20:47
Verträgt sich DOIF eigentlich mit IF?

Also mir ist schon klar, dass DOIF das IF eigentlich überflüssig machen sollte. Aber ich habe beispielsweise einen Anwendungsfall, wo beim Triggern eines Ereignisses bestimmte Aktionen immer durchgeführt werden sollen, andere nur in Abhängigkeit von weiteren Bedingungen. Bei einem reinen DOIF müsste ich die "Immer-Aktionen" in jedem Ausführungsteil wiederholen, was ja nicht Sinn der Sache ist. Deshalb dachte ich mir, ich setze in den Ausführungsteil des DOIF ein paar IFs rein. Aber ich habe das Gefühl, dass es da ein grundsätzliches Problem gibt.
([Datastore])
    (
    IF ([Datastore] eq "Test")(trigger global Datastore_Test)
    )

sollte formal korrekt sein, oder? Führt aber mit set Datastore Test zur Fehlermeldung:
IF (Test eq "Test") (trigger global Datastore_Test) : Bareword "Test" not allowed while "strict subs" in use at (eval 96002) line 1.
set Datastore "Test" hingegen klappt.
Um die "verschwundenen" Anführungszeichen zurückzubekommen, habe es dann testweise mal in
    IF ("[Datastore]" eq "Test")(trigger global Datastore_Test)
geändert und überraschenderweise scheint es so zu funktionieren.

Ist das ein ungewollter Seiteneffekt bei der Kombination von IF und DOIF oder ist das so beabsichtigt? Dann sollte man das vielleicht noch dokumentieren.
ja, es ist tatsächlich ein Seiteneffekt, weil bei FHEM-Kommandos DOIF die Readings in eckigen Klammern ersetzt, bevor IF überhaupt zum Zuge kommt.
Ich muss mir die Problematik genauer anschauen. Evtl. muss ich bei DOIF erkennen, dass ein IF-Befehl ausgeführt werden soll und die Ersetzung nicht vornehmen und sie IF überlassen. Diesen Mechanismus habe ich bereits bei verschtelten IF-Befehlen schon eingebaut, daher sollte es machbar sein.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#344
Zitat von: Damian am 11 August 2014, 09:40:13
ja, es ist tatsächlich ein Seiteneffekt, weil bei FHEM-Kommandos DOIF die Readings in eckigen Klammern ersetzt, bevor IF überhaupt zum Zuge kommt.
Ich muss mir die Problematik genauer anschauen. Evtl. muss ich bei DOIF erkennen, dass ein IF-Befehl ausgeführt werden soll und die Ersetzung nicht vornehmen und sie IF überlassen. Diesen Mechanismus habe ich bereits bei verschtelten IF-Befehlen schon eingebaut, daher sollte es machbar sein.

Gruß

Damian

Mit der neuen Version (1.61 im ersten Post) sollte es keinen Grund mehr geben auf Perl-if ausweichen zu müssen.  ;)

Funktioniert jetzt mit IF, wie man es erwartet.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF