[GELÖST] Warum funktioniert sleep nicht in myUtils?

Begonnen von Invers, 29 März 2017, 00:49:23

Vorheriges Thema - Nächstes Thema

Invers

Da ich keine passende Stelle finde, frage ich mal hier nach:
Warum funktioniert das sleep nicht in folgender Perl-Zeile in MyUtils?

    if ($kanalSoll > $kanalIst) {foreach my $i ($kanalIst..$kanalSoll) {fhem("say $i; sleep 1; set Rollo_Plus push; set DU_FB_aktiv on-for-timer 10;")}};


Nach meinem Verständnis sollte fhem nach jedem Schleifenschritt 1 Sekunde warten, geht aber nicht. Rennt einfach durch. Bei der Testansage  kommt nur 1 und 4, 2 und 3 werden ausgelassen, also wird nicht gewartet.

Hat jemand einen Tipp für mich? Danke im Voraus.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

amenomade

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Invers

Das hatte ich bereits getan, bevor ich hier fragte. Leider habe ich keine Lösung gefunden. Deshalb frage ich ja hier.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

CoolTux

Dein sleep ist ein fhem sleep und hat mit der Schleife nichts zu tun. Das sleep sollte aber eine Verzögerung zwischen der Befehlsverarbeitung von say und set machen.
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

Invers

Ja, das ist auch mein Plan gewesen. Die Schleife wird aber mehrfach durchlaufen. Insofern sollte die Verzögerung doch auch mehrfach auftreten und der Befehl auch mehrfach abgearbeitet werden. Was passiert aber offenbar nicht. Die Schleife wird durchgezählt, also theoretisch auch abgearbeitet. Der Zähler wird ja auch erhöht. Die Verzögerung tritt nicht auf. Ich will quasi bei der Abarbeitung eines jeden Zählers in der Schleife eine Pause erzeugen. Kann es sein, dass sleep innerhalb einer Schleife nicht mehrfach funktioniert?
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

DeeSPe

#5
Die kannst Dir den per fhem auszuführenden Befehl durch die Schleife erst komplett als String zusammenstellen und nach der Schleife zur Ausführung bringen.
Ich benutze das in einer Sonnenaufgangssimulation.
Etwa so:
if ($kanalSoll > $kanalIst)
{
  my $cmd;
  foreach my $i ($kanalIst..$kanalSoll)
  {
    $cmd .= "sleep 2;" if ($cmd);
    $cmd .= "say $i; set Rollo_Plus push; set DU_FB_aktiv on-for-timer 10;";
  }
  fhem $cmd;
}


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Thorsten Pferdekaemper

Hi,
das sleep schickt den ganzen Rest sozusagen in den Hintergrund. D.h. es werden erst alle 3 say-Kommandos ausgeführt und dann erst das, was jeweils nach dem sleep kommt. Der Ablauf ist also ungefähr folgendermaßen:

say 1
say 2
say 3
say 4
(hier vielleicht noch ein bisschen Pause)
set Rollo_Plus push
set DU_FB_aktiv on-for-timer 10
set Rollo_Plus push
set DU_FB_aktiv on-for-timer 10
set Rollo_Plus push
set DU_FB_aktiv on-for-timer 10
set Rollo_Plus push
set DU_FB_aktiv on-for-timer 10

Ich vermute mal, dass "say" schnell hintereinander sich unter Umständen verschluckt.
Um Dir richtig zu helfen müsste man vielleicht etwas mehr Kontext wissen...
Gruß,
   Thorsten

FUIP

justme1968

das sleep sorgt dafür das das nachfolgende kommando auf halde gelegt wird bis es dran ist. der code aussenrum (deine schleife) läuft sofort weiter. das ist auch gut so weil sonst dein komplettes fhem für die ganze zeit blockiert wäre. fhem ist nicht multithreaded.

einen möglichen weg wie man das angehen kann findest du in diesem thread: https://forum.fhem.de/index.php/topic,51906.msg436451.html#msg436451

oder du schaust dir mal das ROLLO modul aus dem wiki an.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

Invers

OK, habe ich verstanden. Sleep verzögert ausschliesslich den einen nachfolgenden Befehl. Schade.
Das Modul Rollo kann ich leider für meine Aufgabe nicht nutzen. Ich muss das richtige Rollo immer über den zugehörigen Kanal der FB ansteuern. Diesen Kanal muss ich also zuerst wählen. Das sollte diese Schleife erledigen, was nun aber leider so nicht geht. Ich habe noch keinen Plan, was ich nun machen könnte. Mal überlegen.

Danke für die Erklärungen.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

Thorsten Pferdekaemper

Zitat von: Invers am 29 März 2017, 09:39:55Diesen Kanal muss ich also zuerst wählen. Das sollte diese Schleife erledigen, was nun aber leider so nicht geht. Ich habe noch keinen Plan, was ich nun machen könnte. Mal überlegen.
Schau Dir den Beitrag von DeeSPe an. Das müsste im Prinzip gehen, vielleicht ein bisschen umsortiert.
Gruß,
   Thorsten
FUIP

Invers

Danke für eure Mühe und Geduld. Bin halt blutiger Perl Anfänger.

Ich habe mal das Beispiel von DeeSpee probiert, bekomme jedoch eine Fehlermeldung, die ich nicht deuten oder beseitigen kann, da ich noch zu wenig Durchblick habe.

Can't modify constant item in concatenation (.) or string at ./FHEM/99_myUtils.pm line 699, near ""sleep 2;" if"

Da ich Teile genau dieser Zeile: cmd .= "sleep 2;" if ($cmd); nicht verstehe, bitte ich um einen Tipp, oder eine Korrektur.
Mein Verständnis scheitert hier am Teil if ($cmd) . Welche Bedingung greift denn hier?

Danke für die Geduld.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

Thorsten Pferdekaemper

Hi,
vor alle "cmd" muss ein "$". Also z.B.:

$cmd .= "sleep 2;" if ($cmd);

So etwas wie

... if ($cmd);

bedeutet grob gesagt "...wenn $cmd nicht leer".
Gruß,
   Thorsten
FUIP

Invers

Dann hätte ich if ($cmd) eher am Zeilenanfang erwartet, weil ja in mir bekannten Programmiersprachen immer if...then benutzt wird. Aber wich werde versuchen, das zu vertiefen. Dankeschön.
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2

Thorsten Pferdekaemper

Zitat von: Invers am 29 März 2017, 10:37:58
Dann hätte ich if ($cmd) eher am Zeilenanfang erwartet, weil ja in mir bekannten Programmiersprachen immer if...then benutzt wird.
Dann willkommen bei Perl...
Soweit ich weiß ist es so: Wenn man das if am Anfang hat, dann braucht man danach {}. Wenn man aber nur ein Statement hat, dann kann man die {} weglassen und schreibt das if danach.
Das mag etwas ungewöhnlich sein, ist aber ein ganz normales Perl-Idiom.
Gruß,
   Thorsten
FUIP

Invers

@Thorsten Pferdekaemper
Dein Code funktioniert hervorragend.
Auch die Erklärung zum if habe ich nun verstanden.
Meinen äusserst erfreuten Dank. Natürlich auch an alle Anderen, die sich meiner Unkenntnis erbarmt haben. :-)
Pi3B+ mit SSD/ Bullseye | FB7590 AX | 12 x Dect200 | CUL433+868 | SDuino | HM-LAN | 3 x Heizung FHT + FKontakte | KeyMatic + 4 FB | HM Wandtaster 2-fach m. LED | 6 x Türkont. TFK-TI | HM-Bew.-Melder innen | 3 x Smoked. HM-SEC-SD-2