Hallo,
Ich bin seit einigen Tagen dabei den Raspi als Server starten. In Python
gibt es ein Modul webserver mit dem kann man ganz einfach den Raspy als
Server laufen. Im CGI Ordner hab ich meine Python-Programme die im
Browser aufgerufen werden und meine Seite erstellen. Jetzt zu meinem
Problem.Im Browser kann ich per Taster verschiedene LEDs durch Paramter
schalten. Und umgekehrt auch einlesen. Jetzt will ich aber ein
Dauermodus erstellen ein Button der je nach Zustand eine andere Farbe
hat. Deshalb hab ich mir eine SQL geschrieben,wenn ich den Button drücke
bekommt x = 1 und wenn ich noch mal drücke wird x wieder 0. Einzeln
funktioniert das auch aber wenn ich das per CGI ausführen lasse
funktioniert es nicht. Obwohl es der gleiche Programm ist. Kann es sich
hierbei um irgendwelche Rechte handeln. Der Ordner CGI wurde mit chmod
u+x bearbeitet wie jeweils die anderen Daten. Oder kann der CGI dies
nicht ausführen. Bevor ich SQL angewandt habe, hatte ich es mit
textdateien versucht. da ging es und einmal nicht. Ich bin ratlos. Danke
LG Charel
Ich habe leider nicht bis in's Detail verstanden, was genau Du machen
willst bzw. wo Dein Problem liegt...
Charel P. schrieb:> Einzeln> funktioniert das auch aber wenn ich das per CGI ausführen lasse> funktioniert es nicht. Obwohl es der gleiche Programm ist. Kann es sich> hierbei um irgendwelche Rechte handeln. Der Ordner CGI wurde mit chmod> u+x bearbeitet wie jeweils die anderen Daten. Oder kann der CGI dies> nicht ausführen.
... ^^^ aber daran kann es imho schon mal nicht liegen, denn Du hast ja
das geschrieben:
> Im CGI Ordner hab ich meine Python-Programme die im> Browser aufgerufen werden und meine Seite erstellen.
Wenn Deine Webseite per CGI durch ein Python-Script erzeugt wird, und Du
zumindest eine Webseite angezeigt bekommst, dann werden Deine
Python-Scripte im CGI-Ordner ja offensichtlich ausgeführt.
Ich würde empfehlen, dass Du Dein Problem nochmal etwas ausführlicher
schilderst (und bspw. einfach mal die fraglichen Python-Scripte
postest); alleine mit den bisherigen Informationen kann man Dir glaube
ich nicht helfen.
Also in dem python script wird durch ein Parameter im Browser die
Datenbank aufgerufen und x = 1 geschrieben. Leider funktionert dies
nicht im CGI. Wenn ich jetzt aber so das Programm starte bzw nur auf die
Datenbank zugreife und was drin schreibe dann funltioniert es .
Welcher Webserver läuft? Apache? Nginx?
Wie ist dein Python eingebunden? Wirklich als CGI (im cgi-bin), oder
evtl. über modpython?
Wenn als CGI: Shebang in Ordnung? Python im Pfad? Script lesbar für
"www-data:www-data"?
Charel schrieb:> Also in dem python script wird durch ein Parameter im Browser die> Datenbank aufgerufen und x = 1 geschrieben.
Schau Dir die Log-Datei Deines Webservers an.
Schwarzseher schrieb:> Welcher Webserver läuft? Apache? Nginx?> Wie ist dein Python eingebunden? Wirklich als CGI (im cgi-bin), oder> evtl. über modpython?> Wenn als CGI: Shebang in Ordnung? Python im Pfad? Script lesbar für> "www-data:www-data"?
Es handelt sich hier bei um den cgi-bin. In python 3 gibt es ein Modul
namens webserver. Und per eine zeile Code kann einen raspi als webserver
laufen lassen
> Welcher Webserver läuft? Apache? Nginx?> Wie ist dein Python eingebunden? Wirklich als CGI (im cgi-bin), oder> evtl. über modpython?> Wenn als CGI: Shebang in Ordnung? Python im Pfad? Script lesbar für> "www-data:www-data"?
[...]
> Schau Dir die Log-Datei Deines Webservers an.
Er hat doch schon im Eröffnungsposting geschrieben, dass er derzeit den
bei Python direkt mitgelieferten ("SimpleHTTPServer") benutzt, der per
1
python3 -m http.server
gestartet wird. Und dieser minimalistische HTTP-Server speichert auch
keine Log-Datei.
@Charel: Mit den bisherigen Informationen kann man imho nur in's Blaue
raten - liegt der Fehler mglw. daran, dass Du beim Aufruf nicht den
--cgi Parameter übergibst?
Auf der von Dir verlinkten Seite wird dieser Parameter zwar gar nicht
erst erwähnt; die Dokumentation des "SimpleHTTPServer"
https://docs.python.org/3.6/library/http.server.html
...klingt beim Überfliegen allerdings so, als ob für CGI dieser
Parameter übergeben werden muss:
1
CGIHTTPRequestHandler can be enabled in the command line by passing the --cgi option:
15 Zoll schrieb:> Der Python-Server gibt sein log auf die Standardausgabe aus, also> umleiten:python3 -m http.server >> server.log
Was ist mit stderr? Vielleicht besser:
python3 -m http.server >>server.log 2>>server.err
Also so sieht +- das Prinzip aus.
Ich klicke im Browser www.....py?0&0 auf den Button Dauermodus grau
(Dauermodus aus) rot (Dauermodus an ) es ist der gleiche Button
Parameter1 --> 0
Parameter 2 --> 0
try:
state = sys.argv[1]
if (state[0] == '0'): #Sektor 1 ausgewählt
if (state[1] == '0'):
#SQL x = 1 Dauermodus an
elif (state[1]== '1'):
#SQL x = 0 Dauermodus aus
elif ... für sektor 2 ....
except:
print('')
Wenn Dauermodus an ist, wird die CSS des Buttons umgeändert funktioniert
auch. Aber für das update in der datenbank funktioniert nicht. Einzeln
getestet geht es aber
Charel P. schrieb:> state = sys.argv[1]> if (state[0] == '0'): #Sektor 1 ausgewählt
Da fehlt schon mal was, lies das von Dir verlinkte Tutorial noch mal.
Ich weiss der fehler den ich habe ist schwer zu verstehen kann leider
den Programm nicht hochladen bin im Urlaub eine wiche lang aber es
beschäftigt mich und hab das Prinzip gerade noch mal geschrieben und
nicht aus der Datei kopiert.
Charel P. schrieb:> Ich weiss der fehler den ich habe ist schwer zu verstehen kann leider> den Programm nicht hochladen bin im Urlaub eine wiche lang aber es> beschäftigt mich und hab das Prinzip gerade noch mal geschrieben und> nicht aus der Datei kopiert.
Demnach kannst Du also auch gar nichts ausprobieren, falls Jemand eine
konkrete Idee hat, woran es liegen könnte.
Sorry, aber SO ist das doch echt völlig sinnlos - melde Dich einfach
nochmal, wenn Du wieder zuhause bist, den Sourcecode hochladen und
konkrete Lösungsvorschläge auch ausprobieren kannst.
Charel schrieb:> http://weigu.lu/tutorials/python_and_raspi/python_webserver/index.html>> dynamische webseite mit CGI und Python so läuft gerade der Server
Wenn du wirklich mit Python den Web und den Pi was machen willst, würde
ich dir raten das ganze über nicht über cgi sondern WSGI zu machen zum
Beispiel mit dem Flask-Framework.
Der Vorteil hierbei ist das Dein Python dauernd läuft und nicht bei
jeden request eine eigene Instanz startet und mehr sugar bietet um den
Code von der Darstellung zu trennen.
Und diese Seite ist die Hauptwebseite und mit der habe ich Probleme,
wenn ich den Button drÜcke wird der Zustand in der Datenbank nicht
geupdated obwohl es in einem anderem Programm geht.
und ich glaub diese Zeile wird nicht durchgeführt, nachdem der Button
ausgefÜhrt wird. Weil ich hab mit der Funktion test() einmal davor und
einmal danach getestet
cursor.execute(sql)
Charel P. schrieb:> und ich glaub diese Zeile wird nicht durchgeführt, nachdem der Button> ausgefÜhrt wird. Weil ich hab mit der Funktion test() einmal davor und> einmal danach getestet>> cursor.execute(sql)
laut meines Editor hat dein whz die zeile 12 mal, welche Zeile meinst
du?
mal Ernsthaft, deine Mischung zwischen Python und html zu Lesen, macht
wenig bis keinen Spaß. Ich empfehle die für die Wartbarkeit das html in
ein jinja2 Template auszulagern und den Pythoncode vom html zu trennen.
Außerdem solltest du mit deinen Magic Nummern aufräumen, die Adressen
des Multiplexer kannst du zum Beispiel mit Sprechenden Namen versehen
und vielleicht die Riesen If/Else durch was eleganteres wie eine List
oder ein Dict verwandeln.
Die Funktionen heat_* machen alle das gleiche, vielleicht solltest du
das eine Funktion mit zwei Parameter umwandeln. Für die image_*
Funktionen gilt das gleiche.
Deine Probleme mit den SQLite werden, wahrscheinlich einfacher Handelbar
wenn du eine Funktion schreibst die den Datenbank zugriff Kapselt.
imonbln hat Recht - in der jetzigen Form ist Dein Code (sorry!) echt
grauenhaft. Dass sich bei diesem Programmierstil irgendwo ein Fehler
einschleicht, ist kein Wunder; und dass Du dann Probleme hast, in diesem
Heuhaufen-Code den Stecknadel-Fehler zu finden, noch weniger.
Ich verstehe, dass Du primär einfach nur den Fehler finden willst; in
diesem speziellen Fall würde ich allerdings erst einmal die Codequalität
verbessern. Vor Allem:
- den Code drastisch kürzen, z.B. indem Du die ganzen redundanten Teile,
die sich immer wiederholen, und wo nur 1-2 Werte anders sind, in eigene
Funktionen auslagerst, denen diese Werte als Parameter übergeben werden.
Durch einen eleganteren Programmierstil solltest Du die Länge des Codes
locker auf die Hälfte oder sogar ein Viertel reduzieren können.
- die ganzen hartcodierten GPIO-Pin-Nummern durch Variablen mit
sprechenden Namen ersetzen
Eine Template-Engine wie jinja zu benutzen, betrachte ich persönlich
hingegen als nicht zwingend nötig. Kann man machen, würde den Code
natürlich auch noch kürzer und lesbarer machen - aber wenn Du die
HTML-Erzeugung in Funktionen auslagerst, dann geht es imho vorerst auch
so, ohne dass Du Dich erst noch mit einer Template-Engine
auseinandersetzen musst.
Ansonsten noch ein kleiner Tipp:
Wenn man ein Problem/einen Fehler finden will, dann ist es nicht gerade
hilfreich, möglicherweise auftretende Exceptions durch
1
try:
2
[...]
3
except:
4
print()
Konstruktionen einfach zu ignorieren...
p.s.: Wäre mal eine schöne Herausforderung, wer diesen Code in den
kürzesten/lesbarsten/elegantesten Code umschreiben kann.
imonbln schrieb:> laut meines Editor hat dein whz die zeile 12 mal, welche Zeile meinst> du?
try:
para = sys.argv[1]
state = para.split('&')
if (state[0] == '0'):
if (state[1] == '0'):
heat_off(0)
print('1/I wurde ausgeschaltet')
elif (state[1] == '1'):
heat_on(0)
print('1/I wurde eingeschaltet')
elif (state[1] == '2'):
connection = sqlite3.connect("database_whz.dB")
cursor = connection.cursor()
sql = "SELECT * FROM weichenheizung WHERE
name='whz1'"
test()
for dsatz in cursor:
cont0 = dsatz[1]
cont0 = int(cont0)
connection.close()
Ich schaue mal was sich machen lässt. Bin leider nicht der beste in
programmieren :-).
Könnte es sein das Simplehttpserver für Datenbanke Root rechte
brauchen. In der Sheel funktioniert es ohne probleme aber wenn es vom
Browser ausgeführt wird halt nicht. Bin gerade dabei mich in lighttpd
server einzuarbeiten
Charel P. schrieb:> Ich schaue mal was sich machen lässt. Bin leider nicht der beste in> programmieren :-).
Naja, Du hast halt offensichtlich einfach noch nicht viel
Programmier-Erfahrung. Vermutlich sahen die ersten Programmier-Versuche
auch bei guten Programmieren ähnlich aus, man erinnert sich nur nicht
mehr daran. :)
> Könnte es sein das Simplehttpserver für Datenbanke Root rechte> brauchen.
Halte ich tendenziell für unwahrscheinlich, dass das Problem daran
liegt.
Derzeit startest das run.py-Skript ja vermutlich ganz normal in der
Shell, mit Deinem gewöhnlichen User-Account.
> In der Sheel funktioniert es ohne probleme aber wenn es vom> Browser ausgeführt wird halt nicht.
Probier doch mal folgendes:
1. Eine schnelle und häufig ausreichende Methode, einen Fehler zu suchen
ist, einfach ein paar Debug-Ausgaben einzufügen; z.B. um zu schauen, ob
bestimmte Werte an einer bestimmten Stelle Deines Programms tatsächlich
genau den Wert haben, den Du erwartest, welche Alternative bei einer
if-Verzweigung tatsächlich genommen wurde etc.
Konkret würde ich vorschlagen, folgende Funktion in Deinen Sourcecode
einzubauen:
1
def debug_message(message):
2
print(message, file=sys.stderr)
und mal speziell die Variable "para" zu prüfen, ob die sowohl bei Aufruf
von der Shell als auch bei Aufruf per Webbrowser tatsächlich in beiden
Fällen exakt den gleichen Wert hat:
1
try:
2
para = sys.argv[1]
3
debug_message('para: "{}"'.format(para))
Weiterhin: Eventuelle Exceptions per
1
try:
2
[...]
3
except:
4
print()
einfach zu ignorieren ist selten eine gute Idee, aber ganz besonders
natürlich dann, wenn Dein Programm einen Fehler hat, den Du finden
willst.
Ersetze das wenigstens durch
1
except:
2
print("Error:", sys.exc_info()[0])
Ändere mal diese beiden Sachen, und führe das Skript dann mal mit
gleichen Parametern sowohl direkt von der Shell als auch per Webbrowser
aus, und schaue dann, ob sich in dem, was in der Shell ausgegeben wird,
etwas ändert.
Joachim S. schrieb:> debug_message('para: "{}"'.format(para))
Hab das getestet. Ich bekomme im Terminal als Fehler Syntax error.
Und ich hab heut nochmal mit der test funktion das Programm getestet.
Noch immer gleicher Fehler im try abzweig wo mit der Datenbank
gearbeitet wird bekomme ich immer dieser Fehler.
Bevor ich mot Datenbanken gearbeitet hatte, benutztete ich einfach
textdateien und dort waren auch sehr viele Fehler . Einmal ging es und
dann wieder nicht. Sollte ich nicht ein richtigen Server installieren
wie lighttpd oder apache?
Charel P. schrieb:> Joachim S. schrieb:>> debug_message('para: "{}"'.format(para))>> Hab das getestet. Ich bekomme im Terminal als Fehler Syntax error.
Aber vermutlich nicht an der von Dir zitierten Stelle. Sondern eher da:
1
print(message, file=sys.stderr)
Diese Anweisung funktioniert nämlich nur ab Python 3, während sie unter
Python 2 einen Syntax Error erzeugt. Ich tippe daher mal, dass Du das
Skript vermutlich noch mit Python 2 laufen lässt. Probiere also doch
einfach mal, das Skript stattdessen mit
1
python3 run.py
zu starten.
(EDIT: Nein, stimmt doch nicht - Dein run.py funktioniert eh nur unter
Python 3, Du scheinst run.py also durchaus mit python3 zu starten. Aber
die Richtung stimmt trotzdem:
Obwohl Du das run.py-Skript mit python3 startest, wird Dein
whz.py-Skript mit python2 gestartet - daher der Syntax Error in der
print(message, file=sys.stderr)-Zeile.
Lösung: Ändere die Shebang-Zeile am Anfang der Datei in:
1
#!/usr/bin/env python3
> Und ich hab heut nochmal mit der test funktion das Programm getestet.> Noch immer gleicher Fehler im try abzweig wo mit der Datenbank> gearbeitet wird bekomme ich immer dieser Fehler.
Welchen Fehler? Poste doch bitte mal die genaue Fehlermeldung/Ausgabe.
> Bevor ich mot Datenbanken gearbeitet hatte, benutztete ich einfach> textdateien und dort waren auch sehr viele Fehler .
Aber Fehler mit try: [...] catch: print() einfach zu ignorieren, ist
natürlich auch keine Lösung.
> Einmal ging es und> dann wieder nicht. Sollte ich nicht ein richtigen Server installieren> wie lighttpd oder apache?
Das ist auf Dauer sicherlich sinnvoll, weil der in Python integrierte
Webserver ja quasi eh nur gedacht ist, um mal schnell was zu testen,
ohne einen vollwertigen HTTP-Server einrichten zu müssen.
Ich bezweifle allerdings stark, dass Dein aktuelles Problem daher kommt,
dass Du stattdessen den SimpleHTTPServer benutzt; daher glaube ich auch
nicht, dass das alleine das jetziges Problem lösen wird.
In der phython sheel bekomme ich nichts. Im terminal wo ich run.py
starte, also jedes mal wenn die Webseite geladen wird steht die adresse
der webseite mit parameterübergabe und CGI ich mach morgen mal ein
Screenshot.
Zum Fehler von vornehin für die fehleranalyse bekomme ich Syntax error
line 200. Und wenn ich im Programm diese Zeile schaue ist es diese Code
von dir.
Mit den textdatei sowie mit der Sql wird das programm nicht mehr durch
geführt bzw. Manchmal bekomme ich auch als fehler broken Pipe. Wenn ich
dann paar mal mit der textdatei probieren dann geht es einwandfrei bis
ich den nächsten button einfüge. Dann gehen die ersten 3 dauerbetrieb
und der neue Button dauerbetrieb nicht mehr obwohl der Code richtig ist.
Deswegen hab ich das mit den textdateien gelassen und bin auf SQLite
gewechselt und dort die gleichen probleme.
Morgen wollte ich apache server installieren und das ganze über den cgi
ausführen oder über php python scripte ausführen.
Charel P. schrieb:> In der phython sheel bekomme ich nichts. Im terminal wo ich run.py> starte, also jedes mal wenn die Webseite geladen wird steht die adresse> der webseite mit parameterübergabe und CGI ich mach morgen mal ein> Screenshot.>> Zum Fehler von vornehin für die fehleranalyse bekomme ich Syntax error> line 200. Und wenn ich im Programm diese Zeile schaue ist es diese Code> von dir.
Die besagte Zeile hat aber nun mal keinen Syntax-Fehler. Der angebliche
Syntax-Fehler steckt wie gesagt vermutlich in der print(message,
file=sys.stderr)-Zeile; Zeile 200 wird Dir vermutlich nur angezeigt,
weil diese Zeile die debug_message()-Funktion aufruft, in der sich die
problematische print(message, file=sys.stderr)-Anweisung findet.
Und diese Anweisung ist wie gesagt nur Python 2 ein Syntax-Fehler.
Mal doch bitte einfach mal wie ich weiter oben geschrieben habe und
ändere die Shebang-Zeile in
1
#!/usr/bin/env python3
Ich wette, dann verschwindet dieser angebliche Syntax-Fehler in Zeile
200. Eventuell löst das sogar das eigentliche Problem, dass Dein Skript
im CGI-Modus nicht funktioniert, direkt aufgerufen aber schon.
So ich hab das heute geändert und bekomme jetzt keine Fehlermeldung
mehr. Aber der fehler bleibt dennoch.
Ich hab in der zwsichen zeit den Apache installiert und den cgi dort
freigeschaltet. Die Phyton datrien hab ich in den Ordner eingefügt. Die
startseite öffnet sich aber ohne css sehe nur den html code im browser.
Das Programm whz.py hab ich auch geöffnet aber lässt sich nicht öffnen.
Ich habe danach in der logdatei nachgeschaut und da stand dass ich die
root rechte nicht habe für die Gpio. Deswegeb wollte ich die config
dateien der Gpio mit chmod 775 bearbeiten das jeder user die rechte hat.
Fazit bei dem simplehttp server könnte es sein das der sql befehle nicht
bearbeiten darf wie hier mit den gpios? Gibt es bei simple auch ne log
datei ?
@TO: je länger ich dein Code betrachte desto mehr stelle ich mir die
Frage, wie das Hardware mässig klappen soll, dein Adressierung
Konfiguiert die Beiden Multiplexer 16-MUX und 8-MUX je nach eingebener
Adresse.
Aber der Wert an dem anderen Multiplexer bleibt ja gültig. Wie
verhinderst du das, dass Einstellen der Heizung zum an zwei Weichen
gesendet wird, oder beim Lesen zwei Eingägne gegeneinander treiben.
Entweder die entsprechenden Pins sind laut deines Kommentar wirklich nur
am 16-MUX, dann Funktioniert deine heat_* und image_* ab Adresse 16 aber
nicht, oder aber an den GPIOS kommen beide Multiplexer an, dann vermisse
ich aber eine Logik, welche das Abschalten des inaktiven Multiplexer in
der Funktion Adressierung macht.
imonbln schrieb:> @TO: je länger ich dein Code betrachte desto mehr stelle ich mir die> Frage, wie das Hardware mässig klappen soll, dein Adressierung> Konfiguiert die Beiden Multiplexer 16-MUX und 8-MUX je nach eingebener> Adresse.>> Aber der Wert an dem anderen Multiplexer bleibt ja gültig. Wie> verhinderst du das, dass Einstellen der Heizung zum an zwei Weichen> gesendet wird, oder beim Lesen zwei Eingägne gegeneinander treiben.>> Entweder die entsprechenden Pins sind laut deines Kommentar wirklich nur> am 16-MUX, dann Funktioniert deine heat_* und image_* ab Adresse 16 aber> nicht, oder aber an den GPIOS kommen beide Multiplexer an, dann vermisse> ich aber eine Logik, welche das Abschalten des inaktiven Multiplexer in> der Funktion Adressierung macht.
Also ich benutze im ganzen 5 verscheidene multiplexer :
2 multiplexer für zum Einschalten und ausschalten
3 Multiplexer für Rückmeldungen einmal Ein Aus und störung
Ein multiplexer besteht aus einem 8 Mux und 16 Mux im ganzen 24
adressen.
Ich kann also im ganzen 24 Weichenheizungen ansteuern.
Für die weichenheizung 1 wird die adresse der 5 Mux auf 0000 gestellt .
Mit dem einen button kann ich einschalten (funktioniert mit
paramterausgabe)
Mit dem anderen button kann ich ausschalten geht auch.
Den Dauerbetrieb button funktioniert nicht wegen sql.
3 rückmeldungen
Ich lese die ergebnisse von 3 multiplexer ein. Wenn 0 V füge ich eine
Led in die webseite ein die aus ist. Wenn 5V ist füge ich eine
leuchtende Led als bild ein. Ich lade in eine stunde ein blockschaltbild
mal hoch