FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Jazzy_Jazz am 12 Januar 2022, 02:00:56

Titel: [Gelöst] Mit Notify Python Scipt starten
Beitrag von: Jazzy_Jazz am 12 Januar 2022, 02:00:56
Hallo Zusammen,

Ich versuche gerade per Notify ein Python script zu starten.

Meine Applikation ist:
Ein USB Relays Modul, dass per Python angesteuert wird um die Beleuchtung der Klingel und auch die Klingel selber ein/aus zu schalten.
Der Zustand an/aus wird jeweils in eine Datei geschrieben.
Mein Python script liest die Datei dann ein und Schaltet die Relays entsprechend.
Per Terminal kann ich das script starten und es wird auch korrekt ausgeführt.

Hier wäre mein Notify:

BeleuchtungKlingel {
open (DATEI, ">/opt/fhem/pythonfiles/BeleuchtungKlingel.py") or die $!;
print DATEI $EVENT eq "on"?"BeleuchtungKlingel = 1":"BeleuchtungKlingel = 0";
close (DATEI);
"sudo python /opt/fhem/pythonfiles/klingelpython.py"
}


Ich habe dem User fhem schon root Rechte gegeben, um das als Problem auszuschließen.
Die Datei habe ich auch mit chmod +x ausführbar gemacht.

Die Datei mit dem Zustand wird korrekt geschrieben, das Python script wird aber nicht gestartet (das sehe ich, weil immer direkt ein Logfile geschrieben wird, wenn das Script startet).

Die vorherigen Beiträge bezüglich Python Scripts zu diesem Thema bin ich schon durchgegangen, das hat mich aber leider soweit noch nicht weiter gebracht...
Titel: Antw:Notify Python Scipt starten
Beitrag von: CoolTux am 12 Januar 2022, 04:06:11
Zitat von: Jazzy_Jazz am 12 Januar 2022, 02:00:56
Hallo Zusammen,

Ich versuche gerade per Notify ein Python script zu starten.

Meine Applikation ist:
Ein USB Relays Modul, dass per Python angesteuert wird um die Beleuchtung der Klingel und auch die Klingel selber ein/aus zu schalten.
Der Zustand an/aus wird jeweils in eine Datei geschrieben.
Mein Python script liest die Datei dann ein und Schaltet die Relays entsprechend.
Per Terminal kann ich das script starten und es wird auch korrekt ausgeführt.

Hier wäre mein Notify:

BeleuchtungKlingel {
open (DATEI, ">/opt/fhem/pythonfiles/BeleuchtungKlingel.py") or die $!;
print DATEI $EVENT eq "on"?"BeleuchtungKlingel = 1":"BeleuchtungKlingel = 0";
close (DATEI);
"sudo python /opt/fhem/pythonfiles/klingelpython.py"
}


Ich habe dem User fhem schon root Rechte gegeben, um das als Problem auszuschließen.
Die Datei habe ich auch mit chmod +x ausführbar gemacht.

Die Datei mit dem Zustand wird korrekt geschrieben, das Python script wird aber nicht gestartet (das sehe ich, weil immer direkt ein Logfile geschrieben wird, wenn das Script startet).

Die vorherigen Beiträge bezüglich Python Scripts zu diesem Thema bin ich schon durchgegangen, das hat mich aber leider soweit noch nicht weiter gebracht...

BeleuchtungKlingel {
open (DATEI, ">/opt/fhem/pythonfiles/BeleuchtungKlingel.py") or die $!;
print DATEI $EVENT eq "on"?"BeleuchtungKlingel = 1":"BeleuchtungKlingel = 0";
close (DATEI);
fhem("\"sudo python /opt/fhem/pythonfiles/klingelpython.py\"");
}
Titel: Antw:Notify Python Scipt starten
Beitrag von: OdfFhem am 12 Januar 2022, 05:31:48
@CoolTux

Ist hier der Umweg über fhem() notwendig, denn man befindet sich ja schon in Perl und könnte einfach den system()-Aufruf nutzen ...

@Jazzy_Jazz

- Die Benamung der Transport-Datei ist zumindest ungewöhnlich, da py etwas anderes suggeriert ... out, in, txt, cfg, usw. scheinen gebräuchlicher ...
- Ist im eigentlichen Script irgendwas, was spezielle Rechte erfordert; wenn nein, dann würde es normalerweise ausreichen, das Script fhem:dialout als Besitzer zuzuordnen und entsprechend ausführbar zu machen ... sudo wäre dann überflüssig ...
Titel: Antw:Mit Notify Python Scipt starten
Beitrag von: Jazzy_Jazz am 12 Januar 2022, 23:40:04
@CoolTux
Danke für deinen Input. Damit hat es jetzt funktioniert

Ich musste zusätzlich noch eine Regel in /etc/udev/ anlegen:
SUBSYSTEM=="usb", ATTRS{idVendor}=="16C0", MODE="0666", GROUP="plugdev"

