Ok, ich gebe es auf. Versuche es seit Stunden und komme nicht weiter. Ähnlich der Batterie Überwachung möchte ich gerne das Reading "motorErr" meiner HM-CC-RT-DN überwachen. Natürlich kann man das auch mittels notify und auch auf das hminfo Device lauschen, aber so langsam geht es mir eher ums Prinzip, wie es mit DOIF geht.
Folgendes möchte ich:
- Alle Device überwachen. Diese heißen immer XY.HZ
- das Reading nennt sich motorErr
- bei keinem Fehler hat es den Status ok
- bei Fehler gibt es verschiedene Stati
Hier mal meine Lösungsvorschläge, welche alle nicht klappten, da immer cmd2 ausgeführt wurde:
([".HZ$:motorErr"] and [$EVENT] eq "motorErr: ok")
(set Test ok)
DOELSEIF ([".HZ$:motorErr"] and [$EVENT] ne "motorErr: ok")
(set Test err)
([".HZ:motorErr"] eq "motorErr: ok")
(set Test ok)
DOELSEIF ([".HZ:motorErr"] ne "motorErr: ok")
(set Test err)
([.*HZ:motorErr] eq "ok")
(set Test ok)
DOELSEIF ([.*HZ:motorErr] ne "motorErr: ok")
(set Test err)
Ich brauche quasi eine Möglichkeit wie ich auf verschieden Devices und auf das gleiche Reading lauschen kann, wie in Beispiel 3. Oder ich muss verstehen, warum bei Beispiel 1 und 2 die Syntax falsch ist und immer wieder cmd2 ausgeführt wird.
Ich kann dir zwar nicht bei deinem DOIF helfen, habe aber für solche Sammelmeldungen das Modul monitoring geschrieben.
Liest sich zwar etwas komplex, aber werde es mal testen. Dafür müsste ich aber alle Error Meldungen von motorErr kennen, oder?
Und wie gesagt, geht es mir inzwischen auch ein bisschen ums Prinzip zu verstehen, warum mein DOIF nicht funktioniert ;)
Zitat von: Amenophis86 am 15 April 2017, 14:20:05
Liest sich zwar etwas komplex, aber werde es mal testen. Dafür müsste ich aber alle Error Meldungen von motorErr kennen, oder?
Und wie gesagt, geht es mir inzwischen auch ein bisschen ums Prinzip zu verstehen, warum mein DOIF nicht funktioniert ;)
In der Commandref zu DOIF gibt es doch das Beispiel der Batterieüberwachung, da müsstest Du doch nur die Regexp anpassen.
define di_battery DOIF ([":battery: low"] and [?$SELF:B_$DEVICE] ne "low")
({DebianMail('yourname@gmail.com', 'FHEM - battery warning from device: $DEVICE')}, setreading $SELF B_$DEVICE low)
DOELSEIF ([":battery: ok"] and [?$SELF:B_$DEVICE] ne "ok")
(setreading $SELF B_$DEVICE ok)
attr di_battery do always
Korrekt aber der MotorErr wirft verschiedene Error aus meine ich. Diese Error kenne und finde ich nicht. Daher muss ich auf ungleich "ok" prüfen und das schaffe ich nicht :)
EDIT:
ok, stehen in der CommandRef und können bei mir wie folgt sein:
ok|ValveTight|adjustRangeTooLarge|adjustRangeTooSmall|communicationERR|unknown|lowBat|ValveErrorPosition
aber jetzt für jedes einen DOIF Strang bauen wäre ja auch doof. Es muss doch möglich sein auf != ok zu prüfen und das mit einem DOIF für alle Devices.
Die Eventabfrage könnte doch so aussehen
[":MotorError: (ValveTight|adjustRangeTooLarge|adjustRangeTooSmall|communicationERR|unknown|lowBat|ValveErrorPosition)"]
und statt
[?$SELF:B_$DEVICE] ne "low"
nimmst Du
[?$SELF:B_$DEVICE] !~ "ValveTight|adjustRangeTooLarge|adjustRangeTooSmall|communicationERR|unknown|lowBat|ValveErrorPosition"
Und das Batteriebeispiel ist für alle Geräte mir "battery" Reading.
Das ist richtig und danke für den Vorschlag. Was ich mich allerdings aktuell noch frage ist folgendes:
Wie muss ich eine DOIF Bedingung schreiben, welche wie folgt sein soll:
- Lausche auf alle Devices mit "HZ" im Namen
- Lausche bei diesen Devices auf das Reading "motorErr"
- Wenn das Reading NICHT "ok" lautet, dann mache folgendes
Ist ähnlich deiner Abfrage, aber leicht abgewandelt. Und dafür sehe ich aktuell noch keine Lösung, was mich ehrlich gesagt wundert. Denn die quasi Bedingung ([.*HZ.*:.*motorErr.*] ne "ok")
geht ja nicht. Und das muss doch irgendwie möglich sein, ohne alle Varianten explizit zu nennen, wie du es gemacht hast.
Wie gesagt, deine Lösung ist top, aber aus Prinzip frage ich mich noch, wie es richtig heißen müsste um das von mir geschriebene zu definieren :)
([.*HZ.*:.*motorErr.*] ne "ok")
funktioniert so nicht, weil dein Ereignistrigger nur wahr oder nicht wahr ist. So etwas lässt sich aber inzwischen mit der erweiterten Syntax
["regex for trigger",<default value>] für Ereignistrigger, initiiert durch einen Default-Wert, realisieren (siehe https://fhem.de/commandref_DE.html#DOIF_Ereignissteuerung_ueber_Auswertung_von_Events).
Übrigens, die ganze .*-Orgie kannst du bei DOIF weglassen ;)
Es sollte so funktionieren:
([HZ:motorErr,""] ne "ok")
Das .* nicht geht war mir ja bewusst, sollte nur zeigen auf was es hinaus laufen sollte.
Und das man ([DEVICE:Reading,""] ne "ok") schreiben kann war mir nicht bewusst. Hatte ich so aus der CommandRef nicht entnommen, weil immer nur überall DEVICE stand und nie auch noch das Reading quasi dabei. Aber danke für die Antwort, werde es mal testen. Hätte mich auch gewundert, wenn es da nix gegeben hätte :D
EDIT:
Dein Vorschlag kann aber nicht funktionieren, da ja ich ja auf alle Device lauschen will, welche HZ im Namen oder am Anfang haben.
([DEVICE:Reading,""] ne "ok")
ist nicht das Gleiche, wie
(["DEVICE:Reading",""] ne "ok")
Im ersten Fall ist ein bestimmtes Reading gemeint, hier sind keine Regex erlaubt. Im zweiten Fall handelt es sich aufgrund der Anführungszeichen um einen Ereignistrigger mit Regex und keine Readingabfrage wie im ersten Fall.
Zitat von: Amenophis86 am 17 April 2017, 11:24:34
EDIT:
Dein Vorschlag kann aber nicht funktionieren, da ja ich ja auf alle Device lauschen will, welche HZ im Namen oder am Anfang haben.
Doch!, schon probiert?
jop und hat nicht funktioniert. Teste es aber gerne nochmal :)
Zitat von: Amenophis86 am 17 April 2017, 11:59:16
jop und hat nicht funktioniert. Teste es aber gerne nochmal :)
Wenn es nicht klappt, dann poste mal die vermeintliche Event-Zeile und ein List deines DOIF-Moduls
Das DOIF:
Internals:
CFGFN
DEF ([HZ:motorErr,""] ne "ok") (set HZ.Test $EVENT)
NAME Test.DOIF
NR 306
NTFY_ORDER 50-Test.DOIF
STATE initialized
TYPE DOIF
Readings:
2017-04-17 12:00:52 cmd 0
2017-04-17 12:00:52 state initialized
Condition:
0 ReadingValDoIf($hash,'HZ','motorErr','""') ne "ok"
Devices:
0 HZ
all HZ
Do:
0:
0 set HZ.Test $EVENT
1:
Helper:
globalinit 1
last_timer 0
sleeptimer -1
Itimer:
Readings:
0 HZ:motorErr
all HZ:motorErr
Regexp:
All:
State:
Attributes:
Eventzeile:
2017-04-17 12:04:26 dummy HZ.Test motorErr: defekto
EDIT:
Verstehe auch nicht ganz, wieso [HZ:motorErr,""] auf alle Device mit HZ im Namen lauschen soll. Das ist doch ne klare Angabe auf das Device HZ und auf das Reading motorErr, oder verstehe ich das immer noch falsch? Oder hast du dich im Beispiel verschrieben und ich sollte ["HZ:motorErr",""] in der DOIF Abfrage nehmen?
EDIT2:
Ok, du scheinst dich verschieben zu haben:
Zitat von: Damian am 17 April 2017, 11:04:52
Es sollte so funktionieren:
([HZ:motorErr,""] ne "ok")
mit
(["HZ:motorErr",""] ne "ok")
funktioniert es. Hier wird also auf HZ im DEVICE Namen gelauscht und auf "motorErr" im Readingsnamen. Und warum genau brauche ich den default-Wert "" am Ende der Suche noch?
Zitat von: Amenophis86 am 17 April 2017, 12:04:54
EDIT2:
Ok, du scheinst dich verschieben zu haben:mit (["HZ:motorErr",""] ne "ok")
funktioniert es. Hier wird also auf HZ im DEVICE Namen gelauscht und auf "motorErr" im Readingsnamen. Und warum genau brauche ich den default-Wert "" am Ende der Suche noch?
Ja, du hast Recht.
Weil der Default-Wert eine neue Funktionalität bei Ereignistriggern impliziert. Es muss ja einen Wert zurückliefern, nämlich den Default-Wert, wenn kein Ereignis passt und noch ein weiterer Trigger in der Bedingung verknüpft wird.
z. B.
((["HZ:motorErr",""] ne "ok") or [08:00])
mit der Definition ohne Default-Wert: ["HZ:motorErr"] ist das Ding immer nur wahr oder nicht wahr.
Ah, ich verstehe. Dann vielen Dank für die Info und Hilfe
Für alle die Suchen hier mal das gesamte DOIF:
define ZE.Motor_Check DOIF (["HZ:motorErr",""] ne "ok" and [?$SELF:B_$DEVICE] ne "ok")
(msg @rr_Etienne title='Thermostat Warnung' $DEVICE meldet den Fehler $EVENT, setreading $SELF B_$DEVICE $EVENT)
DOELSEIF (["HZ:motorErr",""] eq "ok" and [?$SELF:B_$DEVICE] ne "ok")
(setreading $SELF B_$DEVICE ok)
Zitat von: Amenophis86 am 17 April 2017, 12:46:04
Ah, ich verstehe. Dann vielen Dank für die Info und Hilfe
Für alle die Suchen hier mal das gesamte DOIF:
define ZE.Motor_Check DOIF (["HZ:motorErr",""] ne "ok" and [?$SELF:B_$DEVICE] ne "ok")
(msg @rr_Etienne title='Thermostat Warnung' $DEVICE meldet den Fehler $EVENT, setreading $SELF B_$DEVICE $EVENT)
DOELSEIF (["HZ:motorErr",""] eq "ok" and [?$SELF:B_$DEVICE] ne "ok")
(setreading $SELF B_$DEVICE ok)
Dann dürfte für dich auch die neue Aggregationsfunktionalität interessant sein (siehe: https://forum.fhem.de/index.php/topic,70624.msg621112.html#msg621112):
z. B.
defmod ZE.Motor DOIF (["HZ:motorErr",""] ne "ok") (msg @rr_Etienne title='Thermostat Warnung' $DEVICE meldet den Fehler $EVENT)
attr ZE.Motor state Fehler in: [@"HZ:motorErr":motorErr:$_ ne "ok"]
attr ZE.Motor do always
Im Status siehst du alle Devices die den Fehler haben.
werde es mir anschauen. Danke