Interprozesskommunikation

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Bisschen wenig Infos.

    • signale
    • pipes
    • named-pipes
    • shared_memory
    • mmap
    • sockets

    Drittanbieter:

    • zmq
    • mqtt
    • ampq

    Es kann aber auch sein, dass du IPC überhaupt nicht brauchst, sondern den Code einfach integrieren kannst.

    Oftmals wird nach falschen Lösungen für etwas gesucht, das man anders viel einfacher lösen kann.

  • Natürlich. Aber wie meistens bei solchen Fragen besteht hohe x/y-Problemgefahr. Was für ein Problem hast du denn? Vielleicht gibt es ganz andere Lösungen.

  • Auf dem Pi läuft ein Python-Skript, mit welchem per Taster Türen einer Hühnerhütte gesteuert werden können (das Projekt befindet sich noch im Entwicklungsstadium). Nun möchte ich die Steuerung auch über eine App vom Smartphone aus durchführen. Die einfache Lösung wäre natürlich, dass ein weiteres Skript über die App aufgerufen wird, welches den gleichen Code wie das bereits vorhandene Skript (ich nenne es hier mal Steuerskript) beinhaltet. Da ich mich mit App-Programmierung nicht auskenne, bin ich auf SSH-Button-Apps angewiesen, welche im Android-Store angeboten werden. Wie es aussieht, benötige ich dann für jede Steuerfunktion (Öffnen, Stopp, Schließen) ein eigenes Skript, was zur Code-Verdoppelung führen würde.

    Nun stelle ich mir vor, dass ich über die App ein Skript aufrufe, welches ein Signal an das Steuerskript sendet verbunden beispielsweise mit dem Ablegen einer Datei, deren Name der gewünschten Steuerfunktion entspricht (vielleicht geht's auch über Named Pipe, falls es die in Python gibt). Ich würde zwar bei dieser Lösung ebenfalls mehrere Skripte benötigen (eines für jede Steuer-Funktion), die aber nicht den für die Steuerung auszuführenden Code enthalten müssen.

    So, jetzt ist es schön lang geworden. Ich habe aber hoffentlich mein Problem rübergebracht.

  • Wenn es diese Apps auch mit HTTP gibt, nimm das & schreib eine Webserver mit extra Thread für die GPIOs.

    • Offizieller Beitrag

    Wie es aussieht, benötige ich dann für jede Steuerfunktion (Öffnen, Stopp, Schließen) ein eigenes Skript

    Ein Skript für die Steuerung per App würde ausreichen. Dem brauchst Du beim Aufruf per SSH nur Argumente mitgeben und diese im Skript auswerten. Das sollte sich nach der Aktion aber wieder beenden, also nicht mit einer Schleife oder signal.pause() am Leben gehalten werden.

    Im vorhandenen Skript (das vermutlich ständig läuft) könnte man den Status der GPIO abfragen, falls das überhaupt nötig ist, bevor eine Aktion durchgeführt wird.

  • Ein Skript für die Steuerung per App würde ausreichen. Dem brauchst Du beim Aufruf per SSH nur Argumente mitgeben und diese im Skript auswerten.

    Da hast Du natürlich Recht ! Das löst aber mein grundsätzliches Problem nicht, eine Möglichkeit der Kommunikation zwischen dem App-Skript und dem Steuerskript zu finden. Ich stelle es mir so schön naiv vor, dass im Steuerskript zusammen mit den Callbacks für die Taster auch ein Callback für ein von dem App-Skript ausgelöstes Ereignis eingerichtet werden kann.

    Eine umständliche und inperformante Methode wäre, im App-Skript eine Datei zu erzeugen und im Steuerskript in der Ereignisschleife zusätzlich auf die Existenz einer solchen abzufragen. Eine Kommunikation via Sockets wird wahrscheinlich nicht funktionieren, weil das Steuerskript als Client im Listen verharren müsste, der von den Taster-Ereignissen nicht unterbrochen würde.

  • Hier ist von mir exemplarisch vorgemacht, was ich mit Thread und Webanwendung meine:

    https://github.com/deets/brombeer…o/server.py#L57

    Der Thread kann auf GPIO-Ereignisse reagieren oder sie ausloesen, und die Webandwendung kommuniziert die "nach oben", koennte die aber auch problemlos schalten bzw. mit einer queue.Queue() mit dem Thread kommunizieren, der das dann erledigt.

  • Deinen Link muss ich erst einmal verdauen, __deets__, ist für mich noch schwere Kost.

    Die Kommunikation zwischen zwei Python-Skripten via GPIO-Pin funktioniert.

    Sender:

    Code
    import RPi.GPIO as gpio
    PIN_COM = 11
    #
    gpio.setwarnings(False)
    gpio.setmode(gpio.BOARD)
    ....
    gpio.setup(PIN_COM, gpio.OUT)
    gpio.output(PIN_COM, True) # Senden
    gpio.output(PIN_COM, False)

    Empfänger:

    Code
    ....
    PIN_COM = 11
    gpio.setup(PIN_COM, gpio.IN )
    ....
    def empfang(pin):
       print("PIN_COM aktiviert ", pin)
    ....
    gpio.add_event_detect(PIN_COM, gpio.RISING, callback=empfang )

    Mir würde nur noch eine "elegantere" Methode der Parameterübergabe als über den Inhalt einer Datei fehlen.

    • Offizieller Beitrag

    RPi.GPIO hatte ich schon befürchtet... Sieh Dir gpiozero mal an: https://gpiozero.readthedocs.io/en/stable/index.html auch wenn dieser Tipp nur "beiläufig" ist. ;)

    Das bisherige Skript würde mich trotzdem interessieren.

  • Statt Dateien nimm FIFOs. Aber das ist am Ende auch nicht weniger kompliziert als ein Webservice.

    • Offizieller Beitrag

    Da hast Du genau den Punkt meiner Unsicherheit daran getroffen. Imho sollte das funktionieren. Leider kann ich es gerade nicht nochmals testen ob das wirklich nur innerhalb eines Programms funktioniert oder ob die tatsächlichen Zustände der GPIOs ausgelesen werden. Meine Spielereien damit liegen schon ein Weilchen zurück, mir war aber so.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!