Prüfung Zeitebereich mit Daten aus dummy (Datum Problem)

Begonnen von tunguskar, 04 August 2020, 22:23:42

Vorheriges Thema - Nächstes Thema

tunguskar

Hallo zusammen,

Ich sitze jetzt seit einiger Zeit an folgendem Problem.

Ich habe eine Bewässerungsanlage. (8 Ventile) welche nicht gleichzeitig laufen dürfen (ohne Feuchte Sensoren). Ich will nur, dass bei dem schalten eines Schalters Zeiten berechnet werden und zu diesen dann die einzelnen Ventile an sind. Wenn der Schalter ausgeschalten wird, werden die Zeiten zurückgesetzt.

Datzu habe ich jewils ein startzeit dummy und ein endzeit dummy

Bsp:
defmod bewaesserung_gemuesebeet_endzeit dummy
defmod bewaesserung_gemuesebeet_startzeit dummy

nach dem schalten steht in diesen exemplarisch dann auch der gewünschte Zeitbereich.
z.B.
startzeit:
state 22:08

endzeit:
state 23:08

In einem doif verwerte ich dann die beiden states:

defmod bewaesserung_zeitsteuerung DOIF ([[bewaesserung_gemuesebeet_startzeit]-[bewaesserung_gemuesebeet_endzeit]])(set sps.draussen.sprenger.gemuesebeet on)

Problem meines erachtens ist, dass in dem doif die Zeitstempel falsch verwertet werden:

cmd 0 2020-08-04 22:10:00
mode enabled 2020-08-04 22:10:00
state initialized 2020-08-04 22:10:00
timer_01_c01 05.08.2020 22:08:00 2020-08-04 22:10:00
timer_02_c01 04.08.2020 23:08:00 2020-08-04 22:10:00

Er macht hier automatisch von dem Startzeitpunkt den nächsten Tag und nicht den aktuellen.

Oder sehe ich das falsch? (Problem ist, es schaltet nichts :) )

amenomade

Das sieht eher gut aus. Anscheinend wurden die Zeiten um 22:10 kalkuliert. Dann ist es normal, dass 01_c01 am nächsten Tag ist.
Jetzt sollte auch 02_c01 am 05.04 sein.

Wenn es nicht schaltet, hängt das wahrscheinlich am fehlenden do alwayw Attribut.

Zur Analyse wäre es besser, nächstes Mal ein "list" vom DOIF zu liefern.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

tunguskar

Danke dir das hat geholfen. Jetzt schalten der Reihe nach die Ventile. Problem ist noch, dass diese nicht mehr ausgeschalten werden.

das doIf schaut jetzt so aus ( es gibt einen Schalter (bewaesserung_aktivieren) der auf auto mode, deactivate auto mode und manuell gesetzt werden kann)

jedes Ventil hat sein DoIf

defmod bewaesserung_zeitsteuerung_gemuesebeet DOIF ([bewaesserung_aktivieren] eq "startAutoMode" and [[bewaesserung_gemuesebeet_startzeit]-[bewaesserung_gemuesebeet_endzeit]])(set sps.draussen.sprenger.gemuesebeet on) DOELSEIF ([bewaesserung_aktivieren] eq "deactivateAutoMode" or [bewaesserung_aktivieren] eq "startAutoMode") (set sps.draussen.sprenger.gemuesebeet off)


Warum aktiviert er nicht den zweiten zweig wenn der Zeitbereich verlassen wurde?

Ich hab jetzt noch ein attr bewaesserung_zeitsteuerung_gemuesebeet selftrigger all dazu gesetzt das hilft aber nicht

tunguskar

so wie ich das sehe fehlt ihm beim verlassen des ersten Zeitbereichs irgend ein trigger. (obwohl ich das selftrigger all gesetzt habe)

Damian

Du hast keinen DOELSE-Zweig, der ausgeführt werden würde, wenn die Endzeit erreicht ist.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tunguskar

#5
Zitat von: Damian am 05 August 2020, 23:48:29
Du hast keinen DOELSE-Zweig, der ausgeführt werden würde, wenn die Endzeit erreicht ist.
Den brauche ich eigentlich nicht da alle Zustände die ich behandeln will mit dem anderen zweigen abgedeckt sind. Bzw. Was sollte ich dann darin machen? Oder ist das nur für die richtige Funktion? Der Zweig wäre bei mir dann leer.

tunguskar

hab den else zweig jetzt eingesetzt und der strang wird dort dann deaktiviert. Ist es richtig, dass dieser Else Zweig nur erreicht wird wenn das erste DOIF deaktiviert wurde?

Damian

Zitat von: tunguskar am 06 August 2020, 09:20:23
hab den else zweig jetzt eingesetzt und der strang wird dort dann deaktiviert. Ist es richtig, dass dieser Else Zweig nur erreicht wird wenn das erste DOIF deaktiviert wurde?

Der ELSE-Zweig wird dann ausgeführt, wenn ein DOIF-Zweig aufgrund eines Triggers geprüft wurde und die Bedingung nicht wahr ist.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tunguskar

Zitat von: Damian am 06 August 2020, 11:46:38
Der ELSE-Zweig wird dann ausgeführt, wenn ein DOIF-Zweig aufgrund eines Triggers geprüft wurde und die Bedingung nicht wahr ist.

Komisch ist da nur, dass es mit dem else zweig funktioniert und mit dem ifelse zweig nicht

Abfrage schaut so aus (nur exemplarisch)

doif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus)

so geht es:

doif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus) else (schalteVentilAus)

amenomade

#9
Zitat von: tunguskar am 06 August 2020, 14:37:16
Komisch ist da nur, dass es mit dem else zweig funktioniert und mit dem ifelse zweig nicht

