Hauptmenü

einfacher zähler

Begonnen von mroschk, 17 Mai 2019, 12:23:26

Vorheriges Thema - Nächstes Thema

mroschk

Hallo,

um mich mit dem ungemein mächtigen DOIF vertraut zu machen habe ich versucht einen counter in Abhängigkeit von einem Schalter hoch und runterzählen zu lassen.
Bevor die Frage kommt, das ist jetzt nur um mich erst mal mit Fhem allgemein, mit dem Syntax und den einzelnen Modulen vertraut zu machen.

Also ich habe einen dummy Schalter namens "Schalter" erstellt, mit den webCmd ON:OFF.
dann einen dummy namens "count", der den aktuellen zählwert enthält.
dann ein DOIF namens di_count_UPDN, welches dann die arbeit macht :-)

hier die RAW Definition von dem DOIF:
Zitat
defmod di_count_UPDN DOIF ([Schalter] eq "on" && [count] < 1)\
(\
   set count {([count]+1)};;\
   set BadHeizung_Clima ValvePosition [count];;\
) DOELSE ([Schalter] eq "off" && [count] > 0)\
(\
   set count {([count]-1)};;\
)\

attr di_count_UPDN do resetwait
attr di_count_UPDN repeatcmd 0.2
attr di_count_UPDN repeatsame 100
attr di_count_UPDN room counter

setstate di_count_UPDN initialized
setstate di_count_UPDN 2019-05-17 12:10:18 cmd 0
setstate di_count_UPDN 2019-05-17 12:10:18 mode enabled
setstate di_count_UPDN 2019-05-17 12:10:18 state initialized

das Problem ist fogendes:

Wenn count = 0 und ich schalte den Schalter auf ON, dann wird hochgezählt...super.
Wenn aber count > 0 ist und ich den Schalter auf OFF schalte, dann wird count immer nur um 1 verringert??

Das verstehe ich nicht so ganz. Warum wird denn da nicht, genau wie anders herum, heruntergezählt ??
Verstehe ich da noch etwas an dem DOELSE falsch ?

Ich hab das ganze mit zwei DOIF's , eins für UP und eins für DOWN mit den gleichen einstellungen versucht, da funtioniert es. NUr wenn ich beides in ein DOIF machen will, dann funktioniert es nicht.

Hier noch die RAW von den beiden DOIF's für UP und DN getrennt:

UP:
Zitat
defmod di_count_UP DOIF ([Schalter] eq "on" && [count] < 1)\
(\
   set count {([count]+1)};;\
   set BadHeizung_Clima ValvePosition [count];;\
)\

attr di_count_UP do resetwait
attr di_count_UP repeatcmd 0.2
attr di_count_UP repeatsame 100
attr di_count_UP room counter

setstate di_count_UP 2019-05-17 11:35:33 Device count
setstate di_count_UP 2019-05-17 11:34:24 cmd 1
setstate di_count_UP 2019-05-17 11:34:24 cmd_event count
setstate di_count_UP 2019-05-17 11:34:24 cmd_nr 1
setstate di_count_UP 2019-05-17 11:35:04 e_Schalter_STATE off
setstate di_count_UP 2019-05-17 11:35:33 e_count_STATE 0
setstate di_count_UP 2019-05-17 11:49:06 last_cmd cmd_1
setstate di_count_UP 2019-05-17 11:49:06 mode disabled
setstate di_count_UP 2019-05-17 11:49:06 state disabled
setstate di_count_UP 2019-05-17 11:34:24 wait_timer no timer

DN:
Zitat
defmod di_count_DN DOIF ([Schalter] eq "off" && [count] > 9)\
(\
   set count {([count]-1)};;\
)
attr di_count_DN do resetwait
attr di_count_DN repeatcmd 0.2
attr di_count_DN repeatsame 100
attr di_count_DN room counter

setstate di_count_DN disabled
setstate di_count_DN 2019-05-17 11:35:04 Device Schalter
setstate di_count_DN 2019-05-17 11:35:33 cmd 1
setstate di_count_DN 2019-05-17 11:35:33 cmd_event Schalter
setstate di_count_DN 2019-05-17 11:35:33 cmd_nr 1
setstate di_count_DN 2019-05-17 11:35:04 e_Schalter_STATE off
setstate di_count_DN 2019-05-17 11:34:24 e_count_STATE 100
setstate di_count_DN 2019-05-17 11:48:55 last_cmd cmd_1
setstate di_count_DN 2019-05-17 11:48:55 mode disabled
setstate di_count_DN 2019-05-17 11:48:55 state disabled
setstate di_count_DN 2019-05-17 11:35:34 wait_timer no timer

Ich wäre euch für eine kurze Hilfe dankbar, jeder hat ja mal angefangen und ich stehe leider noch ganz am Anfang :-)

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

Damian

Dein DOELSE ist eher ein DOELESEIF ;)

Solche Aufgaben kann man besser im DOIF-Perl-Modus lösen. Dort kannst du mit echten Instanzvariablen arbeiten, deren Zugriffe wesentlich performanter sind als über Dummys (hier: count).
   
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

