Autor Thema: Wie merke ich mir einen alten Wert im DOIF?  (Gelesen 491 mal)

Offline The Grue

  • Full Member
  • ***
  • Beiträge: 167
Wie merke ich mir einen alten Wert im DOIF?
« am: 19 Oktober 2021, 18:27:00 »
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

Online Damian

  • Developer
  • Hero Member
  • ****
  • Beiträge: 8812
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #1 am: 19 Oktober 2021, 19:14:23 »
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

Offline The Grue

  • Full Member
  • ***
  • Beiträge: 167
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #2 am: 20 Oktober 2021, 21:00:17 »
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

Offline betateilchen

  • Developer
  • Hero Member
  • ****
  • Beiträge: 17556
  • s/fhem\.cfg/configDB/g
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #3 am: 20 Oktober 2021, 22:05:27 »
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?
-----------------------
Unaufgeforderte Anfragen per email werden von mir nicht beantwortet. Dafür ist das Forum da.
-----------------------
Lesen gefährdet die Unwissenheit!

Online Damian

  • Developer
  • Hero Member
  • ****
  • Beiträge: 8812
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #4 am: 20 Oktober 2021, 22:51:32 »
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.
« Letzte Änderung: 20 Oktober 2021, 22:53:06 von Damian »
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Offline betateilchen

  • Developer
  • Hero Member
  • ****
  • Beiträge: 17556
  • s/fhem\.cfg/configDB/g
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #5 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.
-----------------------
Unaufgeforderte Anfragen per email werden von mir nicht beantwortet. Dafür ist das Forum da.
-----------------------
Lesen gefährdet die Unwissenheit!

Online Damian

  • Developer
  • Hero Member
  • ****
  • Beiträge: 8812
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #6 am: 21 Oktober 2021, 10:54:49 »
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.

Zitat
Der 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

Offline The Grue

  • Full Member
  • ***
  • Beiträge: 167
Antw:Wie merke ich mir einen alten Wert im DOIF?
« Antwort #7 am: 21 Oktober 2021, 16:24:32 »
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 :)

 

decade-submarginal