Hilfe benötigt: Python-Script, um ein Programm zu starten bzw. zu beenden

  • Hallo zusammen,


    ich bin gerade absolut ratlos, da ich zum ersten Mal mit Python zu tun habe.
    Ich möchte für Kodi bzw. OpenELEC mein Atmolight auf einen Knopf meiner Fernbedienung legen um es an- und abzuschalten.
    Nun habe ich erfahren, dass ich dies in der keymap.xml Datei machen kann mittels des Befehls "RunScript()", welcher ein .py Python-Script ausführen kann.


    Das Script soll als eine Art Schalter immer hin- und her schalten:
    1) Die boblight-x11 Datei ist geladen, dann soll sie gekillt werden
    2) Die boblight-x11 Datei ist nicht geladen, dann soll sie gestartet werden.


    Folgendes würde mir helfen:
    a) eine Bestätigung, dass der Plan so umsetzbar ist.
    b) ein paar Schlüsselworte, nach denen ich googlen kann für einen schnellen Einstieg



    Dankeschön und viele Grüße,
    Marcus

    Hardware: Zalman HD160XT; Asus H97M-Plus, 1024MB RAM, Digital Devices Cine S2 (rev 7), Atric-Einschalter, NEC3520 DVD-Laufwerk, Samsung 256 GB SSD-Festplatte --> darauf yaVDR 0.6
    Hifi: Denon AVR4306, Samsung UE40ES6300

  • a) eine Bestätigung, dass der Plan so umsetzbar ist.

    Ein Python 2 Skript aus Kodi bzw. XBMC heraus aufzurufen sollte kein Problem sein.

    b) ein paar Schlüsselworte, nach denen ich googlen kann für einen schnellen Einstieg

    Python ist gut dokumentiert: https://docs.python.org/2/


    Bei OpenElec.tv müsste es doch genügen den boblightd.service im Python-Skript zu starten oder zu stoppen:

    Code
    import subprocess
    if not subprocess.call(['systemctl', 'status', 'boblightd']):  # Wenn der service läuft, gibt systemctl status den Wert 0 = False in Python zurück, wenn nicht 3
        subprocess.call(['systemctl', 'stop', 'boblightd'])
    else:
        subprocess.call(['systemctl', 'start', 'boblightd'])

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

    Einmal editiert, zuletzt von seahawk1986 ()

  • Wenn der service läuft, gibt systemctl status den Wert 0 = False in Python zurück


    Deshalb müsste doch start und stop vertauscht werden, oder?

    Code
    import subprocess
    # Wenn der service läuft, gibt systemctl status den Wert 0 = False in Python zurück
    if subprocess.call(['systemctl', 'status', 'boblightd']):
        # True: d.h. service läuft nicht, also starten
        subprocess.call(['systemctl', 'start', 'boblightd'])
    else:
        # False: d.h. service läuft, also stoppen
        subprocess.call(['systemctl', 'stop', 'boblightd'])


    Lars

  • Stimmt, da fehlte ein "not" :O

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Danke für eure Hilfe!


    Ich bin mir nicht sicher ob es reicht, diesen Service zu starten/stoppen.
    Soweit ich das in OpenELEC verstehe ist es doch so:


    1) ein Dienst stellt die generelle Infrastruktur zur Verfügung
    2) und das XBMC-Boblight-Addon greift auf diesen Dienst zu, entspechend den Einstellungen in Kodi



    Mich stört aber folgendes an der Lösung innerhalb von Kodi:
    a) Es ist immer an, wenn Videos abgespielt werden
    b) Es ist aber z.B. nicht an, wenn ich in der Oberfläche drin bin oder z.B. Musik höre



    Daher ist mein Plan, dass ich den 2. Punkt auslasse und das Kodi-Addon gar nicht verwende.
    Statt dessen möchte ich auf das boblight-x11 Binary aufbauen, dem es total wurscht ist, was da genau in Kodi drin los ist.
    --> Aber hier halte ich es nun für keine gute Idee, diesem Binary den Service unterm Hintern wegzunehmen. Daher würde ich lieber explizit dieses Binary killen und den Dienst "in Ruhe" lassen.



    Gruß,
    Marcus

    Hardware: Zalman HD160XT; Asus H97M-Plus, 1024MB RAM, Digital Devices Cine S2 (rev 7), Atric-Einschalter, NEC3520 DVD-Laufwerk, Samsung 256 GB SSD-Festplatte --> darauf yaVDR 0.6
    Hifi: Denon AVR4306, Samsung UE40ES6300

  • Hallo nochmal!


    Wie kann ich denn unterscheiden, ob es den Prozess schon gibt oder nicht?
    -- Ich habe folgendes gefunden [1]:


    Damit bekomme ich es hin, einen Prozess zu killen.
    Allerdings hadere ich schon mit der ersten Zeile. Ich hatte erwartet, dass in der Variable proc eine PID als Zahl drin steht, also der Rückgabewert von subprocess.Popen.
    (das macht das prgrep auf der Konsole ja schließlich auch.


    Nur ist es so, dass ich hier zwar mit dem "for pid in proc.stdout" über die verschiedenen PIDs drüber laufe und diese mit dem int(pid) anscheinend in eine Integer-Zahl wandele.
    Aber mit "print proc" oder "int(proc)" wird immer rum gemeckert, dass es sich weder um eine Zahl noch um einen String handelt.


    Wieso funktioniert obige for-Schleife?



    Ich würde gerne als erstes testen, ob es einen Prozess mit dem Namen process_name gibt.
    Abhängig von diesem Test würde ich dann entweder killen oder starten wollen.



    Vielen Dank!


    Gruß,
    Marcus






    [1] http://stackoverflow.com/quest…/kill-process-with-python

    Hardware: Zalman HD160XT; Asus H97M-Plus, 1024MB RAM, Digital Devices Cine S2 (rev 7), Atric-Einschalter, NEC3520 DVD-Laufwerk, Samsung 256 GB SSD-Festplatte --> darauf yaVDR 0.6
    Hifi: Denon AVR4306, Samsung UE40ES6300

  • Wieso benutzt du nicht systemd dafür? Oder läuft da keiner in der Session?
    systemd kann ja auch User-Prozesse steuern.


    Was die for-Schleife betrifft: Wahrscheinlich bekommst du ein Array mit Strings zurück (die einzelnen Zeilen der Ausgabe). Deshalb kannst du darüber iterieren und die einzelnen Elemente ausgeben und umwandeln.


    Lars.

  • Allerdings hadere ich schon mit der ersten Zeile. Ich hatte erwartet, dass in der Variable proc eine PID als Zahl drin steht, also der Rückgabewert von subprocess.Popen.
    (das macht das prgrep auf der Konsole ja schließlich auch.


    Wenn du nur an der Ausgabe interessiert bist, nutzt du am besten subprocess.check_output() (vgl. https://docs.python.org/2/libr….html#module-subprocess):

    Code
    pid = subprocess.check_output(["pgrep", process_name])


    Mit subprocess.Popen() erstellst du ja erst mal eine Instanz von Popen, aber um an stdout oder stderr des aufgerufenen Befehls zu kommen, braucht es dann noch ein proc.communicate(), um an die Ausgabe zu kommen:

    Code
    proc = subprocess.Popen(["pgrep", process_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    # Damit du eine Liste mit den PIDs bekommst, über die du iterieren kannst, musst du den String von stdout auftrennen und die Leerzeilen loswerden:
    for pid in filter(None, stdout.split('\n')):
        try: 
           os.kill(int(pid), 0)
           raise Exception("""wasn't able to kill the process 
                              HINT:use signal.SIGKILL or signal.SIGABORT""")
        except OSError as ex:
           continue


    Ich denke es ist einfacher boblight-X11 in einen eigenen systemd-Service zu packen und den zu steuern.

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

    Einmal editiert, zuletzt von seahawk1986 ()

  • Ich denke es ist einfacher boblight-X11 in einen eigenen systemd-Service zu packen und den zu steuern.


    Das denke ich auch, denn genau dafür ist es ja da. Das kümmert sich dann selbst um alle PIDs usw.


    Lars.

  • Hmm, ich bin nicht sicher, ob mir das weiter hilft.
    Dann muss ich ja trotzdem erst rausfinden, ob oder ob nicht dieser systemd-job gerade läuft etc.


    Ich habe es nun zusammen gefrickelt bekommen.
    Auf meinem Laptop teste ist es mit gedit, und das geht nun auf und zu wie erwartet.


    Hardware: Zalman HD160XT; Asus H97M-Plus, 1024MB RAM, Digital Devices Cine S2 (rev 7), Atric-Einschalter, NEC3520 DVD-Laufwerk, Samsung 256 GB SSD-Festplatte --> darauf yaVDR 0.6
    Hifi: Denon AVR4306, Samsung UE40ES6300

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!