subprocess popen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Hallo,
ich betreibe eine Zugangskontrolle mit 4x4 Matrix und einem HD44780 2x16 Display. Das Programm wurde mittels Python geschrieben und funktioniert soweit ganz gut. Ein RPi 3 dient dabei als Hardware. Nun wollte ich über eine Tastenkombination einige Lampen im Garten schalten. Funksteckdosen kann ich bereits über das Terminal ansteuern. Über einen subprocess sollte das Python Skript einen Befehl im Terminal ausführen und das c++ Programm ansprechen. Wie muss der Inhalt im subprocess aussehen? Ich muss den Unterordner mit den Skript aufrufen und ein Argument ausführen. Hier ein kleines Beispiel

Direkte Eingabe über das Terminal:

cd /home/pi/Desktop/
./Steuerung 1 (die 1 stellt dabei das Argument dar, eine 0 würde die Steckdose wieder ausschalten)

Ablauf über das Skript

subprocess.Popen(/home/pi/Desktop/ ?????????????) :K

Da fehlt mir dann das Wissen. Momentan läuft auf dem RPi3 die aktuellste Stretch Version.
Der loop sollte nach Ausführung des subprocess auf jeden Fall fortgesetzt werden.

Ein echo als print wäre auch noch ganz hilfreich

Schonmal besten Dank für die Hilfe
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@langbnde: so

Code: Alles auswählen

subprocess.call(["./Steuerung", "1" if aktiv else "0"], cwd="/home/pi/Desktop/")
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Vielen Dank,

funktioniert einwandfrei !! :D
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Moin,

ich habe nun noch eine Adafruit Library für einen DHT11 heruntergeladen und frage diesen Sensor über ein Python Skript ab. In diesem Skript
wird der ausgelesene Wert in eine Textdatei geschrieben. Im Hauptskript lese ich den Wert aus und gebe ihn an das 2x16 Display weiter. Nun habe ich aber folgendes Problem:

ich stoße das Skript über den subprocess.call(["./DHT11Skript.py"], cwd=".................") an und die Werte werden in die Textdatei übertragen.Nun verweilt das Programm jedoch endlos in dem call- Befehl. Ich habe es schon mit einem sys.exit() an Ende des aufgerufenen Skripts versucht, doch es
tut sich nichts, der Ablauf wird nicht fortgesetzt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst uns schon das aufgerufene Skript zeigen. Und ein sys.exit() am Ende eines Skriptes ist keine magische Beschwoerunsformel - wenn davor eine Endlosschleife eingebaut ist, wird das nie erreicht. Siehe hier:

Code: Alles auswählen

import sys
while True:
     print("auf ewig gruesst das Murmeltier")
sys.exit() # wird nie aufgerufen
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ein Python Skript über subprocess auszuführen statt zu importieren und dann aufzurufen ist so wie so in 99% der Fälle falsch.
Da solltest du den Skript nochmal dringend überarbeiten.

Gruß, noisefloor
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Ich habe mich mal etwas länger mit meinem Problem beschäftigt.
Im Skript habe ich keine Schleife integriert.

Warum sollte man kein Python Skript via subprocess aufrufen?
Die Abfrage des DHT11 erfolgt nur auf Anfrage über den Benutzer (Matrix Tastenfeld)
Ich halte das Hauptskript schlank und kann ohne Probleme die über subprocess verwendeten Skripte bearbeiten.

In meinem Aufruf subprocess.run("./DHT11Skript.py", stdout= subprocess.PIPE, shell= False, timeout= 8)
fehlte nur die Übergabe via stdout.

Nun wird der Aufruf abgearbeitet und beendet.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Schlankheit erreichst du auch durch modularisierung die Python ja anbietet. Der Weg über subprocess ist zum einen teuer (Systemresourcen, immer wieder laufende Initialisierung die nur einmal laufen müsste), je nach Aufgabe schlicht nicht gangbar (falls verschiedene Skripte dieselben resourcen/Pins etc brauchen, der Zustand des Systems dauerhaft kontrolliert werden muss), erzeugt unnötigen Aufwand um Daten zu strings und wieder zurück zu wandeln, ist schwerer zu entwanzen da Fehler im Unterprozess nicht os ohne weiteres sichtbar werden, etc.

Den einzigen Vorteil den ich sehe: du kannst mit deinem Vorgehen darauf verzichten dich tiefer einzuarbeiten, und stattdessen bestehende Skripte einfach 1-1 benutzen.

Ist das “böse”? Nein. Es mangelt am Anspruch gut zu programmieren und verbaut einem damit den Weg in Richtung größere und komplexere Projkete zu wagen, aber wenn das nicht das Ziel ist - :K
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Da geb ich dir recht.
Dann habe ich die grundlegende Frage warum die heruntergeladene Bibliothek von Adafruit nicht gefunden wird.

Ich bin laut README vorgegangen:

sudo apt-get update
sudo apt-get install build-essential python-dev

cd /home/pi/Adafruit_Python_DHT
sudo python setup.py install

versuche ich dann die Bibliothek Adafruit_DHT zu importieren,
wird sie nicht gefunden.

Deswegen habe ich den subprocess genutzt, denn über das Terminal kann ich das Skript ansprechen.
Kann ich nachvollziehen ob die Bibliothek hinterlegt ist oder habe ich während des install einen Fehler begangen (falscher Unterordner etc.)
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das dürfte nicht sein. Python hat eine paar Pfade, die standardmäßig durchsucht werden. Wenn du - wie im gegebenen Fall, das Adafruit-Modul global installiert hast, dann findet jedes Skript das.

Welchen Fehler bekommst du und zeig' mal deine beiden Skripte.

Gruß, noisefloor
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Testskript mit importierter Adafruit- Library
Dieses kann über das Terminal angesprochen werden ./DHT11Skript.py
Das Skript wurde zuvor mit chmod a+x modifiziert.
################################################################
#!/usr/bin/python
import sys
import Adafruit_DHT

humidity, temperature = Adafruit_DHT.read_retry(11, 4)

if humidity is not None and temperature is not None:
print ('Temp={0:0.1f}*C Humidity={1:0.1f}%').format(temperature, humidity)
DHTinsert = open("DHT11value.txt","w")
DHTinsert.write ('t={0:0.1f}* f={1:0.1f}%'.format(temperature, humidity))
DHTinsert.close()
print ("Bedingung durchlaufen")


else:
print ('Failed to get reading. Try again!')
DHTinsert = open("DHT11value.txt","w")
DHTinsert.write ("Failed to get reading. Try again!")
DHTinsert.close()

sys.exit(1)
##############################################################

Versuche ich das Skript direkt mit Python zu starten kommt folgende Meldung:

raceback (most recent call last):
File "/home/pi/Desktop/DHT11Skript.py", line 3, in <module>
import Adafruit_DHT
ImportError: No module named 'Adafruit_DHT'
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Die Tabs hinter if und else wurden falsch formatiert
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Die Tabs hinter if und else wurden falsch formatiert
Per Konvention rückt man auch mit 4 Leerzeichen ein, nicht mit Tabs. Außerdem solltest du den Code in einen Codeblock setzen - dann werden auch die Einrückungen übernommen.

Irgendwas stimmt bei deinem System nicht. Es sollte keinen Unterschied machen, ob du ein Skript direkt ausführst oder über `subprocess`. Das `Adafruit_DHT` Modul muss ja in beiden Fällen geladen werden.
Führst du dein Skript mit oder ohne Root-Rechten aus?

Gruß, noisefloor
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Ich führe es mit Root- Rechten aus.
Ich habe das gleiche Betriebssystem noch auf einem RPI3 laufen, da werde ich ebenfalls mal die
Library installieren und schauen was passiert.
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

So,
Problem entdeckt. Ich habe das Skript mal in das "/home/pi" Unterverzeichnis gelegt und siehe da es wird
abgearbeitet. Trotzdem ist dort kein Skript mit diesem Namen "Adafruit_DHT" zu finden, oder durchsucht Python
in diesem Moment den Ordner mit dem Namen Adafruit_DHT?? Wo ist denn dann die Library abgelegt?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Ein Paket besteht aus einem Verzeichnis, hier heißt das Paket Adafruit_DHT und ist scheinbar in Deinem home-Verzeichnis installiert, was aber eigentlich nicht sein sollte, wenn Du es mit »setup.py install« installiert hast.
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Jetzt versucht das Skript die RPI 2 Treiber Datei zu öffnen
mit diesem Ergebnis

from . import Raspberry_Pi_2_Driver as driver
ImportError: cannot import name 'Raspberry_Pi_2_Driver'
langbnde
User
Beiträge: 11
Registriert: Montag 29. Januar 2018, 02:42

Ich habe es über die setup.py installiert
Antworten