Wie merke ich mir einen alten Wert im DOIF?

Begonnen von The Grue, 19 Oktober 2021, 18:27:00

Vorheriges Thema - Nächstes Thema

The Grue

Servus!

Um mein Thermostat via Fenstersensor aus- und - je nach vorherigem Zustand - wieder einzuschalten möchte ich mir im DOIF den Wert merken, wenn das Fenster geöffnet wird. Ich dachte, das geht irgendwie so:


defmod Patio.Door.Sensor_DOIF_1 DOIF ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.open$"]) \
({$SELF.previous_mode = ReadingsVal(Livingroom.Thermostat,"thermostatMode", "")})


Geht nicht, sagt das Log:

2021.10.19 18:18:32 1: ERROR evaluating {Patio.Door.Sensor_DOIF_1.previous_mode = ReadingsVal(Livingroom.Thermostat,"thermostatMode", "")}: Bareword "Patio" not allowed while "strict subs" in use at (eval 9838623) line 1.

Ah, strict.. Also hilft vielleicht ein my?

defmod Patio.Door.Sensor_DOIF_1 DOIF ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.open$"]) \
({my $SELF.previous_mode = ReadingsVal(Livingroom.Thermostat,"thermostatMode", "")})


Nö:

2021.10.19 18:20:10 1: ERROR evaluating {my Patio.Door.Sensor_DOIF_1.previous_mode = ReadingsVal(Livingroom.Thermostat,"thermostatMode", "")}: No such class Patio at (eval 9838902) line 1, near "{my Patio"
syntax error at (eval 9838902) line 1, near "my Patio."


Wie mache ich das denn richtig?

cu
Markus

Damian

Im DOIF FHEM-Modus gibt es keine Instanzvariablen, die bis zum nächsten Trigger überleben würden. Du kannst dir den Zustand in einem Reading des DOIF merken. Das geht bekanntlich mit dem FHEM-Befehl: setreading
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

The Grue

Danke, jetzt habe ich eine funktionierende Version :)

defmod Livingroom.ThermostatControl DOIF ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.open$"])  \
(setreading Livingroom.ThermostatControl OldMode  [Livingroom.Thermostat:state], set Livingroom.Thermostat tmOff) \
DOELSEIF ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.closed$"])  \
(set Livingroom.Thermostat [Livingroom.ThermostatControl:OldMode]) \
DOELSE ()


Jetzt habe ich aber eine neue Frage... in einem neuen Thread.

cu
Markus

betateilchen

Zitat von: Damian am 19 Oktober 2021, 19:14:23
Im DOIF FHEM-Modus gibt es keine Instanzvariablen, die bis zum nächsten Trigger überleben würden.

Nur interessehalber: Könnte man nicht den genau dafür (user data) in FHEM vorgesehenen hash %data verwenden?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Damian

#4
Zitat von: betateilchen am 20 Oktober 2021, 22:05:27
Nur interessehalber: Könnte man nicht den genau dafür (user data) in FHEM vorgesehenen hash %data verwenden?
ja, genau das macht der DOIF-Perlmodus. Dort kann man Variablen nutzen, die im Hash des Devices abgelegt werden. Damit der User nicht mit dem hash hantieren muss, kann er einfach $_ voranstellen oder $VAR{<Variable>} angeben. In beiden Fällen wird die Variable im hash angelegt ist damit eine Instanzvariable des definierten DOIF-Devices.

z. B. $_bla="text" wird direkt bei der Definition in $hash->{var}{bla}="text" übersetzt.

Da er aber hier mit FHEM-Modus arbeitet, kann er ruhig im FHEM-Modus bleiben - ist halt etwas weniger performant als reines Perl.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

betateilchen

Ich fürchte, wir reden aneinander vorbei.
Aber da der User seine Aufgabenstellung gelöst hat, brauchen wir das hier nicht weiter zu vertiefen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Damian

Zitat von: betateilchen am 21 Oktober 2021, 10:36:26
Ich fürchte, wir reden aneinander vorbei.
Aber da der User seine Aufgabenstellung gelöst hat, brauchen wir das hier nicht weiter zu vertiefen.

Man kann auch %data nutzen.

ZitatDer eigentliche Zweck von %data ist dem Nutzer eine Möglichkeit zum Speichern von temporären Daten im globalen Kontext zu ermöglichen. Einige Module verwenden %data jedoch auch um modul- & geräteübergreifend Daten auszutauschen.

Wäre aber nicht meine Empfehlung, da global und nicht gekapselt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

The Grue

Ich hab' jetzt doch den Perl-Modus verwendet, weil das Speichern des states nicht immer funktioniert hat. So sollte es jetzt universell funktionieren:

defmod Livingroom.ThermostatControl DOIF { \
  if ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.open$"]) \
  { \
    my $thermostatMode = ReadingsVal("Livingroom.Thermostat", "thermostatMode", "");; \
    $_OldMode = "tm" . ucfirst($thermostatMode);; \
    fhem_set("Livingroom.Thermostat tmOff");; \
  } \
  if ([Patio.Door.Sensor:"^alarm:.AccessControl:.Window/Door.is.closed$"]) \
  { \
    fhem_set("Livingroom.Thermostat ". $_OldMode);; \
  } \
}


Da ist das $_ schon sehr praktisch :)