CoProcess: Unterschied zwischen den Versionen
Justme (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Justme (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 12: | Zeile 12: | ||
* status Readings | * status Readings | ||
= Einführung = | |||
Das Modul CoProcess.pm wurde entwickelt, um in die Kontrolle ständig laufender externer Hilfsprozesse zu vereinfachen. Hierzu | |||
wird der externe Prozess mit umgeleiteter Standard-Ein- und -Ausgabe gestartet. | |||
Das Modul CoProcess | = Benutzung = | ||
* Um die CoProcess Routinen zu verwenden müssen diese mit <code>use CoProcess;</code> eingebunden werden. | |||
* Im Device-Hash müssen Information zum externen Prozess hinterlegt werden. Dies geschieht z.b. in der DefineFn. | |||
* Das Modul muss eine ReadFn Implementieren in der <code>CoProcess::readFn($hash)</code> aufgerufen wird. | |||
== Vorbereitung == | |||
:<syntaxhighlight lang="perl" xstyle="width:80%;"> | :<syntaxhighlight lang="perl" xstyle="width:80%;"> | ||
sub | |||
alexa_Define($$) { | |||
... | |||
$hash->{CoProcess} = { name => 'alexaFHEM', | |||
cmdFn => 'alexa_getCMD', | |||
}; | |||
... | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Zeile 34: | Zeile 41: | ||
| '''<code>name</code>''' || nein || 'alexaFHEM' || Ein Name für diese CoProcess Klasse. Wird verendet um Defaults für Reading- und Attribut-Namen zu erzeugen. | | '''<code>name</code>''' || nein || 'alexaFHEM' || Ein Name für diese CoProcess Klasse. Wird verendet um Defaults für Reading- und Attribut-Namen zu erzeugen. | ||
|- | |- | ||
| '''<code>cmdFn</code>''' || nein || 'alexa_getCMD' || Der Name der Perlfunktion, die die komplette Kommandozeile des zu startenden Prozesses liefert. Wird mit dem Device-Hash als Parameter aufgerufen. Kann '''<code>undef</code>''' zurückliefen wenn nichts gestartet werden soll oder kann. | | '''<code>cmdFn</code>''' || nein || 'alexa_getCMD' || Der Name der Perlfunktion, die die komplette Kommandozeile des zu startenden Prozesses liefert. Wird mit dem Device-Hash als Parameter aufgerufen. Kann '''<code>(undef,$error)</code>''' zurückliefen wenn nichts gestartet werden soll oder kann. | ||
|} | |} | ||
== Starten und Stoppen == | |||
'''<code>CoProcess::start($hash)</code>''' | |||
'''<code>CoProcess::stop($hash)</code>''' | |||
'''<code>CoProcess::terminate($hash)</code>''' | |||
== Lesen und Schreiben == | |||
Damit der gestartete Prozess nicht blockiert, müssen dessen Ausgaben auf jeden Fall abgeholt werden. Dies geschieht über den Aufruf von | |||
'''<code>CoProcess::readFn($hash)</code>''' | |||
aus der ReadFn des Moduls. Dies muss auch dann geschehen wenn diese Ausgaben nicht weiter verarbeitet werden sollen. | |||
=== | :<syntaxhighlight lang="perl" xstyle="width:80%;"> | ||
sub | |||
alexa_Initialize($) { | |||
... | |||
$hash->{ReadFn} = "alexa_Read"; | |||
... | |||
} | |||
sub | |||
alexa_Read($) { | |||
my ($hash) = @_; | |||
my $name = $hash->{NAME}; | |||
my $buf = CoProcess::readFn($hash); | |||
return undef if( !$buf ); | |||
... | |||
} | |||
</syntaxhighlight> | |||
== | == Logfile handling == | ||
Sobald <code>$hash->{logfile}</code> gesetzt ist werden alle Ausgaben des des gestarteten Prozesses dorthin geschrieben. Dies geschieht durch '''CoProcess::readFn($)'''. | |||
== Relevante Internals == | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Internal !! Optional !! Beschreibung | ! Internal !! Optional !! Beschreibung | ||
|- | |- | ||
| '''<code>logfile</code>''' || ja || Muster für den | | '''<code>CoProcess</code>''' || nein || s.o. | ||
|- | |||
| '''<code>logfile</code>''' || ja || Muster für den Namen des zu verwendenden Logfiles. Siehe {{Link2CmdRef|Anker=FileLog}}. Beispiel: '''./log/alexa-%Y-%m-%d.log'''. Bei '''FHEM''' wird das Standard FHEM Logfile verwendet. Wenn nicht gesetzt, werden die Prozess ausgaben nicht automatisch geloggt. | |||
|- | |- | ||
| '''<code>currentlogfile</code>''' || - || Wird von CoProcess automatisch auf den Namen des Aktuellen Logfiles gesetzt wenn '''<code>logfile</code>''' verwendet wird. | | '''<code>currentlogfile</code>''' || - || Wird von CoProcess automatisch auf den Namen des Aktuellen Logfiles gesetzt wenn '''<code>logfile</code>''' verwendet wird. | ||
Zeile 71: | Zeile 98: | ||
|} | |} | ||
== Relevante Attribute == | |||
Im FHEM-Device das CoProcess mit einem Logfile verwendet kann das <code>nrarchive</code> verwendet werden um alte Logfiles zu löschen. | Im FHEM-Device das CoProcess mit einem Logfile verwendet kann das <code>nrarchive</code> verwendet werden um alte Logfiles zu löschen. | ||
Zeile 78: | Zeile 105: | ||
== Verwenden von UndefFn, DelayedShutdownFn und ShutdownFn um laufende CoProzesse korrekt zu beenden == | == Verwenden von UndefFn, DelayedShutdownFn und ShutdownFn um laufende CoProzesse korrekt zu beenden == | ||
In der [[DevelopmentModuleIntro#X_Undef|UndefFn]], [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdownFn]] und [[DevelopmentModuleIntro#X_Shutdown|ShutdownFn]] des Moduls | In der [[DevelopmentModuleIntro#X_Undef|UndefFn]], [[DevelopmentModuleIntro#X_DelayedShutdown|DelayedShutdownFn]] und [[DevelopmentModuleIntro#X_Shutdown|ShutdownFn]] des Moduls muss sichergestellt werden, dass die laufenden externen Prozesse sauber beendet werden. | ||
<u>Beispiel</u> | <u>Beispiel</u> |
Aktuelle Version vom 26. Januar 2019, 17:19 Uhr
An dieser Seite wird momentan noch gearbeitet. |
Dieser Artikel soll Hinweise und Best Practices im Umgang mit dem Modul CoProcess.pm und den daraus bereitgestellten Funktionen bieten.
CoProcess.pm enthält eine Sammlung von Routinen um das Ausführen permanent laufender, externen Hilfsprozesse aus FHEM zu vereinfachen. Hierzu gehören:
- Starten und Stoppen
- Überwachen und automatisch am Laufen halten
- Automatisch bei FHEM Start und Stop
- jeder Zeit manuell
- lokales oder entferntes Starten per SSH
- Umleiten von STDOUT und STDERR des Prozesses ins FHEM log oder in ein separates Logfile
- Rotieren und löschen dieses Logfiles nach FHEM Konventionen
- status Readings
Einführung
Das Modul CoProcess.pm wurde entwickelt, um in die Kontrolle ständig laufender externer Hilfsprozesse zu vereinfachen. Hierzu wird der externe Prozess mit umgeleiteter Standard-Ein- und -Ausgabe gestartet.
Benutzung
- Um die CoProcess Routinen zu verwenden müssen diese mit
use CoProcess;
eingebunden werden. - Im Device-Hash müssen Information zum externen Prozess hinterlegt werden. Dies geschieht z.b. in der DefineFn.
- Das Modul muss eine ReadFn Implementieren in der
CoProcess::readFn($hash)
aufgerufen wird.
Vorbereitung
sub alexa_Define($$) { ... $hash->{CoProcess} = { name => 'alexaFHEM', cmdFn => 'alexa_getCMD', }; ... }
Parameter Optional Beispiel Beschreibung name
nein 'alexaFHEM' Ein Name für diese CoProcess Klasse. Wird verendet um Defaults für Reading- und Attribut-Namen zu erzeugen. cmdFn
nein 'alexa_getCMD' Der Name der Perlfunktion, die die komplette Kommandozeile des zu startenden Prozesses liefert. Wird mit dem Device-Hash als Parameter aufgerufen. Kann (undef,$error)
zurückliefen wenn nichts gestartet werden soll oder kann.
Starten und Stoppen
CoProcess::start($hash)
CoProcess::stop($hash)
CoProcess::terminate($hash)
Lesen und Schreiben
Damit der gestartete Prozess nicht blockiert, müssen dessen Ausgaben auf jeden Fall abgeholt werden. Dies geschieht über den Aufruf von
CoProcess::readFn($hash)
aus der ReadFn des Moduls. Dies muss auch dann geschehen wenn diese Ausgaben nicht weiter verarbeitet werden sollen.
sub alexa_Initialize($) { ... $hash->{ReadFn} = "alexa_Read"; ... } sub alexa_Read($) { my ($hash) = @_; my $name = $hash->{NAME}; my $buf = CoProcess::readFn($hash); return undef if( !$buf ); ... }
Logfile handling
Sobald $hash->{logfile}
gesetzt ist werden alle Ausgaben des des gestarteten Prozesses dorthin geschrieben. Dies geschieht durch CoProcess::readFn($).
Relevante Internals
Internal | Optional | Beschreibung |
---|---|---|
CoProcess |
nein | s.o. |
logfile |
ja | Muster für den Namen des zu verwendenden Logfiles. Siehe commandref/FileLog. Beispiel: ./log/alexa-%Y-%m-%d.log. Bei FHEM wird das Standard FHEM Logfile verwendet. Wenn nicht gesetzt, werden die Prozess ausgaben nicht automatisch geloggt. |
currentlogfile |
- | Wird von CoProcess automatisch auf den Namen des Aktuellen Logfiles gesetzt wenn logfile verwendet wird.
|
log |
- | Filehandle des offenen Logfiles. |
PID |
- | Enthält die PID des laufenden Prozesses. |
FH |
- | Enthält den Filehandle um dem Prozess zu kommunizieren. Zum lesen sollte CoProcess::readFn($) verwendet werden.
|
Relevante Attribute
Im FHEM-Device das CoProcess mit einem Logfile verwendet kann das nrarchive
verwendet werden um alte Logfiles zu löschen.
Verwenden von UndefFn, DelayedShutdownFn und ShutdownFn um laufende CoProzesse korrekt zu beenden
In der UndefFn, DelayedShutdownFn und ShutdownFn des Moduls muss sichergestellt werden, dass die laufenden externen Prozesse sauber beendet werden.
Beispiel
sub alexa_Undefine($$) { my ($hash, $name) = @_; if( $hash->{PID} ) { $hash->{undefine} = 1; $hash->{undefine} = $hash->{CL} if( $hash->{CL} ); $hash->{reason} = 'delete'; CoProcess::stop($hash); return "$name will be deleted after alexa-fhem has stopped or after 5 seconds. whatever comes first."; } delete $modules{$hash->{TYPE}}{defptr}; return undef; }
sub alexa_DelayedShutdownFn($){ my ($hash) = @_; if( $hash->{PID} ) { $hash->{shutdown} = 1; $hash->{shutdown} = $hash->{CL} if( $hash->{CL} ); $hash->{reason} = 'shutdown'; CoProcess::stop($hash); return 1; } return undef; }
sub alexa_Shutdown($){ my ($hash) = @_; CoProcess::terminate($hash); delete $modules{$hash->{TYPE}}{defptr}; return undef; }
Anzeige der laufenden CoProzesse
Mit dem FHEM-Befehl coprocessinfo
lassen sich die laufenden CoProzesse anzeigen.
Module, die CoProcess.pm verwenden
Folgende Module verwenden aktuell CoProcess.pm um parallel laufende Prozesse zu steuern:
- 30_tradfri.pm
- 39_alexa.pm
- 39_gassistant.pm
- 39_siri.pm