[GELÖST] im DoIf einen EVENT-Teil extrahieren - Restzeitanzeige für on-for-timer

Begonnen von dirk_69, 17 Oktober 2025, 18:39:55

Vorheriges Thema - Nächstes Thema

dirk_69

Hallo zusammen,
Ich habe ein Problem damit, dass DoIf das EVTPARTx nicht kennt/verwendet.
Dass es so ist, ist doch noch immer so?

Ich möchte innerhalb eines DoIf als Kommando einen Wert aus dem EVENT als Attribut setzen lassen.
Hier das EVENT:
2025-10-17 18:28:36 MQTT2_DEVICE MQTT2_new_Tasmota_Refoss_POW10 set_on-for-timer 44
(Es soll dabei ein Count-Down-Timer für ein "on-for-timer" erstellt werden, der die Restlaufzeit des "on-for-timer" enthält)
Mit festen Werten funktioniert das ganze bereits ...
defmod DI_TEST_OnFor DOIF ([".*:set_on-for-timer.3600$"])\
  (defmod watches_$DEVICE watches Digital)\
  (set watches_$DEVICE countDownInit 3600)\

Aber ich habe alle möglichen Werte ausser "3600" und kann nicht alles in einzelne DoIf's bauen.
Daher versuche ich den Wert aus dem EVENT zu verwenden...
z.B.
defmod DI_TEST_OnFor DOIF ([".*:set_on-for-timer"])\
 (attr watches_$DEVICE comment $EVTPART0 $EVTPART1 $EVENT {($EVENT=~ m/(.*):(.*)/;; "$1 $2")} )
 (set watches_$DEVICE countDownInit $EVENTPART0)

Die Werteübergabe im comment soll zeigen, was übergeben wird.
Resultat: comment = $EVTPART0 $EVTPART1 set_on-for-timer 44

Ich habe auch versucht, verschiedene Varianten der Werte-Extraktion, die ich hier im Forum gefunden habe, einzusetzen
z.B. {($EVENT=~ m/(.*):(.*)/;; "$1 $2")}
https://forum.fhem.de/index.php?topic=63634.0

Allerdings scheitere ich an der Einbindung.
Kann mir jemand einen Tipp geben, wie ich den Wert aus dem Event übergeben bekomme?
Ich komme hier mit den gefundenen Infos aus dem Forum einfach nicht weiter.

Vielen Dank schon mal an alle, die bis hier gelesen haben ;-)

Damian

Für sowas gibt es eigene Syntax:

ZitatAllgemeine Ereignistrigger können ebenfalls so definiert werden, dass sie nicht nur wahr zum Triggerzeitpunkt und sonst nicht wahr sind, sondern Inhalte des Ereignisses zurückliefern. Initiiert wird dieses Verhalten durch die Angabe eines Default-Wertes.

Syntax:

["regex for trigger",<default value>]

Anwendungsbeispiel:

define di_warning DOIF ([":^temperature",0] < 0) (set pushmsg danger of frost $DEVICE)
attr di_warning do always

hier z. B. attr watches_$DEVICE comment [".*:set_on-for-timer",0]

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

dirk_69

#2
Zitat von: Damian am 18 Oktober 2025, 13:45:09hier z. B.
attr watches_$DEVICE comment [".*:set_on-for-timer",0]

Danke für die Antwort.
Aber ist das nicht eher ein Trigger, was da ausgegeben wird?
vom EVENT "on-for-timer 44" hätte ich gern die 44 im Kommentar. (und dann später im Befehl "set watches_$DEVICE countDownInit ZAHL")
Mit deinem Beispiel erhalte ich folgendes im Kommentar: comment "[::EventDoIf('.*',$hash,'set_on-for-timer',0,'[^\:]*: (.*)','','0')]"
Hier noch mal der relevante Code-Teil wie ich ihn gerade eingebaut habe:
defmod DI_TEST_OnFor DOIF ([".*:set_on-for-timer"])\
  (defmod watches_$DEVICE watches Digital)\
  (attr watches_$DEVICE digitalDisplayPattern countdownwatch)\
  (attr watches_$DEVICE comment [".*:set_on-for-timer",0])\
  (set watches_$DEVICE countDownInit [".*:set_on-for-timer",0])\
  (set watches_$DEVICE start)\

ausgelöst wird es beim folgenden EVENT korrekt, ich habe ja etwas im Comment:
2025-10-18 14:57:11 MQTT2_DEVICE MQTT2_new_Tasmota_Refoss_POW10 set_on-for-timer 44

Also ist die Frage, wie bekomme ich die "44" für weitere Verwendung isoliert.
Wenn du da bitte auch noch mal gucken könntest?

danke Dirk

Damian

ja, die Trigger-Syntax mit Rückgabe des Wertes funktioniert wohl nur in der Bedingung. Deshalb lässt sich die Aufgabe einfacher im Perl-Modus realisieren:

defmod DI_TEST_OnFor DOIF {\
  $_counter= [":^set_on-for-timer",0];;\
  fhem("defmod watches_$device watches Digital");;\
  fhem("attr watches_$device digitalDisplayPattern countdownwatch");;\
  fhem("attr watches_$device comment");;\
  fhem("set watches_$device countDownInit $_counter");;\
  fhem("set watches_$device start");;\
  }

Was mir allerdings im Allgemeinen an der Lösung nicht gefällt ist, dass du jedes Mal mit defmod die Konfiguration änderst (rotes Fragezeichen).
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

dirk_69

Hi,
das ganze DOIF im Perl Mode laufen zu lassen, hatte ich auch schon überlegt.
Da ich aber der Zusammenhang von FHEM und PERL und den Wechsel zwischen den beiden nicht verstehe, hatte ich lieber die Finger davon gelassen.
Dein Beispiel ist aber eigentlich sehr verständlich.
Nur ... bei deinem Beispiel ...
Wo ist da der Trigger? Müsste nicht irgendwo ein "IF" kommen?
... doch es passiert ja was, also irgendetwas löst das DOIF also aus.
$_counter hat aber immer den Wert 0 und nicht die 44 aus dem "EVENT". 
Ich habe hier ein EVENT und kein READING. Könnte es daran liegen?

Damian

#5
Der Perl-Modus ist im Wiki recht genau beschrieben: https://wiki.fhem.de/wiki/DOIF/Perl-Modus

Dort steht auch, dass der Trigger irgendwo im Block stehen kann. Die Triggerangaben (Angaben in eckigen Klammern) haben den gleichen Aufbau wie im FHEM-Modus.

Dass es bei dir nicht funktioniert, liegt offenbar am Event selbst. Die Syntax geht davon aus, dass es einen Doppelpunkt mit Leerzeichen vor der Zahl gibt, was einem typischen Reading-Event entspricht. So habe ich es bei mir getestet. Wenn du keinen Einfluss auf das Event hast, dann musst du die Regex-Angabe selbst angeben. In der Commandref zu Eventauswertung mit Rückgabe eines Wertes steht:

ZitatSyntax:

["regex for trigger":"<regex filter>":<output>,<default value>]

Regex-Filter- und Output-Parameter sind optional. Der Default-Wert ist verpflichtend.

Die Angaben zum Filter und Output funktionieren, wie die beim Reading-Filter. Siehe: Filtern nach Ausdrücken mit Ausgabeformatierung

Wenn kein Filter, wie obigen Beispiel, angegeben wird, so wird intern folgende Regex vorbelegt: "[^\:]*: (.*)" Damit wird der Wert hinter der Readingangabe genommen. Durch eigene Regex-Filter-Angaben kann man beliebige Teile des Events herausfiltern, ggf. über Output formatieren und in der Bedingung entsprechend auswerten, ohne auf Readings zurückgreifen zu müssen.

Die Angabe

$_counter= [":^set_on-for-timer",0];
entspricht also:

$_counter= [":^set_on-for-timer":"[^\:]*: (.*)",0];
Jetzt überlasse ich dir die Aufgabe die Regex so zu ändern, dass nur das letzte Wort des Events, also nur die Zahl, ohne einen vorherigen Doppelpunkt übernommen wird.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

dirk_69

#6
Vielen Dank!
Jetzt funktioniert es.
Dass der Trigger irgendwo stehen kann, hatte ich gelesen, aber das mit den eckigen Klammern als Trigger nicht realisiert.

Hier noch der Code, falls noch jemand eine Restzeit-Anzeige für ein "on-for-timer" sucht:
{
  $_counter= [":^set_on-for-timer":"[^set\_on\-for\-timer ]* (\d+)",0];
  fhem("defmod watches_$device watches Digital");
  fhem("attr watches_$device digitalDisplayPattern countdownwatch");
  fhem("attr watches_$device group Watches");
  fhem("attr watches_$device room Watches");
  fhem("attr watches_$device comment $_counter");
  fhem("attr watches_$device timeAsReading 1");
  fhem("set watches_$device countDownInit $_counter");
  fhem("set watches_$device start");
  }
Damit es funktioniert, wird beim "on-for-timer" ein aussagekräftiges EVENT benötigt.
Dazu das Atribut "setExtensionsEvent" auf 1 setzen.

Damian

Der Stern hinter der eckigen Klammer dürfte überflüssig sein, denn set... kommt ja nur einmal vor.

"[^set\_on\-for\-timer ]* (\d+)"

Das geht auch einfacher:

" (\d+)$"
P.S.
Dieser Countdown besteht aus einer DOIF-Zeile Code ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF