Hallo zusammen,
ich möchte Aktionen ausführen, wenn der Wert [powerfox:Verbrauch_akt] 20 sek. lang erhöht ist und sich in diesen 20 sek. nicht wieder normalisiert!
Allein mit wait kam ich nicht weiter und bin wieder zurück zu at.
([+00:00:20] and [powerfox:Verbrauch_akt] > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 112)
attr DI_dVerbrauchHoch do always
attr DI_dVerbrauchHoch event-on-change-reading .*
Warum wird in diesem Beispiel schon vor Ablauf das Reading test auf 112 gesetzt?
Anlehnend am Beispiel mit der Waschmaschine aus dem Commandref habe ich Folgendes versucht:
([+00:00:20] and ([powerfox:Verbrauch_akt:sec] > 20) > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 112)
Habe beide Beispiel noch mit verschiedenen Möglichkeiten von wait, repeat, etc. ausprobiert und bin nun völlig durcheinander.
Wie geht es richtig?
Vielen Dank & viele Grüße
Hi,
ich meine das geht mit do resetwait und wait Timer 20 sek
Gruß Otto
Hi Otto,
danke Dir, das hatte ich schon probiert:
defmod DI_dVerbrauchHoch DOIF ([powerfox:Verbrauch_akt] > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 444)
attr DI_dVerbrauchHoch do resetwait
attr DI_dVerbrauchHoch event-on-change-reading .*
attr DI_dVerbrauchHoch wait 20
Aber auch wenn ich den Wert für [powerfox:Verbrauch_akt] wieder reduziere, wird nach 20 sek. das Reading gesetzt.
Ich denke Du musst einfach die Logik umdrehen: solange der Wert kleiner ist, ist alles gut. So ist zumindest auch das Beispiel in der Commandref angelegt.
defmod DI_dVerbrauchHoch DOIF ([powerfox:Verbrauch_akt] < [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 444)
Danke Otto, das werde ich heute Abend testen.
Ich habe hier noch eine andere Variante, aber mit den Sekunden haut es nicht hin...
defmod DI_dVerbrauchHoch DOIF ([+00:00:20] and [powerfox:Verbrauch_akt:sec] > 20 and [powerfox:Verbrauch_akt] > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 299)
attr DI_dVerbrauchHoch do always
attr DI_dVerbrauchHoch event-on-change-reading .*
Das funktioniert zwar, aber unsauber. Erstens nach erst ca. 25 Sekunden. Reduziert und erhöht man zum testen ein paar Male den Wert [powerfox:Verbrauch_akt], setzt ihn letztendlich hoch, damit das Reading gesetzt wird, dauert dies sehr viel länger als 20 Sekunden. Werden die 20 Sekunden hier bei Änderung von [powerfox:Verbrauch_akt] nicht resetet?
naja bei deinem zweiten Beispiel wird ja im Raster von 20 Sekunden die Abfrage getriggert, außerdem triggern die anderen Werte dann wenn sie sich ändern. Wobei alles mit and verknüpft ist. Welche Zeitabfolge daraus entsteht ist mMn nicht vorhersehbar.
Zitat von: twinFHEM am 06 März 2023, 13:55:40
defmod DI_dVerbrauchHoch DOIF ([powerfox:Verbrauch_akt] > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 444)
attr DI_dVerbrauchHoch do resetwait
attr DI_dVerbrauchHoch event-on-change-reading .*
attr DI_dVerbrauchHoch wait 20
Aber auch wenn ich den Wert für [powerfox:Verbrauch_akt] wieder reduziere, wird nach 20 sek. das Reading gesetzt.
Meines Erachtens ist das hier schon die halb richtige Definition. Allerdings darf hier erstens kein resetwait gesetzt sein und zweitens muss ein Alternativzweig da sein, für den Fall, dass die Bedingung nicht (mehr) zutrifft. Also:
defmod DI_dVerbrauchHoch DOIF ([powerfox:Verbrauch_akt] > [DI_dVerbrauchHoch:dVerbrauchAktGes20pc]) (setreading savergy_storage test 444) DOELSE ()
attr DI_dVerbrauchHoch event-on-change-reading .*
attr DI_dVerbrauchHoch wait 20
Das müsste dazu führen, dass solange die Bedingung (1) erfüllt ist, der Ausführungsteil auch nach 20 Sekunden einmalig(!) ausgeführt wird. Sobald die Bedingung jedoch nicht (mehr) erfüllt ist - auch innerhalb der Wartezeit -, wechselt er in (2).
Hier mal die Ein Device Version zum testen:
define DI_dVerbrauchHoch DOIF ([$SELF:Verbrauch_akt] < [$SELF:dVerbrauchAktGes20pc]) (setreading $SELF test 444)
attr DI_dVerbrauchHoch do resetwait
attr DI_dVerbrauchHoch wait 20
attr DI_dVerbrauchHoch readingList Verbrauch_akt,dVerbrauchAktGes20pc
attr DI_dVerbrauchHoch room Test
attr DI_dVerbrauchHoch setList Verbrauch_akt:selectnumbers,8,2,18,0,lin dVerbrauchAktGes20pc:8,10,15
setstate DI_dVerbrauchHoch 2023-03-06 17:42:51 Verbrauch_akt 8
setstate DI_dVerbrauchHoch 2023-03-06 17:41:54 dVerbrauchAktGes20pc 10
Das macht genau was twinFHEM will. Solange man unter 20 sec auf set DI_dVerbrauchHoch Verbrauch_akt 8 drückt wird das reading nicht gesetzt.
Zusatznutzen: wenn der Sender ausfällt wird auch "alarmiert" :)
Hallo zusammen,
die Sache mit dem DOELSE () ist ein Aspekt.
Ich habe folgende Version getestet und alles läuft meines Erachtens nach tutti:
defmod DI_dVerbrauchHoch DOIF ([powerfox:Verbrauch_akt] > [$SELF:dVerbrauchAktGes60pc]) (setreading savergy_storage test 60) DOELSEIF ([powerfox:Verbrauch_akt] > [$SELF:dVerbrauchAktGes40pc]) (setreading savergy_storage test 40) DOELSEIF\
([powerfox:Verbrauch_akt] > [$SELF:dVerbrauchAktGes20pc]) (setreading savergy_storage test 20) DOELSE (setreading savergy_storage test OK)
attr DI_dVerbrauchHoch do always
attr DI_dVerbrauchHoch event-on-change-reading .*
attr DI_dVerbrauchHoch userReadings dVerbrauchAktGes20pc { ReadingsVal("savergy_storage","dVerbrauchAktGes",0) * 1.2;;;; },\
dVerbrauchAktGes40pc { ReadingsVal("savergy_storage","dVerbrauchAktGes",0) * 1.4;;;; },\
dVerbrauchAktGes60pc { ReadingsVal("savergy_storage","dVerbrauchAktGes",0) * 1.6;;;; }
attr DI_dVerbrauchHoch wait 20:20:20:20
Die Testversion von Otto123 habe ich als neue Device eingefügt.
Wenn ich [$SELF:dVerbrauchAktGes20pc] höher als [$SELF:Verbrauch_akt] setze, aber innerhalb der 20 Sekunden wieder heruntersetze,
wird das Reading trotzdem gesetzt. Das schaue ich mir aber nochmal näher an.
Ich danke euch beiden herzlichst für eure Hilfe!!!
Du hast die Bemerkung nicht verstanden:
Zusatznutzen: wenn der Sender ausfällt wird auch "alarmiert" :)
Wenn Du einfach 20 sekunden wartest und keinen Wert sendest (nicht auf set drückst) wird auch alarmiert. Du kannst doch dem wait Timer gut "zuschauen".
Und ich sage immer: wenn am Ende vom DOIF ein DOELSE() stehen muss, ist das meistens ein Fehler ;) Duck und weg