[gelöst] wie werden Bedingungen abgehandelt

Begonnen von holle75, 08 Oktober 2019, 12:36:49

Vorheriges Thema - Nächstes Thema

holle75

edit: es hat doch nichts mit dem resetwait zu tun. Eben das resetwait und repeatsame entfernt mit dem selben Ergebnis.

Hallo Ihr, folgendes DOIF ignoriert cmd 2 (wenn wahr und aktiv) und geht, wenn cmd 1 getriggert wird (und nicht wahr ist), in cmd 3. Ich verstehe nicht warum. Das cmd 2 müßte doch greifen, wenn wahr?

DOIF:
([?$SELF:state] ne "cmd_2" and ([?ZirkusOben_TRIGGER_Luefter] eq "off" or [?$SELF:cmd] eq "1.1") and [ZirkusOben_TASTER_PIR:state] =~ "press") (set ZirkusOben_TRIGGER_Luefter on) (set ZirkusOben_TRIGGER_Luefter off)
DOELSEIF ([11:30-15:00] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5) (set ZirkusOben_TRIGGER_Luefter on)
DOELSE (set ZirkusOben_TRIGGER_Luefter off)


attr:
do resetwait
initialize initialized
repeatsame 0:1:1
wait 0,300:60:60



List:
Internals:
   DEF        ([?$SELF:state] ne "cmd_2" and ([?ZirkusOben_TRIGGER_Luefter] eq "off" or [?$SELF:cmd] eq "1.1") and [ZirkusOben_TASTER_PIR:state] =~ "press") (set ZirkusOben_TRIGGER_Luefter on) (set ZirkusOben_TRIGGER_Luefter off)
DOELSEIF ([11:30-15:00] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5) (set ZirkusOben_TRIGGER_Luefter on)
DOELSE (set ZirkusOben_TRIGGER_Luefter off)



   FUUID      5cc5cdcb-f33f-6bb4-afef-2d8676fa3366a6c5
   MODEL      FHEM
   NAME       ZirkusOben_PIR13_Luefter_DOIF
   NOTIFYDEV  ZirkusOben_TASTER_PIR,Container_TEMPFEUCHTESENSOR,global
   NR         999
   NTFY_ORDER 50-ZirkusOben_PIR13_Luefter_DOIF
   STATE      cmd_3
   TYPE       DOIF
   VERSION    20254 2019-09-26 18:06:30
   READINGS:
     2019-10-08 12:19:10   Device          ZirkusOben_TASTER_PIR
     2019-10-08 12:20:10   cmd             3
     2019-10-08 12:20:10   cmd_count       1
     2019-10-08 12:20:10   cmd_event       ZirkusOben_TASTER_PIR
     2019-10-08 12:20:10   cmd_nr          3
     2019-10-08 12:17:25   e_Container_TEMPFEUCHTESENSOR_humidity 55
     2019-10-08 12:04:01   e_Container_TEMPFEUCHTESENSOR_temperature 18.8
     2019-10-08 12:19:10   e_ZirkusOben_TASTER_PIR_state press_short_58
     2019-10-08 11:56:08   mode            enabled
     2019-10-08 12:20:10   state           cmd_3
     2019-10-08 11:56:08   timer_01_c02    09.10.2019 11:30:00
     2019-10-08 11:56:08   timer_02_c02    08.10.2019 15:00:00
     2019-10-08 12:20:10   wait_timer      no timer
   Regex:
     accu:
     cond:
       Container_TEMPFEUCHTESENSOR:
         0:
         1:
           humidity   ^Container_TEMPFEUCHTESENSOR$:^humidity:
           temperature ^Container_TEMPFEUCHTESENSOR$:^temperature:
       ZirkusOben_TASTER_PIR:
         0:
           state      ^ZirkusOben_TASTER_PIR$:^state:
         1:
   attr:
     cmdState:
     repeatsame:
       0
       1
       1
     wait:
       0:
         0
         300
       1:
         60
       2:
         60
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'ZirkusOben_PIR13_Luefter_DOIF','state') ne "cmd_2" and (::InternalDoIf($hash,'ZirkusOben_TRIGGER_Luefter','STATE') eq "off" or ::ReadingValDoIf($hash,'ZirkusOben_PIR13_Luefter_DOIF','cmd') eq "1.1") and ::ReadingValDoIf($hash,'ZirkusOben_TASTER_PIR','state') =~ "press"
     1          ::DOIF_time($hash,0,1,$wday,$hms) and ::ReadingValDoIf($hash,'Container_TEMPFEUCHTESENSOR','humidity') < 70 and ::ReadingValDoIf($hash,'Container_TEMPFEUCHTESENSOR','temperature') > 5
   days:
   do:
     0:
       0          set ZirkusOben_TRIGGER_Luefter on
       1          set ZirkusOben_TRIGGER_Luefter off
     1:
       0          set ZirkusOben_TRIGGER_Luefter on
     2:
       0          set ZirkusOben_TRIGGER_Luefter off
   helper:
     DEVFILTER  ^global$|^ZirkusOben_TASTER_PIR$|^Container_TEMPFEUCHTESENSOR$
     NOTIFYDEV  global|ZirkusOben_TASTER_PIR|Container_TEMPFEUCHTESENSOR
     event      press_short: 58,press_short_58
     globalinit 1
     last_timer 2
     sleepdevice ZirkusOben_TASTER_PIR
     sleepsubtimer -1
     sleeptimer -1
     timerdev   ZirkusOben_TASTER_PIR
     timerevent press_short: 58,press_short_58
     triggerDev ZirkusOben_TASTER_PIR
     timerevents:
       press_short: 58
       press_short_58
     timereventsState:
       press_short: 58
       state: press_short_58
     triggerEvents:
       press_short: 58
       press_short_58
     triggerEventsState:
       press_short: 58
       state: press_short_58
   internals:
     all         ZirkusOben_TRIGGER_Luefter:STATE
   interval:
     0          -1
     1          0
   intervalfunc:
   localtime:
     0          1570613400
     1          1570539600
   readings:
     all         ZirkusOben_TASTER_PIR:state Container_TEMPFEUCHTESENSOR:humidity Container_TEMPFEUCHTESENSOR:temperature
   realtime:
     0          11:30:00
     1          15:00:00
   time:
     0          11:30:00
     1          15:00:00
   timeCond:
     0          1
     1          1
   timer:
     0          0
     1          0
   timers:
     1           0  1
   trigger:
   triggertime:
     1570539600:
       localtime  1570539600
       hash:
     1570613400:
       localtime  1570613400
       hash:
   uiState:
   uiTable:
Attributes:
   do         resetwait
   group      System
   initialize initialized
   repeatsame 0:1:1
   wait       0,300:60:60


jemand eine Idee?

Danke und Gruß

Ellert

Commandref, Einleitung,
ZitatZu beachten ist, dass nur die Bedingungen überprüft werden, die zum ausgelösten Event das dazughörige Device bzw. die dazugehörige Triggerzeit beinhalten
Das auslösende Gerät gibt es nicht in Bed. 2

holle75


holle75

#3
Mmh, muss ich bei der Anforderung dann tatsächlich auf 2 DOIF´s ausweichen? Oder hast du noch eine Idee für mich wie man das lösen könnte?

Ah, werde mich mal mit checkall auseinandersetzen

amenomade

Also... Du musst selbst überlegen, was Du machen möchtest.
In Bedingung 2 gibt es ZirkusOben_TASTER_PIR nicht. Das aber das Device, was gegtriggert hat. Was soll dann passieren?
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

holle75

#5
ich hatte noch im Kopf, dass DOIF von "links nach rechts" die Bedingungen abarbeitet. Dass sich dies nur, wie Ellert schrieb, auf die Bedingung mit dem zugehörigem Device/Event bezieht war mir nicht klar.

Eben die commandref zur Inspiration bemüht und checkall gefunden. Werde ich probieren.

Und klar frag ich nur, wenn mir selber nichts einfällt ;)

Ich möchte zwei Funktionen in ein DOIF packen. Zum Einen ein Anschalten des Lüfters wenn Bewegung (bei kontinuierlicher Bewegung durch resetwait verlängert) und außerdem tagsüber, wenn die Wetterparameter stimmen, von 11:30-15:00. Falls tagsüber, soll eine Bewegung nicht die Zeitspanne aushebeln. In einem DOIF, um das komplexere gegenseitige blockieren von zwei DOIF´s zu umgehen (und um es übersichtlicher zu halten).

amenomade

Du musst aber im Sinn von "trigger" => "Befehl" überlegen.

Etwas triggert (es sei eine Zeitbedingung, ein Event oder eine Statusänderung) => eine oder mehere Bedingungen werden bewertet => ein Befehl wird ausgeführt
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

holle75

Jo, wenn ich eine Abhängigkeit aller Bedingungen untereinander brauche, diese aber komplett unterschiedliche Trigger haben, müsste ich mehrere DOIF´s bemühen, weil, wie ich eben lernen durfte, das DOIF im jeweiligen Fall die anderen Bedingungen ignoriert. Hoffe, ich habe das jetzt richtig verstanden.

Teste gerade mit attr checkall wie sich die Problematik umgehen lässt. Denke, das ist genau das Gesuchte.

amenomade

Zitat von: holle75 am 08 Oktober 2019, 20:38:48

Teste gerade mit attr checkall wie sich die Problematik umgehen lässt. Denke, das ist genau das Gesuchte.
Naja... trotzdem im Sinn von Triggern überlegen. Check all all kann z.B. dazu führen, dass bei einer Änderung von humidity, cmd1 ausgeführt wird, wenn die Bedingung 1 wahr ist
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Damian

Zitat von: holle75 am 08 Oktober 2019, 20:38:48
Jo, wenn ich eine Abhängigkeit aller Bedingungen untereinander brauche, diese aber komplett unterschiedliche Trigger haben, müsste ich mehrere DOIF´s bemühen, weil, wie ich eben lernen durfte, das DOIF im jeweiligen Fall die anderen Bedingungen ignoriert. Hoffe, ich habe das jetzt richtig verstanden.

Teste gerade mit attr checkall wie sich die Problematik umgehen lässt. Denke, das ist genau das Gesuchte.

Meiner Ansicht nach, sollte sich ein Problem immer ohne checkall realisieren lassen. Argumentation:

Bei einem Trigger interessieren andere Zweige nicht, da sich dort nichts geändert hat, hätte sich dort etwas geändert, dann wären sie bereits durch den dazugehörigen Trigger bereits ausgewertet worden. All meine Definitionen kommen ohne checkall aus. checkall birgt Gefahren, die man nicht unterschätzen sollte: siehe https://forum.fhem.de/index.php/topic,104072.0.html

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holle75

#10
... ich verbrachte mit der Aufgabenstellung und diesem DOIF jetzt geschätzte 10 Stunden. Entscheidender Hinweis war, dass nur Bedingungen entsprechend des Triggers/Device geprüft werden. Das hatte ich nicht parat. Ich hatte ansonsten so ziemlich jede (mir) erdenkliche Kombination durch.

Deswegen fragte ich, ob jemand noch eine Idee hat ... und würde mich freuen. Ich habe leider keine mehr.

Die Alternative über 2 DOIF´s und dann im jeweiligen Abfragen wo das Andere steht um nicht mit dem Anderen das Eine auszuhebeln macht das Ganze (für mich) unübersichtlich.

So:
([11:00-15:00] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5) (set ZirkusOben_TRIGGER_Luefter on)
DOELSEIF ([?$SELF:state] ne "cmd_1" and ([?ZirkusOben_TRIGGER_Luefter] eq "off" or [?$SELF:cmd] eq "2.1") and [ZirkusOben_TASTER_PIR:state] =~ "press") (set ZirkusOben_TRIGGER_Luefter on) (set ZirkusOben_TRIGGER_Luefter off)
DOELSE (set ZirkusOben_TRIGGER_Luefter off)


mit:
checkall   all
do         resetwait
group      System
initialize initialized
repeatsame 1:0:1
wait       60:0,300:60 (die 60 sind für den Neustart damit der Lüfter nicht vor der Initialisierung geschaltet wird - HMWIRED)


macht es jetzt nach ersten Tests was es soll.

EDIT: Oha, wie ihr beide anmerktet zu früh gefreut. Jetzt triggert da tatsächlich alles fröhlich rundrum. Mmh, back to zero.


Damian

Du musst die Aufgabenstellung präsentieren und nicht deine (nicht funktionierende) Lösung, denn so versteht keiner was das eigentliche Ziel der 10 stündigen Übung ist ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holle75

#12
Zitat von: holle75 am 08 Oktober 2019, 19:24:53
Ich möchte zwei Funktionen in ein DOIF packen. Zum Einen ein Anschalten des Lüfters wenn Bewegung (bei kontinuierlicher Bewegung durch resetwait verlängert) und außerdem tagsüber, wenn die Wetterparameter stimmen, von 11:00-15:00. Falls tagsüber, soll eine Bewegung nicht diese Zeitspanne aushebeln.

und das sind die Devices/Events/Trigger die eigentlich für mich so total Sinn machen :D :

