Sleep und verschachtelte IF

Begonnen von Rheingold, 14 September 2018, 13:07:52

Vorheriges Thema - Nächstes Thema

Rheingold

Hi,

wie kann ich ein verschachteltes IF bauen und dabei hinter Sleeps ein weiteres IF implementieren?

Ich möchte eine Automatisierung mit gewisser Logik einrichten. Im Grunde, wenn ein Schalter aktiv wird sollen mehrere Lichter geschaltet werden auf Basis ihrer Zustände. Dabei machen die Sleeps Probleme, wenn ein IF danach kommt. Aktuell sieht mein Beispiel so aus und funktioniert.

test_schalter:on
IF ([Beispiel_Status] eq "off" and [GeoStatus] eq "Daheim" )
(set Beispiel_Status on,
IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht),
sleep 1,
set test_schalter off,
set Beispiel_Status off)


Möchte ich nun aber nach dem Sleep ein weiteres IF einbauen (oder verschiebe das Sleep nur eine Zeile hoch) funktioniert nichts mehr.

Folgendes funktioniert gar nicht. Es wird nicht mal die erste Zeile "set Beispiel_Status on" ausgeführt:
test_schalter:on
IF ([Beispiel_Status] eq "off" and [GeoStatus] eq "Daheim" )
(set Beispiel_Status on,
sleep 1,
IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht),
set test_schalter off,
set Beispiel_Status off)

Es kommt keine Fehlermeldung o.ä. :'( Hat jemand einen Tipp, wie ich nach dem Sleep weitere IF einbauen kann?
Fhem auf Raspi 3; Jeelink mit 6x TX29DTH; CUL433 mit 9x RCS 1000 N und Somfy-Steuerung; CUL868; MAX-Cube + Thermostate; Philips Hue & Ikea Tradfri; Google Home Assistant; FTUI für Tablet und SmartPhone via Reverse-Proxy

rabehd

Auch funktionierende Lösungen kann man hinterfragen.

Beta-User

Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Damian

Welche Fehlermeldung kommt denn?

Probier mal

test_schalter:on
IF ([Beispiel_Status] eq "off" and [GeoStatus] eq "Daheim" )
(set Beispiel_Status on,
IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht),
sleep 1,set test_schalter off,
set Beispiel_Status off)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Rheingold

DOIF: prinzipiell schon, aber ich habe noch keinen Ansatz, wie ich noch weitere Verschachtelungen damit abbilden kann. Für Tipps zum einlesen bin ich dankbar.

Perl:
Zitat
{fhem "set Beispiel_Status on; sleep 5; set Beispiel_Status off; set test_schalter off";}
{if (ReadingsVal("Flur_Licht_Status", "state", "") == "off") {fhem "(set Flur_Licht_Status 1_Nacht)";}}
Das hat nicht funktioniert. Auch hier bin ich für Tipps dankbar.
Fhem auf Raspi 3; Jeelink mit 6x TX29DTH; CUL433 mit 9x RCS 1000 N und Somfy-Steuerung; CUL868; MAX-Cube + Thermostate; Philips Hue & Ikea Tradfri; Google Home Assistant; FTUI für Tablet und SmartPhone via Reverse-Proxy

Rheingold

Zitat von: Damian am 14 September 2018, 14:12:30
Welche Fehlermeldung kommt denn?

Probier mal

test_schalter:on
IF ([Beispiel_Status] eq "off" and [GeoStatus] eq "Daheim" )
(set Beispiel_Status on,
IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht),
sleep 1,set test_schalter off,
set Beispiel_Status off)


Das funktioniert. Schiebt man das IF aber hinter das sleep, dann wird nichts ausgeführt.

Thema Fehlermeldung:
Zitat2018.09.14 14:20:52 1: PERL WARNING: Bareword found where operator expected at (eval 5844) line 1, near "'  sleep 10; set test_schalter off;fhem(' IF"
2018.09.14 14:20:52 3: eval: my $SELF='nTest';my $EVENT='on';my $NAME='test_schalter';my $EVTPART0='on';my $TYPE='dummy';{if(InternalIf('Beispiel_Status','STATE','') eq "off" and InternalIf('GeoStatus','STATE','') eq "Daheim" ){fhem('set Beispiel_Status on');fhem('  sleep 10; set test_schalter off;fhem(' IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht)'); set Beispiel_Status off')}}
2018.09.14 14:20:52 1: PERL WARNING: Misplaced _ in number at (eval 5844) line 1.
2018.09.14 14:20:52 3: eval: my $SELF='nTest';my $EVENT='on';my $NAME='test_schalter';my $EVTPART0='on';my $TYPE='dummy';{if(InternalIf('Beispiel_Status','STATE','') eq "off" and InternalIf('GeoStatus','STATE','') eq "Daheim" ){fhem('set Beispiel_Status on');fhem('  sleep 10; set test_schalter off;fhem(' IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht)'); set Beispiel_Status off')}}
2018.09.14 14:20:52 1: PERL WARNING: Bareword found where operator expected at (eval 5844) line 1, near "1_Nacht"
2018.09.14 14:20:52 3: eval: my $SELF='nTest';my $EVENT='on';my $NAME='test_schalter';my $EVTPART0='on';my $TYPE='dummy';{if(InternalIf('Beispiel_Status','STATE','') eq "off" and InternalIf('GeoStatus','STATE','') eq "Daheim" ){fhem('set Beispiel_Status on');fhem('  sleep 10; set test_schalter off;fhem(' IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht)'); set Beispiel_Status off')}}
2018.09.14 14:20:52 1: PERL WARNING: String found where operator expected at (eval 5844) line 1, near ")'); set Beispiel_Status off'"
2018.09.14 14:20:52 3: eval: my $SELF='nTest';my $EVENT='on';my $NAME='test_schalter';my $EVTPART0='on';my $TYPE='dummy';{if(InternalIf('Beispiel_Status','STATE','') eq "off" and InternalIf('GeoStatus','STATE','') eq "Daheim" ){fhem('set Beispiel_Status on');fhem('  sleep 10; set test_schalter off;fhem(' IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht)'); set Beispiel_Status off')}}
2018.09.14 14:20:52 1: ERROR evaluating my $SELF='nTest';my $EVENT='on';my $NAME='test_schalter';my $EVTPART0='on';my $TYPE='dummy';{if(InternalIf('Beispiel_Status','STATE','') eq "off" and InternalIf('GeoStatus','STATE','') eq "Daheim" ){fhem('set Beispiel_Status on');fhem('  sleep 10; set test_schalter off;fhem(' IF ([Flur_Licht_Status] eq "off") (set Flur_Licht_Status 1_Nacht)'); set Beispiel_Status off')}}: syntax error at (eval 5844) line 1, near "'  sleep 10; set test_schalter off;fhem(' IF "

2018.09.14 14:20:52 3: nTest return value: syntax error at (eval 5844) line 1, near "'  sleep 10; set test_schalter off;fhem(' IF "

Fhem auf Raspi 3; Jeelink mit 6x TX29DTH; CUL433 mit 9x RCS 1000 N und Somfy-Steuerung; CUL868; MAX-Cube + Thermostate; Philips Hue & Ikea Tradfri; Google Home Assistant; FTUI für Tablet und SmartPhone via Reverse-Proxy

CoolTux

Zitat von: Rheingold am 14 September 2018, 14:14:16
DOIF: prinzipiell schon, aber ich habe noch keinen Ansatz, wie ich noch weitere Verschachtelungen damit abbilden kann. Für Tipps zum einlesen bin ich dankbar.

Perl:Das hat nicht funktioniert. Auch hier bin ich für Tipps dankbar.


{
    fhem ("set Beispiel_Status on; sleep 5; set Beispiel_Status off; set test_schalter off");
    fhem ("set Flur_Licht_Status 1_Nacht") if (ReadingsVal("Flur_Licht_Status", "state", "") eq "off");
}
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Rheingold

Zitat von: CoolTux am 14 September 2018, 14:24:49

{
    fhem ("set Beispiel_Status on; sleep 5; set Beispiel_Status off; set test_schalter off");
    fhem ("set Flur_Licht_Status 1_Nacht") if (ReadingsVal("Flur_Licht_Status", "state", "") eq "off");
}


Oha, ein Traum  :) Damit komm ich sehr gut weiter. Klar muss ich den Code etwas umstrukturieren, aber dein Ansatz gefällt mir, da ich Befehle pro Gerät respektive Zustand der Geräte schreiben kann :)

Vielen Dank! :)
Fhem auf Raspi 3; Jeelink mit 6x TX29DTH; CUL433 mit 9x RCS 1000 N und Somfy-Steuerung; CUL868; MAX-Cube + Thermostate; Philips Hue & Ikea Tradfri; Google Home Assistant; FTUI für Tablet und SmartPhone via Reverse-Proxy

Beta-User

...scheint ja gar nicht so schwer zu sein.

Allerdings: Warum willst du den Zustand der Geräte irgendwo hin schreiben? Kann man doch jeweils aktuell an den Devices auslesen, oder? Nur, wenn etwas zur späteren Verwendung vor einer Änderung gespeichert werden soll, macht das Sinn. Da kann aber auch das recht neue OldValue helfen.

Und: Es ist meistens einfacher, das "Alt-Reading" im Device selbst zu speichern (setreading()), das spart eine Menge dummies und erhöht die Übersichtlichkeit ;) .

Das mit dem nachgestellten if funktioniert allerdings nur mit einem "Einzeiler" (aber da ist es einfacher zu lesen).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Rheingold

Zitat von: Beta-User am 14 September 2018, 14:55:31
...scheint ja gar nicht so schwer zu sein.

Allerdings: Warum willst du den Zustand der Geräte irgendwo hin schreiben? Kann man doch jeweils aktuell an den Devices auslesen, oder? Nur, wenn etwas zur späteren Verwendung vor einer Änderung gespeichert werden soll, macht das Sinn. Da kann aber auch das recht neue OldValue helfen.

Und: Es ist meistens einfacher, das "Alt-Reading" im Device selbst zu speichern (setreading()), das spart eine Menge dummies und erhöht die Übersichtlichkeit ;) .

Das mit dem nachgestellten if funktioniert allerdings nur mit einem "Einzeiler" (aber da ist es einfacher zu lesen).
Das Schreiben der Zustände ist erst mal eine Zwischenlösung und diente der einfacheren Veranschaulichung hier. Ich bin auch kein Freund von zahllosen Dummys.

Wegen der if-Funktionen: Wie kann ich diese Befehle von einem weiteren IF bzw. if umschließen? Also, dass die folgende Bedingung erst mal gültig sein muss? Klar kann man die in die Bedingung für jede Zeile reinschreiben, aber das sieht so unschön aus :D
IF ([GeoStatus] eq "Daheim" ) (set..... )
Fhem auf Raspi 3; Jeelink mit 6x TX29DTH; CUL433 mit 9x RCS 1000 N und Somfy-Steuerung; CUL868; MAX-Cube + Thermostate; Philips Hue & Ikea Tradfri; Google Home Assistant; FTUI für Tablet und SmartPhone via Reverse-Proxy

Beta-User

Früher hatte ich auch mal einige IF, jetzt bin ich (DO)-IF-frei und mach' sowas nur noch mit Perl.

Wenn du eine Eingangsbedingung hast, kannst du natürlich damit beginnen und dann allen anderen Code innerhalb der Ausführung "{...}" weiter verschachteln, siehe auch hier: https://wiki.fhem.de/wiki/Trick_der_Woche#Struktur_von_.22else_if.22_Verzweigungen (direkter cfg-code, ggf. Zahl der ; anpassen!)

Oder den code mit
return undef if (...); einleiten, dann sollte abgebrochen werden (wenn danach nichts mehr relevantes irgendwo in "else" kommt!).

Statt if geht auch "unless". Das ist wie if, nur eben verneint; die beiden folgenden Zeilen sind also gleichbedeutend:
return undef if (ReadingsVal("Flur_Licht_Status", "state", "") ne "off");
return undef unless (ReadingsVal("Flur_Licht_Status", "state", "") eq "off");


Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Damian

Verschaltete Abfragen würde ich auch in Perl definieren, weil man dann weniger mit unvorhergesehenen Nebeneffekten zu kämpfen hat. Insb. das Problem mit Semikolon doppeln oder nicht entfällt dann.
Hier mal ein Beispiel mit Verzögerung ohne Sleep: https://forum.fhem.de/index.php/topic,84969.msg836239.html#msg836239
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Beta-User

Zitat von: Damian am 14 September 2018, 17:09:57
Insb. das Problem mit Semikolon doppeln oder nicht entfällt dann.
"Eigentlich" ist das mit dem Doppeln des Semikolon kein "Problem", sondern nur was, was man halt wissen/beachten muß. An sich ist es klar: Nur wenn es RAW-Code oder direkter cfg-Code ist verdoppelt, sonst nicht.

Meine eigene Vorgehensweise sieht zwischenzeitlich so aus, dass ich entweder über die Kommandozeile ein neues Device (idR. notify oder at definiere und für den Ausführungsteil erst mal {} einsetze.

Danach wird in der DEF rumhantiert. Dort unterscheidet sich das Arbeiten  eigentlich kaum von normalem Perl-Code in einer myUtils. Also idR. ohne Doppelungen usw., dafür aber mit Fehlermeldungen beim "modify"-Klicken, wenn ich mal wieder irgendwelche Kleinigkeiten wie Semikolons, schließende Klammern und so weiter vergesse ;) ...

Dazu kenne ich zwischenzeitlich auch den Unterschied zwischen den Hochkommata ;) .

Bin halt Purist, kann auf hübsche Verpackungen verzichten und direkt am Motor schrauben 8) . Jeder wie er mag.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Damian

Das Problem bleibt bei sleep (FHEM), ob man Unterroutinen benutzt oder nicht, denn Viele wissen es nicht,  das Semikolon hinter einem sleep gehört zum sleep und ist hier kein FHEM-Trennzeichen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF