Hauptmenü

Ersatz für 'sleep'

Begonnen von ChristianKnorr, 22 September 2014, 22:10:23

Vorheriges Thema - Nächstes Thema

ChristianKnorr

Hallo zusammen,
ich habe ein Script im Einsatz bei dem ich oft den sleep Befehl verwende.
Nun führt dies zum Erliegen des fhem-Prozesses bis das Script abgearbeitet ist.
Wie kann ich das besser machen?

Wecker_Onkyo {
  fhem("set wz_Onkyo on");
  foreach (0..2) {
    fhem("sleep 1;set wz_Onkyo volume 0;");
  }
  fhem("set wz_Onkyo input network;");
  fhem("set wz_Onkyo remoteControl internet-radio-preset %;");
  my $volmax = Value("Wecklautstaerke_max");
  my $sleep = 20;

  foreach my $vol (0..$volmax) {
    fhem("set wz_Onkyo volume $vol;");
    fhem("sleep $sleep;");
  }
}


Danke schonmal und viele Grüße,
Christian...

rudolfkoenig

FHEM-sleep gefolgt von einem Befehl startet dieses Befehl mit einem internen Timer,  ist also sowas wie ein at ohne Namen, und blockiert FHEM nicht. FHEM-sleep ohne ein FHEM-Befehl dahinter ist nichts anderes als ein perl-sleep, und blockiert FHEM. Man sollte die Finger davon lassen.

foreach (0..2) {
    fhem("sleep 1;set wz_Onkyo volume 0;");
}

sollte equivalent sein mit
fhem("sleep 1; set wz_Onkyo,wz_Onkyo,wz_Onkyo volume 0");

Und wenn man statt
  foreach my $vol (0..$volmax) {
    fhem("set wz_Onkyo volume $vol;");
    fhem("sleep $sleep;");
  }

den folgenden Code verwendet:
  foreach my $vol (0..$volmax) {
    fhem("sleep ".($sleep*$volmax)."; set wz_Onkyo volume $vol;");
  }

dann sollte FHEM nicht blockieren.

ChristianKnorr

Okay danke, habe ich geändert und werde es testen.

hanske

Hallo,

ich hatte folgende Konstruktion, die ebenfalls FHEM für die Sleepzeit komplett lahmlegte:
define n_doorOpen notify ms_abc:.level.* IF ([dm_door] eq "off")(set dm_door on, sleep 300, set dm_door off,)
habe es dann gegen ein define xyz at +00... ersetzt.
Ich dachte sleep wäre nur auf Perl Ebene nicht erlaubt, hier gibt es aber anscheinend auch Probleme.
Raspberry Pi (Wheezy), Aeon Labs Z-Wave USB Stick 2, HM-USB Adapter, EBUS 2.0 mit Wemos
diverse HM und Z-Wave Geräte

marvin78

Das könnte ein Problem mit dem IF Befehl sein. Machst du es so, wird es wohl keine Probleme geben:

define n_doorOpen notify ms_abc:.level.* {if (Value("dm_door") eq "off") {fhem("set dm_door on;sleep 300;set dm_door off")}

rudolfkoenig

Vermutlich verwendet IF nicht AnalyzeCommandChain fuer die komplette Befehlsfolge, sondern ruft fuer jedes Befehl AnalyzeCommand auf.

hanske

Hallo,

ich habe noch ein Problem mit dem Einfrieren von Fhem gefunden.
Ich wollte einem zickigen Schalter, der nicht immer reagiert, mit mehreren Aufrufen auf die Sprünge helfen.
Dazu habe ich folgendes notify geschrieben: 

define n_forceOff notify dm_sw1:off {for my $i (0..5){ fhem("set sw_wall off;;sleep 5;;get sw_wall swbStatus");;last if (Value("sw_wall") eq "off")}}

Leider hilft das auch nicht weiter.
Ich habe den Eindruck, dass der Fhem Haupthread dann auch während der Abarbeitung steht.
Im Log steht dann:

2015.01.22 21:48:33 2: After sleep: Timeout reading answer for get swbStatus
2015.01.22 21:48:33 2: ZWave get sw_wall swbStatus
2015.01.22 21:48:36 2: After sleep: Timeout reading answer for get swbStatus
2015.01.22 21:48:36 2: ZWave get sw_wall swbStatus
...

Es sieht für mich so aus als ob das Sleep Fhem dazu bringt, die Antwort auf swbStatus zu verpassen.

Gibt es für das Problem eine elegantere Lösung?
Ich hatte schon an ein sich selbst aufrufendes notify mit einem define at +*00:00:05 gedacht. Dafür bräuchte ich aber einen globalen Zähler um das ganze zu begrenzen.
Raspberry Pi (Wheezy), Aeon Labs Z-Wave USB Stick 2, HM-USB Adapter, EBUS 2.0 mit Wemos
diverse HM und Z-Wave Geräte

rudolfkoenig

Dein Programm ruft "set sw_wall off" 6 mal auf (dirkt hintereinander, ohne Pause), wartet 5 Sekunden, und fragt anschliessend 6 mal nach dem Status. Mir faellt auch keine "elegante" (== kurze) Variante dazu ein.
get swbStatus ist mWn bei richtig durchgefuehrten Association nicht notwendig.

hanske

Ok, das heißt der Parser, der das Sleep interpretiert, löst es aus der Schleife heraus.
Die Schleife wird dann also nicht so abgearbeitet, wie man es von außen betrachtet erwarten würde.
So etwas wie
{fhem("set sw_wall off;;sleep 5;;set sw_wall off;;")}
würde dann das "off" auch direkt hintereinander ausführen?
Ich versuche dann mal einen anderen Ansatz.
Der Schalter ist ein ZWave von Düwi, der leider seinen Zustand nicht unaufgefordert zurückliefert. Insbesondere bekommt Fhem das nicht mit bei lokaler Änderung oder bei einem Auslösen von anderen assoziierten Geräten.

Raspberry Pi (Wheezy), Aeon Labs Z-Wave USB Stick 2, HM-USB Adapter, EBUS 2.0 mit Wemos
diverse HM und Z-Wave Geräte

rudolfkoenig

Ist das eine Sparversion wg. Lizenzkosten in der USA? Das "FHEM sleep" (im Gegensatz zum perl sleep) ist eine einfache Variante eines "FHEM define XX at +...", siehe commandref Eintrag

hanske

Den Witz mit den USA habe ich leider nicht verstanden :(

Meine Frage war:

Würde so etwas wie
{fhem("set sw_wall off;;sleep 5;;set sw_wall off;;")}

dann das "off" auch zweimal direkt hintereinander ausführen und dann erst das sleep?

So hattest Du es ja bei der Schleife erklärt.
Raspberry Pi (Wheezy), Aeon Labs Z-Wave USB Stick 2, HM-USB Adapter, EBUS 2.0 mit Wemos
diverse HM und Z-Wave Geräte

hanske

Ach so, jetzt habe ich es kapiert.
Nein, der Düwi Schalter ist aus Deutschland, würde sonst auch gar nicht mit den anderen Komponenten laufen.
Dass der Status nicht ordentlich gemeldet wird, stand hier auch schon mal im Forum.
Raspberry Pi (Wheezy), Aeon Labs Z-Wave USB Stick 2, HM-USB Adapter, EBUS 2.0 mit Wemos
diverse HM und Z-Wave Geräte

der-Lolo

ich habe mir das so gemerkt und hoffe das es richtig ist:
ein semikolon - befehle werden gleichzeitig ausgeführt
zwei semikolons - befehle werden nacheinander ausgeführt

rudolfkoenig

Nicht wirklich.
Der Parser teilt die Zeile nach einmal Semikolons auf (;), und fuehrt die Einzelteile der Reihe nach aus.
Wenn man eine mit ; getrennte Befehlsfolge einem Befehl wie at oder notifyals Argument uebergeben moechte, dann muss man diese Befehlsfolge mit ;; trennen. Daraus macht der Parser vor dem Aufruf des Befehls ein einfaches ;. Was dieser (FHEM-)Befehl damit macht (sofort ausfuehren oder erst spaeter), haengt vom aufgerufenen Befehl selbst ab.

Ausnahme (Hack) ist der sleep Befehl (in FHEM!). Dieser kennt den Parser, und fischt ihm beim Ausfuehren die bereits aufgeteilten und noch zur Ausfuehrung anstehenden Befehle weg, damit man als Benutzer nicht mit ;; sich rumaergern aergen muss. Damit ist der sleep mit einem namenlosen at Befehl zu vergleichen.

Navigator

Kann man diese Sleeps trotzdem sichtbar machen oder gar löschen? Ich habe einen Sleep 3000 angestoßen, weil in der CommandRef Beschreibung Millisekunden zu lesen ist. In der Syntax steht zwar dann "sec", daß habe ich aber geschickt überlesen.  ;D