GPIOs über einen Webserver mit Python steuern

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Liebe Community,

    ich bin seit einiger Zeit dabei einen Webserver zur Steuerung der Garage zu programmieren. Ich nutze dafür Flask und Jinja und leider komme ich nicht mehr weiter. Ich habe einen Türkontakt an meinem Garagentor. Dieser soll über GPIO 24 seinen Status an den Raspberry Pi übermitteln und auf dem Webserver angezeigt werden. Auf der Website gibt es einen Button. Auf ihm steht "auf" wenn das Garagentor zu ist und "zu" wenn das Garagentor auf ist. Wenn man auf diesen Button klickt, soll auf dem Output (GPIO 23) ein Impuls erfolgen, der das Garagentor öffnet. Der "Refresh" Button ist für eine spätere Schnittstelle von einem Temperatursensor. Ich habe mein Programm mithilfe von diesem Beispiel geschrieben. Hier die Fehlermeldung

    Code
      File "/home/pi/web-server/app.py", line 18
        def main():
        ^
    SyntaxError: invalid syntax

    Dies ist der Python Code

    Hier main.html

  • Moinsen,

    Weil zwischen Zeile 13 und 14 eine schließende Klammer fehlt :baeh2:

    Franky

    Vielen Dank! Nun kommt keine Fehlermeldung mehr. Leider wird der Button nicht richtig angezeigt und es kommt zu keiner Reaktion wenn ich den Input aendere. Der Output funktioniert, weil der gleiche Button sich nicht aktualisiert

  • gummiangler: Anmerkungen zum Quelltext:

    ``as`` beim importieren ist zum umbenennen, `GPIO` wird aber gar nicht umbenannt.

    `request` wird importiert, aber nirgends verwendet.

    Eingrückt wird in Python vier Leerzeichen pro Ebene.

    `main()` ist traditionell der Name für die Hauptfunktion, die hier fehlt, aber vorhanden sein sollte, denn auch bei einer Webanwendung sollte man die globalen Variablen auf ein Minimum reduzieren und eine Hauptfunktion verwenden statt so etwas auf Modulebene zu schreiben.

    `pins` hat *so* auf Modulebene nichts zu suchen. Dort sollten nur Konstanten, Funktionen, Klassen definiert werden.

    Die Datenstruktur ist auch etwas unsinnig, weil immer über die Schlüssel iteriert wird um dann mit dem Schlüssel auf den Wert zuzugreifen. Also eigentlich will man hier immer nur die Werte, aber nirgends wird wirklich sinnvoll über den Schlüssel zugegriffen. Das ist also eher eine Liste mit Wörterbüchern, und die Pin-Nummer ein weiterer Wert in diesen Wörterbüchern.

    Die Pin-Nummern sollten auch nicht hart kodiert an mehreren Stellen im Quelltext stehen, sondern als Konstanten definiert werden. Zumindest dem Ausgabe-Pin kann man dann auch gleich einen sinnvollen Namen geben, der dem Leser verrät wofür der Verwendet wird.

    Es ist wichtig vor dem Programmende `GPIO.cleanup()` aufzurufen.

    In den beiden Routen wiederholt sich der Code zum Auslesen der Eingabepins. So etwas vermeidet man als Programmierer und schreibt dafür eine Funktion, die von beiden Routen aufgerufen werden kann.

    Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

    `templateData` als Zwischenergebnis ist hier unnötig umständlich.

    `changePin` und `message` werden definiert, aber nirgends verwendet.

    Die `action()`-Route macht bei "on" und bei "off" genau das gleiche. Sicher so nicht gewollt.

    Man sollte auch darauf reagieren falls dort etwas anderes als "on" oder "off" rein kommt.

    Das HTML ist auch ein bisschen kaputt und nicht sinnvoll eingerückt. Und die Eingabepins und der Ausgabepin — das funktioniert so auch nicht. Das Argument wird ja auch ignoriert, was auch gut so ist.

    Ungetestet:

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • gummiangler: Anmerkungen zum Quelltext:

    ...

    Vielen Dank für deine Antwort. Da ich gerne in Python programmiere wollte ich meinen Raspberry Pi mal selbst programmieren und keine App aus dem Store dafür verwenden. Ich kenne mich mit Flask und Jinja nicht besonders gut aus, sodass ich folgendes als Vorlage verwendet habe:

    Servieren von Raspberry Pi mit Flask - Matt Richardson, Creative Technologist

    Folgendes ist meine Anwendung (Erklärung zu doppelten on/off)

    Mein Garagentor benötigt zum Öffnen und Schließen einen Impuls. Da man über einen Impuls den Zustand des Gragentors nicht danach abfragen kann, habe ich über die GPIOS einen einfachen HIGH/LOW Türkontakt angeschlossen. Ich möchte nun auf eine Website (IP des Raspi) gehen und dort wird der Zustand des Garagentors angezeigt und der Button an diesen angepasst. Falls man nun auf diesen Button klickt, wird ein Impuls ausgelöst, welcher dazu führt, dass sich der Zustand des Garagentors ändert. Nun soll sich auch nach einer festgelegten Zeit (5 sek.) der Button und die Zustandsanzeige des Garagentors auf den aktuellen (neuen) Zustand ändern. So soll das immer weiter gehen. Falls sich der Zustand anders ändert (in der Garage ist ein Schalter), soll der Wechsel erkannt und der Zustand auf der Website aktualisiert werden.

    Das Programm funktioniert soweit, bis auf einen Punkt:

    Sobald ich auf einem Gerät zum ersten mal den Button aktiviere, wechselt er von 000.000.000.00/00 auf 000.000.000.00/00/on

    Wenn ich nun also die Seite neu lade (Ich kriege es nicht hin, dass er sie von selbst nach Zustandswechsel neu lädt), wird ein weiterer Impuls gesendet, da wieder die .../on Seite aufgerufen wird. Der off Button funktioniert dann nicht mehr.

  • Da beide Buttons letztlich das selbe machen, würde ich da nur einen Button darstellen. Was Du dann noch brauchst ist eine Route, die den Türkontakt liefert und die von der Client-Seite, also JavaScript im Browser regelmässig abgefragt wird, um den Zustand dieses Kontakts darzustellen.

    Man könnte auch Websockets statt regelmässig Status abfragen verwenden, dann wird das aber komplexer.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

Jetzt mitmachen!

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