38. Lektion: Webserver: Unterschied zwischen den VersionenAus Attraktor Wiki
Version vom 12. Februar 2024, 14:44 UhrInhaltsverzeichnisWebserverhttps://github.com/pimoroni/phew
Das Webserver Packet phew!Für den Raspberry Pi Pico W gibt es ein Packet, das alles enthält, was zur Einrichtung eines Webservers auf dem Pico erforderlich ist. Es heißt "phew" und ist von Github unter https://github.com/pimoroni/phew zu beziehen. Das Archiv muss entpackt und dann das Unterverzeichnis "phew" ins Filesystem des Pico kopiert werden.
Was phew! leistet:
Wo es möglich ist, versucht phew! die Menge an Code und Einstellungen, die Sie als Entwickler vornehmen müssen, zu minimieren, indem es vernünftige Standardeinstellungen wählt und einige Kleinigkeiten versteckt, die nur selten angepasst werden müssen. phew! installierenphew! kann mit pip von der Kommandozeile oder von Ihrer bevorzugten IDE aus installiert werden.
Wlan einrichtenUm einen Webserver betreiben zu können, müssen wir zuerst eine Verbindung zu einem Netzwerk herstellen. import network # Wlan Verbindung herstellen wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('ssid', 'key') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) Einfaches Wlan verbindenPhew bietet eine einfachere Möglichkeit die Verbindung zum Wlan herzustellen: >>> from phew import server, connect_to_wifi >>> connect_to_wifi("Attraktor", "blafablafa") '192.168.5.120' Es eine Funktion get_ip_address(). Sie muss aber erst importiert werden: >>> from phew import get_ip_address >>> get_ip_address() '192.168.5.120' Alternatv kann man die IP-Adresse auch gleich beim Connecten speichern: >>> from phew import server, connect_to_wifi >>> ip_adresse = connect_to_wifi("Attraktor", "blafablafa") >>> ip_adresse '192.168.5.120' Den Webserver benutzenStartenDer Webserver wird einfach gestartet. Es ist keine großartige Konfiguration erforderlich. Allerdings müssen vorher noch die Webseiten und ihre Routen definiert werden. from phew import server # hier werden die auszuliefernden Webseiten definiert. Siehe nächste Codebox. server.run() Einfaches BeispielEin Beispiel-Webserver, der auf Anforderung eine Zufallszahl zwischen 1 und 100 (oder optional den vom Aufrufer angegebenen Bereich) zurückgibt: from phew import server, connect_to_wifi connect_to_wifi("<ssid>", "<password>") @server.route("/random", methods=["GET"]) def random_number(request): import random min = int(request.query.get("min", 0)) max = int(request.query.get("max", 100)) return str(random.randint(min, max)) @server.catchall() def catchall(request): return "Not found", 404 server.run() Nach dem Start des Servers ist der Pico blockiert. Code der nach server.run() steht wird nicht mehr ausgeführt!
Webseiten routenUm Webseiten zu erstellen wird zum Einen eine Funktion benötigt, die die Webseite als Rückgabewert zurück gibt und zum Zweiten muss diese Funktion dem Webserver als Route bekannt gemacht werden.
Mit Decorator:Ein Decorator ist ein Konzept, dass eine Funktion dekoriert. D.h. Er ergänzt die Funktion, fügt also eine zusätzliche Funktionalität hinzu.
@server.route("/random", methods=["GET"]) def random_number(request): import random min = int(request.query.get("min", 0)) max = int(request.query.get("max", 100)) return str(random.randint(min, max)) Mit Route-Tabelle:# Webseiten definieren def random_number(request): import random min = int(request.query.get("min", 0)) max = int(request.query.get("max", 100)) return str(random.randint(min, max)) def info_site(request): return "<h1>Infoseite vom Raspberry Pi Pico W</h1>" # Routing Tabelle server.add_route("/random", random_number, methods=["GET"]) server.add_route("/info", info_site, methods=["GET"]) Webseiten erstellenEine Webseite wird erstellt indem eine Funktion definiert wird, die den Inhalt des Response zurück gibt. Der Funktion muss request übergeben werden. @server.route("/test", methods=["GET"]) def test_seite(request): version = '1.0.0' return f"Aktuelle Version {version}", 200 Response erzeugenDer Response ist ein String der alle Informationen enthält die an den Client zurückgegeben werden sollen.
Einfacher TextHier steht hinter return ein String, der den Response enthält. Dieser kann, aber muss nicht, HTML-Auszeichnungen enthalten. Es kann ein kurzer Text sein, oder auch eine umfangreiche Webseite mit HTML-Header und -body. Als zweites Argument kann der HTTP-Code angegeben werden. @server.catchall() def catch_all(request): return "<h1>Hallo, diese Webseite gibt es nicht!</h1>", 404 # oder mit f-string: @server.route("/test", methods=["GET"]) def test_seite(request): version = '1.0.0' return f"Aktuelle Version {version}", 200 # oder mit einer Funktion: @server.route("/random", methods=["GET"]) def random_number(request): import random min = int(request.query.get("min", 0)) max = int(request.query.get("max", 100)) return str(random.randint(min, max)) In einer Variablen@server.route("/info", methods=["GET"]) def info_seite(request): content = ''' <html> <header> .... </header> <body> .... </body> </html> ''' return content, 200 Aus einer DateiUm den Response aus einer Datei zurück zu geben gibt es die Funktion render_template().
from phew.template import render_template HTDOCS = 'htdocs/' @server.route("/test", methods=["GET"]) def test_site(request): return render_template(HTDOCS + "html-test_001.html") Aus einer Datei mit EinfügenUm in eine HTML-Seite zusätzliche Informationen einzufügen kann man die üblichen Stringformatierungsmethoden von Micropython verwenden.
Mit .format():Mit f-string:Phewphew! bietet aber noch eine eigene Methode (emplate Expression) um Inhalte in Dateien einzufügen. Dazu werden in den HTML-Text doppelte geschweifte Klammern eingefügt, die den Namen der Variablen enthalten, deren Wert hier eingefügt werden soll: <h1>Micropython Demoboard Temperatur</h1> Dieses ist eine kleine HTML-Testseite. <br> Temperatur vom BME280: {{temp}} °C <br> Noch ist es nur ein einfacher Test! Beim schreiben der Template-Seite muss darauf geachtet werden, dass für Sonderzeichen und Umlaute HTML-Code geschrieben wird. UTF-8 führt heir zu ungewünschten Ausgaben.
Wenn die Seite nicht existiertDer Server gibt üblicherweise die der Route zugeordnete Webseite zurück. Wenn eine Webseite angefordert wird, die nicht existiert, wird die Servermethode catchall() aufgerufen. @server.catchall() def catch_all(request): return "<h1>Hallo, diese Webseite gibt es nicht!</h1>", 404 # oder aus einer Datei in /htdocs: HTDOCS = 'htdocs/' @server.catchall() def catch_all(request): return render_template(HTDOCS + 'error_404.html') Daten an den Server übergeben
LagerBeispielDie verschiedenen Return-Methoden ausprobierenHier gibt es ein Programm, das den phew-Server einrichtet und einige Seiten mit verschiedenen Return-Methoden bereitstellt. Welche Seiten abgerufen werden können ist unter IP/info abrufbar. # webserver_002.py # # V.0.0.1 # 07.12.2023 # Peter Stöck # # Hier werden die verschiedenen Returnmethoden getestet. from phew import server, connect_to_wifi from phew.template import render_template # Konstanten und Variablen HTDOCS = 'htdocs/' ip_adresse = None SSID = 'Attraktor' PW = 'blafablafa' # Wlan Verbindung herstellen ip_adresse = connect_to_wifi(SSID, PW) print(ip_adresse) # Websiten erstellen @server.route("/string1", methods=["GET"]) def string1(request): return str(42) + ' ist string1' @server.route("/string2", methods=["GET"]) def string2(request): return '''<h1>Infoseite vom Raspberry Pi Pico W</h1><br> Dieses ist string2''' @server.route("/string3", methods=["GET"]) def string3(request): return render_template(HTDOCS + "html-test_002.html") @server.route("/var", methods=["GET"]) def var(request): content = 'Hallo, ich komme aus einer Variablen' return content @server.route("/hallo/<name>", methods=["GET"]) def hallo(request, name): return f"Hallo {name}!" @server.route("/info", methods=["GET"]) def string3(request): content = ''' <h1>Infoseite vom phew-Server</h1> Folgende Seiten sind abrufbar:<br> /string1<br> /string2<br> /string3<br> /var<br> /hallo/Hier Name eingeben<br> /info - diese Seite<br> ''' return content @server.catchall() def catch_all(request): return "<h1>Hallo, diese Webseite gibt es nicht!</h1><br>Sie steht für catch_all.", 404 # Server starten - nun geht nichts anderes mehr:( server.run() Hier die Datei html-test_002.html. Sie muss in das Verzeichnis htdocs kopiert werden. <h1>Überschrift</h1> Dieses ist eine kleine HTML-Testseite. <br> Sie steht für string3 <br> Noch ist es nur ein einfacher Test! Ein praktisches BeispielDieses Programm ermöglicht es die LED ein-/auszuschalten und die Sensoren abzufragen. # webserver_003.py # # Version 0.0.1 # 07.12.2023 # Peter Stöck # # Dieses Programm hat folgende Funktionen: # LED ein- und ausschalten # from phew import server, connect_to_wifi from phew.template import render_template from machine import Pin # Konstanten und Variablen HTDOCS = 'htdocs/' ip_adresse = None pin_von_led = 22 SSID = 'Attraktor' PW = 'blafablafa' # Led aktivieren led_pin = Pin(pin_von_led, Pin.OUT) led_pin.value(0) # Wlan Verbindung herstellen ip_adresse = connect_to_wifi(SSID, PW) print(ip_adresse) # Webseiten erstellen @server.route("/led/<led_status>", methods=["GET"]) def led_ctrl(request, led_status): if led_status == 'ein': led_pin.value(1) elif led_status == 'aus': led_pin.value(0) else: return "<h1>Hallo, diese Funktion gibt es nicht!</h1>", 404 return f"LED wurde {led_status}geschaltet." @server.catchall() def catch_all(request): return "<h1>Hallo, diese Webseite gibt es nicht!</h1>", 404 # Server starten - nun geht nichts anderes mehr:( server.run() HTML-Seiten mit Daten ergänzenMeistens möchte man nicht nur eine statische HTML-Seite ausgeben, sondern z.B. Sensordaten übertragen. Beim Micropython Demoboard könnte es die Temperatur vom BME280 Sensor sein.
from phew.template import render_template HTDOCS = 'htdocs/' temperatur = 23 text = render_template(HTDOCS + "temp2.html", temp=str(temperatur)) for i in text: print(i) Das Ergebnis: b'<h1>Micropython Demoboard Temperatur</h1>\nDieses ist eine kleine HTML-Testseite.\n<br>\nTemperatur vom BME280: ' 23 b' \xc2\xb0C\n<br>\nNoch ist es nur ein einfacher Test!' Phew erzeugt den HTML-Code nicht für die ganze Seite im Stück, sondern erzeugt kleine Blöcke, so dass der Speicherbedarf reduziert wird. Beim schreiben der Template-Seite muss darauf geachtet werden, dass für Sonderzeichen und Umlaute HTML-Code geschrieben wird. UTF-8 führt heir zu ungewünschten Ausgaben. <h1>Micropython Demoboard Temperatur</h1> Dieses ist eine kleine HTML-Testseite. <br> Temperatur vom BME280: {{temp}} °C <br> Noch ist es nur ein einfacher Test! Für das °-Zeichen muss im HTML-Code ° stehen! Das Wiki macht daraus automatisch °! Deshalb konnte ich es im Codeblock nicht richtig darstellen. Lager
Zurück zur "Micropython Kurs 2023 Teil 2" Startseite |