FHEM Forum

FHEM => Automatisierung => Thema gestartet von: kschi am 26 Februar 2020, 23:06:44

Titel: If Bedingungen
Beitrag von: kschi am 26 Februar 2020, 23:06:44
Hi, ich versuche mich grad neu in FHEM und bin nicht so der Programmierer... Ich benötige Hilfe bei einer if Bedingung...

Meine Zirkulationspumpe soll gesteuert werden. Ich habe 2 Bewegungsmelder im unteren und oberen Flur. Wenn einer der beiden Bewegungsmelder reagiert, soll die Pumpe für 30 minuten laufen.
Nach ablauf dieser Zeit (wenn keine weiteren BM aktivitäten festgestellt wurden) soll die Pumpe für 30 min. pausieren, auch wenn danach die BM wieder aktiviert werden.

Dazu habe ich eine Dummy Lampe, die angeht, wenn die Pumpe ausgeht... Diese Dummy Lampe leuchtet dann für 30 min. Keine Ahnung, ob es da ne bessere Alternative gibt...
Der notify für die Pumpe soll dann prüfen, ob einer der beiden BM angeht UND die Dummy Lampe aus ist. Erst wenn die Lampe aus ist, soll die Pumpe wieder an gehen.

defmod n_Zirku_30_min_Timer notify Bewegungsmelder_unten||Bewegungsmelder_oben&&Lampe1 {if(Value("Bewegungsmelder_unten")eq "on"||Value("Bewegungsmelder_oben")eq "on"&&Value("Lampe1")eq "off"){fhem("set Zirkulationspumpe on-for-timer 600")}}

defmod n_test_an notify Zirkulationspumpe:set_off set Lampe1 on;;sleep 600;;set Lampe1 off\

Ich hab schon probiert und gemacht und getan, try & error, aber ich komme hier nicht weiter. Weiß noch nicht einmal, ob man das überhaupt so machen kann....
Danke für Eure Hilfe!

Karsten
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 26 Februar 2020, 23:24:21
Hallo Karsten,

kennst Du diesen Artikel?
https://wiki.fhem.de/wiki/Notify

Der Trigger ist ein regExp, das ist keine logische Abfrage. Die logische Abfrage geht nur im Ausführungsteil.
Machen die Bewegungsmelder wirklich einfach on?

Mach als erstes mal nach der Anleitung im Wiki ein notify mit einem Bewegungsmelder, das erweitern wir dann auf den Zweiten.

Gruß Otto
Titel: Antw:If Bedingungen
Beitrag von: CoolTux am 27 Februar 2020, 06:52:08
Ein Vorschlag. Da ja nach 30min wieder ausgeschalten werden soll wäre ein watchdog doch nicht schlecht. Da hat man dann schon mal das erste 30 min Thema fertig. Alles andere kann man dann ja abfragen.
Titel: Antw:If Bedingungen
Beitrag von: Gisbert am 27 Februar 2020, 08:00:51
Hallo Karsten,

ich habe eine vergleichbare Aufgabe mit einem DOIF gelöst.
Meine Definition sieht wie folgt aus (etwas "entkernt", damit es überschaubar für den Fall hier ist):
defmod Haushaltsraum.Lueftung DOIF ([TH.Haushaltsraum:humidity] > 55 and [TH.Haushaltsraum:temperature] > 18 and [Aussen:temperature] < 23 and [D.Haushaltsraum] =~ "on") \
(set HWR.Ventilator_ESP_Router command gpio 14 set high) \
(set HWR.Ventilator_ESP_Router command gpio 14 set low) \
DOELSEIF ([TH.Haushaltsraum:humidity] <= 55 or [TH.Haushaltsraum:temperature] <= 18 or [D.Haushaltsraum] =~ "off") \
(set HWR.Ventilator_ESP_Router command gpio 14 set low) \
DOELSEIF ([+[1]:00]) \
(set HWR.Ventilator_ESP_Router command gpio 14 set low)
attr Haushaltsraum.Lueftung repeatcmd 600:60:3600
attr Haushaltsraum.Lueftung repeatsame 3:2:10
attr Haushaltsraum.Lueftung wait 1,1200:1:0

Die Wirkung ist die folgende:
Wenn die Einschaltbedingung erfüllt ist, dann bekommt der Lüfter einen Einschaltbefehl, wartet dann 20 Minuten (wait 1200) und schaltet ab. Solange die Bedingung wahr ist / Event vorhanden ist, wiederholt sich das ganze nach weiteren 10 Minuten (repeatcmd 600). Zur Vollständigkeit: repeatsame gibt die Anzahl der Wiederholungen an.
Für deinen Fall brauchst du wahrscheinlich den 2. und 3. Fall des DOIFs nicht.
Der Lüfter läuft 20 Minuten, macht 10 Pause, usw. Der Vorteil dieser Lösung ist, dass man nicht permanente oder temporäre Dummys braucht.

Viele​ Grüße​ Gisbert​
Titel: Antw:If Bedingungen
Beitrag von: kschi am 27 Februar 2020, 18:06:04
Also die ganze Geschichte funktioniert ja schon fast...


defmod n_Zirku_30_min_Timer notify Bewegungsmelder_unten||Bewegungsmelder_oben {if(Value("Bewegungsmelder_unten")eq "on"||Value("Bewegungsmelder_oben")eq "on"){fhem("set Zirkulationspumpe on-for-timer 600")}}

Dieser Teil würde schon funktionieren. Die BM erkennen, schalten die Pumpe, wenn die Pumpe ausgeht, geht die Dummylampe an. Nur der Teil  der die Lampe abfragt, funktioniert noch nicht... Die Pumpe darf halt nur angehen, wenn einer der beiden BM angeht UND die Lampe aus ist... Wie würde man das abfragen?

Ein watchdog geht glaube ich nicht, weil der alle x minuten nachschaut, ob ein Zustand noch anliegt. Wenn vor der Abfrage des watchdog einer den BW wieder aktiviert, geht auch gleich die Pumpe an, und das soll sie halt nicht...
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 27 Februar 2020, 21:02:20
Der Teil "Bewegungsmelder_unten||Bewegungsmelder_oben" kann eigentlich nicht gehen. Der ist Unfug!

Und eine Lampe sehe ich in deinem Code nicht  ??? :o

Da Du nicht bereit bist Fragen zu beantworten und Hinweise zu befolgen, magst Du ein list Bewegungsmelder_unten zeigen?

Gruß Otto
Titel: Antw:If Bedingungen
Beitrag von: kschi am 27 Februar 2020, 22:33:58
Hm, im letzten Post habe ich geschrieben, dass dieser Teil bereits funktioniert. Im ersten Post ist der Code, der nicht funktioniert...

Und so ein großer unfug kann mein Code nicht sein, denn er funktioniert scheinbar... Auch wenn er wahrscheinlich so nicht geschrieben werden darf oder kann...

Zitat
Da Du nicht bereit bist Fragen zu beantworten und Hinweise zu befolgen, magst Du ein list Bewegungsmelder_unten zeigen?

Gruß Otto

Internals:
   CID        shelly1_E098068CDA08
   DEF        shelly1_E098068CDA08
   DEVICETOPIC Bewegungsmelder_unten
   FUUID      5e46d21c-f33f-1d52-f4a6-eeae016da607d009
   IODev      mqtt
   LASTInputDev mqtt
   MSGCNT     637
   NAME       Bewegungsmelder_unten
   NR         25
   STATE      off
   TYPE       MQTT2_DEVICE
   mqtt_MSGCNT 637
   mqtt_TIME  2020-02-27 22:27:27
   READINGS:
     2020-02-27 20:25:56   fw_ver          20200206-083100/v1.5.10@e6a4205e
     2020-02-27 20:25:56   id              shelly1-E098068CDA08
     2020-02-27 22:27:27   input0          0
     2020-02-27 20:25:56   ip              192.168.20.67
     2020-02-27 22:08:16   longpush_0      1
     2020-02-27 20:25:56   mac             E098068CDA08
     2020-02-27 20:25:56   new_fw          false
     2020-02-27 20:25:56   online          true
     2020-02-27 22:27:27   relay0          off
     2020-02-27 22:27:27   state           off
Attributes:
   IODev      mqtt
   devStateIcon {my $onl = ReadingsVal($name,"online","false") eq "false" ? "rot" : ReadingsVal($name,"new_fw","false") eq "true" ? "gelb" : "gruen";; my $light = ReadingsVal($name,"state","off");; my $show = '<a href="';;$show .= $onl eq "gelb" ? "/fhem?cmd.dummy=set $name x_update&XHR=1\">" : "http://".ReadingsVal($name,"ip","none").' "target="_blank">';;$show .= FW_makeImage("10px-kreis-".$onl)."</a>";; "<div> $show <a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($light)."</a></div>" }
   model      shelly1
   readingList shellies/shelly1-E098068CDA08/relay/0:.* state
  shellies/shelly1-E098068CDA08/relay/0:.* relay0
  shellies/shelly1-E098068CDA08/input/0:.* input0
  shellies/shelly1-E098068CDA08/online:.* online
  shellies/shelly1-E098068CDA08/announce:.* { json2nameValue($EVENT) }
  shellies/announce:.* { $EVENT =~ m,..id...shelly1-E098068CDA08...mac.*, ? json2nameValue($EVENT) : undef }
shelly1_E098068CDA08:shellies/shelly1-E098068CDA08/longpush/0:.* longpush_0
   room       Technik,Wohnzimmer
   setList    off:noArg shellies/shelly1-E098068CDA08/relay/0/command off
  on:noArg shellies/shelly1-E098068CDA08/relay/0/command on
  x_update:noArg shellies/shelly1-E098068CDA08/command update_fw
  x_mqttcom shellies/shelly1-E098068CDA08/command $EVTPART1
Titel: Antw:If Bedingungen
Beitrag von: CoolTux am 27 Februar 2020, 23:17:05
defmod n_Zirku_30_min_Timer notify Bewegungsmelder_unten||Bewegungsmelder_oben {if(Value("Bewegungsmelder_unten")eq "on"||Value("Bewegungsmelder_oben")eq "on"){fhem("set Zirkulationspumpe on-for-timer 600")}}

ganz böse

||

Ein wunder das die das noc nicht um die Ohren geflogen ist

defmod n_Zirku_30_min_Timer notify Bewegungsmelder_unten|Bewegungsmelder_oben {if(Value("Bewegungsmelder_unten")eq "on"||Value("Bewegungsmelder_oben")eq "on"){fhem("set Zirkulationspumpe on-for-timer 600")}}

schon ok so

defmod n_Zirku_30_min_Timer notify (Bewegungsmelder_unten|Bewegungsmelder_oben).(on|off) {if(Value("Bewegungsmelder_unten")eq "on"||Value("Bewegungsmelder_oben")eq "on"){fhem("set Zirkulationspumpe on-for-timer 600")}}


Viel besser
So viel zum Thema RegEx
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 27 Februar 2020, 23:24:16
Wie Marko sagt --> || keine Ahnung wie man darauf kommt. Das wäre rein von der Logik ein ODER - aber das hat im regEx vom Trigger im notify nix zum suchen .... Und ist ein Fall für *Popcorn*

Mein Tip war ja: mach den Eventmonitor auf ...

Du willst ja nur, dass bei on etwas passiert!? Warum auf ALLES oder auf on|off triggern und dann abfragen ob on war?
Ich würde ja erstmal sagen, das sollte gehen, minimalistisch :) genaueres kann nur der Eventmonitor sagen :D
defmod n_Zirku_30_min_Timer notify (Bewegungsmelder_unten|Bewegungsmelder_oben):.on set Zirkulationspumpe on-for-timer 1800

Jetzt willst Du noch, dass dann die Pumpe erstmal 30 min Pause hat, der Dummy Lampe ist doch nur ein Hilfskonstrukt oder?

Also spendieren wir einfach noch eine Pause:
attr n_Zirku_30_min_Timer disabledAfterTrigger 1800

Es ging doch um 30 min = 1800 sec - oder? 600 sec = 10 min ! ::)

BTW: Das etwas scheinbar fast funktioniert - ist doch nicht unbedingt ein festgesetzter Lösungsansatz?

Gruß Otto
Titel: Antw:If Bedingungen
Beitrag von: CoolTux am 28 Februar 2020, 06:03:31
Oh das nur mit on habe ich überlesen.

Das on kommt doch im Reading state oder, ich glaube da greift :.on nicht als RegEx. War glaube :on oder sogar nur .on


Grüße
Titel: Antw:If Bedingungen
Beitrag von: kschi am 28 Februar 2020, 06:38:09
Hey, danke erst einmal für eure vorschläge! Werd ich heute Nachmittag mal ausprobieren. Ich komme halt noch nicht so mit der Syntax klar, wann ein . Ein : oder beides, dann welche klammer... dann einmal nur ein ODER | dann wieder zwei ||...

Die lampe ist nur ein dummy. Wenn die an ist, darf die pumpe nicht angehen, egal,ob die BM anschlagen.
Titel: Antw:If Bedingungen
Beitrag von: CoolTux am 28 Februar 2020, 06:48:06
Das | ist aber kein oder bei einer RegEx. Schau mal im Netz nach Regexpression. Da findest einige Beispiele.
Hier kannst auch testen
https://regex101.com/
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 28 Februar 2020, 09:50:38
@kschi Bitte nicht einfach "blind probieren" sondern versuchen zu verstehen!
Also Eventmonitor auf und Bewegungsmelder_unten auslösen und die Events anschauen. Den Event - der einmalig ist mit dem on - auswählen und ein notify erzeugen lassen. Das ist dann auf alle Fälle der richtige Syntax. Da kannst Du überprüfen ob der Trigger so
(Bewegungsmelder_unten|Bewegungsmelder_oben):.on
oder so
(Bewegungsmelder_unten|Bewegungsmelder_oben):onsein muss. Wahrscheinlich letzteres.

Deinen Einwand mit der Lampe habe ich jetzt wieder nicht mehr verstanden.  :'(
Ich habe die Lampe durch disabledAfterTrigger ersetzt, aber wenn Du unbedingt ne Lampe haben willst!? - müssen wir es anders machen.
Titel: Antw:If Bedingungen
Beitrag von: kschi am 29 Februar 2020, 07:32:58
Hey danke für die Nachhilfe. Ich habe aber tatsächlich mit dem Eventmonitor ein erstes Notify erstellt, deswegen diese Geschichte ohne runden Klammern. Den Rest habe ich mir aus Forenbeiträgen zusammengesammelt und versucht zu verstehen. Als es denn geklappt hat, obwohl es offensichtlich falsch ist, habe ich verstanden... wahrscheinlich immer noch nicht richtig ;-)

Auf jeden Fall geht schon einmal die Pumpensteuerung, wenn BM oben oder unten auslösen. Das Attribut disabledAfterTrigger erscheint mir nicht passend denn wenn jemand im Haus ist und die BM auslöst, soll die Pumpe auf jeden Fall weiterlaufen, bzw den Zeitraum der Laufzeit verlängern. Die Pumpe hört also auf zu laufen, wenn das letzte BM Signal 30 Minuten her ist. Wenn sie ausgegangen ist, soll sie aber auch für eine Zeit aus bleiben und nicht sofort wieder angehen, wenn trotzdem jemand einen BW auslöst. (häufige Schaltvorgänge kurz hintereinander sollen für die Pumpe nicht so toll sein..)

Deswegen meine Idee mit einer Dummylampe die angeht, wenn die Pumpe aus geht. Die Dummylampe bleibt dann eine entsprechende Zeit an. Wobei bei einer Dummylampe das on-for-timer 1800 irgendwie nicht funktioniert? Ich habe es jedenfalls nicht hinbekommen. Alternativ soll sie angehen, ne runde schlafen und danach wieder ausgehen: set Lampe1 on;sleep 1800;set Lampe1 off

Damit die Pumpe auch wieder angeht, wenn die Lampe aus ist, muss das notify n_Zirku_30_min_Timer nicht nur die BW erkennen, sondern erst dann angehen wenn außerdem die Dummylampe aus ist...

Ich versuche mal anhand der richtigen Syntax was hinzubekommen...

Danke erst einmal,
Karsten
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 29 Februar 2020, 09:33:13
Guten Morgen,
es geht eben nichts über eine genaue Beschreibung :)
Du willst also:
Die Pumpe soll angehen, allerdings frühestens nachdem sie 1800 sec aus war.
Die Pumpe soll von den BM solange sie läuft aber sofort immer nachgetriggert werden.

Richtig verstanden?

Das klingt spontan eher nach DOIF damit man nicht einen Sack Geräte hat.
Ich überlege mal mit? Ein Ansatz von meinem Flurlicht zum nachtriggern:
define di_Pumpe DOIF ([Bewegungsmelder_unten:"on"] or [Bewegungsmelder_oben:"on"]) (set Zirkulationspumpe on)(set Zirkulationspumpe off)
attr di_Pumpe do resetwait
attr di_Pumpe wait 0,1800
Jetzt vielleicht noch cmdpause (https://fhem.de/commandref_DE.html#DOIF_cmdpause)? Ist nur erstmal ins unreine gedacht :)
So eventuell? Hab das nicht getestet.
attr di_Pumpe cmdpause 1800

Ich bin unsicher was Deine Events betrifft und wie sich die Zustände wirklich ändern, da die Wirksamkeit der Attribute vom Zustandswechsel abhängen. Muss man am Besten mal mit drei Dummies durchspielen.

Gruß Otto
Titel: Antw:If Bedingungen
Beitrag von: kschi am 04 März 2020, 20:06:34
Hallo Otto,

also ich verzweifle hier und ich steige beim besten Willen durch diese verschachtelte Syntax mit fhem und perl nicht durch...Dazu kommen noch diverse verschachtelte Klammern, das ist ja echt was für Tüftler und Programmierer... Aber ich versuche nicht so schnell aufzugeben...

Ich stecke jetzt in diesem DOIF fest. Momentan habe ich 2 Dummyschalter, die meine BM symbolisieren. Dann habe ich eine Dummypumpe, die Zeit x läuft und diese Dummylampe, die einfach im Hintergrund abgefragt werden soll. Diese Dummylampe geht für Zeit X an, wenn die Pumpe aus geht.

Internals:
   DEF        (Schalter1|Schalter2).(on|off) {if(Value("Schalter1")eq "on"||Value("Schalter2")eq "on"){fhem("set Pumpe on;sleep 10;set Pumpe off")}}

   FUUID      5e57fe2c-f33f-1d52-6a76-640a29839c5e00be
   NAME       n_pumpe
   NR         40
   NTFY_ORDER 50-n_pumpe
   REGEXP     (Schalter1|Schalter2).(on|off)
   STATE      2020-03-04 19:48:37
   TRIGGERTIME 1583347717.88894
   TYPE       notify
   READINGS:
     2020-03-04 19:48:32   state           active
Attributes:


Die Pumpe darf nur angehen, wenn die Dummylampe aus ist und einer der Bewegungsmelder anspricht.

Auf deutsch würde ich das jetzt so sagen:

Mache wenn (Schalter1|Schalter2) angeht, erst mal ne Überprüfung ob (Lampe) aus ist. Wenn Lampe aus, dann mach die Pumpe an. Wenn Lampe an, mach gar nichts.

Mit dem Codeschnipsel unten würde ich das jetzt so schreiben wollen:

define di_Pumpe DOIF ([Schalter1:"on"] or [Schalter2:"on"]) (if(Value("Lampe") eq "off") {fhem("set Pumpe on")}

Aber wie so oft, funktioniert das einfach nicht... Wer kann mir helfen?
Titel: Antw:If Bedingungen
Beitrag von: Otto123 am 04 März 2020, 21:23:12
Du nimmst irgendwie spanisch, ungarisch und deutsch, wirfst jeweils sein paar Brocken in den Becher und schüttest Sie auf den Tisch.
Ich weiß nicht genau wie Du das, wohin schreibst, aber das muss vor Fehlern nur so hageln. :-X
define di_Pumpe DOIF (([Schalter1:"on"] or [Schalter2:"on"]) and [Lampe] eq "off") (set Pumpe on)

Gruß Otto