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
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
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
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?
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.
Ich fürchte, wir reden aneinander vorbei.
Aber da der User seine Aufgabenstellung gelöst hat, brauchen wir das hier nicht weiter zu vertiefen.
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.
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 :)