Abfrage schaut so aus (nur exemplarisch)

doif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus)

so geht es:

doif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus) else (schalteVentilAus)

Ich glaube, Du kannst ruhig die Aussagen von Damian (Entwickler von DOIF) trauen... und auch DOIF besser verstehen.

Zitatdoif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus)

Die Zeit triggert nur die erste Bedingung. Wenn das Ende der Zeitperiode erreicht ist, hat ohne DOELSE das DOIF keine Ausweichmöglichkeit und bleibt im ersten Zustand. Die zweite (DOELSEIF) Bedingung wird gar nicht geprüft, da sie keine Zeittrigger hat.
Die DOELSE Bedingung wird dagegen immer getriggert, wenn ein Trigger dazu führt, dass die Bedingung wo dieses Trigger enthalten ist nicht mehr wahr ist.

Was vielleicht ohne DOELSE funktionieren würde, wäre:
Zitatdoif (aktiverZeitbereich AND schalterStehtAufAuto) (schalteVentilEin) elseIf (nichtaktiverZeitbereich OR schalterStehtAufAuto OR schalterStehtAufDeaktivieren) (schalteVentilAus)
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

tunguskar

Zitat von: amenomade am 06 August 2020, 19:31:08
Ich glaube, Du kannst ruhig die Aussagen von Damian (Entwickler von DOIF) trauen... und auch DOIF besser verstehen.

Die Zeit triggert nur die erste Bedingung. Wenn das Ende der Zeitperiode erreicht ist, hat ohne DOELSE das DOIF keine Ausweichmöglichkeit und bleibt im ersten Zustand. Die zweite (DOELSEIF) Bedingung wird gar nicht geprüft, da sie keine Zeittrigger hat.
Die DOELSE Bedingung wird dagegen immer getriggert, wenn ein Trigger dazu führt, dass die Bedingung wo dieses Trigger enthalten ist nicht mehr wahr ist.

Was vielleicht ohne DOELSE funktionieren würde, wäre:

Sorry ich glaube das natürlich was er sagt. Ich will es nur verstehen. Komme aus der c Welt und bin etwas irritiert. Das mit dem  nicht im Zeitbereich geht leider nicht und der else zweig macht mich grad nicht ganz glücklich, da ich dieses ventil nur von doif ausschalten will wenn der autoMode an ist. Im manuellen mode soll das nicht ausgeschalten werden. wenn irgend ein trigger kommt.

amenomade

#11
Zitat von: tunguskar am 06 August 2020, 21:50:57
Das mit dem  nicht im Zeitbereich
Wie hast Du denn versucht, es zu implementieren?

Das ganze hat nicht wirklich mit C oder perl zu tun, sondern mit Events und Triggern

Zitatda ich dieses ventil nur von doif ausschalten will wenn der autoMode an ist
Dann mach einfach ein IF im Befehl deines DOELSE
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

tunguskar

Zitat von: amenomade am 06 August 2020, 21:55:25
Wie hast Du denn versucht, es zu implementieren?

Das ganze hat nicht wirklich mit C oder perl zu tun, sondern mit Events und Triggern

Prinzipiell schon da in c ein If()elseif()...else immer komplett abgearbeitet wird wenn die Bedingung darüber nicht wahr ist

DOIF (not[Zeitbereich] and schalterStehtAufAutoMode)(ventilZu) DOELSEIF ([zeitbereich] and schalterStehtAufAutoMode) (ventilAuf)

tunguskar

ich denke aber ich bin noch weit von dem Verstehen entfernt :-)

amenomade

not[begin-end] geht ja nicht... aber [end-begin] geht.

Zum Verständnis hilft das Lesen von CommandRef:
ZitatDie Angaben werden immer von links nach rechts abgearbeitet. Logische Abfragen werden in DOIF/DOELSEIF-Bedingungen vornehmlich mit Hilfe von and/or-Operatoren erstellt. Zu beachten ist, dass nur die Bedingungen überprüft werden, die zum ausgelösten Event das dazughörige Device bzw. die dazugehörige Triggerzeit beinhalten. Kommt ein Device in mehreren Bedingungen vor, so wird immer nur ein Kommando ausgeführt, und zwar das erste, für das die dazugehörige Bedingung in der abgearbeiteten Reihenfolge wahr ist.

Das DOIF-Modul arbeitet mit Zuständen. Jeder Ausführungszweig DOIF/DOELSEIF..DOELSEIF/DOELSE stellt einen eigenen Zustand dar (cmd_1, cmd_2, usw.). Das Modul merkt sich den zuletzt ausgeführten Ausführungszweig und wiederholt diesen standardmäßig nicht. Ein Ausführungszweig wird erst dann wieder ausgeführt, wenn zwischenzeitlich ein anderer Ausführungszweig ausgeführt wurde, also ein Statuswechsel des DOIF-Moduls stattgefunden hat. Dieses Verhalten ist sinnvoll, um zu verhindern, dass zyklisch sendende Sensoren (Temperatur, Feuchtigkeit, Helligkeit, usw.) zu ständiger Wiederholung des selben Befehls oder Befehlsabfolge führen.

Du musst im Sinn von EVENTS denken. Das kann man auch in C++ machen, das ist aber ein andere Art von Programmierung als eine sequenzielle  Programmierung.

Wenn ich grob schematisiere:

DOIF([begin-end]) bedeutet irgendwie "wenn begin oder end erreicht werden (das sind Zeit Events), ist diese Bedingung betroffen, und es wird getestet, ob es wahr ist, und ggf den Befehl ausgeführt".

DOIF ([device:reading] eq "blabla") bedeutet "wenn ein Event auf Device / Reading kommt, ist diese Bedingung betroffen, und ...
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus