Funktion ausführen nur wenn sich Wert erhöht

Begonnen von hummeruli, 15 Juni 2026, 19:26:21

Vorheriges Thema - Nächstes Thema

hummeruli

Leider stehe ich gerade voll au dem Schlauch.
Ich brauche eine Art Zähler der immer dann wenn sich ein Wert erhöht ein Relais schaltet. Wenn sich der Wert verringert, dann darf er nichts machen.

Also zum Beispiel:

Zähler = 0                  "keine Reaktion"
Zähler wechselt von 0 > 1   "Relais schaltet eine Sekunde (mit ON-FOR-TIMER 1)"
Zähler wechselt von 1 > 2   "Relais schaltet eine Sekunde (mit ON-FOR-TIMER 1)"
''
Zähler wechselt von 7 > 5   "keine Reaktion"
Zähler wechselt von 3 > 0   "keine Reaktion"

Würde mich freuen wenn mir jemand einen Schubser geben könnte.

Danke

Uli
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Wo steht denn der Zähler bzw. wo kommt er her?
Wenn er aus einem Reading kommt, dann kannst du vermutlich mittels attr oldreadings <readingName> und OldReadingsNum() arbeiten. Dann kannst du alten und neuen Wert vergleichen, also z.B.
if (ReadingsNum("device", "readingName", "1") > OldReadingsNum("device", "readingName", "2")) {
    fhem("set relay on");
}
(Nur der Vollständigkeit halber, um oldreadings verwenden zu können, muss das jeweilige Reading ein Event erzeugen. Wenn es nicht funktioniert also im Event Monitor schauen, ob das der Fall ist und wenn nicht, dann event-on-* anpassen.)

hummeruli

#2
Zitat von: passibe am 15 Juni 2026, 19:41:48Wo steht denn der Zähler bzw. wo kommt er her?
Wenn er aus einem Reading kommt, dann kannst du vermutlich mittels attr oldreadings <readingName> und OldReadingsNum() arbeiten. Dann kannst du alten und neuen Wert vergleichen, also z.B.
if (ReadingsNum("device", "readingName", "1") > OldReadingsNum("device", "readingName", "2")) {
    fhem("set relay on");
}
(Nur der Vollständigkeit halber, um oldreadings verwenden zu können, muss das jeweilige Reading ein Event erzeugen. Wenn es nicht funktioniert also im Event Monitor schauen, ob das der Fall ist und wenn nicht, dann event-on-* anpassen.)

Danke für die schelle Antwort, aber wenn ich deinen Code verstehe macht er es ja nur von 1 > 2. Oder?

Es geht darum um bei einem Unifi Cloudkey der an FHEM angebunden ist ein Relais jedes mal wenn ein Gerät sich einloggt zu schalten. Wenn Jemand das WLAN verlässt juckt es nicht.
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

rabehd

Zitat von: hummeruli am 15 Juni 2026, 19:46:56macht er es ja nur von 1 > 2. Oder?
nein.

Tipp: Bitte mal nachlesen zu ReadingsNum und OldReadingsNum.
Auch funktionierende Lösungen kann man hinterfragen.

hummeruli

Wenn ich das aber richtig verstehe, so wird das Relais nur einmal eingeschaltet und bleibt an. Ich brauche ja dass das Relais jedes mal wenn sich der Wert erhöht, für eine Sekunde anzieht (ON-FOR-TIMER 1.
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Zitat von: hummeruli am 15 Juni 2026, 19:46:56macht er es ja nur von 1 > 2
Nein. Das > ist "größer als". 1 > 2 kann also schon gar nicht true werden und den Code im if ausführen, weil 1 nicht größer 2 ist.

Die 1 und 2 in den Klammern sind die Defaultwerte, d.h. das, was (Old)ReadingsNum ausgibt, wenn das Reading nicht existiert oder aus irgendeinem anderen Grund nicht ausgelesen werden kann. Ich habe diese Defaultwerte extra so gewählt, dass, sollten beide Defaultwerte zum Einsatz kommen, das if nicht ausgeführt wird. Einfach zur Sicherheit. Vermutlich wäre es besser die 2 auf irgendeine hohe Zahl, 9999999 oder so, zu ändern.

on-for-timer kannst du ja einfach benutzen, statt nur on.

Guybrush

für den fall gibt es doch das attribut "event-on-change". das setzt du auf das readings, welches den zähler hoch zählt. es wird dann nur noch bei änderung des wertes ein event gefeuert, wo du dann über NOTIFY deine Logik hinterlegen kannst.

hummeruli

Zitat von: Guybrush am 16 Juni 2026, 08:45:36für den fall gibt es doch das attribut "event-on-change". das setzt du auf das readings, welches den zähler hoch zählt. es wird dann nur noch bei änderung des wertes ein event gefeuert, wo du dann über NOTIFY deine Logik hinterlegen kannst.
Das geht leider nicht da er hoch und runter zählt. Genau gesagt die Anzahl der eingeloggten User im WLAN.
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Hier braucht es doch gar kein event-on-* ...

Die Bedingung lässt sich einfach mit "größer als" abbilden. Wenn ein Wert größer ist als der andere (alte) Wert, dann soll fhem on-for-timer 1 ausführen. So kompliziert ist das nun wirklich nicht.

Hast du denn mal die Lösung mit oldreadings ausprobiert?

hummeruli

Zitat von: passibe am 16 Juni 2026, 13:07:42Hier braucht es doch gar kein event-on-* ...

Die Bedingung lässt sich einfach mit "größer als" abbilden. Wenn ein Wert größer ist als der andere (alte) Wert, dann soll fhem on-for-timer 1 ausführen. So kompliziert ist das nun wirklich nicht.

Hast du denn mal die Lösung mit oldreadings ausprobiert?

Das mit oldreadings habe ich nirgends gefunden, was nicht bedeuten soll dass es nirgends steht.
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Commandref ist bekannt?
https://fhem.de/commandref_DE.html#perl (bisschen scrollen, oder strg+f mit "OldReadingsNum" benutzen)
https://fhem.de/commandref_DE.html#oldreadings (hier zum Attribut)

Googlen geht auch:
site:fhem.de oldreadings

Ansonsten hatte ich es eigentlich in meiner Antwort erklärt, was du machen musst:
1. Bei deinem unifi-Gerät oldreadings-Attribut mit dem reading, von dem du den alten Wert speichern willst, füllen
2. z.B. ein Notify erstellen, das auf ein Event, das von diesem Reading kommt, hört
3. Den Perl-Code geringfügig anpassen (richtiger Name des devices, richtiger Name des readings, ggfs. defaultwerte ändern, Schaltbefehl auf on-for-timer ändern)
4. Fertig

Wenn du da noch Unterstützung brauchst, dann poste einfach mal deine Versuche. Ohne es einfach zu versuchen, wird das nichts.

hummeruli

ich hatte es mit einem DOIF versucht, wobei dieser jedoch eben nur das erste mal, also von 0 nach 1 reagiert.

defmod checkFeuer DOIF ([cloudkey:-UC_wlan_users] > 0) (set Optokoppler on-for-timer 1)
Das oldreadings habe ich jetzt gefunden, stehe aber auf dem Schlauch wie ich es dort anwenden könnte.

Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Zitat von: passibe am 16 Juni 2026, 17:29:21Ansonsten hatte ich es eigentlich in meiner Antwort erklärt, was du machen musst:
1. Bei deinem unifi-Gerät oldreadings-Attribut mit dem reading, von dem du den alten Wert speichern willst, füllen
2. z.B. ein Notify erstellen, das auf ein Event, das von diesem Reading kommt, hört
3. Den Perl-Code geringfügig anpassen (richtiger Name des devices, richtiger Name des readings, ggfs. defaultwerte ändern, Schaltbefehl auf on-for-timer ändern)
4. Fertig
Bitte diese Schritte befolgen, am besten ein notify verwenden. DOIF ist hier overkill bzw. nervig, weil es kompliziert ist, die Bedingung als Perl zu formulieren. Zu dem "nur einmal auslösen": es gibt attr <DOIF-Device> do always. Ist aber irrelevant, bitte einfach notify benutzen

Übrigens scheint da irgendwo in deinem Kopf noch ein Knoten zu sein, weil es bringt dir nichts, dass du stumpf auf "größer als null" prüfst; du musst ja den alten mit dem neuen Wert vergleichen. Dazu brauchst du oldreadings.

hummeruli

Habe das soweit ich es verstanden habe umgesetzt.

defmod Feuer_ntf notify cloudkey:-UC_wlan_users > cloudkey:oldreadings:-UC_wlan_users (set Optokoppler on-for-timer 1)
Ich kann das Notify mit trigger anstoßen, so dass eventCount hoch zählt. Das Relais schaltet jedoch nicht.
Ich vermute dass ich das mit dem oldreadings nicht richtig umsetze. Im cloudkey (das verwendete Modul) habe ich das Attribut oldreadings gesetzt.
Beim Erstellen dieser Nachricht kamen weder Tiere zu Schaden, noch wurde Papier verschwendet. Alles von mir geschriebene ist biologisch abbaubar.


FHEM auf Debian Buster in einr Proxmox VM , LaCrosseGateway, AVR-NET-IO, Homematic, Alexa, S300TH, Signalduino..........

passibe

Zitat von: hummeruli am 16 Juni 2026, 21:53:39cloudkey:oldreadings:-UC_wlan_users
Das hier verstehe ich nicht

Dieser Vergleich direkt im notify dürfte wohl auch nicht funktionieren, wo hast du das denn her?

Bitte im notify einfach den perl-code nutzen, den ich oben gepostet habe (natürlich anpassen!)
Zitat von: passibe am 15 Juni 2026, 19:41:48if (ReadingsNum("device", "readingName", "1") > OldReadingsNum("device", "readingName", "2")) {
    fhem("set relay on");
}

Im Zweifel das notify auch erstmal leer aus dem Event Monitor heraus erstellen.

Ansonsten: Hast du in cloudkey auch das attribut oldreadings auf -UC_wlan_users gesetzt? (Und sicher, dass das Reading mit einem - anfängt? Also stimmt -UC_wlan_users oder UC_wlan_users?)