Ausführen eines Befehls nach Verlassen eines DOIF-Zustands

Begonnen von timtom, 21 April 2017, 15:26:43

Vorheriges Thema - Nächstes Thema

timtom

Hallo zusammen,

ich bin dabei meine Heizungssteuerung weiter zu optimieren. Derzeit nutze ich folgendes vereinfachtes DOIF zur Ansteuerung von LightScenes
di_ZuhauseStatusLS DOIF (
[Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "Abwesend")\
  (set ZuhauseStatusLS scene SummerAbsent) DOELSEIF \
([Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "Zuhause")\
  (set ZuhauseStatusLS scene SummerHome) DOELSEIF \
([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "Abwesend")\
  (set ZuhauseStatusLS scene WinterAbsent) DOELSEIF \
([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "Gone")\
  (set ZuhauseStatusLS scene WinterGone) DOELSEIF \
([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "Zuhause")\
  (set ZuhauseStatusLS scene WinterHome) DOELSEIF \
attr di_ZuhauseStatusLS do always


Das funktioniert soweit schon mal gut. Mit ist jedoch aufgefallen, dass wenn ich aus dem Status "Winter+Gone" komme, noch einen Zwischenbefehl anstoßen möchte. Dieser wird nicht benötigt, wenn ich zwischen den anderen Status wechsele. Laut Commandref sollte es bei DOIF ein Reading last_cmd geben. Dies finde ich dort aber nicht.
Gibt es noch noch eine andere Möglichkeit?

Ellert

Das Reading last_cmd wird nur im Zusammenhang mit set disable gesetzt, um bei set enable den vorherigen Zustand zu setzen.

Das Reading state wird erst nach der Befehlsauführung auf den geänderten Zustand gesetzt, daher könntest Du in die betreffenden Zweige eine IF-Abfrage einbauen

(IF ($cmd = 5) (<Zwischenbefehl>), set ZuhauseStatusLS scene ... )

ComputerZOO

Moin moin,
passt hier vielleicht nur bedingt rein (aber dafür will ich kein neues Thema aufmachen). Wie kann ich:
Log 3, "DIES IST EIN TEXT FÜR DAS LOGFILE, LEVEL 3;
in ein DOIF einfügen?

Ellert

Zitat von: ComputerZOO am 22 April 2017, 11:23:47
Moin moin,
passt hier vielleicht nur bedingt rein (aber dafür will ich kein neues Thema aufmachen). Wie kann ich:
Log 3, "DIES IST EIN TEXT FÜR DAS LOGFILE, LEVEL 3;
in ein DOIF einfügen?
Schau mal unter "Angaben im Ausführungsteil" nach.

ComputerZOO

Danke  ;)
Lösung: {Log 3, "DIES IST EIN TEXT FÜR DAS LOGFILE, LEVEL 3}

timtom

Zitat von: Ellert am 21 April 2017, 18:15:02
Das Reading last_cmd wird nur im Zusammenhang mit set disable gesetzt, um bei set enable den vorherigen Zustand zu setzen.

Das Reading state wird erst nach der Befehlsauführung auf den geänderten Zustand gesetzt, daher könntest Du in die betreffenden Zweige eine IF-Abfrage einbauen

(IF ($cmd = 5) (<Zwischenbefehl>), set ZuhauseStatusLS scene ... )
Ok, prima. Danke. Kann man das alles auch noch irgendwie "schicker" lösen? Also außer den beiden Möglichkeiten?
1) Dein Vorschlag wäre es ja, in das DOIF jeweils noch ein IF einzuschachteln.
2) Man müsste die das gesamte DOIF-Konstrukt duplizieren und und jeweils 1x mit $cdm=5 und ohne machen

Ellert

zu 2): Nein, der Zwischenbefehl wird nur ausgeführt, wenn vorher der Status 5 war, der set-Befehl immer.

timtom

Zitat von: Ellert am 22 April 2017, 15:55:28
zu 2): Nein, der Zwischenbefehl wird nur ausgeführt, wenn vorher der Status 5 war, der set-Befehl immer.
Sorry, da hab ich mich wohl missverständlich ausgedrückt. Ich hatte hierbei an sowas gedacht.

...
DOIF [Heizungsmodus:state] eq "Sommer" and ($cmd = 5)
  (set Zwischenbefehl)
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF  [Heizungsmodus:state] eq "Sommer"
  (set ZuhauseStatusLS scene SummerAbsent)
...


Rein theoretisch würde ja deine IF-Lösung gehen. Hier geht es mit wohl eher um den Programmierstil ;)

Ellert

Zitat($cmd = 5)

Die runden Klammern sind nicht erforderlich (s. Rangfolge von Operatoren)
"=" ist ein Zuweisungsoperator, kein Vergleichsoperator, s. DOIF-Doku Ereignissteuerung

timtom

Ok, d.h.
...
DOIF [Heizungsmodus:state] eq "Sommer" and [$SELF:state] eq "5"
  (set Zwischenbefehl)
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF  [Heizungsmodus:state] eq "Sommer" and [$SELF:state] ne "5"
  (set ZuhauseStatusLS scene SummerAbsent)
...


oder so?

...
DOIF [Heizungsmodus:state] eq "Sommer"
  (IF ([$SELF:state] eq "5") (<Zwischenbefehl>))
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF...


Ellert

Fast richtig  ;)

[$SELF:cmd] == 5 oder [$SELF] eq "cmd_5" oder [$SELF:state] eq "cmd_5" oder $cmd == 5

Auch so, weil "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."
...
DOIF [Heizungsmodus:state] eq "Sommer" and $cmd eq "5"
  (set Zwischenbefehl)
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF  [Heizungsmodus:state] eq "Sommer"
  (set ZuhauseStatusLS scene SummerAbsent)
...

timtom

Danke. Ich möchte es ja auch in paar Monaten auch noch verstehen. Also entweder paar Bedingungen mehr oder Kommentare ;)

Dann werd ich das die Tage mal testen.

Per

#12
Müssen die Bedingungen gesammt nicht mehr in runde Klammern?
...
DOIF ([Heizungsmodus:state] eq "Sommer" and $cmd eq "5")
  (set Zwischenbefehl)
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF  ([Heizungsmodus:state] eq "Sommer")
  (set ZuhauseStatusLS scene SummerAbsent)
...

timtom

Zitat von: Per am 25 April 2017, 13:39:41
Müssen die Bedingungen gesammt nicht mehr in runde Klammern?
Ups, habe ich im "richtigen" Code natürlich auch gemacht ;)

timtom

Zitat von: Ellert am 24 April 2017, 15:44:33
Fast richtig  ;)

Also, nach etwas hin und her sieht es jetzt so aus. Passt das oder habe ich da einen Denkfehler drin?
define di_ZuhauseStatusLS DOIF ([Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "KurzWeg") ## Wechsel der LightScenes im Sommer-Modus
  (set ZuhauseStatusLS scene SummerAbsent)
DOELSEIF ([Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "LangeWeg")
  (set ZuhauseStatusLS scene SummerGone)
DOELSEIF ([Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "Zuhause")
  (set ZuhauseStatusLS scene SummerHome)
DOELSEIF ([Heizungsmodus:state] eq "Sommer" and [ZuhauseStatus:state] eq "Auto")
  (set ZuhauseStatusLS scene SummerAuto)
DOELSEIF (([Heizungsmodus:state] eq "Winter" and [ZuhauseStatusLS:state] =~ "Summer") ##Schaltet die Thermostate erst in den Auto-Modus, wenn man von einer Summer- in eine Winter-LightScene wechselt
  (set ZuhauseStatusLS scene WinterAuto)
DOELSEIF ([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "KurzWeg")
  (IF ([ZuhauseStatusLS:state] eq "WinterGone") (set ZuhauseStatusLS scene WinterAuto), set ZuhauseStatusLS scene WinterAbsent) ##Schaltet die Thermostate erst in den Auto-, wenn diese vorher im Energiespar-Modus waren
DOELSEIF ([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "LangeWeg")
  (set ZuhauseStatusLS scene WinterGone)
DOELSEIF ([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "Zuhause")
  (IF ([ZuhauseStatusLS:state] eq "WinterGone") (set ZuhauseStatusLS scene WinterAuto), set ZuhauseStatusLS scene WinterHome) ##Schaltet die Thermostate erst in den Auto-, wenn diese vorher im Energiespar-Modus waren
DOELSEIF ([Heizungsmodus:state] eq "Winter" and [ZuhauseStatus:state] eq "Auto")
  (set ZuhauseStatusLS scene WinterAuto)