mroschk

Hallo,

danke für die Antwort.
Ich muss ja irgendwo anfangen, und da wollte ich nicht gleich auch noch mit pearl anfangen und es geht mir ja auch darum erst mal das DOIF zu verstehen.
Eigentlich hieß das auch DOELSEIF, da hatte ich wohl gerade etwas ausprobiert, als ich den Code hier reinkopiert hatte.

Auf jeden fall geht es auch damit nicht.

Ich verstehe nicht warum der das nur einmal macht und nicht genauso wie im DOIF ([Schalter] eq "on" && [count] < 1)?
Das komische ist ja, das er auch in der DOELSEIF ankommt. Sieht man , das dann immer "cmd_2" kommt.

Aber warum zählt er denn nich von 100 bis 0, sondern bei jedem klick auf Schalter immer nur um 1 herunter ??

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

amenomade

repeatcmd 0.2:0.2
repeatsame 100:100
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

mroschk

Ahh, super...funktioniert.

Schön wäre noch zu wissen wo sowas steht?
Entweder habe ich es überlesen oder es steht wirklich nirgends (glaube ich nicht, denn die Erklärungen sind eigentlich recht gut.), das man das so machen muss.

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

amenomade

#5
Im CommandRef
ZitatWiederholungen der Ausführung von Kommandos werden pro Befehlsfolge über das Attribut "repeatcmd" definiert. Syntax:

attr <DOIF-modul> repeatcmd <Sekunden für Befehlsfolge des ersten DO-Falls>:<Sekunden für Befehlsfolge des zweiten DO-Falls>:...
ZitatMit dem Attribut repeatsame <maximale Anzahl von cmd_1>:<maximale Anzahl von cmd_2>:... wird die maximale Anzahl hintereinander folgenden Ausführungen festgelegt.

Jetzt warte ich auf eine andere Frage ;) Ich vermute, das funktioniert immer noch nicht ganz, wie Du es möchtest...
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

mroschk

Danke, ach so ist das gemeint...naja, wenn man das erst mal verstanden hat, dann gehts.

Ich glaube du wartest auf die Frage was passiert, wenn count nicht auf 100 steht, wenn man den Schalter auf OFF stellt um herunter zu zählen...
und du hast Recht...ist mir auch schon aufgefallen.
Der zählt ja dann in den Minus bereich herein.

in DOESEIF steht zwar "DOELSEIF ([Schalter] eq "off" && [count] > 0)", aber das hat ja damit nichts zu tun.
Man müsste also irgendwie eine Abbruch Abfrage für das repeatCmd haben.... keine Ahnung, aber das kostet mich sicher wieder eine Nach :-)

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

amenomade

#7
ZitatIch glaube du wartest auf die Frage was passiert, wenn count nicht auf 100 steht, wenn man den Schalter auf OFF stellt um herunter zu zählen...
und du hast Recht...ist mir auch schon aufgefallen.
Der zählt ja dann in den Minus bereich herein.
Ganz genau ;) Und über 100 kann er auch gehen
Die Bedingungen werden nicht bei jeder Iteration wieder bewertet, sondern die Befehle einfach wiederholt. Bis ein Trigger kommt. Da standardmässig ein DOIF sich selbst nicht triggert, bleibt nur [Schalter], um ein Zustandswechsel zu produzieren. [count] hat keinen Einfluss mehr.

Ich würde es so machen:
defmod di_count_UPDN DOIF ([Schalter] eq "on" and [count] < 100)\
  (set count {([count]+1)})\
DOELSEIF ([Schalter] eq "off" and [count] > 0)\
  (set count {([count]-1)})\


attr di_count_UPDN do resetwait
attr di_count_UPDN room counter
attr di_count_UPDN selftrigger wait
attr di_count_UPDN wait 0.2:0.2
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

mroschk

Hallo,

irgendwie scheint es das noch nicht zu sein.
Ich hab die definition so geändert, aber er zählt immer noch "drüber":
Zitat
defmod di_count_UPDN DOIF ([Schalter] eq "on" && [count] < 1 && [count] < 99)\
(\
   set count {([count]+1)};;\
   # set BadHeizung_Clima ValvePosition [count];;\
) DOELSEIF ([Schalter] eq "off" && [count] > 0)\
(\
   set count {([count]-1)};;\
)\

attr di_count_UPDN do resetwait
attr di_count_UPDN repeatcmd 0.2:0.2
attr di_count_UPDN repeatsame 100:100
attr di_count_UPDN room counter
attr di_count_UPDN selftrigger wait
attr di_count_UPDN wait 0.2:0.2

hmm....

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

amenomade

repeatsame und repeatcmd weg

Und "[count] < 1 && [count] < 99" ist falsch. Es muss nur "<100" (oder "< 99") sein, sonst zählt er nicht mehr hoch
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

mroschk

