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


rudolfkoenig

Als Endbenutzer kann man die sleeps nicht loeschen.

Die deutsche Uebersetzung der Doku war falsch, da hat man meine englische Doku missverstanden. Ich habe jetz beide Versionen ueberarbeitet.

Damian

Ich frage mich warum sleep ohne angehängten Befehl überhaupt das System blockiert. In solchem Falle wäre wahrscheinlich nichts tun die bessere Alternative.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

justme1968

und noch eine warnung ausspucken.

gruß
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Naja, sleep hat mWn angefangen als "echter" sleep Ersatz. Die Funktion als namensloser at kam spaeter dazu.

Seid ihr sicher, dass die urspruengliche Funktion eine Warnung verdient?
Damit muesste auch die Doku umformuliert werden.

Damian

Zitat von: rudolfkoenig am 21 Juli 2015, 16:48:18
Naja, sleep hat mWn angefangen als "echter" sleep Ersatz. Die Funktion als namensloser at kam spaeter dazu.

Seid ihr sicher, dass die urspruengliche Funktion eine Warnung verdient?
Damit muesste auch die Doku umformuliert werden.

Die Warnung ist eine Sache, aber:

Ein echter Sleep macht in einem "echten" Multitasking-System Sinn. Aber wer braucht ein stehendes FHEM?

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

justme1968

gibt es denn eine wirklich sinnvolle verwendung für das sleep ohne argumente oder macht es mehr probleme als es löst?

wen der meinung ist sein fhem lahm legen zu müssen kann das ja immer noch mit {sleep 10} machen.

gruss
andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Ok, kommt auf die TODO Liste, hoffentlich ist sourceforge irgendwannmal soweit.
Leider haben sie SVN ganz am Ende der Prio-Liste gesetzt.

JudgeDredd

Hallo Zusammen,

ich grabe das Thema hier nochmal aus, da ich bei der Suche nach einer Lösung noch nicht fündig geworden bin.

Ich möchte gerne genau das gleiche Vorhaben wie der Threadersteller (ChristianKnorr) umsetzen.
Sprich einen Wecker der in Stufen die Lautstärke anhebt.

Leider kam zu dem Vorschlag von "rudolfkoenig" hierzu kein Feedback.
Ich habe aber nun den Code:
  foreach my $vol (0..$volmax) {
    fhem("sleep ".($sleep*$volmax)."; set wz_Onkyo volume $vol;");
  }

mal ausprobiert und muss leider sagen, das es bei mir nicht funktioniert.

Bei dem Beispiel, blockiert FHEM zwar nicht, aber zuerst wird der SLEEP gemacht und danach läuft die Schleife in einem Rutsch durch.
Ein "langsames" anheben der Lautstärke erfolgt also leider nicht.

Hat sich bei der Problemlösung in den letzten 2,5 Jahren hierzu etwas in FHEM getan ?
Kann mir jemand einen Tip geben wonach ich suchen muss, oder gibt es nach wie vor keine Möglichkeit dies umzusetzen ?

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Hyper-V | Debian 12 (VM)

justme1968

nach wie vor gibt es die von rudolf vorgeschlagene variante die auch funktioniert wenn man den code vervollständigt und z.b. $sleep richtig setzt.

eine zweite variante ist in diesem thread: https://forum.fhem.de/index.php?topic=51906.0 beschrieben.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

fl_Indigo

nochmal für einen laien wie mich:

ist dieser aufruf von sleep in einem DOIF blockierend oder nicht?


([Temperaturen:AnforderungPelletsofen] eq "EIN") (sleep 61; set TelegramBot message Pelletsofen gestartet! Kesselstart {([HC_Pelletsofen:countsPerDay]);} heute)
DOELSEIF
([Temperaturen:AnforderungPelletsofen] eq "AUS") (sleep 61; set TelegramBot message Pelletsofen gestoppt! Laufzeit {(my $langezahl=([HC_Pelletsofen:pulseTimeEdge]/3600); my $kurzezahl=sprintf "%.1f", $langezahl;
return $kurzezahl;)} Stunden)

CoolTux

Nein ist nicht blockierend. Aber Du solltest im DOIF besser das DOIF eigene sleep verwenden. Das ist das Attribut wait.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net