([11:00-15:00] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5) (set ZirkusOben_TRIGGER_Luefter on)
DOELSEIF ([?$SELF:state] ne "cmd_1" and ([?ZirkusOben_TRIGGER_Luefter] eq "off" or [?$SELF:cmd] eq "2.1") and [ZirkusOben_TASTER_PIR:state] =~ "press") (set ZirkusOben_TRIGGER_Luefter on) (set ZirkusOben_TRIGGER_Luefter off)
DOELSE (set ZirkusOben_TRIGGER_Luefter off)

Damian

#13
Dann würde ich zwei DOIFs definieren. Eines, was nur auf Bewegung reagiert mit Verlängerung, wie in der Commandref, mit einer zusätzlichen Und-Verknüpfung, die den Zustand des anderen DOIF auswertet um die Bewegung zu übersteuern.

Es ist oft einfacher mehrere DOIFs zu definieren, als sich zu viele Abhängigkeiten in ein DOIF einzuhandeln.

Programmierer können auf DOIF-Perl ausweichen, dort kann man insb. unabhängige Dinge besser in ein DOIF Modul packen, dafür ist die Programmierung aufwändiger.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holle75

Mmh, dann bin ich da, wo ich seit 10 Stunden nicht hin will  ;D ;D ;D

Aber wenn du das sagst, gibt es wahrscheinlich keinen galanteren Weg

Danke!

Damian

Zitat von: holle75 am 08 Oktober 2019, 22:39:59
Mmh, dann bin ich da, wo ich seit 10 Stunden nicht hin will  ;D ;D ;D

Aber wenn du das sagst, gibt es wahrscheinlich keinen galanteren Weg

Danke!

Vielleicht gibt es den in einem DOIF. Die Frage ist nur: Wirst du ihn in einem Jahr noch mal nachvollziehen können, wenn eine Änderung oder Erweiterung ansteht?
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holle75

... wohl war. Aber man denkt immer "das muß doch auch sexier gehen" ... und wahrscheinlich macht man sich unnötig das Leben schwer.
"Best practice" lernt man eben nur anhand von Beispielen (oder Fragen)


Damian

Zitat von: holle75 am 08 Oktober 2019, 22:46:17
... wohl war. Aber man denkt immer "das muß doch auch sexier gehen" ... und wahrscheinlich macht man sich unnötig das Leben schwer.
"Best practice" lernt man eben nur anhand von Beispielen (oder Fragen)

Ja, ich habe DOIF (FHEM-Modul) für typische einfache Automatisierungsfälle programmiert (alle Beispiele in der Commandref sind einfach gestrickt). Es verführt dazu immer mehr Komplexität, in einem Modul abzubilden. Dafür ist der FHEM-Modus mit seiner flachen Hierarchie (if-elsif) nicht gut geeignet. Für komplexere Probleme muss man entweder mehrere Module definieren oder eben "strukturiert programmieren", dafür habe ich den DOIF-Perl-Modus entwickelt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

holle75

Früher oder später schaue ich mir den perl-Modus mal an ... wahrscheinlich großartig, aber wohl doch eher etwas für Menschen, die sowieso schon Perl kennen/können, denke ich. DOIF als FHEM-Modul war/ist für mich (und wahrscheinlich viele) unter anderem der Grund, mich näher mit FHEM zu beschäftigen.... und ohne DOIF würden viele Perl-Unwissende wahrscheinlich die Segel streichen, bevor die Genialität von FHEM erkannt wird.

Was wollte ich sagen? Danke für DOIF und Danke für den Support! ... auch an die anderen üblichen Verdächtigen.

amenomade

Wie wäre es mit:
([11:00-14:55] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5)
     (set ZirkusOben_TRIGGER_Luefter on)
DOELSEIF ( [ZirkusOben_TASTER_PIR:state] =~ "press")
     (set ZirkusOben_TRIGGER_Luefter on)
DOELSE
     (set ZirkusOben_TRIGGER_Luefter off)

wait 60:0:300
und keinem anderen attr?
Wenn die Wetterparameter nicht mehr stimmen, würde der Lüfter 5mn länger an bleiben, aber das würde de facto so eine Art Hysterese einbauen, wenn humidity oder temperature schwanken. Oder sehe ich das falsch?
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

holle75

so würde

[ZirkusOben_TASTER_PIR:state] =~ "press"  -> der Bewegungsmelder

Bedingung 1 beenden auch wenn die Zeit noch nicht abgelaufen ist.

