Verständnisfrage insb. zur Mehrfachnutzung eines Ausführungsteils

Begonnen von FHEMAN, 14 Dezember 2020, 21:08:47

Vorheriges Thema - Nächstes Thema

FHEMAN

Hallo,

keine Frage, DOIF ist mega. Und irgendwie denke ich jedes Mal, ich kann alles damit lösen, und meist fehlen am Ende ein paar Prozent zu meinem Glück...
was sicherlich an mein Unvermögen liegt ::)
Daher ohne viel Umschweife mal gefragt, wie kann ich das folgende Konstrukt elegant lösen
([TFK.Schuppeneingang.Sw.Dummy] eq "closed" and ([Alarmanlage] eq "on" or ([TFK.Eingang.Sw.04.Verschluss] eq "closed" and [TFK.Nebeneingang.Sw.04.Verschluss] eq "closed") or [TFK.Schuppeneingang.Sw.Dummy:state:sec]>3600 or ([isTwilight] eq "on" and [TFK.Schuppeneingang.Sw.Dummy:state:sec]>600))) (
{
fhem("set Keymatic.Schuppentuer:FILTER=r:lock!=locked lock")
}
)

Ich habe gelernt, anstelle von :sec muss ich wait nutzen, da :sec nicht selbst triggert. Allerdings habe ich dann 3-4 CMDs mit ein und demselben Ergebnis. In diesem Fall ist die Pflege der einen Zeile im Ausführungsteil kein Problem. Bei anderen, komplexeren DOIFs jedoch schon.
Geht es daher irgendwie besser / eleganter?
Kann ich z.B. eine Art globale Funktion über allen CMDs definieren, die ich innerhalb der CMDs aufrufe und bei der ich alle DOIF Vorteile nutzen kann?

Danke für ein wenig Input...
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Im DOIF FHEM-Modus kannst du eigene Perl-Routinen aufrufen, es gibt aber keine globalen DOIF-Attribute

Im DOIF-Perlmodus kannst du dagegen mit Templates arbeiten, damit kann man gleiche Abläufe mehrfach verwenden:

https://wiki.fhem.de/wiki/DOIF/Templates

das kann man bis zu Szenarien mit WEB-GUI ausbauen:

https://wiki.fhem.de/wiki/DOIF/Automatisierung
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Danke für den Hint, das sieht schon vielversprechend aus. Und direkt kommen mir Fragen bei der Umsetzung:
Kann ich bei Template Bedingungen auch verschiedene "wait" Zeiträume hinterlegen?
Die Syntax aus dem Beispiel Zimmertemperaturen: {$1;;   ## Zeitangabe\ erschließt sich mir nicht - warum muss hier eine geschweifte Klammer vorangestellt sein und nicht eine einfache?
So recht kriege ich mein Konstrukt oben nicht in ein Template überführt. Mal vereinfacht, wie setze ich hier folgende Bedingung:
([Tuer] eq "closed" and [Alarmanlage] eq "on" and [Tuer:state:sec]>3600)
Hier bringt ja ein pauschales wait nichts, da nach Aktivieren der Alarmanlage nicht 1h gewartet werden soll.

PS: Bietest du auch doif-Intensivkurse an? ;)
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Die Vorgehensweise ist folgende:

1) Zuerst ein FHEM-DOIF in gleichwertiges Perl-DOIF übersetzen
2) Im zweiten Schritt variable Stellen durch Platzhalter ($1, $2 usw) ersetzen und ein Template definieren.
3) Template für verschiedene Devices (Szenarien) aufrufen

Als variable Stelle könnte z. B. hier das Device gelten:

([$1] eq "closed" and [Alarmanlage] eq "on" and [$1:state:sec]>3600)




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

FHEMAN

Ich dachte, ich wäre schon bei Punkt 2. Deswegen verstehe ich noch nicht, wie aus DOIF ([05:00|8])() auf einmal DOIF DEF TPL ({[05:00|8]}) wird. Der Perlmodus erwartet doch {} in Kombination von "if" bei den Bedingungstriggern, oder nicht? (Und den Platzhalter sehe ich einfach als String-Ersetzungstext) Na ich durchwühle wohl nochmal die umfangreiche Doku..
//Edit: In der Doku habe ich nun entdeckt, dass ich bestimmte Trigger ohne "if" mit ";" getrennt angeben kann.

ZitatAls variable Stelle könnte z. B. hier das Device gelten:

([$1] eq "closed" and [Alarmanlage] eq "on" and [$1:state:sec]>3600)

Aber dann triggert das CMD doch niemals nach der definierten Zeit?
Und unterschiedliche waits kann ich nicht nutzen bei den verschiedenen Platzhalten?

Ich will das gerne als DOIF umsetzen, brauche aber noch einige Schubse bitte..
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: FHEMAN am 15 Dezember 2020, 16:13:39
Ich dachte, ich wäre schon bei Punkt 2. Deswegen verstehe ich noch nicht, wie aus DOIF ([05:00|8])() auf einmal DOIF DEF TPL ({[05:00|8]}) wird. Der Perlmodus erwartet doch {} in Kombination von "if" bei den Bedingungstriggern, oder nicht? (Und den Platzhalter sehe ich einfach als String-Ersetzungstext) Na ich durchwühle wohl nochmal die umfangreiche Doku..
//Edit: In der Doku habe ich nun entdeckt, dass ich bestimmte Trigger ohne "if" mit ";" getrennt angeben kann.

Aber dann triggert das CMD doch niemals nach der definierten Zeit?
Und unterschiedliche waits kann ich nicht nutzen bei den verschiedenen Platzhalten?

Ich will das gerne als DOIF umsetzen, brauche aber noch einige Schubse bitte..

Es triggert auch sonst nicht nach einer bestimmten Zeit. Mit sec wird nur das Alter des Readings abgefragt.

DOIF im Perlmodus arbeitet weitgehend ohne Attribute, wait wird dort mit sec_Exec realisiert: https://fhem.de/commandref_DE.html#DOIF_set_Exec

Dort kann man ebenso mit Platzhaltern arbeiten, die verschiedene Verzögerungen darstellen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Danke für den Hinweis zu set_Exec. Immer, wenn ich mit DOIF aufgeben möchte, kommt eine Lösung zum Vorschein. Ich habe den Aufruf oben jetzt folgendermaßen gelöst:

([TFK.Schuppeneingang.Sw.Dummy] eq "closed" and ([Alarmanlage] eq "on" or ["isTwilight"] or ([TFK.Eingang.Sw.04.Verschluss] eq "closed" and [TFK.Nebeneingang.Sw.04.Verschluss] eq "closed"))) (
{
my $timer = 0;
if ("[Alarmanlage]" ne "on") {
$timer = ("[isTwilight]" eq "on") ? "600" : "3600";
}
set_Exec("timer",$timer,'fhem("set Keymatic.Schuppentuer:FILTER=r:lock!=locked lock")','ReadingsVal("TFK.Schuppeneingang.Sw.Dummy","state","open") eq "closed"')

}

Sollte eine der Bedingungen im unwahr werden, wird der Timer gecancelt, richtig?
isTwilight nutze ich als Eventtrigger. Ich bin gespannt, ob es klappt heute Abend.
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

("[Alarmanlage]" ne "on") wird nicht funktionieren

dann schon eher:

([Alarmanlage] ne "on")

Alarmanlage wirkt dann aber triggernd

daher eher:

([?Alarmanlage] ne "on")


Am besten, wenn es nicht triggern soll, gleich mit

(ReadingsVal("Alarmanlage","state","") ne "on")

abfragen.

Das Gleiche gilt für "isTwilight"
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Zitat von: Damian am 16 Dezember 2020, 15:01:18
("[Alarmanlage]" ne "on") wird nicht funktionieren
Ich habe das bisher verwendet, um ungültige Stringvergleiche zu vermeiden. Manchmal war die Variable laut Log leer (nicht ""). Aber er betrachtet alles in "" wohl als Regex.

del_Exec kann und muss ich nicht in DOELSE() aufrufen?
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: FHEMAN am 16 Dezember 2020, 19:38:09
Ich habe das bisher verwendet, um ungültige Stringvergleiche zu vermeiden. Manchmal war die Variable laut Log leer (nicht ""). Aber er betrachtet alles in "" wohl als Regex.

del_Exec kann und muss ich nicht in DOELSE() aufrufen?

del_Exec kannst du nicht in DOELSE () aufrufen, weil im Perlmodus kein DOELSE existiert ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Zitat von: FHEMAN am 16 Dezember 2020, 13:10:53

([TFK.Schuppeneingang.Sw.Dummy] eq "closed" and ([Alarmanlage] eq "on" or ["isTwilight"] or ([TFK.Eingang.Sw.04.Verschluss] eq "closed" and [TFK.Nebeneingang.Sw.04.Verschluss] eq "closed"))) (
{
my $timer = 0;
if ("[Alarmanlage]" ne "on") {
$timer = ("[isTwilight]" eq "on") ? "600" : "3600";
}
set_Exec("timer",$timer,'fhem("set Keymatic.Schuppentuer:FILTER=r:lock!=locked lock")','ReadingsVal("TFK.Schuppeneingang.Sw.Dummy","state","open") eq "closed"')

}
)


Mit dieser Konstruktion gibt es den Perl Fehler, dass set_Exec unbekannt ist.
Ich vermute, es liegt daran, dass der Bedingungsteil noch in DOIF Notation ist? Was ich gerne so beibehalten würde. Aber wie muss ich die () dann richtig setzen?
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: FHEMAN am 21 Dezember 2020, 16:49:53
Mit dieser Konstruktion gibt es den Perl Fehler, dass set_Exec unbekannt ist.
Ich vermute, es liegt daran, dass der Bedingungsteil noch in DOIF Notation ist? Was ich gerne so beibehalten würde. Aber wie muss ich die () dann richtig setzen?

klar, das ist ein DOIF im FHEM-Modus und nicht im Perl-Modus, nur dort funktioniert set_Exec. Siehe https://fhem.de/commandref_DE.html#DOIF_Perl_Modus

Der Perl-Modus fängt nicht mit ( an.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Boah, habe es nun umgebaut.. fühlt sich nun alles ganz anders an.. keine checkall etc. Funktionen mehr. DOELSE() ist dann sicherlich auch überflüssig geworden, oder gibt es ein else {{}}?
Wenigstens ist jetzt das eigentlich verwirrende Wort DOELSE weg ;)
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: FHEMAN am 21 Dezember 2020, 17:34:51
Boah, habe es nun umgebaut.. fühlt sich nun alles ganz anders an.. keine checkall etc. Funktionen mehr. DOELSE() ist dann sicherlich auch überflüssig geworden, oder gibt es ein else {{}}?
Wenigstens ist jetzt das eigentlich verwirrende Wort DOELSE weg ;)

Es gibt alles, was es in Perl gibt, insb. else, elsif usw. und so gut wie keine Attribute ;) - man muss etwas umdenken, dafür kann man besser "programmieren"
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

FHEMAN

Ich kämpfe weiter.. Kannst Du mir das bitte näher erklären:
Zitat von: Damian am 16 Dezember 2020, 15:01:18
("[Alarmanlage]" ne "on") wird nicht funktionieren

dann schon eher:

([Alarmanlage] ne "on")

Ich erhalte bei Bedingungen in der Art

([Resident1:state] eq "off" or [Resident2:state] eq "off")

die Fehlermeldung

doif.Test: off eq "off" or off eq "off": Unknown command off, try help.

Für mich sieht das so aus, als würden da "" fehlen?
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB