Hauptmenü

Funktionsablauf

Begonnen von TM4889, 20 Mai 2018, 13:36:37

Vorheriges Thema - Nächstes Thema

TM4889

Ich habe mal eine kurze Frage bezüglich des DOIF-Funktionsablaufes aus dem Wiki. https://wiki.fhem.de/w/images/1/18/DOIF_Aufbau_Ablauf_nSVG.png

Gibt es eine Möglichkeit die Schrittkette nach Start der Befehlsausführung fortzusetzen ohne auf Beendigung des Befehls zu warten?
In meinem Fall wird nur ein Script gestartet, welches jedoch Readings ändert die als Trigger für das DOIF dienen. Somit erfolgt nach Reading-Änderung keine erneute Ausführung des DOIF.

Ich habe mir jetzt erstmal damit beholfen, dass ich im Script ein temporäres AT anlege und dieses dann die Readings ändert. Hat jemand eine bessere Idee, falls das oben genannte nicht möglich ist?

Ellert

Schon mal do always, checkall oder selftrigger probiert?

Damian

Am besten den set-Befehl mit wait verzögern und das Attribut selftrigger wait setzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Zitat von: TM4889 am 20 Mai 2018, 13:36:37Hat jemand eine bessere Idee
Du könntest den konkreten Code posten, dann müsste man keine so globale Tipps geben.

TM4889

Verzögerung mit wait und selftrigger bringt keine Änderung. Dadurch wird meines erachtens nur der Aufruf des Scriptes verzögert.

Diese Funktion ändert am Ende das Reading in einem Dummy, welches über das DOIF überwacht wird. Das DOIF sollte dann den Status eines Gerätes ändern, da liegt aber der Fehler. Dies geschieht nicht, da das DOIF du Funktion unten aufgerufen hat und in dem Moment noch nicht abgeschlossen wurde.

Der auskommentierte Teil am Codeende ist die Problemstelle. Ich habe mir derzeit erstmal mit dem AT darunter beholfen.


## Fenster-"offen"-Erkennung
sub HZG_HMSECRHS_WindowOpen($$$) {
my ($MANAGEMENT_DEVICE, $EVENT_DEVICE, $EVENT) = @_;

#my $Event_Room = $EVENT_DEVICE; $Event_Room =~ s/\..*//g;
my $ControlDevice = $MANAGEMENT_DEVICE; $ControlDevice =~ s/(_Management)//g;
my $ClimaDevice = $ControlDevice; $ClimaDevice =~ s/(Control)/Clima/g;
my $Event_Value = $EVENT; $Event_Value =~ s/(.*: )//g; $Event_Value =~ s/( .*)//g;
my $WinOpen_State = ReadingsVal("$ControlDevice","window_open","???");
my $WinOpen_DeviceName = $ControlDevice."_winopen";

if (($WinOpen_State ne "off") || ($WinOpen_State ne "on") || ($WinOpen_State ne "set_on") || ($WinOpen_State ne "???")) {
$WinOpen_State = "???";
}
   
if (($Event_Value eq "open") || ($Event_Value eq "tilted")) {
fhem ("set $ControlDevice window_open set_on");
   
my $winopen_delay = ReadingsVal("Parameter_Heizung","winopen_delay","00:00:00");
my $winopen_dT = ReadingsVal("Parameter_Heizung","winopen_dT",0);

my $CurrentMode = ReadingsVal($ControlDevice,"controlMode","???");
my $CurrentMesuredTemp = ReadingsVal($ClimaDevice,"measured-temp","???");
my $dT_winopen = $CurrentMesuredTemp - $winopen_dT;

if (($WinOpen_State eq "off") || ($WinOpen_State eq "???")) {
fhem (" define tmpAT.on_$WinOpen_DeviceName at +$winopen_delay { \n" .
  " my \$CurrentMode=ReadingsVal(\"$ControlDevice\",\"controlMode\",\"???\");; \n" .
  " my \$CurrentSetpoint=ReadingsVal(\"$ClimaDevice\",\"desired-temp\",0);; \n" .
  " fhem (\"set $ControlDevice controlMode winopen;; \n" .
  " set $ControlDevice window_open on;; \n" .
  " set $ControlDevice before_ControlMode \$CurrentMode;; \n" .
  " set $ControlDevice before_DesiredTemp \$CurrentSetpoint\");; \n" .
  " if(defined \$defs{'tmpAT.on_$WinOpen_DeviceName'}){fhem(\"delete tmpAT.on_$WinOpen_DeviceName\")};; \n" .
  " if(defined \$defs{'tmpNotify.on_$WinOpen_DeviceName'}){fhem(\"delete tmpNotify.on_$WinOpen_DeviceName\")}}");
fhem (" attr tmpAT.on_$WinOpen_DeviceName room Funktionen");
fhem (" attr tmpAT.on_$WinOpen_DeviceName group tmp_Heizung");

fhem (" define tmpNotify.on_$WinOpen_DeviceName notify $ClimaDevice:measured-temp:.* { \n" .
  " my \$CurrentTemp=ReadingsVal(\"$ClimaDevice\",\"measured-temp\",0);; \n" .
  " if (\$CurrentTemp <= $dT_winopen) { \n" .
  " fhem (\"set tmpAT.on_$WinOpen_DeviceName execNow\");; \n" .
  " if(defined \$defs{'tmpAT.on_$WinOpen_DeviceName'}){fhem(\"delete tmpAT.on_$WinOpen_DeviceName\")};; \n" .
  " if(defined \$defs{'tmpNotify.on_$WinOpen_DeviceName'}){fhem(\"delete tmpNotify.on_$WinOpen_DeviceName\")} }}");
fhem (" attr tmpNotify.on_$WinOpen_DeviceName room Funktionen");
fhem (" attr tmpNotify.on_$WinOpen_DeviceName group tmp_Heizung");
}
}

elsif ($Event_Value eq "closed") {
if (($WinOpen_State eq "set_on") || ($WinOpen_State eq "???")) {
if (defined $defs {"tmpAT.on_$WinOpen_DeviceName"}) {fhem ("delete tmpAT.on_$WinOpen_DeviceName")};
if (defined $defs {"tmpNotify.on_$WinOpen_DeviceName"}) {fhem ("delete tmpNotify.on_$WinOpen_DeviceName")};
fhem ("set $ControlDevice window_open off");
}

my $ModeBefore = ReadingsVal($ControlDevice,"before_ControlMode",0);
my $TempBefore = ReadingsVal($ControlDevice,"before_DesiredTemp",0);


my $DeviceModes = AttrVal($ControlDevice,"setList",0);
$DeviceModes =~ s/.*controlMode://; # alle Einträge bis 'controlMode' entfernen
$DeviceModes =~ s/ .*//g; # alle Einträge nach 'controlMode' entfernen
my $isValidMode = 0;
my @arrayDeviceModes = split(/,/,$DeviceModes);
foreach (@arrayDeviceModes){
if ($ModeBefore eq $_) {$isValidMode = 1}
}
if ($isValidMode == 0) {$ModeBefore = "auto"}

if (($WinOpen_State eq "on") || ($WinOpen_State eq "???")) {
if (defined $defs {"tmpAT.on_$WinOpen_DeviceName"}) {fhem ("delete tmpAT.on_$WinOpen_DeviceName")};
if (defined $defs {"tmpNotify.on_$WinOpen_DeviceName"}) {fhem ("delete tmpNotify.on_$WinOpen_DeviceName")};
#fhem ("set $ControlDevice controlMode $ModeBefore");

#if ($TempBefore > ReadingsVal("$ClimaDevice","desired-temp","???")) {
# fhem ("set $ClimaDevice desired-temp $TempBefore");
#}
#fhem ("set $ControlDevice window_open off");
#fhem ("set $ControlDevice before_ControlMode ???");
#fhem ("set $ControlDevice before_DesiredTemp ???");

fhem (" define tmpAT.off_$WinOpen_DeviceName at +00:00:01 { \n" .
  " if ($TempBefore > ReadingsVal(\"$ClimaDevice\",\"desired-temp\",\"???\")) { \n" .
  " fhem (\"set $ClimaDevice desired-temp $TempBefore\")} \n" .
  " fhem (\"set $ControlDevice controlMode $ModeBefore;; \n" .
  " set $ControlDevice before_ControlMode ???;; \n" .
  " set $ControlDevice before_DesiredTemp ???;; \n" .
  " set $ControlDevice window_open off\");; \n" .
  " if(defined \$defs{'tmpAT.off_$WinOpen_DeviceName'}){fhem('delete tmpAT.offa_$WinOpen_DeviceName')}}");
fhem (" attr tmpAT.off_$WinOpen_DeviceName room Funktionen");
fhem (" attr tmpAT.off_$WinOpen_DeviceName group tmp_Heizung");
}
}
}

Per

Warum rufst du den Befehlsteil nicht direkt auf, statt den überwachten Dummy zu ändern?

Im Übrigen sehe ich nirgends ein DOIF...

TM4889

Zitat von: Per am 24 Mai 2018, 11:48:39
Warum rufst du den Befehlsteil nicht direkt auf, statt den überwachten Dummy zu ändern?

Im Übrigen sehe ich nirgends ein DOIF...

Es soll als Funktionserweiterung für ein HM-CC-RT-DN dienen. Da die Readings von ihm in zur Anzeige in Readinggroups und in FTUI dienen soll, war es so gedacht: Clima Channel aktualisiert Reading im Dummy (auto, manual, set_auto, etc.), wenn andere Betriebsart in Dummy gesetzt wird als wie der Clima-Standard, hat das Reading im Dummy Vorrang und wird nicht mehr vom Clima Channel aktualisiert (außer am Thermostat selbst wird umgestellt). Hatte dies anfangs anstatt des DOIF mit einem Notify gelöst, wodurch ich jedoch eine Endlosschleife hatte.

Das DOIF hatte ich vergessen.

##<~ 1. set controlMode ~>
##<~ 2. set WindowOpen  ~>
define BAD.HKTH.001_Control_Management DOIF \
(["BAD.HKTH.001_Clima:controlMode"] or ["BAD.HKTH.001_Control:controlMode"]) { \
HZG_HMCCRTDN_changeControleMode ("$SELF", "$DEVICE", "$EVENT") \
} \
DOELSEIF (["BAD.FDK.001:contact"]) { \
HZG_HMSECRHS_WindowOpen ("$SELF", "$DEVICE", "$EVENT") \
}
attr BAD.HKTH.001_Control_Management do always
attr BAD.HKTH.001_Control_Management room Funktionen
attr BAD.HKTH.001_Control_Management group Heizung
#define_end