@OdfFhem
Danke auch für deinen Input.

Zitat von: OdfFhem am 12 Januar 2022, 05:31:48

@Jazzy_Jazz

- Die Benamung der Transport-Datei ist zumindest ungewöhnlich, da py etwas anderes suggeriert ... out, in, txt, cfg, usw. scheinen gebräuchlicher ...
Ja das ist meiner Faulheit geschuldet, so kann ich die Dateien einfach in mein Python script ohne Umwege importieren und FHEM sollte das egal sein was für eine Endung an die Datei geschrieben wird....

Zitat von: OdfFhem am 12 Januar 2022, 05:31:48
- Ist im eigentlichen Script irgendwas, was spezielle Rechte erfordert; wenn nein, dann würde es normalerweise ausreichen, das Script fhem:dialout als Besitzer zuzuordnen und entsprechend ausführbar zu machen ... sudo wäre dann überflüssig ...
Ja für den Zugriff auf die HID devices braucht man meines Wissens nach root Rechte. Ich bin mir aber auch nicht sicher. Das werde ich noch mal aussuchen. Aber zunächst funktioniert es ja soweit und die Relays können jetzt meine Klingel sowie die Beleuchtung des Klingelschildes ein/aus schalten. 
Titel: Antw:Notify Python Scipt starten
Beitrag von: CoolTux am 13 Januar 2022, 09:29:12
Zitat von: OdfFhem am 12 Januar 2022, 05:31:48
@CoolTux

Ist hier der Umweg über fhem() notwendig, denn man befindet sich ja schon in Perl und könnte einfach den system()-Aufruf nutzen ...

@Jazzy_Jazz

- Die Benamung der Transport-Datei ist zumindest ungewöhnlich, da py etwas anderes suggeriert ... out, in, txt, cfg, usw. scheinen gebräuchlicher ...
- Ist im eigentlichen Script irgendwas, was spezielle Rechte erfordert; wenn nein, dann würde es normalerweise ausreichen, das Script fhem:dialout als Besitzer zuzuordnen und entsprechend ausführbar zu machen ... sudo wäre dann überflüssig ...

system() kann im ungünstigsten Fall FHEM blockieren, daher fhem()
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: OdfFhem am 14 Januar 2022, 06:05:21
@CoolTux

... aus einem ganz anderen Thema ...
Zitat von: frober am 13 Januar 2022, 21:24:33
Warum willst du von Perl nach Fhem um dort Perl aufzurufen?

Die Perl-Funktion system() zwingt den Aufrufenden auf jeden Fall zum Warten. Wie verhindert der fhem()-Aufruf das Blockieren ... wird der fhem()-Aufruf mit einem eigenen Prozess abgearbeitet ?
Sollte das der Fall sein, würde man das Ergebnis von system() nie verarbeiten können ...
Bräuchte man das Ergebnis von system() sowieso nicht, könnte man aber auch gleich exec() verwenden ...
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: Otto123 am 14 Januar 2022, 10:22:37
Zitat von: OdfFhem am 14 Januar 2022, 06:05:21
Sollte das der Fall sein, würde man das Ergebnis von system() nie verarbeiten können ...
Bräuchte man das Ergebnis von system() sowieso nicht, könnte man aber auch gleich exec() verwenden ...
Ohohohoh :o :o :o
exec() beendet das laufen Programm und startet ein neues -> ergo FHEM wird beendet. https://perldoc.perl.org/functions/exec
system() macht einen fork und liefert als Ergebnis wahr oder falsch, je nach dem ob die Ausführung erfolgreich war oder nicht. Es ist der exit Status vom aufgerufenen Programm. In FHEM kommt aber bei system() immer -1 zurück. https://perldoc.perl.org/functions/system
qx() liefert das Ergebnis des ausgeführten Programms zurück. https://perldoc.perl.org/perlop#Quote-Like-Operators

Man kann externe Programme so aufrufen, das sie sofort zurückkehren und in einem extra Prozess weiterarbeiten. Dann kann man aber das Ergebnis nicht im aufrufenden Prozess als Rückgabe erwarten.
Beispiel bash -c 'sleep 10 &'bash -c 'sleep 10'
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: OdfFhem am 14 Januar 2022, 11:54:36
bzgl. exec()

Bislang habe ich keinen eigenen Anwendungsfall dafür und das Ganze nur theoretisch durchdacht und scheinbar ein wenig falsch verstanden.

Ich dachte:

Perl gibt mit exec() die Kontrolle für das, was als Parameter übergeben wurde, an einen eigenständigen Prozess ab und läuft selbst ganz normal direkt weiter ... Ergebnis der exec()-Ausführung interessiert in keinster Weise.

Perl führt mit system() in einem abhängigen Prozess das aus, was als Parameter übergeben wurde, und wartet auf das Ergebnis der Ausführung (fehlerhaft oder eben nicht) und läuft erst dann weiter ...

qx() ist wie system(), nur dass man tatsächlich einen frei gestaltbaren Rückgabewert erhält ...

Da insbesondere die erste Annahme falsch zu sein scheint, kann man für die eigenen Notizen festhalten,  dass es keine Perl-Routine mit z.B. direkt hintereinander stehenden exec-Aufrufen geben kann ... alles hinter dem ersten exec wird ja nie ausgeführt.

Richtig oder immer noch falsch verstanden ?
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: Otto123 am 14 Januar 2022, 12:02:37
mMn richtig verstanden
ZitatThe exec function executes a system command and never returns;

Allerdings: qx() ist wie system() - stimmt nicht im vollen Umfang. qx hat einen anderen Syntax als system was Form und quotes betrifft!
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: OdfFhem am 14 Januar 2022, 12:32:03
qx() kenne ich im Grunde aus dem Shell-Bereich; dort verwendet man genau dafür gerne die "rückwärtigen", einfachen Anführungszeichen ... `date`

Auf jeden Fall schon mal schönen Dank fürs "nachdenklich machen" ...
... das WE ist zwar nicht regnerisch und lädt zu anderen Beschäftigungen ein,
aber ein bisschen Zeit für eigene Perl-Erfahrungen sollten drin sein.

Noch eine kleine Frage: Ich packe ein paar Testanweisungen in ein Perl-Skript und führe es am Prompt aus ... dann führe ich die Testanweisungen (nicht das Skript) direkt in der FHEM-Perl-Umgebung aus. Das Verhalten sollte doch in beiden Fällen gleich sein, oder ?
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: Otto123 am 14 Januar 2022, 13:13:50
Ja mit ein paar Unterschieden: siehe auch https://fhem.de/commandref_DE.html#perl
die semikolon müssen in der FHEM Kommandozeile verdoppelt(geschützt) werden der FHEM Parser "frisst" sie sonst
Das Ergebnis der letzten Zuweisung wird automatisch im Browser angezeigt aber print Ausgabe landen im LogFile und im Browser sieht man eine 1. Ich sammle die Ausgaben immer in $ret und mache am Ende return $ret, dann habe ich den Wert im Browser.
Dumper hilft "undurchsichtige" Daten wie Array Hashes usw. anzuschauen. Der gibt auch direkt im Browser aus.
Längere Script kopiere ich als sub in die myUtils, da braucht man die semikolon nicht verändern

Ich teste generell die meisten Perl Anweisungen direkt in FHEM. Ist ja die Umgebung wo ich es brauche :)
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: OdfFhem am 16 Januar 2022, 11:26:55
@Otto123

So, mittlerweile hatte ich ein wenig Zeit und habe mich mit dem falsch verstandenen exec() sowie den Alternativen auseinandergesetzt.

*** exec()

Am Prompt zwei Anweisungen in einem Perl-Skript festgehalten und dann war klar: beim Aufruf vom ersten exec() ist Schluss:
- die Doku habe ich mir dann auch nochmals näher angeschaut, aber die Formulierung scheint doch recht "schwach/mehrdeutig" ...
Zitat
The exec function executes a system command and never returns; use system instead of exec if you want it to return.
It fails and returns false only if the command does not exist and it is executed directly instead of via your system's command shell.
- die erste Formulierung schickt den Aufrufenden "gefühlt" in die Endlosschleife; Zurückkommen wird ja nichts (ich dachte natürlich kein Resultat), aber das der Aufrufende "stirbt", steht ja auch nicht da
- die zweite Formulierung hingegen sagt deutlich, dass never nicht wirklich never bedeutet (und der Aufrufende vermutlich nicht immer "stirbt", oder doch ?)

Ein echter Anwendungsfall für diesen SuperSonderSpezial-Anwendungsfall ist mir direkt noch nie untergekommen, aber beim zweiten Grübeln erinnerte mich exec() ein wenig an einen Staffellauf:
- Wenn die Übergabe klappt, kriegt man nichts zurück ... nicht mal den Stab
- Wenn die Übergabe nicht klappt, dann gibt's spürbare Reaktionen ... im Zweifel auch mit dem Stab

*** system()

funktioniert im Grunde wie erwartet

*** qx()

funktioniert im Grunde wie erwartet
Titel: Antw:[Gelöst] Mit Notify Python Scipt starten
Beitrag von: Otto123 am 16 Januar 2022, 15:05:26
ich lese die beiden Sätze so:
Wenn das Kommando existiert wird es ausgeführt und kommt nicht zurück. Ich meine das aufrufende Programm wird dadurch beendet.
Randbemerkung: Im Falle von FHEM kann das bedeuten, FHEM wird durch systemd neu gestartet. (ein Test gerade eben bestätigt das)
Wenn das Kommando nicht existiert, bekommt man einen Fehler und es geht weiter - kommt zurück. Auch getestet :)