Und Bedingung 2 würde sich bei erneuter Bewegung nicht verlängern.

Schätz ich mal so ...

amenomade

#21
Zitat von: holle75 am 09 Oktober 2019, 00:06:13
so würde

[ZirkusOben_TASTER_PIR:state] =~ "press"  -> der Bewegungsmelder

Bedingung 1 beenden auch wenn die Zeit noch nicht abgelaufen ist.

Warum denn? So lange eine Bedingung wahr bleibt, passiert nichts.

Zitat von: holle75 am 09 Oktober 2019, 00:06:13
Und Bedingung 2 würde sich bei erneuter Bewegung nicht verlängern.

Schätz ich mal so ...
Bei erneuter Bewegung, wenn inzwischen Bedingung2 nicht mehr wahr war, wird er wieder auf Bedingung2 kommen, oder? Das einzige Nachteil ist, dass jedes Mal wiederholt "set ... on" geschickt wird
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

holle75

Zitat von: amenomade am 09 Oktober 2019, 00:38:30
Warum denn? So lange eine Bedingung wahr bleibt, passiert nichts.
Das war ja mein Problem. Sobald Bedingung 2 getriggert wird, wird Bedingung 1 nicht mehr "geprüft" (wenn dort nicht das selbe device/event verbaut ist). Ich hatte es auch so gedacht verstanden zu haben, schön von links oben nach rechts unten ... und wo die Bedingung passt oder passend bleibt, wird ausgeführt oder belassen. Ist aber nicht so.

amenomade

Ahja stimmt. Dann lass den Bewegungsmelder in Bedingung 1 systematisch mitwirken:

([11:00-14:55] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5 and [ZirkusOben_TASTER_PIR:state] =~ ".*")
     (set ZirkusOben_TRIGGER_Luefter on)
DOELSEIF ( [ZirkusOben_TASTER_PIR:state] =~ "press")
     (set ZirkusOben_TRIGGER_Luefter on)
DOELSE
     (set ZirkusOben_TRIGGER_Luefter off)

wait 60:0:300

Bleibt die Frage für Bedingung 2: wenn keine Bewegung, geht der Bewegungsmelder auf einen anderen Status, so dass bei erneurter Bewegung die Bedingung wieder getriggert wird?

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

holle75

Mmh, gute Idee für Bedingung 1. Probier ich.

Zitat von: amenomade am 09 Oktober 2019, 01:40:53
Bleibt die Frage für Bedingung 2: wenn keine Bewegung, geht der Bewegungsmelder auf einen anderen Status, so dass bei erneurter Bewegung die Bedingung wieder getriggert wird?

Der Bewegungsmelder behält seinen status bis zu erneuter Bewegung. Ohne Bewegung keine Statusänderung. Ohne resetwait müßte Bedingung 2 aber erstmal die 300 seks abarbeiten um in Bedingung 3 zu kommen und erst dann könnte erneut getriggert -> Bedingung 2 wieder eintreten. Denke ich. Öfteres An/Aus wäre halbhübsch.
Aber hier könnte man ja mit den bereits versuchten attr arbeiten. In der Theorie müßte ich in meine DEF nur das

and [ZirkusOben_TASTER_PIR:state] =~ ".*"

in Bedingung 1 einbauen.

Zitat von: holle75 am 08 Oktober 2019, 21:58:43


So:
([11:00-15:00] and [Container_TEMPFEUCHTESENSOR:humidity] < 70 and [Container_TEMPFEUCHTESENSOR:temperature] > 5) (set ZirkusOben_TRIGGER_Luefter on)
DOELSEIF ([?$SELF:state] ne "cmd_1" and ([?ZirkusOben_TRIGGER_Luefter] eq "off" or [?$SELF:cmd] eq "2.1") and [ZirkusOben_TASTER_PIR:state] =~ "press") (set ZirkusOben_TRIGGER_Luefter on) (set ZirkusOben_TRIGGER_Luefter off)
DOELSE (set ZirkusOben_TRIGGER_Luefter off)


mit:

do         resetwait
group      System
initialize initialized
repeatsame 1:0:1
wait       60:0,300:60 (die 60 sind für den Neustart damit der Lüfter nicht vor der Initialisierung geschaltet wird - HMWIRED)




Per

Zitat von: amenomade am 09 Oktober 2019, 00:38:30Das einzige Nachteil ist, dass jedes Mal wiederholt "set ... on" geschickt wird
Dafür gibt es FILTER, wenn einen das wirklich stört.