Frage zu Sleep und Block von Fhem

Begonnen von flipse, 03 April 2022, 19:10:08

Vorheriges Thema - Nächstes Thema

flipse

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

Otto123

#1
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
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Damian

Warten in FHEM in Perl programmiert geht nur über Timer.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Jamo

#3
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";
}
}
Bullseye auf iNUC, Homematic + HMIP(UART/HMUSB), Debmatic, HUEBridge, Zigbee/Conbee III, FB7690, Alexa (fhem-lazy), Livetracking, LaCrosse JeeLink, LoRaWan / TTN / Chirpstack, Sonos, ESPresence

flipse

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

Otto123

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.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Docter

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

rudolfkoenig

{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")}

Otto123

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!
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Docter

Danke... bei mir scheint das auf die Schnell zu klappen, aber nur mit einem ; statt zwei ;;

Docter

Danke, das kappt nun..., ihr seid die Besten.

Otto123

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.
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Docter

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.