FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: uron am 11 März 2023, 13:18:58

Titel: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 11 März 2023, 13:18:58
Hallo Gemeinde,
ich bastele nun seit Stunden an einer Schaltlogik und bekomme sie nicht ans Laufen.

Die gewünschte Schaltlogik ist folgende, ich beschreibe sie zunächst mal mit meinen Worten:
wenn ((Wert der Variablen a >1100) oder (Wert der Variablen a > 20 und Wert der Variablen b >500))
dann (wenn Variable c < 23 schalte ShellyPlugS on, sonst schalte ShellyPlugS off)

Variable a = Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn")
Variable b = Value("LeistungsmesserShellyPlugS:KW:.*")
Variable c = Value("controme.0.14.actualTemperature")

Fehler: Wenn Wert der Variablen a < 20 und Variable b > 500, schaltet ShellyPlugS nicht wieder auf off

Meine nicht funktionierende Syntax lautet wie folgt:
define PVLuefterONOFF notify powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn {if ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 20) && (Value("LeistungsmesserShellyPlugS:KW:.*") > 500))) {if(Value("controme.0.14.actualTemperature") <23) {fhem ("set LeistungsmesserShellyPlugS on")} else {fhem ("set LeistungsmesserShellyPlugS off")}}}

Fehlen da Klammern, sind sie falsch gesetzt oder was mache ich falsch? Könnt ihr mir helfen?

Update1:
Ich habe meine Befehlsfolge nochmals ein wenig umgebaut, ohne dass sie nun funktioniert - Hintergrund ist nun die Abfrage in der UND-Bedingung, ob ShellyPlugS bereits eingeschaltet ist:
powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn {if ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {if(Value("controme.0.14.actualTemperature") <23) {fhem ("set LeistungsmesserShellyPlugS on")} else {fhem ("set LeistungsmesserShellyPlugS off")}}}

Fehlerbeschreibung neu:
Fehler: Wenn Wert der Variablen a < 20 und ShellyPlugS = on, schaltet ShellyPlugS nicht wieder auf off

Update2:
Ich habe meine Befehlsfolge erneut geändert und die Temperatur-Abfrage vor dem "set ...... on" weggelassen.
Im Moment schaltet die Befehlsfolge den ShellyPlugS korrekt aus, wenn die Bedingungen entsprechend erfüllt sind. Morgen führe ich weitere Tests durch und gebe hoffentlich das finale OK:
{if ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {fhem ("set LeistungsmesserShellyPlugS on")} else {fhem ("set LeistungsmesserShellyPlugS off")}}

Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 11 März 2023, 20:55:07
Wie oft triggert bei dir powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn?
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 06:06:52
alle 60 Sekunden!

Ich könnte die Temperaturabfrage Value("controme.0.14.actualTemperature") natürlich auch 2x in die if-Abfrage bei jedem ODER einbauen - das sollte gelingen - aber ich sehe es sportlich und wollte diese Temperaturbedingung nur einmal "einbauen".

Die eigentliche Frage ist ja die: kann ich in der Ausführungsanweisung noch ein "if" unterbringen. Wenn JA, wie?
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 12 März 2023, 08:23:11
Zitat von: uron am 12 März 2023, 06:06:52
alle 60 Sekunden!
Dir ist bewusst, dass du ggf. alle 60 Sekunden deinen Aktor schaltest?
Zitat
Die eigentliche Frage ist ja die: kann ich in der Ausführungsanweisung noch ein "if" unterbringen. Wenn JA, wie?

genauso, wie du den if schon verwendet hast: if (...) {...}


Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 09:01:50
OK, stimmt mit dem minütlichen Schalten des Aktors, darauf hatte ich bislang noch keine Augenmerk gerichtet.
Nun habe ich dies Problem dann doch wieder mit einer if-Abfrage in der Ausführungsanweisung gelöst. Lt. Eventmonitor ist die Schalthäufigkeit nun auf das Minimum reduziert.

