DOIF Regex mit Reading Best Practice

Begonnen von mackshot, 05 Januar 2020, 12:00:16

Vorheriges Thema - Nächstes Thema

mackshot

Liebe FHEM User,

ich bin ein großer Fan von DOIF und nutze es wirklich für viele Zwecke. Es macht mir große Freude.

Eine Sache bei Nutzung von "RegExen" macht mir allerdings Probleme und ich frage mich,
a) ob ich hier etwas nicht verstanden habe,
b) ob man das DOIF darum erweitern kann oder
c) was hier Euer Best Practice / Lösungsansatz ist.

In meiner Hausautomation habe ich ein DOIF, welches mir sobald "irgendein" Fenster offen ist (alle FensterSensoren enden bei mir auf den Namen "_OpenSensor") etwas auslöst... siehe (aufs wesentliche reduzierte) Definition
define di_fensteroffen DOIF (["_OpenSensor$:open"]) ( set fensteroffen 1 )

Da ich diese Regel nun gerne auf ein Subset von Fenstern (Critical - etwas Einbruchgefährdete) beschränken möchte, und für diese schon ein spezielles Reading für den Status habe "state-critical", möchte ich dies auch in meinem DOIF abbilden... Leider schaffe ich dies nur so:

define di_fensteroffen-critical DOIF (["_OpenSensor$"] and ReadingsVal("$DEVICE", "state-critical", "") eq "open")  ( set fensteroffen-critical 1 )


Lieber (weil kürzer/schöner und syntaktisch am nicht-regex-doif-fall orientiert) wäre mir eine Definition in folgender Form:

define di_fensteroffen-critical DOIF (["_OpenSensor$":state-critical] eq "open")  ( set fensteroffen-critical 1 )


Dies geht aber nicht. Ich bin gespannt auf Eure Vorschläge, Anmerkungen, Hinweise, ...

Mir ist klar, dass man die Gruppierung der "critical" Fenster auch anders vornehmen kann, etwa über das Attribut "group" oder "room", aber meine Frage/Problem bleibt: "ich möchte mit einer Regex für die Gerätedefinition starten, aber dann - wie bei einem nicht-regex-doif - auf ein Reading leicht zugreifen".

Vielen Dank
Markus

Damian

define di_fensteroffen-critical DOIF (["_OpenSensor$":state-critical,0] eq "open")  ( set fensteroffen-critical 1 )

könnte schon funktionieren.

siehe: https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events

da steht u. a.:
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 ...
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

Zitat von: Damian am 05 Januar 2020, 12:11:33
define di_fensteroffen-critical DOIF (["_OpenSensor$":state-critical,0] eq "open")  ( set fensteroffen-critical 1 )

könnte schon funktionieren.

siehe: https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events

da steht u. a.:

Vielen Dank für das Feedback. Das habe ich probiert, aber das klappt leider nicht:

Führe ich Dein Beispiel aus (habe die "-" durch "_" ersetzt)
define di_fensteroffen_critical DOIF (["_OpenSensor$":state_critical,0] eq "open")  ( )
erhalte ich folgenden Fehler:
di_fensteroffen_critical DOIF: wrong filter Regex: state_critical

Damian

Zitat von: mackshot am 05 Januar 2020, 12:16:40
Vielen Dank für das Feedback. Das habe ich probiert, aber das klappt leider nicht:

Führe ich Dein Beispiel aus (habe die "-" durch "_" ersetzt)
define di_fensteroffen_critical DOIF (["_OpenSensor$":state_critical,0] eq "open")  ( )
erhalte ich folgenden Fehler:
di_fensteroffen_critical DOIF: wrong filter Regex: state_critical

Na dann:

define di_fensteroffen_critical DOIF (["_OpenSensor$:^state_critical",0] eq "open")  ( )
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

#4
Zitat von: Damian am 05 Januar 2020, 12:18:06
Na dann:

define di_fensteroffen_critical DOIF (["_OpenSensor$:^state_critical",0] eq "open")  ( )

Gerade zur Sicherheit nochmal getestet. Das nimmt er an, aber das löst nicht aus. Habe alle gültigen ^^ Varianten mit ^ und $ für das Reading probiert... :(

Edit: Ich nutze DOIF
Version $Id: 98_DOIF.pm 20484 2019-11-09 19:33:35Z Damian

Damian

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

mackshot

Hallo,

sorry für die späte Antwort, aber ich habe hier nochmal von Vorne begonnen und einen Fehler bei mir gefunden. Hier zunächst mal die Ausgaben der Events

2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor battery: ok
2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor contact: open (to VCCU)
2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor open
2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor trigger_cnt: 120
2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor batteryState: ok
2020-01-05 15:51:00 CUL_HM Wohnen.Balkontuer_OpenSensor state_critical: open


Ich habe mal verschiedene Varianten ausprobiert und hier mein Ergebnis:


FallDefinition DOIF mit RegExplöst ausDefinition DOIF ohne RegExplöst ausKommentar
1(["_OpenSensor$:open"])ja([Wohnen.Balkontuer_OpenSensor:"open"])jaAlles gut
2(["_OpenSensor$:state_critical"] eq "open")ja([Wohnen.Balkontuer_OpenSensor:state_critical] eq "open")jaAlles gut
3(["_OpenSensor$"] eq "open") bzw. (["_OpenSensor$", 0] eq "open")nein([Wohnen.Balkontuer_OpenSensor] eq "open")jaIch hätte erwartet, dass hier auch der RegExp Fall auslöst.
4(["_OpenSensor$:&STATE"] eq "open")nein([Wohnen.Balkontuer_OpenSensor:&STATE] eq "open")jaIch hätte erwartet, dass hier auch der RegExp Fall auslöst.
5(["_OpenSensor$:state"] eq "open")nein([Wohnen.Balkontuer_OpenSensor:state] eq "open")jaIch hätte erwartet, dass hier auch der RegExp Fall auslöst.


  • In Fall 3-5 passiert für mich Unerwartetes.
  • Im Fall 5 verstehe ich schon, dass "state" nicht in den Events auftaucht, und das dies die Erklärung dafür sein wird, aber wieso klappt es dann im nicht-RegExp Fall?
  • Wäre es nicht wünschenswert, dass das Verhalten im RegExp und nicht-RegExp Fall gleich ist?

Ich hoffe ich habe nichts übersehen und bin sehr gespannt auf Deine Meinung und Erläuterung Damian.

Vielen Dank
Markus

Damian

#7
Es funktioniert alles, wie programmiert.

1. Ereignistrigger können keine Readingsinhalte liefern, denn sie sind nicht eindeutig (es kann mehrere Readings geben, die auf eine Regex zutreffen)
2. Ereignistirgger sind im Normalfall nur wahr oder falsch.
3. Wenn beim Ereignsitrigger ein Defaultwert angegeben wird, so wird die Angabe hinter dem Ereignis genommen und nicht aus dem Reading (steht so in der Commandref)
4. Meine Regex kommt bei dir im Punkt 2 vor, das ist die einzige die funktionieren kann, denn open kommt hinter "state_critical:"
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

Vielen Dank für Dein Erläuterung. Leider bleiben bei mir einige offene Fragen, aber ich glaube die zentrale ist...

Wieso funktioniert Fall 5 ohne RegExp? Hier nutze ich doch auch die Ereignissteuerung (wenn ich das richtig verstehe: https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung) und ich sehe keinen Eintrag für "state" im EventLog.

Damian

#9
Die Bezeichnungen sind verwirrend.

Mit Ereignissteuerung werden Angaben bezeichnet, die auf Events reagieren - das Gegenstück zu Zeitsteuerung.

Zu Ereignissteuerung gehören:

1) [<device>]   reagiert auf alle Events von <device>, liefert Status des Devices, Vergleich mit eq ist sinnvoll
2) [<device>:<reading>] reagiert nur auf Events von <device> mit entsprechendem Reading, liefert den Inhalt des Readings, Vergleich mit eq ist sinnvoll
3) ["<Regex zu device>:<Regex zum Reading"]  reagiert auf passende Events, liefert beim passenden Treffer true, sonst ist es false (hier ist ein Vergleich mit eq nicht sinnvoll)
4) ["<Regex zu device>:<Regex zum Reading", Default] reagiert auf passende Events, liefert den Teil des Events hinter dem Reading mit Doppelpunkt, Vergleich mit eq sinnvoll

Deine Angaben 2 - 5 sind alle nicht sinnvoll, weil sie zum Typ 3) gehören und da ist der Vergleich mit eq nicht sinnvoll.

Die Angabe 2 wäre nur dann sinnvoll, wenn du ein Defaultwert angegeben hättest, also:

(["_OpenSensor$:state_critical",0] eq "open")
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mackshot

Vielen Dank für die weiteren Erläuterungen. Habe das jetzt alles nochmal nachvollzogen und verstanden. Vielen Dank nochmals.