Hi zusammen,
ich wende mich mit einem vermutlich trivialen Problem an euch. Hier der Kontext:
Für ein Uni-Projekt muss ich eine Sturmwarnung mit FHEM umsetzen. Dazu nutze ich ein DOIF. Es soll ausgelöst werden, wenn die Werte meines Windsensors gewisse Schwellenwerte überschreiten. Die Schwellenwerte sind als selectNumbers-Eingabeflächen über webCmd realisiert und werden zu Testzwecken auf 0 gesetzt.
Zudem braucht meine Bedingung noch einen weiteren Teil: das DOIF soll nur einmal pro Tag ausgelöst werden, wobei der Zeitpunkt des "wieder scharf schaltens" auch angepasst werden können soll. Daher habe ich ein weiteres Eingabefeld, dieses mal einen uzsu-Toggle definiert. Das Feld fungiert als Flag, ob an diesem Tag schon einmal eine Warnung gesendet wurde. Den Wert setze ich mit einem at zum Wunschzeitpunkt zurück. Auch diesen Wert stelle ich zu Testzwecken natürlich händisch richtig ein.
Diese beiden Bedingungen verbinde ich mit einem "and".
Mein eigentliches Problem besteht nun darin, dass die Bedingung meines DOIFs immer als falsch evaluiert zu werden scheint, da das DOIF als state immer "CMD_2" hat. Besonders seltsam daran ist, dass beide Teile der Bedingung für sich genommen funktionieren, zusammen jedoch nicht mehr.
Kann mir evtl. jemand von euch sagen, was ich falsch mache?
Hier die Definition meines DOIFs:
define WindMonitoring DOIF (([MyWindSensor:windSpeed] ge [$SELF:thresholdWindSpeed] or [MyWindSensor:windGust] ge [$SELF:thresholdWindGust]) and [$SELF:alreadyNotified] eq "NEIN") (set StormWarningPushMessage message [$SELF:notifyText],set WindMonitoring alreadyNotified JA)
Hallo SCKWorld2012,
schick doch mal das ganze define...möglichst per Code einfügen Button....
hi Hermann123,
das war das ganze define für das DOIF. Die restlichen Definitionen sollten hier ja nicht relevant sein, oder? Wie gesagt, für sich genommen funktionieren die Teile der Bedingung ja. Hier nochmal der Code "richtig" formatiert
define WindMonitoring DOIF (([MyWindSensor:windSpeed] ge [$SELF:thresholdWindSpeed] or [MyWindSensor:windGust] ge [$SELF:thresholdWindGust]) and [$SELF:alreadyNotified] eq "NEIN") (set StormWarningPushMessage message [$SELF:notifyText],set WindMonitoring alreadyNotified JA)
Ich kenne ja DOIF zu wenig aber:
müsste das
Zitat
set WindMonitoring alreadyNotified JA
nicht mittels setreading gemacht werden?
Also:
setreading WindMonitoring alreadyNotified JA
Weil es soll doch das reading alreadyNotified des DOIF (WindMonitoring) auf JA gesetzt werden?
(wer setzt es denn dann zurück?)
EDIT: und wer setzt es denn überhaupt mal auf NEIN? Weil sonst stimmt ja die Abfrage eq "NEIN" schon nicht...
Und: besser ein list statt nur dem define, also list Devicename (in deinem Fall list WindMonitoring)...
Gruß, Joachim
Hi Joachim,
ich kenne mich auch nicht aus, aber das Ausprobieren des "Do" Teils für sich hat funktioniert, dementsprechend habe ich darüber nicht weiter nachgedacht. Vielleicht kann da ja einer der alteingesessenen Fhem-Experten etwas Klarheit schaffen.
Das eigentliche Problem löst das aber leider noch nicht :/
Gruß
Simon
Ich denke das Problem wird dann sein, das Du die Reading oder EventReadings
[$SELF:thresholdWindSpeed]
[$SELF:notifyText]
nicht definierst hast.
Schau mal in der Refenz unter "Erzeugen berechneter Readings ohne Events" oder "Erzeugen berechneter Readings mit Events".
Vielleicht ist das ja die Lösung....
...kenne DOIF auch nicht, würde aber annehmen, dass es die "Doppelbedingung" ist: Es können praktisch nie zwei Ereignisse gleichzeitig eintreffen. Steht irgendwo in dieser überbordenden commandref zu DOIF...
Hi Hermann,
danke für deine Antwort. Die Readings definiere ich unmittelbar im Anschluss zum DOIF. Ich habe hier nur den Code dazu nicht eingestellt. Wie gesagt, die einzelnen Teile der Bedingung funktionieren, auch die Readings werden anstandslos ausgelesen und der "notifyText" Text in meine Nachricht eingefügt.
Hi Beta-User,
ich nutze in dem DOIF doch gar kein Event? Oder habe ich da das Konzept falsch verstanden? Beim Aufbau der Bedingungen und deren Kombination habe ich mich am Fhem-Wiki orientiert, da sah das ganz ähnlich aus.
Hi,
der do Teil funktioniert für sich alleine, aber eben nicht in dem DOIF das hier:
set WindMonitoring alreadyNotified JA
heisst ja eigentlich
set $SELF alreadyNotified JA
Das triggert sich selbst!
[$SELF:alreadyNotified] eq "NEIN"
Das wird entweder verhindert oder nicht ausgeführt.
Eventuell hilft [?$SELF:alreadyNotified] eq "NEIN" und sleep 1;set $SELF alreadyNotified JA
Aber da bin ich nicht sicher.
Gruß Otto
Hi Otto,
habe jetzt den fraglichen Teil jetzt mal aus dem "Do" Block herausgenommen, sodass es sich nicht mehr selbst Triggern dürfte.
Vorher habe ich mal versucht nur den den [$SELF:alreadyNotified] eq "NEIN"
Teil in der Bedingung stehen zu lassen - so hat es funktioniert.
Die zusammegesetzte Bedingung funktioniert aber immer noch nicht :-[
Immerhin scheint es kein allzu offensichtlicher Fehler zu sein - dann habe ich ja immerhin meine Hausaufgaben in Sachen Recherche gemacht.
Gruß
Simon
Zitat von: SCKWorld2012 am 21 Dezember 2021, 11:30:42
ich nutze in dem DOIF doch gar kein Event? Oder habe ich da das Konzept falsch verstanden?
Wenn ich aber das hier lese: JA, falsch verstanden und besser mal nachlesen/nachholen :)
fhem ist (eigentlich) Event-Gesteuert.
Also es passiert etwas (auch ein "Timer" "passiert") und dann wird reagiert: notify/DOIF/FileLog/...
Kein Event, keine Reaktion...
Und: fhem ist single-Threaded, d.h. es gibt immer nur EINEN Event zur Zeit (wichtig bei DOIF, wo man schon mal mehrere Events "abfragen" will)...
Und: poste doch (trotzdem) mal das gesamte DOIF (also list WindMonitoring und evtl. auch von weiteren beteiligten Devices)...
Gruß, Joachim
Zitat von: SCKWorld2012 am 21 Dezember 2021, 12:21:08
Immerhin scheint es kein allzu offensichtlicher Fehler zu sein - dann habe ich ja immerhin meine Hausaufgaben in Sachen Recherche gemacht.
Wir haben das ständig...
[MyWindSensor:windSpeed] und
[MyWindSensor:windGust] sind zumindest nach meiner Interpretation der Einleitung zu DOIF Ereignistrigger...:ZitatKombinierte Ereignis- und Zeitsteuerung
define di_lamp DOIF ([06:00-09:00] and [sensor:brightness] < 40) (set lamp on) DOELSE (set lamp off)
Aber wie schon geschrieben: DOIF kapiere ich auch nicht und löse sowas dann via notify.
PS: Du bist der Student, der eine Aufgabe erhalten hat. Etwas vertiefte Recherche ist DEIN JOB, nicht unserer ;) .
Die zusammengefügten Bedingungen ...
da empfehle ich auch immer eine Logiktabelle, damit man sieht was man erwarten kann. Du hast drei Bedingungen. Man muss die Klammer erst abarbeiten.
(A oder B) und C
0 0 -> 0 0 0 -> 0
1 0 -> 1 1 0 -> 0
0 1 -> 1 0 1 -> 0
1 1 -> 1 1 1 -> 1
C ist also für deinen Fall dominierend A oder B (oder beide) muss wahr sein und C muss wahr sein für den CMD_1 Fall und zwar zur gleichen Zeit.
Alle Deine Bedingungen triggern und lösen das DOIF aus. Eventuell ist es gut auf einen Trigger zu verzichten und da nur Abfrage zu machen.
Muss das (Zeile 3):
0 1 -> 1 0 1 -> 0
nicht (auch) so:
0 1 -> 1 1 0 -> 0
EDIT: oder auch so 0 1 -> 1 1 1 -> 1
sein?
Oder verstehe ich die Tabelle falsch?
(und fehlen nicht generell noch ein paar Zeilen?)
EDIT: wobei ja klar ist worauf du hinaus willst/wolltest 8)
Gruß, Joachim
Hi zusammen,
ich denke ich antworte lieber in einer Nachricht auf mehrere Dinge:
Danke für deine Antwort Joachim - ich habe mich wohl zu schwammig ausgedrückt :) Dass Fhem auf Ereignissen basiert ist mir klar. Was ich meinte war, dass ich ja in der Bedingung keine Werte nutze, die nicht über ein einzelnes Event hinaus persistiert wären.
Hey Beta-User, ja, die Änderungen dieser Readings sind die Trigger. Das sollte doch aber an sich kein Problem verursachen, oder?
Genau, ich bin ein Student, der eine Aufgabe bekommen hat, vollkommen richtig. Und als solcher sitze ich jetzt den dritten Tag vor einer ansonsten vollständig gelösten Aufgabe, habe unzählige Seiten der Referenz und massenweise Forenbeiträge gelesen, bin aber leider immer noch nicht schlauer. Deswegen habe ich mich entschlossen hier diejenigen zu fragen, von denen ich gerne Lernen würde.
Hi Otto, mit Logiktabellen bin ich bestens vertraut :) In meinem Fall ist das genau so gedacht: Die "dominierende" Bedingung ist die Prüfung, ob heute noch keine Warnung versendet wurde. Ist dies der Fall, dann soll geprüft werden, ob entweder der Wert für die Windgeschwindigkeit, der Wert für die Windböhengeschwindigkeit oder beide höher sind als die definierten Schwellenwerte. Sind beide Teile der Bedingung erfüllt, soll eine Warnung gesendet werden. Zum Testen habe ich sowohl eingestellt, dass heute noch keine Warnung versendet wurde und dass die Werte der Sensoren beide über den Schwellenwerten lagen.
Und zum Abschluss hier einfach mal der ganze Code den ich habe, abgesehen vom Windsensor und der PushNotifier Anbindung:
define WindMonitoring DOIF (([MyWindSensor:windSpeed] ge [$SELF:thresholdWindSpeed] or [MyWindSensor:windGust] ge [$SELF:thresholdWindGust]) and [$SELF:alreadyNotified] eq "NEIN") (set StormWarningPushMessage message [$SELF:notifyText])
attr WindMonitoring room StormWarning
attr WindMonitoring readingList thresholdWindSpeed thresholdWindGust resetTime notifyText alreadyNotified
attr WindMonitoring setList thresholdWindSpeed:selectnumbers,0,0.1,350,1,lin thresholdWindGust:selectnumbers,0,0.1,350,1,lin resetTime:time notifyText:textField alreadyNotified:uzsuToggle,NEIN,JA
attr WindMonitoring webCmdLabel Schwellenwert Windgeschwindigkeit :Schwellenwert Windboee :Benachrichtigung wieder scharf schalten um :Benachrichtigungstext :Benachrichtigung heute schon erfolgt
set WindMonitoring thresholdWindSpeed 15
set WindMonitoring thresholdWindGust 15
set WindMonitoring resetTime 06:00
set WindMonitoring notifyText Achtung, es herrscht starker Wind!
set WindMonitoring alreadyNotified NEIN
attr WindMonitoring webCmd thresholdWindSpeed:thresholdWindGust:resetTime:notifyText:alreadyNotified
define WindMonitoringAlarmReset at *{ReadingsVal("WindMonitoring","resetTime","")} set WindMonitoring alreadyNotified NEIN
define WindMonitringAlarmResetTimeChange notify WindMonitoring:resetTime.* modify WindMonitoringAlarmReset *{ReadingsVal("WindMonitoring","resetTime","")} set WindMonitoring alreadyNotified NEIN
attr WindMonitoringAlarmReset room StormWarning
attr WindMonitringAlarmResetTimeChange room StormWarning
Hallo Joachim,
ja ich hätte eine komplette Tabelle machen können 2³ aber ich habe quasi zwei getrennet gemacht. Weil ja aus den Klammern von der Sache her wieder nur eins wird. Also so wie es da steht 2² für or und 2² für and.
@SCKWorld2012 wenn Du Dir das list des DOIF im Fall des richtigen und falschen Schaltens anschaust siehst Du ev. etwas mehr: Zusammenhang Zeiten und Events.
Gruß Otto
Ich habe jetzt aufgegeben und das Problem stattdessen dadurch gelöst, dass ich eine zweite DOIF erstellt und die Bedingung über die beiden verteilt habe.
Danke an alle, die versucht haben mir zu helfen.
Warum die kombinierte Bedinung nicht funktioniert hat würde mich trotzdem immer noch interessieren.
Vielleicht noch bedenken: DOIF ist so konstruiert, dass es genau einmal auslöst wenn die Bedingung erfüllt ist. Der Zustand muss sich erst wieder in die andere Richtung ändern, damit die Auswertung neu beginnen kann. Dafür das es anders ist - gibt es so allgemein etwas unverständliche Konstruktionen.
Also ich denke nicht, dass falsch evaluiert wird, ich denke, dass nicht evaluiert wird ;)
Wenn Du einfach ein notify auf MyWindSensor:windSpeed:.* machst und deine Bedingungen genauso dahinter schreibst, wird das wohl funktionieren. ReadingsNum() und Co kennst Du ja :)
Gruß Otto
Ich denke, mit der Ausgabe von "list WindMonitoring" im vermeintlich nicht funktionierenden Zustand hätte man dir hier helfen können. Es mag jetzt funktionieren, aber beim nächsten mal wirst du dir wieder die Zähne ausbeißen, da die Ursache des Problems nicht erkannt wurde.
Tatsächlich habe ich die Lösung jetzt doch noch gefunden - es hat mich einfach nicht locker gelassen.
Wenn ich beide Bedingungen kombiniert habe, hat der veroderte Teil solange nicht mehr funktioniert, bis ich die Dezimalstellen der Eingabefelder auf 0 gesetzt habe. Dann ging es wieder.
Sehr merkwürdige Geschichte.
Jedenfalls nochmal danke für die Antworten :)
P.S.: Du hast Recht Damian, mit einer Workaround-Lösung gebe ich mich eigentlich auch nie zufrieden ;)
"le" ist halt nicht wirklich gut geeignet für Zahlenvergleiche...
Zitat von: Beta-User am 21 Dezember 2021, 16:27:25
"le" ist halt nicht wirklich gut geeignet für Zahlenvergleiche...
ja, daher mit < > arbeiten, da (10 le 2) wahr ist. Und daran denken: DOIF arbeitet standardmäßig im FHEM Modus zustandsorientiert, ein cmd_1 wird erst dann wieder ausgeführt, wenn zuvor cmd_2 dran war.