Hiermit teste ich nun unter den verschiedensten Bedingungen und werde zu gegebener Zeit berichten:
{if ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "off") {fhem ("set LeistungsmesserShellyPlugS on")}} else {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"){fhem ("set LeistungsmesserShellyPlugS off")}}}

Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: MadMax-FHEM am 12 März 2023, 09:09:31
Mal unabhängig vom bislang geführten Gespräch:

Wie soll das funktionieren?

(Value("LeistungsmesserShellyPlugS:KW:.*")


EDIT: RegEx bei Value (ebenso wie ReadingsVal, ReadingsNum, AttrVal usw.) wäre mir neu, dass das ginge...

Zusätzlich: Value() "frägt" STATE ab also ein Internal kein Reading!
Besser ReadingsVal() bzw. ReadingsNum()

EDIT: bzgl. Value() https://forum.fhem.de/index.php/topic,132625.msg1267426.html#msg1267426

Gruß, Joachim
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 12 März 2023, 09:21:09
Zitat von: uron am 12 März 2023, 09:01:50
OK, stimmt mit dem minütlichen Schalten des Aktors, darauf hatte ich bislang noch keine Augenmerk gerichtet.
Nun habe ich dies Problem dann doch wieder mit einer if-Abfrage in der Ausführungsanweisung gelöst. Lt. Eventmonitor ist die Schalthäufigkeit nun auf das Minimum reduziert.

Hiermit teste ich nun unter den verschiedensten Bedingungen und werde zu gegebener Zeit berichten:
{if ((Value("powerfox2.0.devices.XXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "off") {fhem ("set LeistungsmesserShellyPlugS on")}} else {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"){fhem ("set LeistungsmesserShellyPlugS off")}}}

Ich mache sowas etwas kürzer:

define di_shelly DOIF ([powerfox2.0.devices.XXXXXXXX.currentFeedIn] > 1100 or [powerfox2.0.devices.XXXXXXXXXX.currentFeedIn] > 20) (set LeistungsmesserShellyPlugS on) DOELSE (set LeistungsmesserShellyPlugS off)

Ach ja, hier wird nur einmal geschaltet, ein weiteres if kann man sich sparen ;)
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 15:02:35
Zitat von: MadMax-FHEM am 12 März 2023, 09:09:31
Mal unabhängig vom bislang geführten Gespräch:

Wie soll das funktionieren?

(Value("LeistungsmesserShellyPlugS:KW:.*")


EDIT: RegEx bei Value (ebenso wie ReadingsVal, ReadingsNum, AttrVal usw.) wäre mir neu, dass das ginge...

Zusätzlich: Value() "frägt" STATE ab also ein Internal kein Reading!
Besser ReadingsVal() bzw. ReadingsNum()

EDIT: bzgl. Value() https://forum.fhem.de/index.php/topic,132625.msg1267426.html#msg1267426

Gruß, Joachim
Oh Danke, ich glaubte, mit ReadingsVal () könnte ich auch Readings abfragen - wieder mal etwas gelernt!
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 15:05:06
Zitat von: Damian am 12 März 2023, 09:21:09
Ich mache sowas etwas kürzer:

define di_shelly DOIF ([powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn] > 1100 or [powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn] > 20) (set LeistungsmesserShellyPlugS on) DOELSE (set LeistungsmesserShellyPlugS off)

Ach ja, hier wird nur einmal geschaltet, ein weiteres if kann man sich sparen ;)

Klingt einfacher, allerdings fehlt mir bei der Bedingung "[powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn] > 20" das und "LeistungsmesserShellyPlugS = on" oder lese ich das nicht richtig?
Nachteil: da powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn alle 60s getriggert wird, schalte ich das Device auch alle 60s, oder?
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: MadMax-FHEM am 12 März 2023, 15:05:24
Zitat von: uron am 12 März 2023, 15:02:35
Oh Danke, ich glaubte, mit ReadingsVal () könnte ich auch Readings abfragen - wieder mal etwas gelernt!

Natürlich, wie der Name sagt ;)

Aber auch hier gilt: es muss ein Devicename und ein Readingname sein! Kein RegEx!

Gruß, Joachim
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: RalfRog am 12 März 2023, 15:16:56
Zitat von: uron am 12 März 2023, 15:02:35
Oh Danke, ich glaubte, mit ReadingsVal () könnte ich auch Readings abfragen - wieder mal etwas gelernt!

Wie MadMAx geschrieben hat sollte man sich den ReadingsNum auch merken, der hat manchmal durchaus auch Vorteile. Ich vergess den auch immer wieder.
=> ReadingsNum(<devicename>,<reading>, <defaultvalue>,<round>)

Gruß Ralf
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 15:26:53
an alle: ihr seid so gut, meine Defizite auszumerzen  ;)
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 12 März 2023, 16:49:09
Zitat von: uron am 12 März 2023, 15:05:06
Klingt einfacher, allerdings fehlt mir bei der Bedingung "[powerfox2.0.devices.XXXXXXXX.currentFeedIn] > 20" das und "LeistungsmesserShellyPlugS = on" oder lese ich das nicht richtig?

Du möchtest LeistungsmesserShellyPlugS auf on schalten wenn es schon on ist? Da musst du deine Logik noch mal überdenken. ;)

Zitat
Nachteil: da powerfox2.0.devices.XXXXXXXX.currentFeedIn alle 60s getriggert wird, schalte ich das Device auch alle 60s, oder?

oder! ;)

Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 12 März 2023, 17:54:42
Zitat von: Damian am 12 März 2023, 16:49:09
Du möchtest LeistungsmesserShellyPlugS auf on schalten wenn es schon on ist? Da musst du deine Logik noch mal überdenken. ;)

oder! ;)
Du liegst richtig, die Logik kam ursprünglich aus dem Gedanken, immer wenn getriggert wird (alle 60s), schalte ich den Sollstatus (Schalter) neu - das kann man besser machen, da gebe ich dir Recht.

Die eigentliche Problemstellung ist die, dass ich einen 1000W-Verbraucher dann einschalten will, wenn meine PV-Anlage mindestens 1100W Überschuss produziert.
Wenn der 1000W-Verbraucher aber eingeschaltet ist, sollte der Überschuss 20W nicht unterschreiten - über die Grenzwerte kann man streiten.

Eine elegantere Logik wäre sicher die: Wenn 1100W PV-Überschuss, dann soll der Verbraucher eingeschaltet werden wenn er aus ist. Ist der PV-Überschuss < 20W ist und der Verbraucher eingeschaltet, soll er ausgeschaltet werden.
Titel: Antw:Logikproblem mit if else und mehreren Bedingungen
Beitrag von: uron am 18 März 2023, 21:00:53
So, nach einigen erfolgreichen Tests unter Realbedingungen gebe ich hier nun meinen Lösung bekannt und kennzeichne demgemäß auch das Thema als solches - vielleicht interessiert es ja einmal jemanden.
define PVLuefterONOFF notify powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn {if ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "off") {fhem ("set LeistungsmesserShellyPlugS on")}} else {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"){fhem ("set LeistungsmesserShellyPlugS off")}}}

Danke für die Unterstützung im Forum auf dem Weg zur Lösung auch wenn ich vielleicht einen komplizierteren Weg gegangen bin.
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Stephan27 am 12 Juni 2023, 15:33:05
Zitat von: Damian am 12 März 2023, 09:21:09
Zitat von: uron am 12 März 2023, 09:01:50OK, stimmt mit dem minütlichen Schalten des Aktors, darauf hatte ich bislang noch keine Augenmerk gerichtet.
Nun habe ich dies Problem dann doch wieder mit einer if-Abfrage in der Ausführungsanweisung gelöst. Lt. Eventmonitor ist die Schalthäufigkeit nun auf das Minimum reduziert.

Hiermit teste ich nun unter den verschiedensten Bedingungen und werde zu gegebener Zeit berichten:
{if ((Value("powerfox2.0.devices.XXXXXXXX.currentFeedIn") > 1100) || ((Value("powerfox2.0.devices.XXXXXXXX.currentFeedIn") > 20) && (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"))) {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "off") {fhem ("set LeistungsmesserShellyPlugS on")}} else {if (ReadingsVal("LeistungsmesserShellyPlugS", "state", "n.a.") eq "on"){fhem ("set LeistungsmesserShellyPlugS off")}}}

Ich mache sowas etwas kürzer:

define di_shelly DOIF ([powerfox2.0.devices.XXXXXXXX.currentFeedIn] > 1100 or [powerfox2.0.devices.XXXXXXXXXX.currentFeedIn] > 20) (set LeistungsmesserShellyPlugS on) DOELSE (set LeistungsmesserShellyPlugS off)
Ach ja, hier wird nur einmal geschaltet, ein weiteres if kann man sich sparen ;)

Hallo Damian,

vielen Dank für diesen Einwurf.
Ich versuche gerade was ähnliches wie der TE und bin da eher an deinem Ansatz interessiert.

"DOELSE (set LeistungsmesserShellyPlugS off)" ist ein "Trigger" auf den "State" eines Device oder kann ich damit einen beliebigen "Setter" ansprechen?
Bei mir wäre das Device z.B. "vitoconnect" und das bringt den Set "ww_einmaliges_aufladen" (active/ deactive) mit. Könnte ich also einfach "set ww_einmaliges_aufladen active" machen?
Was mache ich wenn Readings, "Getter oder Setter" nicht eindeutig sind? Also wenn ich z.B. Vitoconnect1 und Vitoconnect2 haben und beide haben den SET für ww_einmaliges_aufladen?
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 12 Juni 2023, 16:42:02
Zitat von: Stephan27 am 12 Juni 2023, 15:33:05Hallo Damian,

vielen Dank für diesen Einwurf.
Ich versuche gerade was ähnliches wie der TE und bin da eher an deinem Ansatz interessiert.

"DOELSE (set LeistungsmesserShellyPlugS off)" ist ein "Trigger" auf den "State" eines Device oder kann ich damit einen beliebigen "Setter" ansprechen?
Bei mir wäre das Device z.B. "vitoconnect" und das bringt den Set "ww_einmaliges_aufladen" (active/ deactive) mit. Könnte ich also einfach "set ww_einmaliges_aufladen active" machen?
Was mache ich wenn Readings, "Getter oder Setter" nicht eindeutig sind? Also wenn ich z.B. Vitoconnect1 und Vitoconnect2 haben und beide haben den SET für ww_einmaliges_aufladen?


Du kannst einen beliebigen FHEM-Befehl angeben, der auch in der in der Kommandozeile funktioniert, das muss noch nicht mal ein set-Befehl sein. Sollte es ein Perl-Befehl sein, dann musst du statt runder Klammern geschweifte nehmen. In der Commandref zu DOIF findest du unzählige Beispiele.
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Stephan27 am 12 Juni 2023, 16:56:07
Zitat von: Damian am 12 Juni 2023, 16:42:02
Zitat von: Stephan27 am 12 Juni 2023, 15:33:05...

Perfekt, Dankeschön.
Ich hatte es im Prinzip richtig adaptiert "set <device> <"SETTER"> activate" und wenn man am Ende den Status noch richtig schreibt, dann klappt es nicht nur mit dem Nachbarn, sondern auch mit der bedingungsabhängigen Steuerung von Geräten im FHEM. :-) 

Welche boolsche Logik-Operatoren kennt FHEM denn? Im commandref und auch google hilft mir gerade nicht.
|| (or) und && (and) ist ja schon verwendete. Ich denke XOR (^^ ?)  und AND NOT (!& ?) wäre vlt. noch ganz nützlich.


Edit2:
Kann man das mit den Klammer so machen?

(([MQTT_HAUS_XXX:SML_Power_act] < -3000 and [vitoconnect:WW-Isttemperatur] < 48) or ([MQTT_HAUS_XXX:SML_Power_act] < -100 and [vitoconnect:WW-einmaliges_Aufladen] == 1)) (set vitoconnect WW-einmaliges_Aufladen activate) DOELSE (set vitoconnect WW-einmaliges_Aufladen deactivate)(steht jetzt so im DEF von meinem DOIF)

Also
Wenn der Hauszähler mehr als 3kw Ausspeisung meldet UND die WW-Temperatur kleiner 48°c ODER wenn der Zähler mehr als 100 Watt Ausspeisung meldet und WW aktiv ist dann soll er WW machen, sonst soll er ausschalten.

P.S.: rein logisch würde mir das Einschaltsignal reichen und dann kann er einmal durchackern, ich möchte aber auch verhindern dass er in den Netzbezug geht. Normalerweise brauche ich meinen Speicher nicht so "heiß", aber der PV-Überschuss soll halt doch irgendwo noch sinnvoll genutzt werden.

Es scheint erstmal zu funktionieren.
Ob das mit den Bedingungen so passt sehe ich aber wahrscheinlich erst Morgen.
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 12 Juni 2023, 22:32:44
Die Bedingung wird vom Perl-Interpreter ausgewertet, daher ist alles möglich, was Perl kennt und das ist schon sehr viel. Auch die Reihenfolge der Auswertung ist festgelegt, siehe z. B. :

http://perl-seiten.privat.t-online.de/html/perl_op.html
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Stephan27 am 14 Juni 2023, 10:16:58
Zitat von: Damian am 12 Juni 2023, 22:32:44Die Bedingung wird vom Perl-Interpreter ausgewertet, daher ist alles möglich, was Perl kennt und das ist schon sehr viel. Auch die Reihenfolge der Auswertung ist festgelegt, siehe z. B. :

http://perl-seiten.privat.t-online.de/html/perl_op.html


Besten Dank.

Mein DOIF scheint zu funktionieren, wobei er zu schnell hin und her "prellt" und ständig ein und aus schaltet.
Ich habe jetzt mal das Attribut cmdpause mit 300:300 gesetzt in der Hoffnung, dass damit beide Befehle/ Bedingungen für 5 Minuten nicht überprüft werden.
Sollte passen?

Und vlt. gerade noch dazu.
Auf wieviele Werte bezieht sich denn die Funktion des Median? Ich überlege gerade ob ich einen Average z.B. über 30 Sekunden/ Werte einsetze oder ich den Median nutzen kann? (geht um Momentanverbrauch des Stromzähler)
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Damian am 14 Juni 2023, 11:18:30
Zitat von: Stephan27 am 14 Juni 2023, 10:16:58
Zitat von: Damian am 12 Juni 2023, 22:32:44Die Bedingung wird vom Perl-Interpreter ausgewertet, daher ist alles möglich, was Perl kennt und das ist schon sehr viel. Auch die Reihenfolge der Auswertung ist festgelegt, siehe z. B. :

http://perl-seiten.privat.t-online.de/html/perl_op.html


Die Anzahl der ausgewerteten Werte wird hinter avg bzw. med angegeben, so steht des in der Commandref.

Besten Dank.
Mein DOIF scheint zu funktionieren, wobei er zu schnell hin und her "prellt" und ständig ein und aus schaltet.
Ich habe jetzt mal das Attribut cmdpause mit 300:300 gesetzt in der Hoffnung, dass damit beide Befehle/ Bedingungen für 5 Minuten nicht überprüft werden.

Und vlt. gerade noch dazu. Auf wieviele Werte bezieht sich denn die Funktion des Median? Ich überlege gerade ob ich einen Average z.B. über 30 Sekunden/ Werte einsetze oder ich den Median nutzen kann. (geht um Momentanverbrauch des Stromzähler)
Titel: Aw: (gelöst) Logikproblem mit if else und mehreren Bedingungen
Beitrag von: Stephan27 am 14 Juni 2023, 11:22:26
Ahh okay,
da habe ich mich durch das Beispiel vom Median in der Commandref ablenken lassen und dachte der funktioniert anders als der Average.