Hallo zusammen,
ich habe mir ein Script gebaut, was regelmäßig meinen Hausstatus prüft und ggf. notwendige Anpassungen vornimmt (bspw.: Garagentor schließen).
Sofern eine Statusänderung angestoßen wurde, muss das script kurz warten (bei Garage etwas länger) und dann den Sollstatus nochmal prüfen.
Aktuell habe ich es nach der Logik etwa so:
1) Prüfe, ob Sollstatus
2) Wenn Sollstatus != IST status und Änderung kann vorgenommen werden --> Ändern
3) Wenn Änderung angestoßen, warte X Sekunden
4) Prüfe ob Sollstatus = IstStatus
4.1) Wenn ungleich, dann E-Mail Nachricht
Leider klappt das bei meinem Garagentor nicht und ich weiß nicht was da los ist.
if ($deviceIstStatus ne $deviceSollStatus)
{
$logPrefix="[NOT OK]";
#IstStatus entspricht nicht dem Sollstatus
$body = "<h2>".$mailSubject."</h2>";
$body = $body. "<br/>". aktuelleZeit() . ": Status vorher: " . $deviceName . ": ".$deviceIstStatus." (ReadingsTime: ".$deviceIstTimestamp.")";
# Soll der Status korrigiert werden?
if ($setState ne "")
{
Log 1, "[deviceStateAutoReset] Setze neuen Status: ".$deviceName. " Status: ".$setState. " Wartezeit: ".$waitSecondsForNewState;
fhem("set ".$deviceName." ".$setState);
#Warten, damit das Device geschaltet werden kann (z.B. bei Garagentor)
sleep($waitSecondsForNewState);
$body = $body. "<br/>". aktuelleZeit() . ": Status neu: " . $deviceName . ": ". ReadingsVal($deviceName, $stateVal,'valuerror'). " (ReadingsTime: ". ReadingsTimestamp($deviceName, $stateVal,'valuerror').")";
if ($deviceSollStatus eq ReadingsVal($deviceName, $stateVal,'valuerror'))
{
$mailSubject = "[INFO] " . $mailSubject ." - Erfolgreich";
$body = $body. "<br/><br/>";
$body = $body. "Erfolgreich.";
}
else
{
$mailSubject = "[ERROR] " . $mailSubject ."- Statusänderung fehlgeschlagen";
}
}
Könnt ihr mir helfen?
Außerdem stimmen die Uhrzeiten auch nicht, die ich auslese mit aktuelleZeit()
Garage schließen
03.04.2022 16:04:31: Status: Garage_Tor: open (ReadingsTime: 2022-04-03 16:30:48)
03.04.2022 16:04:01: Status aktuell: Garage_Tor: closing (ReadingsTime: 2022-04-03 16:32:31)
Funktion: deviceStateAutoReset
Kann es sein, dass sleep fhem komplett blockt und auch der neue Status nicht ordentlich ausgelesen werden kann?
Ich danke euch schon mal
Zitat von: flipse am 03 April 2022, 19:10:08
Kann es sein, dass sleep fhem komplett blockt und auch der neue Status nicht ordentlich ausgelesen werden kann?
Ja ein Perl sleep blockiert.
Leider fehlt die Info wo Du diesen Code aufrufst. Du solltest diese Logik in FHEM abbilden.
Pack den Teil hiernach: fhem("set ".$deviceName." ".$setState) in eine extra Perl sub und ändere den Befehl in der Art:
fhem("set $deviceName $setState ; sleep $waitSecondsForNewState; {DeineSub()}")
Hier wird ein FHEM Sleep verwendet, das blockiert nicht.
Gruß Otto
Warten in FHEM in Perl programmiert geht nur über Timer.
Hallo flipse,
was Du machen willst geht, und zwar so, wir als schema unten im code beschrieben. Du musst das sleep "$waitSecondsForNewState" in einen fhem befehl packen, und danach die perl sub "check_if_sollstatusEQiststatus" aufrufen, die den check macht.
Der code ist nur beispielhaft, also nicht funktionsfähig, aber vom Prinzip funktioniert das so.
fhem ("sleep $waitSecondsForNewState; {check_if_sollstatusEQiststatus()}");
sub Sollstatus {
# => Code hier für prüfung ob Sollstatus != IST status und Änderung kann vorgenommen werden --> Ändern
if ($deviceIstStatus ne $deviceSollStatus) {
if ($setState ne ""){
fhem("set ".$deviceName." ".$setState);
fhem ("sleep $waitSecondsForNewState; {check_if_sollstatusEQiststatus()}");
}
}
}
sub check_if_sollstatusEQiststatus {
if ($deviceSollStatus eq ReadingsVal($deviceName, $stateVal,'valuerror'))
{
$mailSubject = "[INFO] " . $mailSubject ." - Erfolgreich";
$body = $body. "<br/><br/>";
$body = $body. "Erfolgreich.";
}
else
{
$mailSubject = "[ERROR] " . $mailSubject ."- Statusänderung fehlgeschlagen";
}
}
danke, das werde ich gleich versuchen.
eine frage: Kann ich denn auch innerhalb des fhem("") Befehls einen Rückgabewert definieren, den ich in der Sub einer Variablen zuweise, damit ich in der eigentlichen Sub weitermachen kann?
z.B.
$sollstatus = fhem ("sleep $waitSecondsForNewState; {check_if_sollstatusEQiststatus()}");
check_if_sollstatusEQiststatus hat natürlich einen return Value
Der Sinn des FHEM sleep ist, den Block rauszunehmen. Das was nach dem sleep kommt wird separat ausgeführt.
Du willst im Moment der Ausführung ein Feedback Deiner Sub? Das wird so nix. Du willst so wieder eine Warteschleife.
Das was Jamo geschrieben hat ist der Weg.
define DOIF_HUE_CTRL_Ankleide DOIF (\
([00:00 - 10:00])\
and\
([MQTT2_zigbee_Motion:Motion_01_occupancy] eq "true")\
and\
([MQTT2_zigbee_Motion:Motion_01_illuminance] < 3000)\
)\
\
(\
(set HUEDevice29 bri 250)\
(set HUEDevice30 bri 250) \
({fhem("set HUEDevice29 on")})\
({fhem("set HUEDevice30 on")})\
)\
\
DOELSEIF\
(\
([10:00 - 23:59])\
and\
([MQTT2_zigbee_Motion:Motion_01_occupancy] eq "true")\
and\
([MQTT2_zigbee_Motion:Motion_01_illuminance] < 3000)\
)\
\
(\
(set HUEDevice29 bri 250)\
(set HUEDevice30 bri 250) \
({fhem("set HUEDevice29 on")})\
({fhem("set HUEDevice30 on")})\
)\
\
\
DOELSEIF\
(\
## ([04:50 - 23:00])\
## and\
(\
([MQTT2_zigbee_Motion:Motion_01_occupancy] eq "false")\
)\
)\
\
(\
({fhem("set HUEDevice29 off")})\
({sleep(0.3);; fhem("set HUEDevice30 off")})\
)\
attr DOIF_HUE_CTRL_Ankleide DbLogExclude .*
attr DOIF_HUE_CTRL_Ankleide do resetwait
attr DOIF_HUE_CTRL_Ankleide room 99.92 HUE_CTRL
jetzt macht ihr mir Angst...
Würde der Sleep Aufruf in dem DOIF (letzte Zeile) FHEM blockieren?
Wait funktioniert lieder nicht, und ich verstehe nicht warum, darum der Workarround.
Danke
Thomas
{sleep(0.3);; fhem("set HUEDevice30 off")}
Das blockiert FHEM fuer 0.3 Sekunden.
{fhem("sleep 0.3;; set HUEDevice30 off")}
Das sollte ohne blockieren funktionieren, da das FHEM sleep Befehl den Rest der Kommandozeile merkt, und diesen nach 0.3 Sekunden (per internen Timer) aufruft.
Man kann es auch mit dem vorherigen Befehl zusammenfassen:
{fhem("set HUEDevice29 off;; sleep 0.3;; set HUEDevice30 off")}
Also falls ich die Logik noch richtig aus den vielen Zeilenumbrüchen rauslesen konnte :)
könnte man die "Sprünge" aus fhem nach perl und zurück nach fhem komplett, sowie einige der vielen Klammern weglassen:
...
DOELSEIF ([04:50 - 23:00] and [MQTT2_zigbee_Motion:Motion_01_occupancy] eq "false")\
( set HUEDevice29 off" ;; sleep 0.3;; set HUEDevice30 off" )
Achtung die doppelten ;; sind für die Raw DEF!
Danke... bei mir scheint das auf die Schnell zu klappen, aber nur mit einem ; statt zwei ;;
Danke, das kappt nun..., ihr seid die Besten.
Zitat von: Docter am 05 Mai 2025, 15:08:14aber nur mit einem ; statt zwei ;;
Naja wie schreibe ich es :) das ewige Missverständnis...
Du hast Raw Def gepostet - ich habe für Raw Def geschrieben. Wenn Du es in die DEF schreibst, darf es nur ein ; sein. Die \ als Zeilenfortsetzung darf man in die DEF auch nicht schreiben die gehören nur in die Raw Def.
Danke, hatte es irgendwann begriffen.
Mir ist nun auch klar, warum das wait nicht ging..
Der Fehler lag bei mir. Ich dachte bei Hue setze ich mit bri150 die Helligkeit, aber mir war nicht klar, daß damit das Leutmittel sofort angeht.
Egal, bin froh was gelernt zu haben und das nun ohne Wait zu können.
Danke.