Das hattest du aber selbst so geschrieben...sorry.
Ausserdem zählt er so nicht, wenn ich das beides rausnehme:
Zitat
defmod di_count_UPDN DOIF ([Schalter] eq "on" and [count] < 100)\
  (set count {([count]+1)})\
DOELSEIF ([Schalter] eq "off" and [count] > 0)\
  (set count {([count]-1)})\

attr di_count_UPDN do resetwait
attr di_count_UPDN room counter
attr di_count_UPDN selftrigger wait

komisch
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

Prof. Dr. Peter Henning

Die Skriptsprache von FHEM ist keine universelle Programmiersprache und hat keine konsistente Syntax. Das bedeutet: Es ist ein vollkommen verfehlter Ansatz, damit komplexere Programmlogik (und das beginnt schon bei diesem "Zähler"...) realisieren zu wollen. So etwas sollte immer in Perl realisiert werden - wie man übrigens auch an den Tipps ablesen kann, DOIF im Perl-Modus zu verwenden...

Also, konstruktiver Vorschlag: Perl lernen und dann so etwas wie "Zähler" realisieren.

LG

pah

mroschk

Hallo,

danke für den Hinweis, das mach ich auch.
Wie oben geschrieben, das war nur mal ein Versuch um das DOIF erst mal zu verstehen und ein bisschen zu probieren.
Irgendwo muss man ja anfangen :-)

Pearl kommt natürlich auch noch zum Einsatz, wobei es da etwas schwieriger wird, damit FHEM nicht blockiert wird.
Das hatte ich schon mal bei was anderem probiert und kenne ich auch aus C#. Da muss man auch immer aufpassen, das einem die HUI nicht einfriert.

Matthias
ich stehe leider noch am Anfang mit FHEM :-)
deConz Stick
Maple_CUL 868 MAX Mode für Max! HT + Stackable 433
Xiaomi Roborock S5 (weiß, 2. Generation)

Damian

In FHEM sind 0,2 Sekunden schon recht knapp. Welche praktische Anwendung könnte diese Aufgabe haben? Evtl. sanftes Ein- oder Ausschalten einer Lampe über einen Dimmer. Das allerdings über FHEM zu realisieren, ist keine gute Idee, denn man produziert sehr viel Traffic, der je nach Aktor (z. B. bei HM) schnell zu einer Blockade (ein-Prozent-Regel) führt. Die Lösung für solche Aufgaben sollte, ja muss im Aktor (hier Dimmer) selbst bereits realisiert sein. Allein ein simples Blicken ist besser im Aktor aufgehoben, als es in FHEM nachzubilden.

Ich würde mich eher an den Beispielen in der Commandref zu DOIF orientieren, die ja einen sinnvollen praktischen Hintergrund haben. Und wie gesagt, wenn du Programmiererfahrung hast, dann schau dir Perl (nicht Pearl) genauer an, denn das wirst du in FHEM überall brauchen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

amenomade

#14
Zitat von: mroschk am 18 Mai 2019, 00:43:01
Das hattest du aber selbst so geschrieben...sorry.
Ausserdem zählt er so nicht, wenn ich das beides rausnehme:
komisch
Naja... für die nicht funktionierende Lösung ja. Aber dann habe ich geschrieben:
defmod di_count_UPDN DOIF ([Schalter] eq "on" and [count] < 100)\
  (set count {([count]+1)})\
DOELSEIF ([Schalter] eq "off" and [count] > 0)\
  (set count {([count]-1)})\


attr di_count_UPDN do resetwait
attr di_count_UPDN room counter
attr di_count_UPDN selftrigger wait
attr di_count_UPDN wait 0.2:0.2

Also... so wie es hier steht. Nur das, und genau das (cf. wait Attribute) und es sollte funktionieren. Wenn Du improvisierst... kann ich die Ergebnisse nicht garantieren...

Und da Du verstehen möchtest, die Erklärung:
mit "selftrigger wait" triggert [count] auch. Das heisst, jedes Mal wenn [count] sich ändert, wird die Bedingung wieder getestet. Deswegen brauchst Du nur noch die Grenzen in der Bedingungen
Mit "wait 0.2:0.2" sind die Befehle jedes Mal 0.2 Sek verzögert

Somit die Logik: "wenn [count] oder [Schalter] sich ändert, prüfe die Bedingungen, warte 0.2s und führe entspr. einen Befehl aus.. was dazu führt, [count] neu zu kalkulieren... was wieder zum Anfang bringt, da [count] triggert.
Deswegen braucht man jetzt weder repeatcmd noch repeatsame: wird durch Triggern von [count] ersetzt

Für die konkrete Anwendung davon, bin ich davon ausgegangen, dass es nur zum Testen war, und das Du zukünftig z.B. eher 60s oder so haben wirst. Sonst siehe Anmerkung von Damian. Wegen 'Perl Modus' kann ich nicht wirklich helfen, da ich in der DOIF-Perl Syntax noch keine Zeit investiert habe. Ich schaffe bisher alles was ich brauche mit "normalem" DOIF-Modus
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus