FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: TeeVau am 14 Januar 2015, 20:57:14

Titel: BlockingCall: readingsSingleUpdate
Beitrag von: TeeVau am 14 Januar 2015, 20:57:14
Hallo,

mein Vorhaben ist folgendes:
Für das Text2Speech Modul wollte ich die Länge der MP3 Datei, die abgespielt wird, in ein Reading schreiben. Somit kann man z.B. bei Beginn des Abspielen einen Timer starten, um etwas zu steuern.
Im Modul wird in der Routine Text2Speech_Set ein BlockingCall ausgeführt.
Innerhalb das Forks ermittel ich durch eine weitere Funktion die Länge einer MP3 Datei. Das klappt auch alles und lässt sich per Log3 testweise ausgeben.
Allerdings kann ich, innerhalb des Forks, kein Reading erzeugen. Vermutlich eben weil es ein Fork ist?!
Zum Testen habe ich mal versucht ein Reading zu beschreiben innerhalb der "done" Routine, die nach dem erfolgreichen Abarbeiten aufgerufen wird. Das funktioniert, allerdings erst nachdem die MP3 Datei fertig abgespielt ist. Das macht natürlich keinen Sinn, ich brauche das reading unmittelbar nachdem der set Befehl abgesetzt wird.

Hat jemand eine Idee, wie ich aus einem Fork heraus ein Reading beschreiben kann?

Noch etwas input:
BlockingCall aufruf bei set BEfehl:
      $hash->{helper}{RUNNING_PID} = BlockingCall("Text2Speech_DoIt", $hash, "Text2Speech_Done", 60, "Text2Speech_AbortFn", $hash) unless(exists($hash->{helper}{RUNNING_PID}));

Innerhalb Text2Speech_DoIt wird eine Funktion aufgerufen mit:
          $cmd = Text2Speech_BuildMplayerCmdString($hash, $Mp3WrapFile);


In der Routine Text2Speech_BuildMplayerCmdString versuche ich das reading zu beschreiben mit
  readingsSingleUpdate($hash, "duration", "$mp3Duration", 1);


Aber eben ohne Erfolg...

Hat jemand eine Lösung, eine Idee oder einen Denkanstoß wie ich das reading beschreiben kann?
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: Reinerlein am 14 Januar 2015, 21:04:32
Hallo TeeVau,

wie wäre es, die Länge des MP3 vor dem BlockingCall zu ermitteln und in das Reading zu schreiben?
Danach dann der Aufruf zum Abspielen...

Grüße
Reinerlein
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: TeeVau am 14 Januar 2015, 22:11:28
In dem BlockingCall wird alles gemacht :-)
Also Text downloaden, falls nicht im cache. Mehrere Sätze in unterschiedlichen MP3 Files werden zu einem MP3 gemerged etc.

Es wäre natürlich eine Möglichkeit das alles in einzelne forks aufzuteilen, aber das wäre schon ein extremer Eingriff in das Modul. Dazu fehlt mir zu einem die Zeit, zum anderen würde ich das nicht ohne Rücksprache mit dem Modulauthor machen. Damit krempelt man ja alles um ;-)
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: rudolfkoenig am 14 Januar 2015, 22:35:21
Es gibt ein BlockingInformParent, mit dem man sowas machen kann.

98_update.pm schickt die Logmeldungen auf diesem Weg zum Bildschirm, wenn man updateInBackground gesetzt hat.
Dazu wird die Log Funktion mit einer Neuen (update_Log2Event) ueberschrieben, die wiederum
  BlockingInformParent("DoTrigger", ["global", $text, 1], 0);
  BlockingInformParent("Log", [$level, $text], 0);

aufruft. Die erste Zeile sorgt fuer eine Logausgabe im FHEMWEB/telnet, die Zweite fuer das Protokollieren.
Achtung: die Parameter duerfen keine Newlines enthalten.
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: TeeVau am 15 Januar 2015, 10:22:38
Habe es mal mit BlockingInformParent versucht, bin mir aber nicht im klaren wo der Fehler ist. Es klappt nämlich nicht :-(

Den ursprünglichen Befehl
readingsSingleUpdate($hash, "duration", "$mp3Duration", 1);

habe ich ersetzt durch:
BlockingInformParent("readingsSingleUpdate", [$hash, "duration", $mp3Duration, 1], 0);


Es tut sich aber nichts im Reading. Verbose 5 zeigt mir an:
2015.01.15 10:16:30 5: Cmd: >{readingsSingleUpdate('HASH(0x6a8260)','duration','0.9','1')}<
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: rudolfkoenig am 15 Januar 2015, 10:42:07
$hash ist natuerlich Murks, Zeiger ueber Prozessgrenzen hinweg geht nicht.

Es koennte mit sowas wie \$defs{NAME} klappen oder mit noch mehr \, wenn nicht, dann muss man eine Wrapperfunktion schreiben, der keine Zeiger erwartet, und diese aufrufen.
Titel: Antw:BlockingCall: readingsSingleUpdate
Beitrag von: TeeVau am 16 Januar 2015, 11:43:56
So tief steck ich dann nicht Perl und FHEM code ;-) Habe es mit einer Wrapper Funktion gelöst. Für die Nachwelt:

Im Fork Prozess wird folgendes aufgerufen:
BlockingInformParent("Text2Speech_readingsSingleUpdateByName", [$hash->{NAME}, "duration", "$mp3Duration"], 0);

Damit wird die Funktion Text2Speech_readingsSingleUpdateByName(), wenn ich es richtig verstanden habe, nicht im Child gestartet, sondern im Parent Prozess.

Und die Funktion sieht so aus:
sub Text2Speech_readingsSingleUpdateByName($$$) {
  my ($devName, $readingName, $readingVal) = @_;
  my $hash = $defs{$devName};
  Log3 $hash, 4, "Text2Speech_readingsSingleUpdateByName: Dev:$devName Reading:$readingName Val:$readingVal";
  readingsSingleUpdate($defs{$devName}, $readingName, $readingVal, 1);
}


Damit funktioniert es. Danke für die Unterstützung!