DoIf Verständnis Fragen: Wie wird Doif abgearbeitet...

Begonnen von rhoffm34, 22 Juni 2021, 20:11:28

Vorheriges Thema - Nächstes Thema

rhoffm34

Hallo zusammen. Ich habe eine Frage: Wie wird folgendes DoIf abgearbeitet

(das ist ein abstraktes Beispiel um die Wirkweise zu verstehen...)

{
if ([$SELF:wert1])
{
fhem("set schalter A");
if ([$SELF:wert2])
{
fhem("set schalter B");
if ([$SELF:wert3])
{
fhem("set schalter C");
if ([$SELF:wert4])
{
fhem("set schalter D");
if ([$SELF:wert5])
{
fhem("set schalter E");
}
}
}
}
}
}


Ausgangssituation: wert1 bis wert5 sind nicht wahr (also == 0, wahr ist == 1).

Ich bin davon ausgegangen wenn wert1 wahr wird kommt "set schalter A" und wartet darauf das wert2 wahr wird um dann "set schalter B" auzuführen um dann auf den wert3 zu warten.

Tatsächlich ist es aber so das wenn wert 1 und wert2 wahr sind und anschließend wert3 wahr wird alles durchgerattert wird bis zu wert3.
Folgendes ist dann im EventMonitor zu beobachten:

2021-06-22 19:33:47 dummy schalter A
2021-06-22 19:33:47 dummy wert1 1
2021-06-22 19:33:49 dummy schalter A
2021-06-22 19:33:49 dummy schalter B
2021-06-22 19:33:49 dummy wert2 1
2021-06-22 19:33:52 dummy schalter A
2021-06-22 19:33:52 dummy schalter B
2021-06-22 19:33:52 dummy schalter C
2021-06-22 19:33:52 dummy wert3 1


Das bedeutet das "set schalter A" dreimal ausgeführt wird obwohl zum Beispiel (wenn schalter A ein Homematic Schalter wäre) der Schalter schon nach dem ersten abarbeiten des DoIf eingeschaltet ist.

Habe ich einen Denkfehler? Wie kann ich es bewerkstelligen das "set schalter A" nur einmal ausgeführt wird?

Viel Grüße

Otto123

Zitat von: rhoffm34 am 22 Juni 2021, 20:11:28
Ich bin davon ausgegangen wenn wert1 wahr wird kommt "set schalter A" und wartet darauf das wert2 wahr wird um dann "set schalter B" auzuführen um dann auf den wert3 zu warten.
Hi,

wie kommst Du zu der Annahme?
Zum Einen: Dein Code ist einfach ein Stück Perl, das wird so abgearbeitet wie es da steht, Wartepositionen gibt es da nicht: Also wenn wahr dann Ausführung. Wenn der erste Ausdruck nie wahr ist passiert niemals etwas!
Zum Anderen: DOIF wird getriggert wenn sich einer der beteiligten Werte ändert. Bei jedem Trigger wird das Stück Perl abgearbeitet.
Die DOIF Spezialität liegt genau darin (ein beteiligter Wert ändert sich: DOIF arbeitet) und in der Notation der Readings im [device:reading] Style.

Wenn Du einzel Abarbeitung willst, musst Du es einzeln schreiben:
{
if () {}
if () {}
if () {}
}


Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

rhoffm34

Hallo Otto,

vielen Dank, ich habe verstanden was Du schreibst.

Wenn dann die Werte wert1 bis wert4 nacheinander wahr werden wird schalterA vier mal geschaltet, obwohl er nur einmal geschaltet werden soll, oder?

{
if ([$SELF:wert1])
{
fhem("set schalterA on");
if ([$SELF:wert2])
{
fhem("set schalterB on");
if ([$SELF:wert3])
{
fhem("set schalterC on");
if ([$SELF:wert4])
{
fhem("set schalterD on");
if ([$SELF:wert5])
{
fhem("set schalterE on");
}
}
}
}
}
}

PS ich habe den Bsp Code noch mal angepasst...

Das ist bei Homematic Geräten dann doof wegen dem Traffic.

Eine Idee wie ich das umgehen kann?


Gruß,

Ralf



Otto123

Hallo Ralf,

also ohne DOIF habe ich "zu Fuß" diese Idee:
define wert1 dummy
define schalterA dummy
define wert2 dummy
define schalterB dummy
define wert3 dummy
define schalterC dummy
define wert4 dummy
define schalterD dummy
define n_test notify wert1:1 set schalterA on;; sleep wert2:1;;set schalterB on;;sleep wert3:1;;set schalterC on;; sleep wert4:1;;set schalterD on
attr schalter.,wert.,n_test room Test

Aber das setzt Deine Aufgabe um und hat nichts damit zu tun DOIF zu verstehen. Ob DOIF dafür eine einfache Lösung hat, weiß ich leider nicht.
mMn ist das was für Modul sequence ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Sany

Hallo Ralf,

2 Auszüge aus der Commandref zu DOIF-Perl:
ZitatEin DOIF-Block wird ausgeführt, wenn dieser bedingt durch Ereignis- und Zeittrigger in eckigen Klammern innerhalb des Blocks, getriggert wird
...und dann ziemlich sicher von "Anfang" bis "Ende" des Blocks.
ZitatEreignis-/Zeittrigger sind intern Perlfunktionen, daher können sie an beliebiger Stelle im Perlcode angegeben werden, wo Perlfunktionen vorkommen dürfen,

In Deinem Beispiel würde ich sagen: allein das $SELF sorgt bei Änderung dafür, daß alle Stellen mit $SELF getriggert werden. Ist die Bedingung dann wahr wird der Ausführungsteil durchlaufen, bis zur nächsten Bedingung, die nicht wahr ist. Das ist so ein wenig wie die leidige Abfrage beim fhem-DOIF auf den state eines Devices, dessen Zustand sich nicht geändert hat, aber andere Readings die Abfrage triggern.
Ich versteh nicht so ganz was Du erreichen willst, aber Du könntest ja mal die Bedingungen als Event-trigger formulieren, die sind dann nur im Moment des Triggers wahr. Oder wie Otto es beschrieb in einzelne Zweige. Und wenn die Abfragen voneinander abhängig sein müssen dann in einzelnen Zweigen die Abfragen bis auf den Trigger mit [? nicht-triggernd schreiben.
Kommt aber wohl auf die Aufgabenstellung an, wie man das dann löst.

Gruß

Sany
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....