Variablenübergabe von Website in Python Programm

  • Für eine Projektarbeit ist das "Endziel" mit einem Raspberry Pi vorbeifahrende Objekte auf dem Fließband zu erkennen und darauf eine Eintrag in eine externe SQL-Datenbank zu schreiben und dabei Parameter über eine Website zu ändern.
    Sowohl Programm, als auch die Anbindung an die SQL-Datenbank stehen und funktionieren reibungslos.
    In Sachen Website und Parameterübergabe habe ich allerdings nichts befriedigendes gefunden.

    Im Programm sind 9 Parameter, die verändert werden müssen. Darunter Strings, ints und booleans. Auf der Website sollen später Textfelder und Checkboxes zum einstellen der Parameter sein, sowie jeweils ein Knopf zum Starten und Beenden des Programms.
    Die Parameter werden also nicht im laufenden Betrieb geändert.

    Wie kann ich also die eingestellten Parameter auf der Website beim Programmstart an das PythonProgramm übergeben. Als Keywords bin ich schon auf php gestoßen, bin damit aber auf keinen Lösungsweg gekommen.

    Für Hilfe jeglicher Art wäre ich dankbar :)

  • Vielen Dank für den Link :)
    Nehme ich die html aus dem Beispiel und passe sie auf meine Bedürfnisse an, kann ich so über die Website den Erkennungsprozess starten.
    Allerdings tun sich mir noch Fragen auf, für die ich nach ein paar Stunden keine Antwort gefunden habe.

    - Wie kann ich den commands des WebRequesthandlers einen Parameter mitgeben? (websocket_send('Messung_Starten')
    oder kann ich aus dem PythonScript direkt auf das html zugreifen?
    - Wie kann ich für diesen Parameter den Inhalt eines Textfeldes benutzen?

  • Du musst schon das gesamte Konstrukt verwenden, nicht nur die *.html

    apache2 oder nginx oder was auch immer du bisher genutzt hast kannst du deinstallieren/löschen. Mit der Anleitung nutzt du ausschließlich python, kein php oder apache2.

    Lies dir die Anleitung noch mal in Ruhe durch, ggf auch den Beitrag zur Erweiterung (siehe hinter dem Eintrag in der Linksammlung: "eine Erklärung zur eigenen Erweiterung" und #2 ist noch ein Link)

  • Ich habe meine Website ist inzwischen gebaut und gewünschte Parameter des Pythonscripts in eine .csv ausgelagert. Diese werden dann bei jedem start der Messung eingelesen. Nun versuche ich seit Stunden mittels JavaScript diese csv in ein array einzulesen und dann die einzelnen Einträge in die Textfelder beim Websiteaufruf einzutragen. Leider habe ich keine Lösung gefunden. Mit Jquery und Ajax kann ich zwar eine txt bzw csv einlesen, aber keine, die auf dem Raspberry lokal liegt, sondern nur, wenn diese auf einem Server liegt. Gibt es denn keine Möglichkeit das zu lösen?

  • Nu denk doch mal nach... Wenn man vom Client aus mit JS eine beliebige Datei von außerhalb des Server-Roots laden könnte, wäre dies fatal!
    Nein, der Server gibt dir nur Dateien zurück, die innerhalb der (Server-) Rootstruktur vorhanden sind. Evtl. kann man aber serverseitig die Datei auslesen und zurückgeben. Was spricht denn nun dagegen, alle benötigten Dateien im Server-Verzeichnis zu speichern, wie es sich eigentlich gehört?

    LG

  • Hallo,

    JS kann vom Browser aus nicht lesend auf das lokale Dateisystem zugreifen. Jedenfalls nicht so, wie du das gerne hättest. Warum hat linusg ja schon erklärt.

    Wenn du Werte in den Formularfeldern vorbelegen willst, dann machst du das serverseitig, indem die zum Erstellen der Seite eine Template Engine benutzt. Die meisten Webframeworks haben eine an Bord, ansonsten ist Jinja2 unter Python sehr populär.

    Was natürlich auch ginge wäre, dass der Nutzer eine CSV-Datei auf den Server lädt, diese dort verarbeitet wird und so die Formularfelder vorbelegt werden.

    Gruß, noisefloor

  • Das machst Sinn :) Ja es ist kein Problem die Datei in das Serververzeichnis zu speichern. Wo befindet sich denn das Root Verzeichnis? Bei Apache ist es ja usr/www. Ich nutze Bottle, wie in meigrafds Tutorial. Auslesen würde ich sie mit folgendem JavaScript. Chrome meldet aktuell, die Datei wäre nicht auffindbar. Hatte sie in das gleiche Verzeichnis, wie die index-html gelegt.


    Code
    function csvRead(){
    
    
      var Parameter = []
      $.get('./Parameter.csv', function(data){
      Parameter=jquery.csv("/n")(data);
      });
      
    }

    Einmal editiert, zuletzt von JanFrederick (22. Mai 2017 um 11:44)

  • Vor mehr als 40 Jahren hat man das noch simpel und effektiv gemacht:
    Programm 1 schreibt die Patameter in ein File,
    Programm 2 liest die Parameter aus diesem File.
    Dabei wurde vorrausgesetzt, dass der "Programmierer" die User- und Gruppenverwaltung von Unix kennt.


    Servus !

    RTFM = Read The Factory Manual, oder so

  • Hallo,

    Zitat

    Vor mehr als 40 Jahren hat man das noch simpel und effektiv gemacht:


    Vor 40 Jahren hat man doch gestanzte Lochkarten per Rohrpost verschickt, oder? *SCNR*

    Zurück zum Thema:
    JanFrederick: WSGI-Appliktion kennen kein Root-Verzeichnis wie beim Webserver. Jedes Webframework hat aber in der Regel eine Konvention / best practice, wo statische bzw. hochgeladene Dateien liegen sollen.

    Das JavaScript, dass du gepostet hast, macht so IMHO auch wenig Sinn...

    Gruß, noisefloor

  • In meiner Anleitung wird das im 1.Abschnitt beschrieben:

    Zitat


    Jedes mal wenn ihr die Seite aufruft (ladet) ändert sich der "Test: xxx" Text, also beim ersten Aufruf steht da zB. "Test: 970", drückt ihr dann F5 (reload) steht da "Test: 160" usw. Was da passiert wurde zuvor im Script festgelegt: Beim generieren/rendern des templates wird die Variable "test" in den HTML Code eingesetzt.
    Das kann man für Statische Informationen verwenden wie zum Beispiel Variablen für JavaScript die man nicht unbedingt fest (hardcoded) in den HTML Code einbauen möchte, sondern bequemer nur das Python Script anpassen brauch... Oder eine Debug-Ausgabe von JavaScript die ihr nur bei Bedarf einschaltet, oder einsetzen einer Versionsnummer etc..

    Bau dir einfach eine Funktion zum auslesen und aufbereiten deiner csv Datei und binde das dann entsprechend in MainHandler() o.ä. ein.

    Alternativ ginge auch sowas (siehe index.html) aber das ist IHMO eher unschön ;)


  • In meiner Anleitung wird das im 1.Abschnitt beschrieben:


    Bau dir einfach eine Funktion zum auslesen und aufbereiten deiner csv Datei und binde das dann entsprechend in MainHandler() o.ä. ein.

    Alternativ ginge auch sowas (siehe index.html) aber das ist IHMO eher unschön ;)

    Genau das habe ich gemacht. Funktioniert soweit auch :):D :thumbs1:

    Allerdings, habe ich momentan immer die Fehlermeldung
    Traceback (most recent call last):
    File "web_bottle.py", line 148, in <module>
    ws.join(1)
    NameError: name 'ws' is not defined

    ws.join(1) ist ganz am ende.

    Das Programm funktioniert jedoch reibungslos. Sowohl Website, als auch daraus gestartete andere Scripte.
    Nur das Terminal wird davon leider blockiert.


    Wenn ich nun die Felder aus meinem HTML auslesen möchte, nutze ich dann den bottle.request Befehl?

  • JanFrederick
    So ein Gebastel kann gar nicht funktionieren.
    Ich würde mich zu erst mal den Grundlagen von Python widmen und dann für ein Rahmenwerk entscheiden, welches deinem Vorhaben entspricht. Das hier ist pure Grausamkeit.

    Edit:
    Wenn du ein Rahmenwerk mit Websocket Unterstützung brauchst (für was auch immer), dann schau dir Tornado an.

  • Dass das Terminal blockiert wird ist klar, es wird ja auch gewartet bis der Prozess bzw das Script beendet wird.... Sofern du das Script dann dauerhaft einsetzen willst musst du es halt automatisch starten lassen.

    Was mich aktuell ein bisschen verwundert ist, warum du "threading" und "multiprocessing" verwendest? Zeig bitte mal dein MCP3008Auslesen Script.

    Auch das WirrWarr ganz oben mit den import Zeilen sowie dem völlig überflüssigen "global gestartet" in der WebRequestHandler() Funktion offenbaren das Du dich intensiver mit Python beschäftigen musst - sorry wenn das zu hart klingt, ich trauere grad meiner sooo schönen Vorlage nach ;)
    Die Einrückungen inkl. und nach "global gestartet" sind ebenfalls fehlerhaft - für Python sind Einrückungen extrem wichtig.
    ...Immer wieder taucht"global" auf... *würg*
    Die Einrückungen in allen anderen Funktionen / routes sind ebenfalls defekt.
    Ich kann mir da nicht vorstellen dass das ein Copy&Paste Problem ist, das säh anders aus... Das sieht mir vielmehr nach einer bunten Mischen zwischen Leerzeichen und Tabs aus wobei die Tabs beim Einfügen nicht mitgekommen sind... Das ist ebenso fatal, das bunte mischen. Gewöhne dir 4 Leerzeichen pro Einrückung an - kann man in jedem guten Editor einstellen.

    Das nächste was auffällt: Deine 2 for's in der MainHandler() kann man besser machen ;) Und absolute Pfade zur *.csv wären ebenfalls angebracht - guck dir dazu mal Zeile 130 des originals an, da wird auch ein absoluter Pfad fürs 'templates' Verzeichnis erzeugt.

    Deine index.html enthält leider auch einige Fehler, wie zum Beispiel das nicht schließen der <label oder <input 's.. Wo ein < da muss auch ein > sein. Mag sein das es derzeit trotzdem zu funktionieren scheint, aber dann nur weil dein Browser sich quält - werf maln Blick in die Browser-Console = F12
    Ich entdecke auch einige Fehler beruhend auf falsche Leerzeichen, zB:

    Code
    id ="sqlFalse"name="SQL"

    Allgemein solltest du dir in HTML angewöhnen keine Leerzeichen zwischen Setting und = sowie Value zu setzen:

    Code
    id="sqlFalse" name="SQL"

    Last but not least: Bist du wirklich sicher das du WebSocket unbedingt benötigst? Ich sehe aktuell kein Grund wieso du unbedingt WS haben musst :s

  • Hallo,

    als erstes würde ich - unabhängig vom Webteil - das Einlesen der CSV-Datei gerade rücken. Das du die Instanz des Readers in `portofoil_list` packst sieht ziemlich falsch aus, dass du daraus `names` ableitest überflüssig und `newlist` wird gar nicht verwendet.

    Wenn das funktioniert kannst du das an eine Route binden.

    Gruß, noisefloor

  • Ich bin dankbar für Kritik. Mein allgemeinen Programmierkenntnisse sind vorhaden, aber nicht sonderlich ausgeprägt. Python und Webinterfaces sind komplettes Neuland für mich. Sachen, wie "global gestartet" habe ich eingefügt, dass der Prozess nicht zweimal startet. Multiprozess habe ich genutzt, um die Endlosschleife des MCP3008Auslesen.py auszuführen und trotzdem web_Bottle.py nicht zu blockieren. Ich habe mir das "ergoogelt" und es hat funktioniert. Geht vermutlich auch mit Thread.

    MCP3008 Code:


    Zum Schreiben nutze ich den Geany Editor des Raspberry

    Ja das Einlesen der *.csv habe ich gekürzt ::) Den absoluten Pfad füge ich noch ein. Muss ich mich kurz informieren, was ich da tue ::)

    Ob ich WebSocket brauche weiß ich nicht. Da ich neu bin, habe ich mich durch dein Tutorial gearbeitet und gedacht: "Ja das könnte funktionieren". Falls es eine elegantere Lösung gibt bin ich offen für Vorschäge. Es sollen nur möglich sein die Messung zu starten, stoppen, und die Parameter zu ändern, ohne direkt über ssh, direkt oder vnc Viewer verbunden zu sein.

    Ich habe mal deine Web_bottle.py laufen lassen und es kommt der selbe fehler mit ws.join() wie im vorherigen post.

    HTML:

    Meine web_bottle

    noisefloor

    okay :) Danke für den Tipp. Werd ich mir morgen mal anschauen.


    p.S. Der Fehler kam , weil ich den Server automatisch beim booten gestartet habe und ich ihn somit nicht nocheinmal öffnen kann :wallbash:

    Einmal editiert, zuletzt von JanFrederick (23. Mai 2017 um 14:38)

  • Wenn selbst du nicht weißt ob WebSocket überhaupt benötigt wird, dann nutze die 3. Variante von meiner Anleitung ;)

    Die Einrückungen sind noch immer defekt und sorgen dafür dass das Script nicht ordnungsgemäß funktioniert. Wie gesagt sind Einrückungen für Python extrem wichtig. Solange du das nicht gefixt hast wirst du kein zufriedenstellendes Ergebnis erhalten. Auch dein MCP3008Auslesen Script scheint davon getroffen zu sein.

    FAQ => Nützliche Links / Linksammlung => HowTo: CODE / PHP Code im Forum posten

    Stell erst mal auf die 3. Variante um, poste den Code (oder den codepad Link dafür) erneut und dann sehn wir weiter

Jetzt mitmachen!

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